| # jsonptr |
| |
| This program has two goals: |
| |
| 1. be a production-quality [JSON](https://json.org/) formatter (pretty-printer) |
| that supports the JSON Pointer (RFC 6901) query syntax. |
| 2. demonstrate how to use [Wuffs' low-level JSON parsing C |
| API](https://nigeltao.github.io/blog/2020/jsonptr.html). An alternative, |
| higher-level C++ API is used in the sibling |
| [example/jsonfindptrs](/example/jsonfindptrs) program. |
| |
| |
| ## Building |
| |
| It has no dependencies other than Wuffs. |
| |
| $ gcc -O3 jsonptr.cc -o jsonptr |
| |
| |
| ## Example |
| |
| $ grep foo ../../test/data/rfc-6901-json-pointer.json |
| "foo": ["bar", "baz"], |
| $ ./jsonptr -query=/foo/1 ../../test/data/rfc-6901-json-pointer.json |
| "baz" |
| |
| It also supports the JWCC ([JSON With Commas and |
| Comments](https://nigeltao.github.io/blog/2021/json-with-commas-comments.html)) |
| syntax. |
| |
| $ echo '/* Note the commas. */[1,2,[30,31]]' | ./jsonptr -jwcc |
| /* Note the commas. */ |
| [ |
| 1, |
| 2, |
| [ |
| 30, |
| 31, |
| ], |
| ] |
| |
| |
| ## Usage |
| |
| $ ./jsonptr -help |
| Usage: jsonptr -flags input.json |
| |
| Flags: |
| -c -compact-output |
| -d=NUM -max-output-depth=NUM |
| -q=STR -query=STR |
| -s=NUM -spaces=NUM |
| -t -tabs |
| -fail-if-unsandboxed |
| -input-allow-comments |
| -input-allow-extra-comma |
| -input-allow-inf-nan-numbers |
| -input-jwcc |
| -jwcc |
| -output-comments |
| -output-extra-comma |
| -output-inf-nan-numbers |
| -strict-json-pointer-syntax |
| |
| The input.json filename is optional. If absent, it reads from stdin. |
| |
| ---- |
| |
| jsonptr is a JSON formatter (pretty-printer) that supports the JSON |
| Pointer (RFC 6901) query syntax. It reads UTF-8 JSON from stdin and |
| writes canonicalized, formatted UTF-8 JSON to stdout. |
| |
| Canonicalized means that e.g. "abc\u000A\tx\u0177z" is re-written |
| as "abc\n\txŷz". It does not sort object keys, nor does it reject |
| duplicate keys. Canonicalization does not imply Unicode normalization. |
| |
| Formatted means that arrays' and objects' elements are indented, each |
| on its own line. Configure this with the -c / -compact-output, -s=NUM / |
| -spaces=NUM (for NUM ranging from 0 to 8) and -t / -tabs flags. |
| |
| The -input-allow-comments flag allows "/*slash-star*/" and |
| "//slash-slash" C-style comments within JSON input. Such comments are |
| stripped from the output unless -output-comments was also set. |
| |
| The -input-allow-extra-comma flag allows input like "[1,2,]", with a |
| comma after the final element of a JSON list or dictionary. |
| |
| The -input-allow-inf-nan-numbers flag allows non-finite floating point |
| numbers (infinities and not-a-numbers) within JSON input. This flag |
| requires that -output-inf-nan-numbers also be set. |
| |
| The -output-comments flag copies any input comments to the output. It |
| has no effect unless -input-allow-comments was also set. Comments look |
| better after commas than before them, but a closing "]" or "}" can |
| occur after arbitrarily many comments, so -output-comments also requires |
| that one or both of -compact-output and -output-extra-comma be set. |
| |
| With -output-comments, consecutive blank lines collapse to a single |
| blank line. Without that flag, all blank lines are removed. |
| |
| The -output-extra-comma flag writes output like "[1,2,]", with a comma |
| after the final element of a JSON list or dictionary. Such commas are |
| non-compliant with the JSON specification but many parsers accept them |
| and they can produce simpler line-based diffs. This flag is ignored when |
| -compact-output is set. |
| |
| Combining some of those flags results in speaking JWCC (JSON With Commas |
| and Comments), not plain JSON. For convenience, the -input-jwcc or -jwcc |
| flags enables the first two or all four of: |
| -input-allow-comments |
| -input-allow-extra-comma |
| -output-comments |
| -output-extra-comma |
| |
| ---- |
| |
| The -q=STR or -query=STR flag gives an optional JSON Pointer query, to |
| print a subset of the input. For example, given RFC 6901 section 5's |
| sample input (https://tools.ietf.org/rfc/rfc6901.txt), this command: |
| jsonptr -query=/foo/1 rfc-6901-json-pointer.json |
| will print: |
| "baz" |
| |
| An absent query is equivalent to the empty query, which identifies the |
| entire input (the root value). Unlike a file system, the "/" query |
| does not identify the root. Instead, "" is the root and "/" is the |
| child (the value in a key-value pair) of the root whose key is the empty |
| string. Similarly, "/xyz" and "/xyz/" are two different nodes. |
| |
| If the query found a valid JSON value, this program will return a zero |
| exit code even if the rest of the input isn't valid JSON. If the query |
| did not find a value, or found an invalid one, this program returns a |
| non-zero exit code, but may still print partial output to stdout. |
| |
| The JSON specification (https://json.org/) permits implementations that |
| allow duplicate keys, as this one does. This JSON Pointer implementation |
| is also greedy, following the first match for each fragment without |
| back-tracking. For example, the "/foo/bar" query will fail if the root |
| object has multiple "foo" children but the first one doesn't have a |
| "bar" child, even if later ones do. |
| |
| The -strict-json-pointer-syntax flag restricts the -query=STR string to |
| exactly RFC 6901, with only two escape sequences: "~0" and "~1" for |
| "~" and "/". Without this flag, this program also lets "~n", |
| "~r" and "~t" escape the New Line, Carriage Return and Horizontal |
| Tab ASCII control characters, which can work better with line oriented |
| (and tab separated) Unix tools that assume exactly one record (e.g. one |
| JSON Pointer string) per line. |
| |
| ---- |
| |
| The -d=NUM or -max-output-depth=NUM flag gives the maximum (inclusive) |
| output depth. JSON containers ([] arrays and {} objects) can hold other |
| containers. When this flag is set, containers at depth NUM are replaced |
| with "[…]" or "{…}". A bare -d or -max-output-depth is equivalent to |
| -d=1. The flag's absence is equivalent to an unlimited output depth. |
| |
| The -max-output-depth flag only affects the program's output. It doesn't |
| affect whether or not the input is considered valid JSON. The JSON |
| specification permits implementations to set their own maximum input |
| depth. This JSON implementation sets it to 1024. |
| |
| Depth is measured in terms of nested containers. It is unaffected by the |
| number of spaces or tabs used to indent. |
| |
| When both -max-output-depth and -query are set, the output depth is |
| measured from when the query resolves, not from the input root. The |
| input depth (measured from the root) is still limited to 1024. |
| |
| ---- |
| |
| The -fail-if-unsandboxed flag causes the program to exit if it does not |
| self-impose a sandbox. On Linux, it self-imposes a SECCOMP_MODE_STRICT |
| sandbox, regardless of whether this flag was set. |