]> granicus.if.org Git - jq/commitdiff
Add --tab and -indent n options
authorNicolas Williams <nico@cryptonector.com>
Thu, 4 Jun 2015 01:20:11 +0000 (20:20 -0500)
committerNicolas Williams <nico@cryptonector.com>
Thu, 4 Jun 2015 01:20:11 +0000 (20:20 -0500)
docs/content/3.manual/manual.yml
jv.h
jv_print.c
main.c

index 95d8d53fe3307bb0a873744f3f1d0b4ed07c0490..8028e47ad67393a1d91d40209bb6355be2b90cb5 100644 (file)
@@ -140,6 +140,14 @@ sections:
         will result in more compact output by instead putting each
         JSON object on a single line.
 
+      * `--tab`:
+
+        Use a tab for each indentation level instead of two spaces.
+
+      * `--indent n`:
+
+        Use the given number of spaces (no more than 8) for indentation.
+
       * `--colour-output` / `-C` and `--monochrome-output` / `-M`:
 
         By default, jq outputs colored JSON if writing to a
diff --git a/jv.h b/jv.h
index aa374ad14ab350d62496b2b538556e0e34ecd38b..28f6ae053a8a744446a4f673455bc1c7c19fe40c 100644 (file)
--- a/jv.h
+++ b/jv.h
@@ -159,14 +159,20 @@ jv jv_object_iter_value(jv, int);
 
 int jv_get_refcnt(jv);
 
