Add example/jsonptr -strict-json-pointer-syntax
diff --git a/example/jsonptr/jsonptr.cc b/example/jsonptr/jsonptr.cc
index 3345b57..1486c70 100644
--- a/example/jsonptr/jsonptr.cc
+++ b/example/jsonptr/jsonptr.cc
@@ -121,6 +121,7 @@
     "    -i=NUM  -indent=NUM\n"
     "    -o=NUM  -max-output-depth=NUM\n"
     "    -q=STR  -query=STR\n"
+    "    -s      -strict-json-pointer-syntax\n"
     "    -t      -tabs\n"
     "            -fail-if-unsandboxed\n"
     "\n"
@@ -167,13 +168,20 @@
     "object has multiple \"foo\" children but the first one doesn't have a\n"
     "\"bar\" child, even if later ones do.\n"
     "\n"
+    "The -s or -strict-json-pointer-syntax flag restricts the -query=STR\n"
+    "string to exactly RFC 6901, with only two escape sequences: \"~0\" and\n"
+    "\"~1\" for \"~\" and \"/\". Without this flag, this program also lets\n"
+    "\"~n\" and \"~r\" escape the New Line and Carriage Return ASCII control\n"
+    "characters, which can work better with line oriented Unix tools that\n"
+    "assume exactly one value (i.e. one JSON Pointer string) per line.\n"
+    "\n"
     "----\n"
     "\n"
     "The -o=NUM or -max-output-depth=NUM flag gives the maximum (inclusive)\n"
     "output depth. JSON containers ([] arrays and {} objects) can hold other\n"
     "containers. When this flag is set, containers at depth NUM are replaced\n"
     "with \"[…]\" or \"{…}\". A bare -o or -max-output-depth is equivalent to\n"
-    "NUM=1. The flag's absence is equivalent to an unlimited output depth.\n"
+    "-o=1. The flag's absence is equivalent to an unlimited output depth.\n"
     "\n"
     "The -max-output-depth flag only affects the program's output. It doesn't\n"
     "affect whether or not the input is considered valid JSON. The JSON\n"
@@ -413,6 +421,14 @@
           if (*ptr != '/') {
             break;
           }
+        } else if (*j == 'n') {
+          if (*ptr != '\n') {
+            break;
+          }
+        } else if (*j == 'r') {
+          if (*ptr != '\r') {
+            break;
+          }
         } else {
           break;
         }
@@ -445,8 +461,11 @@
   // validate returns whether the (ptr, len) arguments form a valid JSON
   // Pointer. In particular, it must be valid UTF-8, and either be empty or
   // start with a '/'. Any '~' within must immediately be followed by either
-  // '0' or '1'.
-  static bool validate(char* query_c_string, size_t length) {
+  // '0' or '1'. If strict_json_pointer_syntax is false, a '~' may also be
+  // followed by either 'n' or 'r'.
+  static bool validate(char* query_c_string,
+                       size_t length,
+                       bool strict_json_pointer_syntax) {
     if (length <= 0) {
       return true;
     }
@@ -461,11 +480,24 @@
       if (!o.is_valid()) {
         return false;
       }
-      if (previous_was_tilde && (o.code_point != '0') &&
-          (o.code_point != '1')) {
-        return false;
+
+      if (previous_was_tilde) {
+        switch (o.code_point) {
+          case '0':
+          case '1':
+            break;
+          case 'n':
+          case 'r':
+            if (strict_json_pointer_syntax) {
+              return false;
+            }
+            break;
+          default:
+            return false;
+        }
       }
       previous_was_tilde = o.code_point == '~';
+
       s.ptr += o.byte_length;
       s.len -= o.byte_length;
     }
@@ -484,6 +516,7 @@
   size_t indent;
   uint32_t max_output_depth;
   char* query_c_string;
+  bool strict_json_pointer_syntax;
   bool tabs;
 } flags = {0};
 
@@ -547,11 +580,12 @@
     if (!strncmp(arg, "q=", 2) || !strncmp(arg, "query=", 6)) {
       while (*arg++ != '=') {
       }
-      if (Query::validate(arg, strlen(arg))) {
-        flags.query_c_string = arg;
-        continue;
-      }
-      return usage;
+      flags.query_c_string = arg;
+      continue;
+    }
+    if (!strcmp(arg, "s") || !strcmp(arg, "strict-json-pointer-syntax")) {
+      flags.strict_json_pointer_syntax = true;
+      continue;
     }
     if (!strcmp(arg, "t") || !strcmp(arg, "tabs")) {
       flags.tabs = true;
@@ -561,6 +595,12 @@
     return usage;
   }
 
+  if (flags.query_c_string &&
+      !Query::validate(flags.query_c_string, strlen(flags.query_c_string),
+                       flags.strict_json_pointer_syntax)) {
+    return "main: bad JSON Pointer (RFC 6901) syntax for the -query=STR flag";
+  }
+
   flags.remaining_argc = argc - c;
   flags.remaining_argv = argv + c;
   return nullptr;