From 75421cbfe32ae6428fe08b6ba83f1f7ac0322c33 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Sun, 16 Dec 2012 19:46:41 +0000 Subject: [PATCH] Add the ability to specify input files on the commandline. See #21. --- docs/content/3.manual/manual.yml | 6 +++- main.c | 58 +++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/docs/content/3.manual/manual.yml b/docs/content/3.manual/manual.yml index 6e8065c6..5acb212c 100644 --- a/docs/content/3.manual/manual.yml +++ b/docs/content/3.manual/manual.yml @@ -33,12 +33,16 @@ manpage_intro: | ## SYNOPSIS - `jq` [...] + `jq` [...] [...] `jq` can transform JSON in various ways, by selecting, iterating, reducing and otherwise mangling JSON documents. For instance, running the command `jq 'map(.price) | add'` will take an array of JSON objects as input and return the sum of their "price" fields. + + By default, `jq` reads a stream of JSON objects (whitespace + separated) from `stdin`. One or more may be specified, in + which case `jq` will read input from those instead. The are described in the [INVOKING JQ] section, they mostly concern input and output formatting. The is written diff --git a/main.c b/main.c index 64cb1fd4..252ebd5a 100644 --- a/main.c +++ b/main.c @@ -16,10 +16,11 @@ static const char* progname; static void usage() { fprintf(stderr, "\njq - commandline JSON processor [version %s]\n", JQ_VERSION); - fprintf(stderr, "Usage: %s [options] \n\n", progname); + fprintf(stderr, "Usage: %s [options] [file...]\n\n", progname); fprintf(stderr, "For a description of the command line options and\n"); fprintf(stderr, "how to write jq filters (and why you might want to)\n"); - fprintf(stderr, "see the jq documentation at http://stedolan.github.com/jq\n\n"); + fprintf(stderr, "see the jq manpage, or the online documentation at\n"); + fprintf(stderr, "http://stedolan.github.com/jq\n\n"); exit(1); } @@ -102,14 +103,53 @@ static jv slurp_file(const char* filename) { return data; } +FILE* current_input; +const char** input_filenames; +int ninput_files; +int next_input_idx; +static int read_more(char* buf, size_t size) { + while (!current_input || feof(current_input)) { + if (current_input) { + fclose(current_input); + current_input = 0; + } + if (next_input_idx == ninput_files) { + return 0; + } + if (!strcmp(input_filenames[next_input_idx], "-")) { + current_input = stdin; + } else { + current_input = fopen(input_filenames[next_input_idx], "r"); + } + if (!current_input) { + fprintf(stderr, "%s: %s: %s\n", progname, input_filenames[next_input_idx], strerror(errno)); + } + next_input_idx++; + } + + if (!fgets(buf, sizeof(buf), current_input)) buf[0] = 0; + return 1; +} + int main(int argc, char* argv[]) { if (argc) progname = argv[0]; const char* program = 0; + input_filenames = malloc(sizeof(const char*) * argc); + ninput_files = 0; + int further_args_are_files = 0; for (int i=1; i 0) { @@ -216,7 +256,7 @@ int main(int argc, char* argv[]) { process(slurped); } } - + free(input_filenames); bytecode_free(bc); return 0; }