"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "main.c" between
jq-1.5.tar.gz and jq-1.6.tar.gz

About: jq is a lightweight and flexible command-line JSON processor.

main.c  (jq-1.5):main.c  (jq-1.6)
skipping to change at line 20 skipping to change at line 20
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
#include <io.h> #include <io.h>
#include <fcntl.h> #include <fcntl.h>
#include <processenv.h> #include <processenv.h>
#include <shellapi.h> #include <shellapi.h>
#include <wchar.h> #include <wchar.h>
#include <wtypes.h> #include <wtypes.h>
#endif #endif
#if !defined(HAVE_ISATTY) && defined(HAVE__ISATTY)
#undef isatty
#define isatty _isatty
#endif
#if defined(HAVE_ISATTY) || defined(HAVE__ISATTY)
#define USE_ISATTY
#endif
#include "compile.h" #include "compile.h"
#include "jv.h" #include "jv.h"
#include "jq.h" #include "jq.h"
#include "jv_alloc.h" #include "jv_alloc.h"
#include "util.h" #include "util.h"
#include "version.h" #include "src/version.h"
int jq_testsuite(jv lib_dirs, int verbose, int argc, char* argv[]); int jq_testsuite(jv lib_dirs, int verbose, int argc, char* argv[]);
static const char* progname; static const char* progname;
/* /*
* For a longer help message we could use a better option parsing * For a longer help message we could use a better option parsing
* strategy, one that lets stack options. * strategy, one that lets stack options.
*/ */
static void usage(int code) { static void usage(int code, int keep_it_short) {
FILE *f = stderr; FILE *f = stderr;
if (code == 0) if (code == 0)
f = stdout; f = stdout;
int ret = fprintf(f, int ret = fprintf(f,
"jq - commandline JSON processor [version %s]\n" "jq - commandline JSON processor [version %s]\n"
"Usage: %s [options] <jq filter> [file...]\n\n" "\nUsage:\t%s [options] <jq filter> [file...]\n"
"\tjq is a tool for processing JSON inputs, applying the\n" "\t%s [options] --args <jq filter> [strings...]\n"
"\tgiven filter to its JSON text inputs and producing the\n" "\t%s [options] --jsonargs <jq filter> [JSON_TEXTS...]\n\n"
"\tfilter's results as JSON on standard output.\n" "jq is a tool for processing JSON inputs, applying the given filter to\n"
"\tThe simplest filter is ., which is the identity filter,\n" "its JSON text inputs and producing the filter's results as JSON on\n"
"\tcopying jq's input to its output unmodified (except for\n" "standard output.\n\n"
"\tformatting).\n" "The simplest filter is ., which copies jq's input to its output\n"
"\tFor more advanced filters see the jq(1) manpage (\"man jq\")\n" "unmodified (except for formatting, but note that IEEE754 is used\n"
"\tand/or https://stedolan.github.io/jq\n\n" "for number representation internally, with all that that implies).\n\n"
"\tSome of the options include:\n" "For more advanced filters see the jq(1) manpage (\"man jq\")\n"
"\t -c\t\tcompact instead of pretty-printed output;\n" "and/or https://stedolan.github.io/jq\n\n"
"\t -n\t\tuse `null` as the single input value;\n" "Example:\n\n\t$ echo '{\"foo\": 0}' | jq .\n"
"\t -e\t\tset the exit status code based on the output;\n" "\t{\n\t\t\"foo\": 0\n\t}\n\n",
"\t -s\t\tread (slurp) all inputs into an array; apply filter to it;\n" JQ_VERSION, progname, progname, progname);
"\t -r\t\toutput raw strings, not JSON texts;\n" if (keep_it_short) {
"\t -R\t\tread raw strings, not JSON texts;\n" fprintf(f,
"\t -C\t\tcolorize JSON;\n" "For a listing of options, use %s --help.\n",
"\t -M\t\tmonochrome (don't colorize JSON);\n" progname);
"\t -S\t\tsort keys of objects on output;\n" } else {
"\t --tab\tuse tabs for indentation;\n" (void) fprintf(f,
"\t --arg a v\tset variable $a to value <v>;\n" "Some of the options include:\n"
"\t --argjson a v\tset variable $a to JSON value <v>;\n" " -c compact instead of pretty-printed output;\n"
"\t --slurpfile a f\tset variable $a to an array of JSON texts read from <f> " -n use `null` as the single input value;\n"
;\n" " -e set the exit status code based on the output;\n"
"\tSee the manpage for more options.\n", JQ_VERSION, progname); " -s read (slurp) all inputs into an array; apply filter to
it;\n"
" -r output raw strings, not JSON texts;\n"
" -R read raw strings, not JSON texts;\n"
" -C colorize JSON;\n"
" -M monochrome (don't colorize JSON);\n"
" -S sort keys of objects on output;\n"
" --tab use tabs for indentation;\n"
" --arg a v set variable $a to value <v>;\n"
" --argjson a v set variable $a to JSON value <v>;\n"
" --slurpfile a f set variable $a to an array of JSON texts read from <f
>;\n"
" --rawfile a f set variable $a to a string consisting of the contents
of <f>;\n"
" --args remaining arguments are string arguments, not files;\n
"
" --jsonargs remaining arguments are JSON arguments, not files;\n"
" -- terminates argument processing;\n\n"
"Named arguments are also available as $ARGS.named[], while\n"
"positional arguments are available as $ARGS.positional[].\n"
"\nSee the manpage for more options.\n");
}
exit((ret < 0 && code == 0) ? 2 : code); exit((ret < 0 && code == 0) ? 2 : code);
} }
static void die() { static void die() {
fprintf(stderr, "Use %s --help for help with command-line options,\n", prognam e); fprintf(stderr, "Use %s --help for help with command-line options,\n", prognam e);
fprintf(stderr, "or see the jq manpage, or online docs at https://stedolan.gi thub.io/jq\n"); fprintf(stderr, "or see the jq manpage, or online docs at https://stedolan.gi thub.io/jq\n");
exit(2); exit(2);
} }
static int isoptish(const char* text) { static int isoptish(const char* text) {
skipping to change at line 104 skipping to change at line 131
} }
return 0; return 0;
} }
enum { enum {
SLURP = 1, SLURP = 1,
RAW_INPUT = 2, RAW_INPUT = 2,
PROVIDE_NULL = 4, PROVIDE_NULL = 4,
RAW_OUTPUT = 8, RAW_OUTPUT = 8,
ASCII_OUTPUT = 32, ASCII_OUTPUT = 32,
COLOUR_OUTPUT = 64, COLOR_OUTPUT = 64,
NO_COLOUR_OUTPUT = 128, NO_COLOR_OUTPUT = 128,
SORTED_OUTPUT = 256, SORTED_OUTPUT = 256,
FROM_FILE = 512, FROM_FILE = 512,
RAW_NO_LF = 1024, RAW_NO_LF = 1024,
UNBUFFERED_OUTPUT = 2048, UNBUFFERED_OUTPUT = 2048,
EXIT_STATUS = 4096, EXIT_STATUS = 4096,
SEQ = 8192, EXIT_STATUS_EXACT = 8192,
RUN_TESTS = 16384, SEQ = 16384,
RUN_TESTS = 32768,
/* debugging only */ /* debugging only */
DUMP_DISASM = 32768, DUMP_DISASM = 65536,
}; };
static int options = 0; static int options = 0;
static const char *skip_shebang(const char *p) {
if (strncmp(p, "#!", sizeof("#!") - 1) != 0)
return p;
const char *n = strchr(p, '\n');
if (n == NULL || n[1] != '#')
return p;
n = strchr(n + 1, '\n');
if (n == NULL || n[1] == '#' || n[1] == '\0' || n[-1] != '\\' || n[-2] == '\\'
)
return p;
n = strchr(n + 1, '\n');
if (n == NULL)
return p;
return n+1;
}
static int process(jq_state *jq, jv value, int flags, int dumpopts) { static int process(jq_state *jq, jv value, int flags, int dumpopts) {
int ret = 14; // No valid results && -e -> exit(4) int ret = 14; // No valid results && -e -> exit(4)
jq_start(jq, value, flags); jq_start(jq, value, flags);
jv result; jv result;
while (jv_is_valid(result = jq_next(jq))) { while (jv_is_valid(result = jq_next(jq))) {
if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) { if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) {
fwrite(jv_string_value(result), 1, jv_string_length_bytes(jv_copy(result)) if (options & ASCII_OUTPUT) {
, stdout); jv_dumpf(result, stdout, JV_PRINT_ASCII);
} else {
fwrite(jv_string_value(result), 1, jv_string_length_bytes(jv_copy(result
)), stdout);
}
ret = 0; ret = 0;
jv_free(result); jv_free(result);
} else { } else {
if (jv_get_kind(result) == JV_KIND_FALSE || jv_get_kind(result) == JV_KIND _NULL) if (jv_get_kind(result) == JV_KIND_FALSE || jv_get_kind(result) == JV_KIND _NULL)
ret = 11; ret = 11;
else else
ret = 0; ret = 0;
if (options & SEQ) if (options & SEQ)
priv_fwrite("\036", 1, stdout, dumpopts & JV_PRINT_ISATTY); priv_fwrite("\036", 1, stdout, dumpopts & JV_PRINT_ISATTY);
jv_dump(result, dumpopts); jv_dump(result, dumpopts);
} }
if (!(options & RAW_NO_LF)) if (!(options & RAW_NO_LF))
priv_fwrite("\n", 1, stdout, dumpopts & JV_PRINT_ISATTY); priv_fwrite("\n", 1, stdout, dumpopts & JV_PRINT_ISATTY);
if (options & UNBUFFERED_OUTPUT) if (options & UNBUFFERED_OUTPUT)
fflush(stdout); fflush(stdout);
} }
if (jv_invalid_has_msg(jv_copy(result))) { if (jq_halted(jq)) {
// jq program invoked `halt` or `halt_error`
options |= EXIT_STATUS_EXACT;
jv exit_code = jq_get_exit_code(jq);
if (!jv_is_valid(exit_code))
ret = 0;
else if (jv_get_kind(exit_code) == JV_KIND_NUMBER)
ret = jv_number_value(exit_code);
else
ret = 5;
jv_free(exit_code);
jv error_message = jq_get_error_message(jq);
if (jv_get_kind(error_message) == JV_KIND_STRING) {
fprintf(stderr, "%s", jv_string_value(error_message));
} else if (jv_get_kind(error_message) == JV_KIND_NULL) {
// Halt with no output
} else if (jv_is_valid(error_message)) {
error_message = jv_dump_string(jv_copy(error_message), 0);
fprintf(stderr, "%s\n", jv_string_value(error_message));
} // else no message on stderr; use --debug-trace to see a message
fflush(stderr);
jv_free(error_message);
} else if (jv_invalid_has_msg(jv_copy(result))) {
// Uncaught jq exception // Uncaught jq exception
jv msg = jv_invalid_get_msg(jv_copy(result)); jv msg = jv_invalid_get_msg(jv_copy(result));
jv input_pos = jq_util_input_get_position(jq); jv input_pos = jq_util_input_get_position(jq);
if (jv_get_kind(msg) == JV_KIND_STRING) { if (jv_get_kind(msg) == JV_KIND_STRING) {
fprintf(stderr, "jq: error (at %s): %s\n", fprintf(stderr, "jq: error (at %s): %s\n",
jv_string_value(input_pos), jv_string_value(msg)); jv_string_value(input_pos), jv_string_value(msg));
} else { } else {
msg = jv_dump_string(msg, 0); msg = jv_dump_string(msg, 0);
fprintf(stderr, "jq: error (at %s) (not a string): %s\n", fprintf(stderr, "jq: error (at %s) (not a string): %s\n",
jv_string_value(input_pos), jv_string_value(msg)); jv_string_value(input_pos), jv_string_value(msg));
skipping to change at line 174 skipping to change at line 243
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
jq_state *jq = NULL; jq_state *jq = NULL;
int ret = 0; int ret = 0;
int compiled = 0; int compiled = 0;
int parser_flags = 0; int parser_flags = 0;
int nfiles = 0; int nfiles = 0;
int badwrite; int badwrite;
jv program_arguments = jv_array(); jv ARGS = jv_array(); /* positional arguments */
jv program_arguments = jv_object(); /* named arguments */
#ifdef WIN32 #ifdef WIN32
SetConsoleOutputCP(CP_UTF8);
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
_setmode(fileno(stdout), _O_TEXT | _O_U8TEXT); _setmode(fileno(stdout), _O_TEXT | _O_U8TEXT);
_setmode(fileno(stderr), _O_TEXT | _O_U8TEXT); _setmode(fileno(stderr), _O_TEXT | _O_U8TEXT);
int wargc; int wargc;
wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
assert(wargc == argc); assert(wargc == argc);
size_t arg_sz; size_t arg_sz;
for (int i = 0; i < argc; i++) { for (int i = 0; i < argc; i++) {
argv[i] = alloca((arg_sz = WideCharToMultiByte(CP_UTF8, argv[i] = alloca((arg_sz = WideCharToMultiByte(CP_UTF8,
skipping to change at line 209 skipping to change at line 278
perror("malloc"); perror("malloc");
ret = 2; ret = 2;
goto out; goto out;
} }
int dumpopts = JV_PRINT_INDENT_FLAGS(2); int dumpopts = JV_PRINT_INDENT_FLAGS(2);
const char* program = 0; const char* program = 0;
jq_util_input_state *input_state = jq_util_input_init(NULL, NULL); // XXX add err_cb jq_util_input_state *input_state = jq_util_input_init(NULL, NULL); // XXX add err_cb
int further_args_are_files = 0; int further_args_are_strings = 0;
int further_args_are_json = 0;
int args_done = 0;
int jq_flags = 0; int jq_flags = 0;
size_t short_opts = 0; size_t short_opts = 0;
jv lib_search_paths = jv_null(); jv lib_search_paths = jv_null();
for (int i=1; i<argc; i++, short_opts = 0) { for (int i=1; i<argc; i++, short_opts = 0) {
if (further_args_are_files) { if (args_done) {
jq_util_input_add_input(input_state, argv[i]); if (further_args_are_strings) {
nfiles++; ARGS = jv_array_append(ARGS, jv_string(argv[i]));
} else if (further_args_are_json) {
ARGS = jv_array_append(ARGS, jv_parse(argv[i]));
} else {
jq_util_input_add_input(input_state, argv[i]);
nfiles++;
}
} else if (!strcmp(argv[i], "--")) { } else if (!strcmp(argv[i], "--")) {
if (!program) usage(2); if (!program) usage(2, 1);
further_args_are_files = 1; args_done = 1;
} else if (!isoptish(argv[i])) { } else if (!isoptish(argv[i])) {
if (program) { if (program) {
jq_util_input_add_input(input_state, argv[i]); if (further_args_are_strings) {
nfiles++; ARGS = jv_array_append(ARGS, jv_string(argv[i]));
} else if (further_args_are_json) {
ARGS = jv_array_append(ARGS, jv_parse(argv[i]));
} else {
jq_util_input_add_input(input_state, argv[i]);
nfiles++;
}
} else { } else {
program = argv[i]; program = argv[i];
} }
} else { } else {
if (argv[i][1] == 'L') { if (argv[i][1] == 'L') {
if (jv_get_kind(lib_search_paths) == JV_KIND_NULL) if (jv_get_kind(lib_search_paths) == JV_KIND_NULL)
lib_search_paths = jv_array(); lib_search_paths = jv_array();
if (argv[i][2] != 0) { // -Lname (faster check than strlen) if (argv[i][2] != 0) { // -Lname (faster check than strlen)
lib_search_paths = jv_array_append(lib_search_paths, jq_realpath(jv_ string(argv[i]+2))); lib_search_paths = jv_array_append(lib_search_paths, jq_realpath(jv_ string(argv[i]+2)));
} else if (i >= argc - 1) { } else if (i >= argc - 1) {
skipping to change at line 256 skipping to change at line 339
} }
if (isoption(argv[i], 'r', "raw-output", &short_opts)) { if (isoption(argv[i], 'r', "raw-output", &short_opts)) {
options |= RAW_OUTPUT; options |= RAW_OUTPUT;
if (!short_opts) continue; if (!short_opts) continue;
} }
if (isoption(argv[i], 'c', "compact-output", &short_opts)) { if (isoption(argv[i], 'c', "compact-output", &short_opts)) {
dumpopts &= ~(JV_PRINT_TAB | JV_PRINT_INDENT_FLAGS(7)); dumpopts &= ~(JV_PRINT_TAB | JV_PRINT_INDENT_FLAGS(7));
if (!short_opts) continue; if (!short_opts) continue;
} }
if (isoption(argv[i], 'C', "color-output", &short_opts)) { if (isoption(argv[i], 'C', "color-output", &short_opts)) {
options |= COLOUR_OUTPUT; options |= COLOR_OUTPUT;
if (!short_opts) continue; if (!short_opts) continue;
} }
if (isoption(argv[i], 'M', "monochrome-output", &short_opts)) { if (isoption(argv[i], 'M', "monochrome-output", &short_opts)) {
options |= NO_COLOUR_OUTPUT; options |= NO_COLOR_OUTPUT;
if (!short_opts) continue; if (!short_opts) continue;
} }
if (isoption(argv[i], 'a', "ascii-output", &short_opts)) { if (isoption(argv[i], 'a', "ascii-output", &short_opts)) {
options |= ASCII_OUTPUT; options |= ASCII_OUTPUT;
if (!short_opts) continue; if (!short_opts) continue;
} }
if (isoption(argv[i], 0, "unbuffered", &short_opts)) { if (isoption(argv[i], 0, "unbuffered", &short_opts)) {
options |= UNBUFFERED_OUTPUT; options |= UNBUFFERED_OUTPUT;
if (!short_opts) continue; continue;
} }
if (isoption(argv[i], 'S', "sort-keys", &short_opts)) { if (isoption(argv[i], 'S', "sort-keys", &short_opts)) {
options |= SORTED_OUTPUT; options |= SORTED_OUTPUT;
if (!short_opts) continue; if (!short_opts) continue;
} }
if (isoption(argv[i], 'R', "raw-input", &short_opts)) { if (isoption(argv[i], 'R', "raw-input", &short_opts)) {
options |= RAW_INPUT; options |= RAW_INPUT;
if (!short_opts) continue; if (!short_opts) continue;
} }
if (isoption(argv[i], 'n', "null-input", &short_opts)) { if (isoption(argv[i], 'n', "null-input", &short_opts)) {
skipping to change at line 294 skipping to change at line 377
options |= FROM_FILE; options |= FROM_FILE;
if (!short_opts) continue; if (!short_opts) continue;
} }
if (isoption(argv[i], 'j', "join-output", &short_opts)) { if (isoption(argv[i], 'j', "join-output", &short_opts)) {
options |= RAW_OUTPUT | RAW_NO_LF; options |= RAW_OUTPUT | RAW_NO_LF;
if (!short_opts) continue; if (!short_opts) continue;
} }
if (isoption(argv[i], 0, "tab", &short_opts)) { if (isoption(argv[i], 0, "tab", &short_opts)) {
dumpopts &= ~JV_PRINT_INDENT_FLAGS(7); dumpopts &= ~JV_PRINT_INDENT_FLAGS(7);
dumpopts |= JV_PRINT_TAB | JV_PRINT_PRETTY; dumpopts |= JV_PRINT_TAB | JV_PRINT_PRETTY;
if (!short_opts) continue; continue;
} }
if (isoption(argv[i], 0, "indent", &short_opts)) { if (isoption(argv[i], 0, "indent", &short_opts)) {
if (i >= argc - 1) { if (i >= argc - 1) {
fprintf(stderr, "%s: --indent takes one parameter\n", progname); fprintf(stderr, "%s: --indent takes one parameter\n", progname);
die(); die();
} }
dumpopts &= ~(JV_PRINT_TAB | JV_PRINT_INDENT_FLAGS(7)); dumpopts &= ~(JV_PRINT_TAB | JV_PRINT_INDENT_FLAGS(7));
int indent = atoi(argv[i+1]); int indent = atoi(argv[i+1]);
if (indent < -1 || indent > 7) { if (indent < -1 || indent > 7) {
fprintf(stderr, "%s: --indent takes a number between -1 and 7\n", prog name); fprintf(stderr, "%s: --indent takes a number between -1 and 7\n", prog name);
die(); die();
} }
dumpopts |= JV_PRINT_INDENT_FLAGS(indent); dumpopts |= JV_PRINT_INDENT_FLAGS(indent);
i++; i++;
if (!short_opts) continue; continue;
} }
if (isoption(argv[i], 0, "seq", &short_opts)) { if (isoption(argv[i], 0, "seq", &short_opts)) {
options |= SEQ; options |= SEQ;
if (!short_opts) continue; continue;
} }
if (isoption(argv[i], 0, "stream", &short_opts)) { if (isoption(argv[i], 0, "stream", &short_opts)) {
parser_flags |= JV_PARSE_STREAMING; parser_flags |= JV_PARSE_STREAMING;
if (!short_opts) continue; continue;
} }
if (isoption(argv[i], 0, "stream-errors", &short_opts)) { if (isoption(argv[i], 0, "stream-errors", &short_opts)) {
parser_flags |= JV_PARSE_STREAM_ERRORS; parser_flags |= JV_PARSE_STREAM_ERRORS;
if (!short_opts) continue; continue;
} }
if (isoption(argv[i], 'e', "exit-status", &short_opts)) { if (isoption(argv[i], 'e', "exit-status", &short_opts)) {
options |= EXIT_STATUS; options |= EXIT_STATUS;
if (!short_opts) continue; if (!short_opts) continue;
} }
// FIXME: For --arg* we should check that the varname is acceptable // FIXME: For --arg* we should check that the varname is acceptable
if (isoption(argv[i], 0, "args", &short_opts)) {
further_args_are_strings = 1;
further_args_are_json = 0;
continue;
}
if (isoption(argv[i], 0, "jsonargs", &short_opts)) {
further_args_are_strings = 0;
further_args_are_json = 1;
continue;
}
if (isoption(argv[i], 0, "arg", &short_opts)) { if (isoption(argv[i], 0, "arg", &short_opts)) {
if (i >= argc - 2) { if (i >= argc - 2) {
fprintf(stderr, "%s: --arg takes two parameters (e.g. --arg varname va lue)\n", progname); fprintf(stderr, "%s: --arg takes two parameters (e.g. --arg varname va lue)\n", progname);
die(); die();
} }
jv arg = jv_object(); if (!jv_object_has(jv_copy(program_arguments), jv_string(argv[i+1])))
arg = jv_object_set(arg, jv_string("name"), jv_string(argv[i+1])); program_arguments = jv_object_set(program_arguments, jv_string(argv[i+
arg = jv_object_set(arg, jv_string("value"), jv_string(argv[i+2])); 1]), jv_string(argv[i+2]));
program_arguments = jv_array_append(program_arguments, arg);
i += 2; // skip the next two arguments i += 2; // skip the next two arguments
if (!short_opts) continue; continue;
} }
if (isoption(argv[i], 0, "argjson", &short_opts)) { if (isoption(argv[i], 0, "argjson", &short_opts)) {
if (i >= argc - 2) { if (i >= argc - 2) {
fprintf(stderr, "%s: --argjson takes two parameters (e.g. --argjson va rname text)\n", progname); fprintf(stderr, "%s: --argjson takes two parameters (e.g. --argjson va rname text)\n", progname);
die(); die();
} }
jv v = jv_parse(argv[i+2]); if (!jv_object_has(jv_copy(program_arguments), jv_string(argv[i+1]))) {
if (!jv_is_valid(v)) { jv v = jv_parse(argv[i+2]);
fprintf(stderr, "%s: invalid JSON text passed to --argjson\n", prognam if (!jv_is_valid(v)) {
e); fprintf(stderr, "%s: invalid JSON text passed to --argjson\n", progn
die(); ame);
die();
}
program_arguments = jv_object_set(program_arguments, jv_string(argv[i+
1]), v);
} }
jv arg = jv_object();
arg = jv_object_set(arg, jv_string("name"), jv_string(argv[i+1]));
arg = jv_object_set(arg, jv_string("value"), v);
program_arguments = jv_array_append(program_arguments, arg);
i += 2; // skip the next two arguments i += 2; // skip the next two arguments
if (!short_opts) continue; continue;
} }
if (isoption(argv[i], 0, "argfile", &short_opts) || if (isoption(argv[i], 0, "argfile", &short_opts) ||
isoption(argv[i], 0, "rawfile", &short_opts) ||
isoption(argv[i], 0, "slurpfile", &short_opts)) { isoption(argv[i], 0, "slurpfile", &short_opts)) {
int raw = isoption(argv[i], 0, "rawfile", &short_opts);
const char *which; const char *which;
if (isoption(argv[i], 0, "argfile", &short_opts)) if (isoption(argv[i], 0, "argfile", &short_opts))
which = "argfile"; which = "argfile";
else if (raw)
which = "rawfile";
else else
which = "slurpfile"; which = "slurpfile";
if (i >= argc - 2) { if (i >= argc - 2) {
fprintf(stderr, "%s: --%s takes two parameters (e.g. --%s varname file name)\n", progname, which, which); fprintf(stderr, "%s: --%s takes two parameters (e.g. --%s varname file name)\n", progname, which, which);
die(); die();
} }
jv arg = jv_object(); if (!jv_object_has(jv_copy(program_arguments), jv_string(argv[i+1]))) {
arg = jv_object_set(arg, jv_string("name"), jv_string(argv[i+1])); jv data = jv_load_file(argv[i+2], raw);
jv data = jv_load_file(argv[i+2], 0); if (!jv_is_valid(data)) {
if (!jv_is_valid(data)) { data = jv_invalid_get_msg(data);
data = jv_invalid_get_msg(data); fprintf(stderr, "%s: Bad JSON in --%s %s %s: %s\n", progname, which,
fprintf(stderr, "%s: Bad JSON in --%s %s %s: %s\n", progname, which, argv[i+1], argv[i+2], jv_string_value(data));
argv[i+1], argv[i+2], jv_string_value(data)); jv_free(data);
jv_free(data); ret = 2;
jv_free(arg); goto out;
ret = 2; }
goto out; if (strcmp(which, "argfile") == 0 &&
jv_get_kind(data) == JV_KIND_ARRAY && jv_array_length(jv_copy(data
)) == 1)
data = jv_array_get(data, 0);
program_arguments = jv_object_set(program_arguments, jv_string(argv[i+
1]), data);
} }
if (isoption(argv[i], 0, "argfile", &short_opts) &&
jv_get_kind(data) == JV_KIND_ARRAY && jv_array_length(jv_copy(data))
== 1)
data = jv_array_get(data, 0);
arg = jv_object_set(arg, jv_string("value"), data);
program_arguments = jv_array_append(program_arguments, arg);
i += 2; // skip the next two arguments i += 2; // skip the next two arguments
if (!short_opts) continue; continue;
} }
if (isoption(argv[i], 0, "debug-dump-disasm", &short_opts)) { if (isoption(argv[i], 0, "debug-dump-disasm", &short_opts)) {
options |= DUMP_DISASM; options |= DUMP_DISASM;
continue;
}
if (isoption(argv[i], 0, "debug-trace=all", &short_opts)) {
jq_flags |= JQ_DEBUG_TRACE_ALL;
if (!short_opts) continue; if (!short_opts) continue;
} }
if (isoption(argv[i], 0, "debug-trace", &short_opts)) { if (isoption(argv[i], 0, "debug-trace", &short_opts)) {
jq_flags |= JQ_DEBUG_TRACE; jq_flags |= JQ_DEBUG_TRACE;
if (!short_opts) continue; continue;
} }
if (isoption(argv[i], 'h', "help", &short_opts)) { if (isoption(argv[i], 'h', "help", &short_opts)) {
usage(0); usage(0, 0);
if (!short_opts) continue; if (!short_opts) continue;
} }
if (isoption(argv[i], 'V', "version", &short_opts)) { if (isoption(argv[i], 'V', "version", &short_opts)) {
printf("jq-%s\n", JQ_VERSION); printf("jq-%s\n", JQ_VERSION);
ret = 0; ret = 0;
goto out; goto out;
} }
if (isoption(argv[i], 0, "run-tests", &short_opts)) { if (isoption(argv[i], 0, "run-tests", &short_opts)) {
i++; i++;
// XXX Pass program_arguments, even a whole jq_state *, through; // XXX Pass program_arguments, even a whole jq_state *, through;
skipping to change at line 423 skipping to change at line 519
} }
// check for unknown options... if this argument was a short option // check for unknown options... if this argument was a short option
if (strlen(argv[i]) != short_opts + 1) { if (strlen(argv[i]) != short_opts + 1) {
fprintf(stderr, "%s: Unknown option %s\n", progname, argv[i]); fprintf(stderr, "%s: Unknown option %s\n", progname, argv[i]);
die(); die();
} }
} }
} }
if (isatty(fileno(stdout))) { #ifdef USE_ISATTY
if (isatty(STDOUT_FILENO)) {
dumpopts |= JV_PRINT_ISATTY; dumpopts |= JV_PRINT_ISATTY;
#ifndef WIN32 #ifndef WIN32
/* Disable colour by default on Windows builds as Windows /* Disable color by default on Windows builds as Windows
terminals tend not to display it correctly */ terminals tend not to display it correctly */
dumpopts |= JV_PRINT_COLOUR; dumpopts |= JV_PRINT_COLOR;
#endif #endif
} }
#endif
if (options & SORTED_OUTPUT) dumpopts |= JV_PRINT_SORTED; if (options & SORTED_OUTPUT) dumpopts |= JV_PRINT_SORTED;
if (options & ASCII_OUTPUT) dumpopts |= JV_PRINT_ASCII; if (options & ASCII_OUTPUT) dumpopts |= JV_PRINT_ASCII;
if (options & COLOUR_OUTPUT) dumpopts |= JV_PRINT_COLOUR; if (options & COLOR_OUTPUT) dumpopts |= JV_PRINT_COLOR;
if (options & NO_COLOUR_OUTPUT) dumpopts &= ~JV_PRINT_COLOUR; if (options & NO_COLOR_OUTPUT) dumpopts &= ~JV_PRINT_COLOR;
if (getenv("JQ_COLORS") != NULL && !jq_set_colors(getenv("JQ_COLORS")))
fprintf(stderr, "Failed to set $JQ_COLORS\n");
if (jv_get_kind(lib_search_paths) == JV_KIND_NULL) { if (jv_get_kind(lib_search_paths) == JV_KIND_NULL) {
// Default search path list // Default search path list
lib_search_paths = JV_ARRAY(jv_string("~/.jq"), lib_search_paths = JV_ARRAY(jv_string("~/.jq"),
jv_string("$ORIGIN/../lib/jq"), jv_string("$ORIGIN/../lib/jq"),
jv_string("$ORIGIN/lib")); jv_string("$ORIGIN/lib"));
} }
jq_set_attr(jq, jv_string("JQ_LIBRARY_PATH"), lib_search_paths); jq_set_attr(jq, jv_string("JQ_LIBRARY_PATH"), lib_search_paths);
char *origin = strdup(argv[0]); char *origin = strdup(argv[0]);
skipping to change at line 457 skipping to change at line 558
exit(1); exit(1);
} }
jq_set_attr(jq, jv_string("JQ_ORIGIN"), jv_string(dirname(origin))); jq_set_attr(jq, jv_string("JQ_ORIGIN"), jv_string(dirname(origin)));
free(origin); free(origin);
if (strchr(JQ_VERSION, '-') == NULL) if (strchr(JQ_VERSION, '-') == NULL)
jq_set_attr(jq, jv_string("VERSION_DIR"), jv_string(JQ_VERSION)); jq_set_attr(jq, jv_string("VERSION_DIR"), jv_string(JQ_VERSION));
else else
jq_set_attr(jq, jv_string("VERSION_DIR"), jv_string_fmt("%.*s-master", (int) (strchr(JQ_VERSION, '-') - JQ_VERSION), JQ_VERSION)); jq_set_attr(jq, jv_string("VERSION_DIR"), jv_string_fmt("%.*s-master", (int) (strchr(JQ_VERSION, '-') - JQ_VERSION), JQ_VERSION));
#if (!defined(WIN32) && defined(HAVE_ISATTY)) || defined(HAVE__ISATTY) #ifdef USE_ISATTY
if (!program && (!isatty(STDOUT_FILENO) || !isatty(STDIN_FILENO)))
#if defined(HAVE__ISATTY) && defined(isatty)
#undef isatty
#define isatty _isatty
#endif
if (!program && isatty(STDOUT_FILENO) && !isatty(STDIN_FILENO))
program = "."; program = ".";
#endif #endif
if (!program) usage(2); if (!program) usage(2, 1);
if (options & FROM_FILE) { if (options & FROM_FILE) {
char *program_origin = strdup(program); char *program_origin = strdup(program);
if (program_origin == NULL) { if (program_origin == NULL) {
perror("malloc"); perror("malloc");
exit(2); exit(2);
} }
jv data = jv_load_file(program, 1); jv data = jv_load_file(program, 1);
if (!jv_is_valid(data)) { if (!jv_is_valid(data)) {
data = jv_invalid_get_msg(data); data = jv_invalid_get_msg(data);
fprintf(stderr, "%s: %s\n", progname, jv_string_value(data)); fprintf(stderr, "%s: %s\n", progname, jv_string_value(data));
jv_free(data); jv_free(data);
ret = 2; ret = 2;
goto out; goto out;
} }
jq_set_attr(jq, jv_string("PROGRAM_ORIGIN"), jq_realpath(jv_string(dirname(p rogram_origin)))); jq_set_attr(jq, jv_string("PROGRAM_ORIGIN"), jq_realpath(jv_string(dirname(p rogram_origin))));
compiled = jq_compile_args(jq, jv_string_value(data), jv_copy(program_argume ARGS = JV_OBJECT(jv_string("positional"), ARGS,
nts)); jv_string("named"), jv_copy(program_arguments));
program_arguments = jv_object_set(program_arguments, jv_string("ARGS"), jv_c
opy(ARGS));
compiled = jq_compile_args(jq, skip_shebang(jv_string_value(data)), jv_copy(
program_arguments));
free(program_origin); free(program_origin);
jv_free(data); jv_free(data);
} else { } else {
jq_set_attr(jq, jv_string("PROGRAM_ORIGIN"), jq_realpath(jv_string("."))); / / XXX is this good? jq_set_attr(jq, jv_string("PROGRAM_ORIGIN"), jq_realpath(jv_string("."))); / / XXX is this good?
ARGS = JV_OBJECT(jv_string("positional"), ARGS,
jv_string("named"), jv_copy(program_arguments));
program_arguments = jv_object_set(program_arguments, jv_string("ARGS"), jv_c
opy(ARGS));
compiled = jq_compile_args(jq, program, jv_copy(program_arguments)); compiled = jq_compile_args(jq, program, jv_copy(program_arguments));
} }
if (!compiled){ if (!compiled){
ret = 3; ret = 3;
goto out; goto out;
} }
if (options & DUMP_DISASM) { if (options & DUMP_DISASM) {
jq_dump_disassembly(jq, 0); jq_dump_disassembly(jq, 0);
printf("\n"); printf("\n");
skipping to change at line 555 skipping to change at line 656
if (jq_util_input_errors(input_state) != 0) if (jq_util_input_errors(input_state) != 0)
ret = 2; ret = 2;
out: out:
badwrite = ferror(stdout); badwrite = ferror(stdout);
if (fclose(stdout)!=0 || badwrite) { if (fclose(stdout)!=0 || badwrite) {
fprintf(stderr,"Error: writing output failed: %s\n", strerror(errno)); fprintf(stderr,"Error: writing output failed: %s\n", strerror(errno));
ret = 2; ret = 2;
} }
jv_free(ARGS);
jv_free(program_arguments); jv_free(program_arguments);
jq_util_input_free(&input_state); jq_util_input_free(&input_state);
jq_teardown(&jq); jq_teardown(&jq);
if (ret >= 10 && (options & EXIT_STATUS)) if (ret >= 10 && (options & EXIT_STATUS))
return ret - 10; return ret - 10;
if (ret >= 10) if (ret >= 10 && !(options & EXIT_STATUS_EXACT))
return 0; return 0;
return ret; return ret;
} }
 End of changes. 50 change blocks. 
105 lines changed or deleted 216 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)