summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Williams <nico@cryptonector.com>2014-12-24 11:18:53 -0600
committerNicolas Williams <nico@cryptonector.com>2014-12-24 11:21:18 -0600
commit0053aa868ca4082847523c677591f6817e04b961 (patch)
treee6ba59ceb11943287056c0f5880bb4fafa624c53
parentfab20486489e871863adbce56568edb381238ed0 (diff)
Add @tsv; fix #645
-rw-r--r--builtin.c23
-rw-r--r--docs/content/3.manual/manual.yml5
-rw-r--r--tests/all.test19
3 files changed, 32 insertions, 15 deletions
diff --git a/builtin.c b/builtin.c
index 2d345fc7..1fef9a17 100644
--- a/builtin.c
+++ b/builtin.c
@@ -334,7 +334,7 @@ static jv escape_string(jv input, const char* escapings) {
const char* cstart;
int c = 0;
while ((i = jvp_utf8_next((cstart = i), end, &c))) {
- assert(c != -1);
+ assert(c > 0);
if (c < 128 && lookup[c]) {
ret = jv_string_append_str(ret, lookup[c]);
} else {
@@ -358,13 +358,24 @@ static jv f_format(jq_state *jq, jv input, jv fmt) {
} else if (!strcmp(fmt_s, "text")) {
jv_free(fmt);
return f_tostring(jq, input);
- } else if (!strcmp(fmt_s, "csv")) {
+ } else if (!strcmp(fmt_s, "csv") || !strcmp(fmt_s, "tsv")) {
+ const char *quotes, *sep, *escapings;
+ if (!strcmp(fmt_s, "csv")) {
+ quotes = "\"";
+ sep = ",";
+ escapings = "\"\"\"\0";
+ } else {
+ assert(!strcmp(fmt_s, "tsv"));
+ quotes = "";
+ sep = "\t";
+ escapings = "\t\\t\0";
+ }
jv_free(fmt);
if (jv_get_kind(input) != JV_KIND_ARRAY)
return type_error(input, "cannot be csv-formatted, only array");
jv line = jv_string("");
jv_array_foreach(input, i, x) {
- if (i) line = jv_string_append_str(line, ",");
+ if (i) line = jv_string_append_str(line, sep);
switch (jv_get_kind(x)) {
case JV_KIND_NULL:
/* null rendered as empty string */
@@ -383,9 +394,9 @@ static jv f_format(jq_state *jq, jv input, jv fmt) {
}
break;
case JV_KIND_STRING: {
- line = jv_string_append_str(line, "\"");
- line = jv_string_concat(line, escape_string(x, "\"\"\"\0"));
- line = jv_string_append_str(line, "\"");
+ line = jv_string_append_str(line, quotes);
+ line = jv_string_concat(line, escape_string(x, escapings));
+ line = jv_string_append_str(line, quotes);
break;
}
default:
diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml
index cf78c7cd..929d18f2 100644
--- a/docs/content/3.manual/manual.yml
+++ b/docs/content/3.manual/manual.yml
@@ -1454,6 +1454,11 @@ sections:
with double quotes for strings, and quotes escaped by
repetition.
+ * `@tsv`:
+
+ The input must be an array, and it is rendered as TSV
+ with tabs escaped as `\t`.
+
* `@sh`:
The input is escaped suitable for use in a command-line
diff --git a/tests/all.test b/tests/all.test
index 8d27d331..e91810f0 100644
--- a/tests/all.test
+++ b/tests/all.test
@@ -61,15 +61,16 @@ null
null
"interpolation"
-@text,@json,([1,.] | @csv),@html,@uri,@sh,@base64
-"<>&'\""
-"<>&'\""
-"\"<>&'\\\"\""
-"1,\"<>&'\"\"\""
-"&lt;&gt;&amp;&apos;&quot;"
-"%3C%3E%26'%22"
-"'<>&'\\''\"'"
-"PD4mJyI="
+@text,@json,([1,.] | (@csv, @tsv)),@html,@uri,@sh,@base64
+"<>&'\"\t"
+"<>&'\"\t"
+"\"<>&'\\\"\\t\""
+"1,\"<>&'\"\"\t\""
+"1\t<>&'\"\\t"
+"&lt;&gt;&amp;&apos;&quot;\t"
+"%3C%3E%26'%22%09"
+"'<>&'\\''\"\t'"
+"PD4mJyIJ"
# regression test for #436
@base64