add -r flag to allow printing all control-characters - json2tsv - JSON to TSV c… | |
git clone git://git.codemadness.org/json2tsv | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 33d5e77ed74ebe2ac9495ca3f4dbde493b26b69f | |
parent a8950873f2e40fe767530b8e58b723c8b56abc33 | |
Author: Hiltjo Posthuma <[email protected]> | |
Date: Tue, 5 Nov 2019 20:46:45 +0100 | |
add -r flag to allow printing all control-characters | |
No performance change with -O2 or higher with gcc or clang using no flags set. | |
Minor tweaks: | |
- rename showindices to nflag variable. | |
- reword and improve formatting of man page. | |
- improve parsing of options. | |
Diffstat: | |
M json2tsv.1 | 24 ++++++++++++++++-------- | |
M json2tsv.c | 21 ++++++++++++++++----- | |
2 files changed, 32 insertions(+), 13 deletions(-) | |
--- | |
diff --git a/json2tsv.1 b/json2tsv.1 | |
@@ -1,4 +1,4 @@ | |
-.Dd October 20, 2019 | |
+.Dd November 5, 2019 | |
.Dt JSON2TSV 1 | |
.Os | |
.Sh NAME | |
@@ -7,13 +7,19 @@ | |
.Sh SYNOPSIS | |
.Nm | |
.Op Fl n | |
+.Op Fl r | |
.Sh DESCRIPTION | |
.Nm | |
reads JSON data from stdin. | |
It outputs each JSON type to a TAB-Separated Value format per line. | |
-The | |
-.Fl n | |
-flag can be used to show the indices for array types (by default off). | |
+.Pp | |
+The options are as follows: | |
+.Bl -tag -width Ds | |
+.It Fl n | |
+Show the indices for array types (by default off). | |
+.It Fl r | |
+Show all control-characters (by default off). | |
+.El | |
.Sh TAB-SEPARATED VALUE FORMAT | |
The output format per line is: | |
.Bd -literal | |
@@ -21,8 +27,10 @@ nodename<TAB>type<TAB>value<LF> | |
.Ed | |
.Pp | |
Control-characters such as a newline, TAB and backslash (\\n, \\t and \\\\) are | |
-escaped in the nodename and value fields. | |
-Other control-characters are removed. | |
+always escaped in the nodename and value fields. | |
+Other control-characters are removed, unless the option | |
+.Fl r | |
+is set. | |
.Pp | |
The type field is a single byte and can be: | |
.Bl -tag -width Ds | |
@@ -49,8 +57,8 @@ Characters in object keys such as a dot or brackets are not e… | |
output, this can change the meaning of the nodename field. | |
.It | |
The JSON parser handles all valid JSON. | |
-It also allows some invalid JSON extension: it does not do a complete | |
-validation on numbers and is not strict with unicode input. | |
+It also allows some invalid JSON extensions: it does not do a complete | |
+validation on numbers and is not strict with handling unicode input. | |
See also RFC8259 section 9. Parsers. | |
.It | |
The maximum depth of objects or arrays is hard-coded to 64 levels deep. | |
diff --git a/json2tsv.c b/json2tsv.c | |
@@ -13,7 +13,8 @@ | |
#include "json.h" | |
-static int showindices = 0; /* -n flag: show indices count for arrays */ | |
+static int nflag = 0; /* -n flag: show indices count for arrays */ | |
+static int rflag = 0; /* -r flag: show all control-characters */ | |
void | |
printvalue(const char *s) | |
@@ -26,7 +27,7 @@ printvalue(const char *s) | |
case '\t': putchar('\\'); putchar('t'); break; | |
default: | |
/* ignore other control chars */ | |
- if (iscntrl((unsigned char)*s)) | |
+ if (!rflag && iscntrl((unsigned char)*s)) | |
continue; | |
putchar(*s); | |
} | |
@@ -48,7 +49,7 @@ processnode(struct json_node *nodes, size_t depth, const char… | |
if (nodes[i].type == TYPE_OBJECT) { | |
putchar('.'); | |
} else if (nodes[i].type == TYPE_ARRAY) { | |
- if (showindices) { | |
+ if (nflag) { | |
printf("[%zu]", nodes[i].index); | |
} else { | |
putchar('['); | |
@@ -67,13 +68,23 @@ processnode(struct json_node *nodes, size_t depth, const ch… | |
int | |
main(int argc, char *argv[]) | |
{ | |
+ int i, j; | |
+ | |
if (pledge("stdio", NULL) == -1) { | |
fprintf(stderr, "pledge stdio: %s\n", strerror(errno)); | |
return 1; | |
} | |
- if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'n') | |
- showindices = 1; | |
+ for (i = 1; i < argc; i++) { | |
+ if (argv[i][0] != '-') | |
+ continue; | |
+ for (j = 1; argv[i][j]; j++) { | |
+ switch (argv[i][j]) { | |
+ case 'n': nflag = 1; break; | |
+ case 'r': rflag = 1; break; | |
+ } | |
+ } | |
+ } | |
switch (parsejson(processnode)) { | |
case JSON_ERROR_MEM: |