From b27b366ba0e10787e462100e49cf8739dbe40cb3 Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Sat, 15 May 2021 11:27:40 +0100 Subject: [PATCH] query-runlisp-config.c: Add `-M' option for machine-readable output. Organization: Straylight/Edgeware From: Mark Wooding --- query-runlisp-config.1.in | 14 +++++++- query-runlisp-config.c | 68 ++++++++++++++++++++++++++++----------- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/query-runlisp-config.1.in b/query-runlisp-config.1.in index 07a5893..d49da57 100644 --- a/query-runlisp-config.1.in +++ b/query-runlisp-config.1.in @@ -49,7 +49,8 @@ query-runlisp-config \- inspect and debug runlisp configuration files .SH SYNOPSIS . .B query-runlisp-config -.RB [ \-Lqv ] +.RB [ \-LMqv ] +.RB [ +M ] .RB [ \-c .IR conf ] .RB [ \-o @@ -108,6 +109,17 @@ and immediately exit with status 0. List all of the known section names to standard output. . .TP +.BR "\-M" ", " "\-\-machine-readable" +Don't print prefixes or header lines to the output. +This makes it easier to use +.B query-runlisp-config +from simple scripts. +Negate with +.B +M +or +.BR \-\-no-machine-readable . +. +.TP .BI "\-c" "\fR, " "\-\-config-file=" conf Read configuration from .IR conf . diff --git a/query-runlisp-config.c b/query-runlisp-config.c index ed8e6ce..7335a81 100644 --- a/query-runlisp-config.c +++ b/query-runlisp-config.c @@ -61,6 +61,7 @@ static struct op *oplist; /* list of queued-up operations */ static unsigned flags = 0; /* flags for the application */ #define AF_BOGUS 0x0001u /* invalid command-line syntax */ #define AF_SETCONF 0x0002u /* explicit configuration */ +#define AF_PLAIN 0x0004u /* don't print labels */ /*----- Main code ---------------------------------------------------------*/ @@ -104,7 +105,7 @@ static void version(FILE *fp) static void usage(FILE *fp) { fprintf(fp, "\ -usage: %s [-Lqv] [-c CONF] [-o [SECT:]VAR=VAL]\n\ +usage: %s [-LMqv] [+M] [-c CONF] [-o [SECT:]VAR=VAL]\n\ [-l SECT] [-p [SECT:]VAR] [-w [SECT:]VAR] [-x [SECT:]VAR]\n", progname); } @@ -127,6 +128,7 @@ Configuration:\n\ \n\ Output:\n\ -L, --list-sections List all known section names in order.\n\ + -M, --machine-readable Don't print headers or labels.\n\ -l, --list-variables=SECTION List all defined variables in SECTION.\n\ -p, --print-variable=[SECT:]VAR Print the raw (unexpanded) value of VAR.\n\ -w, --split-variable=[SECT:]VAR Expand and word-split VAR and print.\n\ @@ -150,6 +152,7 @@ int main(int argc, char *argv[]) { "help", 0, 0, 'h' }, { "version", 0, 0, 'V' }, { "list-sections", 0, 0, 'L' }, + { "machine-readable", OPTF_NEGATE, 0, 'M' }, { "config-file", OPTF_ARGREQ, 0, 'c' }, { "list-variables", OPTF_ARGREQ, 0, 'l' }, { "set-option", OPTF_ARGREQ, 0, 'o' }, @@ -173,14 +176,24 @@ int main(int argc, char *argv[]) * a list until later. */ optprog = (/*unconst*/ char *)progname; + +#define FLAGOPT(ch, f) \ + case ch: \ + flags |= f; \ + break; \ + case ch | OPTF_NEGATED: \ + flags &= ~f; \ + break + for (;;) { - i = mdwopt(argc - 1, argv + 1, "hVLc:l:o:p:qvw:x:", opts, 0, 0, + i = mdwopt(argc - 1, argv + 1, "hVLM+c:l:o:p:qvw:x:", opts, 0, 0, OPTF_NOPROGNAME); if (i < 0) break; switch (i) { case 'h': help(stdout); exit(0); case 'V': version(stdout); exit(0); case 'L': add_op(&tail, OP_LISTSEC, 0); break; + FLAGOPT('M', AF_PLAIN); case 'c': read_config_path(optarg, 0); flags |= AF_SETCONF; break; case 'l': add_op(&tail, OP_LISTVAR, optarg); break; case 'o': if (set_config_var(optarg)) flags |= AF_BOGUS; break; @@ -193,6 +206,8 @@ int main(int argc, char *argv[]) } } +#undef FLAGOPT + /* Check that everything worked. */ optind++; if (optind < argc) flags |= AF_BOGUS; @@ -207,48 +222,63 @@ int main(int argc, char *argv[]) switch (op->code) { case OP_LISTSEC: - printf("sections:\n"); + if (!(flags&AF_PLAIN)) printf("sections:\n"); for (config_start_section_iter(&config, &si); (sect = config_next_section(&si)); ) - printf("\t%s\n", CONFIG_SECTION_NAME(sect)); + printf("%s%s\n", + flags&AF_PLAIN ? "" : "\t", + CONFIG_SECTION_NAME(sect)); break; case OP_LISTVAR: sect = config_find_section(&config, 0, op->arg); - if (!sect) - printf("section `%s' not found\n", op->arg); - else { - printf("section `%s' variables:\n", CONFIG_SECTION_NAME(sect)); + if (sect) { + if (!(flags&AF_PLAIN)) + printf("section `%s' variables:\n", CONFIG_SECTION_NAME(sect)); for (config_start_var_iter(&config, sect, &vi); (var = config_next_var(&vi)); ) - printf("\t%s\n", CONFIG_VAR_NAME(var)); + printf("%s%s\n", + flags&AF_PLAIN ? "" : "\t", + CONFIG_VAR_NAME(var)); + } else { + if (flags&AF_PLAIN) lose("section `%s' not found", op->arg); + else printf("section `%s' not found\n", op->arg); } break; case OP_RAW: find_var(op->arg, §, &var); - if (!var) printf("%s not found\n", op->arg); - else printf("%s = %s\n", op->arg, var->val); + if (flags&AF_PLAIN) { + if (var) puts(var->val); + else lose("variable `%s' not found", op->arg); + } else { + if (var) printf("%s = %s\n", op->arg, var->val); + else printf("%s not found\n", op->arg); + } break; case OP_SUBST: find_var(op->arg, §, &var); - if (!var) - printf("%s not found\n", op->arg); - else { + if (var) { dstr_reset(&d); config_subst_var(&config, sect, var, &d); - printf("%s = %s\n", op->arg, d.p); + if (flags&AF_PLAIN) puts(d.p); + else printf("%s = %s\n", op->arg, d.p); + } else { + if (flags&AF_PLAIN) lose("variable %s not found", op->arg); + else printf("%s not found\n", op->arg); } break; case OP_SPLIT: find_var(op->arg, §, &var); - if (!var) - printf("%s not found\n", op->arg); - else { + if (var) { argv_reset(&av); config_subst_split_var(&config, sect, var, &av); dstr_reset(&d); argv_string(&d, &av); - printf("%s = %s\n", op->arg, d.p); + if (flags&AF_PLAIN) puts(d.p); + else printf("%s = %s\n", op->arg, d.p); + } else { + if (flags&AF_PLAIN) lose("variable %s not found", op->arg); + else printf("%s not found\n", op->arg); } break; -- [mdw]