-enum {
+enum jv_print_flags {
   JV_PRINT_PRETTY   = 1,
   JV_PRINT_ASCII    = 2,
   JV_PRINT_COLOUR   = 4,
   JV_PRINT_SORTED   = 8,
   JV_PRINT_INVALID  = 16,
   JV_PRINT_REFCOUNT = 32,
+  JV_PRINT_TAB      = 64,
+  JV_PRINT_SPACE0   = 256,
+  JV_PRINT_SPACE1   = 512,
+  JV_PRINT_SPACE2   = 1024,
 };
+#define JV_PRINT_INDENT_FLAGS(n) \
+    ((n) < 0 || (n) > 7 ? JV_PRINT_TAB | JV_PRINT_PRETTY : (n) == 0 ? 0 : (n) << 8 | JV_PRINT_PRETTY)
 void jv_dumpf(jv, FILE *f, int flags);
 void jv_dump(jv, int flags);
 void jv_show(jv, int flags);
index 4b6c4bb9253e017797763b36eccb2de00d2161fa..8615bec6cd445a95ea627adaa7325093a5e1e946 100644 (file)
@@ -37,9 +37,14 @@ static void put_str(const char* s, FILE* fout, jv* strout) {
   put_buf(s, strlen(s), fout, strout);
 }
 
-static void put_space(int n, FILE* fout, jv* strout) {
-  while (n--) {
-    put_char(' ', fout, strout);
+static void put_indent(int n, int flags, FILE* fout, jv* strout) {
+  if (flags & JV_PRINT_TAB) {
+    while (n--)
+      put_char('\t', fout, strout);
+  } else {
+    n *= ((flags & (JV_PRINT_SPACE0 | JV_PRINT_SPACE1 | JV_PRINT_SPACE2)) >> 8);
+    while (n--)
+      put_char(' ', fout, strout);
   }
 }
 
@@ -110,8 +115,6 @@ static void jvp_dump_string(jv str, int ascii_only, FILE* F, jv* S) {
   put_char('"', F, S);
 }
 
-enum { INDENT = 2 };
-
 static void put_refcnt(struct dtoa_context* C, int refcnt, FILE *F, jv* S){
   char buf[JVP_DTOA_FMT_MAX_LEN];
   put_char(' ', F, S);
@@ -184,23 +187,23 @@ static void jv_dump_term(struct dtoa_context* C, jv x, int flags, int indent, FI
     put_str("[", F, S);
     if (flags & JV_PRINT_PRETTY) {
       put_char('\n', F, S);
-      put_space(indent+INDENT, F, S);
+      put_indent(indent + 1, flags, F, S);
     }
     jv_array_foreach(x, i, elem) {
       if (i!=0) {
         if (flags & JV_PRINT_PRETTY) {
           put_str(",\n", F, S);
-          put_space(indent+INDENT, F, S);
+          put_indent(indent + 1, flags, F, S);
         } else {
           put_str(",", F, S);
         }
       }
-      jv_dump_term(C, elem, flags, indent + INDENT, F, S);
+      jv_dump_term(C, elem, flags, indent + 1, F, S);
       if (colour) put_str(colour, F, S);
     }
     if (flags & JV_PRINT_PRETTY) {
       put_char('\n', F, S);
-      put_space(indent, F, S);
+      put_indent(indent, flags, F, S);
     }
     if (colour) put_str(colour, F, S);
     put_char(']', F, S);
@@ -216,7 +219,7 @@ static void jv_dump_term(struct dtoa_context* C, jv x, int flags, int indent, FI
     put_char('{', F, S);
     if (flags & JV_PRINT_PRETTY) {
       put_char('\n', F, S);
-      put_space(indent+INDENT, F, S);
+      put_indent(indent + 1, flags, F, S);
     }
     int first = 1;
     int i = 0;
@@ -250,7 +253,7 @@ static void jv_dump_term(struct dtoa_context* C, jv x, int flags, int indent, FI
       if (!first) {
         if (flags & JV_PRINT_PRETTY){
           put_str(",\n", F, S);
-          put_space(indent+INDENT, F, S);
+          put_indent(indent + 1, flags, F, S);
         } else {
           put_str(",", F, S);
         }
@@ -267,12 +270,12 @@ static void jv_dump_term(struct dtoa_context* C, jv x, int flags, int indent, FI
       put_str((flags & JV_PRINT_PRETTY) ? ": " : ":", F, S);
       if (colour) put_str(COLRESET, F, S);
       
-      jv_dump_term(C, value, flags, indent + INDENT, F, S);
+      jv_dump_term(C, value, flags, indent + 1, F, S);
       if (colour) put_str(colour, F, S);
     }
     if (flags & JV_PRINT_PRETTY) {
       put_char('\n', F, S);
-      put_space(indent, F, S);
+      put_indent(indent, flags, F, S);
     }
     if (colour) put_str(colour, F, S);
     put_char('}', F, S);
@@ -300,7 +303,7 @@ void jv_dump(jv x, int flags) {
 /* This one is nice for use in debuggers */
 void jv_show(jv x, int flags) {
   if (flags == -1)
-    flags = JV_PRINT_PRETTY | JV_PRINT_COLOUR;
+    flags = JV_PRINT_PRETTY | JV_PRINT_COLOUR | JV_PRINT_INDENT_FLAGS(2);
   jv_dumpf(jv_copy(x), stderr, flags | JV_PRINT_INVALID);
   fflush(stderr);
 }
diff --git a/main.c b/main.c
index 4ada621deff8a4d920512be1aa789fcb9bc3bfce..246b2dfd88efe98bc97cb91510dccd5dfc874376 100644 (file)
--- a/main.c
+++ b/main.c
@@ -48,6 +48,7 @@ static void usage(int code) {
     "\t -C\t\tcolorize JSON;\n"
     "\t -M\t\tmonochrome (don't colorize JSON);\n"
     "\t -S\t\tsort keys of objects on output;\n"
+    "\t --tab\tuse tabs for indentation;\n"
     "\t --arg a v\tset variable $a to value <v>;\n"
     "\t --argjson a v\tset variable $a to JSON value <v>;\n"
     "\t --slurpfile a f\tset variable $a to an array of JSON texts read from <f>;\n"
@@ -91,7 +92,6 @@ enum {
   RAW_INPUT             = 2,
   PROVIDE_NULL          = 4,
   RAW_OUTPUT            = 8,
-  COMPACT_OUTPUT        = 16,
   ASCII_OUTPUT          = 32,
   COLOUR_OUTPUT         = 64,
   NO_COLOUR_OUTPUT      = 128,
@@ -174,6 +174,7 @@ int main(int argc, char* argv[]) {
     goto out;
   }
 
+  int dumpopts = JV_PRINT_INDENT_FLAGS(2);
   const char* program = 0;
 
   jq_util_input_state input_state = jq_util_input_init(NULL, NULL); // XXX add err_cb
@@ -221,7 +222,7 @@ int main(int argc, char* argv[]) {
         if (!short_opts) continue;
       }
       if (isoption(argv[i], 'c', "compact-output", &short_opts)) {
-        options |= COMPACT_OUTPUT;
+        dumpopts &= ~(JV_PRINT_TAB | JV_PRINT_INDENT_FLAGS(7));
         if (!short_opts) continue;
       }
       if (isoption(argv[i], 'C', "color-output", &short_opts)) {
@@ -260,6 +261,26 @@ int main(int argc, char* argv[]) {
         options |= RAW_OUTPUT | RAW_NO_LF;
         if (!short_opts) continue;
       }
+      if (isoption(argv[i], 0, "tab", &short_opts)) {
+        dumpopts &= ~JV_PRINT_INDENT_FLAGS(7);
+        dumpopts |= JV_PRINT_TAB | JV_PRINT_PRETTY;
+        if (!short_opts) continue;
+      }
+      if (isoption(argv[i], 0, "indent", &short_opts)) {
+        if (i >= argc - 1) {
+          fprintf(stderr, "%s: --indent takes one parameter\n", progname);
+          die();
+        }
+        dumpopts &= ~(JV_PRINT_TAB | JV_PRINT_INDENT_FLAGS(7));
+        int indent = atoi(argv[i+1]);
+        if (indent < -1 || indent > 7) {
+          fprintf(stderr, "%s: --indent takes a number between -1 and 7\n", progname);
+          die();
+        }
+        dumpopts |= JV_PRINT_INDENT_FLAGS(indent);
+        i++;
+        if (!short_opts) continue;
+      }
       if (isoption(argv[i], 0, "seq", &short_opts)) {
         options |= SEQ;
         if (!short_opts) continue;
@@ -279,7 +300,7 @@ int main(int argc, char* argv[]) {
       // FIXME: For --arg* we should check that the varname is acceptable
       if (isoption(argv[i], 0, "arg", &short_opts)) {
         if (i >= argc - 2) {
-          fprintf(stderr, "%s: --arg takes two parameters (e.g. -a varname value)\n", progname);
+          fprintf(stderr, "%s: --arg takes two parameters (e.g. --arg varname value)\n", progname);
           die();
         }
         jv arg = jv_object();
@@ -291,7 +312,7 @@ int main(int argc, char* argv[]) {
       }
       if (isoption(argv[i], 0, "argjson", &short_opts)) {
         if (i >= argc - 2) {
-          fprintf(stderr, "%s: --argjson takes two parameters (e.g. -a varname text)\n", progname);
+          fprintf(stderr, "%s: --argjson takes two parameters (e.g. --argjson varname text)\n", progname);
           die();
         }
         jv v = jv_parse(argv[i+2]);
@@ -314,7 +335,7 @@ int main(int argc, char* argv[]) {
         else
           which = "slurpfile";
         if (i >= argc - 2) {
-          fprintf(stderr, "%s: --%s takes two parameters (e.g. -a varname filename)\n", progname, which);
+          fprintf(stderr, "%s: --%s takes two parameters (e.g. --%s varname filename)\n", progname, which, which);
           die();
         }
         jv arg = jv_object();
@@ -370,7 +391,6 @@ int main(int argc, char* argv[]) {
     }
   }
 
-  int dumpopts = 0;
 #ifndef WIN32
   /* Disable colour by default on Windows builds as Windows
      terminals tend not to display it correctly */
@@ -378,7 +398,6 @@ int main(int argc, char* argv[]) {
     dumpopts |= JV_PRINT_COLOUR;
 #endif
   if (options & SORTED_OUTPUT) dumpopts |= JV_PRINT_SORTED;
-  if (!(options & COMPACT_OUTPUT)) dumpopts |= JV_PRINT_PRETTY;
   if (options & ASCII_OUTPUT) dumpopts |= JV_PRINT_ASCII;
   if (options & COLOUR_OUTPUT) dumpopts |= JV_PRINT_COLOUR;
   if (options & NO_COLOUR_OUTPUT) dumpopts &= ~JV_PRINT_COLOUR;