diff options
-rw-r--r-- | build-aux/getopt.m4 | 110 | ||||
-rw-r--r-- | src/format.c | 14 | ||||
-rw-r--r-- | src/grecs-lex.l | 6 | ||||
-rw-r--r-- | src/grecs.hin | 1 | ||||
-rw-r--r-- | src/preproc.c | 3 |
5 files changed, 75 insertions, 59 deletions
diff --git a/build-aux/getopt.m4 b/build-aux/getopt.m4 index c7357d1..97a2cd5 100644 --- a/build-aux/getopt.m4 +++ b/build-aux/getopt.m4 @@ -85,93 +85,94 @@ dnl --------------------------------------- dnl Set options given as arguments. define([<_getopt_set_options>], [<ifelse([<$1>],,, [<_getopt_set_option([<$1>]) _getopt_set_options(shift($@))>])>]) -dnl format_authors(name[,name...]) +dnl __getopt_format_authors(name[,name...]) dnl ------------------------------ -define([<format_authors>],dnl +define([<__getopt_format_authors>],dnl [<ifelse([<$1>],,NULL,[<"$1", -format_authors(shift($@))>])>]) +__getopt_format_authors(shift($@))>])>]) -dnl upcase(ARGS...) +dnl __getopt_upcase(ARGS...) dnl Concatenate and convert ARGS to upper case. dnl -define([<upcase>], [<translit([<$*>], [<a-z>], [<A-Z>])>]) +define([<__getopt_upcase>], [<translit([<$*>], [<a-z>], [<A-Z>])>]) -dnl concat(ARGS...) +dnl __getopt_concat(ARGS...) dnl Concatenate arguments, inserting ", " between each pair of them. dnl -define([<concat>],[<ifelse([<$#>],1,[<$1>],[<$1, concat(shift($@))>])>]) +define([<__getopt_concat>],[<ifelse([<$#>],1,[<$1>],[<$1, __getopt_concat(shift($@))>])>]) -dnl flushleft(ARGS...) +dnl __getopt_flushleft(ARGS...) dnl Concatenate ARGS and remove any leading whitespace dnl -define([<flushleft>], - [<patsubst([<concat($*)>], [<^[ ]+>])>]) +define([<__getopt_flushleft>], + [<patsubst([<__getopt_concat($*)>], [<^[ ]+>])>]) -dnl chop(ARGS...) +dnl __getopt_chop(ARGS...) dnl Concatenate ARGS and remove any trailing whitespace dnl -define([<chop>], +define([<__getopt_chop>], [<patsubst([<$*>], [<[ ]+$>])>]) -dnl escape(ARGS...) +dnl __getopt_escape(ARGS...) dnl Concatenate ARGS and escape any occurrences of double-quotes with dnl backslashes. dnl -define([<escape>], -[<patsubst([<concat($*)>],[<[\"]>],[<\\\&>])>]) +define([<__getopt_escape>], +[<patsubst([<__getopt_concat($*)>],[<[\"]>],[<\\\&>])>]) -dnl prep(ARG) +dnl __getopt_prep(ARG) dnl Prepare ARG for including in C strings: replace newlines and any dnl preceding and following whitespace by a single space character, remove dnl leading whitespace, and escape double-quotes. dnl -define([<prep>], - [<escape(flushleft(patsubst([<$1>],[<[ ]* +define([<__getopt_prep>], + [<__getopt_escape(__getopt_flushleft(patsubst([<$1>],[<[ ]* +[ ]*>],[< >])))>]) -dnl SHORT_OPTS +dnl __GETOPT_SHORT_OPTS dnl Accumulator for the 3rd argument of getopt_long dnl -define([<SHORT_OPTS>],[<_getopt_if_option_set([<nopermute>],+)>]) +define([<__GETOPT_SHORT_OPTS>],[<_getopt_if_option_set([<nopermute>],+)>]) dnl GROUP(STRING) dnl Begin a named group of options dnl define([<GROUP>],[<dnl divert(3) - { NULL, NULL, 0, N_("prep([<$1>])") }, + { NULL, NULL, 0, N_("__getopt_prep([<$1>])") }, divert(-1)>]) -# quote(args) - convert args to single-quoted string -define([<quote>], [<ifelse([<$#>], [<0>], [<>], [<[<$*>]>])>]) -define([<dquote>], [<[<$@>]>]) +# __getopt_quote(args) - convert args to single-quoted string +define([<__getopt_quote>], [<ifelse([<$#>], [<0>], [<>], [<[<$*>]>])>]) +define([<__getopt_dquote>], [<[<$@>]>]) define([<__GATHER_OPTIONS>],[< -define([<KEY>],ifelse([<$2>],,[<OPTION_>]upcase(patsubst($1,-,_)),'$2')) +pushdef([<__GETOPT_KEY>],ifelse([<$2>],,[<OPTION_>]__getopt_upcase(patsubst($1,-,_)),'$2')) ifelse([<$2>],,[< divert(1) - KEY, + __GETOPT_KEY, divert(-1) >]) -define([<SELECTOR>],ifdef([<SELECTOR>],SELECTOR) case KEY:) +define([<__GETOPT_SELECTOR>],ifdef([<__GETOPT_SELECTOR>],__GETOPT_SELECTOR) case __GETOPT_KEY:) ifelse([<$1>],,,[< divert(2) - { "$1", ARGTYPE, 0, KEY }, + { "$1", __GETOPT_ARGTYPE, 0, __GETOPT_KEY }, divert(-1)>]) dnl -define([<SHORT_OPTS>],dquote(SHORT_OPTS[<>]dnl -ifelse([<$2>],,,[<$2>]ifelse(ARGTYPE,[<no_argument>],,ARGTYPE,[<required_argument>],:,ARGTYPE,[<optional_argument>],::)))) +define([<__GETOPT_SHORT_OPTS>],__getopt_dquote(__GETOPT_SHORT_OPTS[<>]dnl +ifelse([<$2>],,,[<$2>]ifelse(__GETOPT_ARGTYPE,[<no_argument>],,__GETOPT_ARGTYPE,[<required_argument>],:,__GETOPT_ARGTYPE,[<optional_argument>],::)))) dnl ifelse([<$1>],,,dnl -[<define([<LONG_TAG>],ifelse(LONG_TAG,,[<--$1>],[<LONG_TAG; --$1>]))>]) +[<define([<__GETOPT_LONG_TAG>],ifelse(__GETOPT_LONG_TAG,,[<--$1>],[<__GETOPT_LONG_TAG; --$1>]))>]) ifelse([<$2>],,,dnl -[<define([<SHORT_TAG>],ifelse(SHORT_TAG,,[<-$2>],[<SHORT_TAG; -$2>]))>]) +[<define([<__GETOPT_SHORT_TAG>],ifelse(__GETOPT_SHORT_TAG,,[<-$2>],[<__GETOPT_SHORT_TAG; -$2>]))>]) +popdef([<__GETOPT_KEY>]) >]) dnl OPTION(long-opt, short-opt, [arg], [descr]) dnl Introduce a command line option. Arguments: dnl long-opt Long option. dnl short-opt Short option (a single char) @@ -186,18 +187,19 @@ dnl enclosed in square brackets, the option takes an optional argument. dnl Otherwise, the argument is required. dnl dnl If descr is not given the option will not appear in the --help and dnl --usage outputs. dnl define([<OPTION>],[< -pushdef([<LONG_TAG>]) -pushdef([<SHORT_TAG>]) -pushdef([<ARGNAME>],[<$3>]) -pushdef([<HIDDEN>],ifelse([<$4>],,1,0)) -pushdef([<DOCSTRING>],[<prep([<$4>])>]) -pushdef([<ARGTYPE>],[<ifelse([<$3>],,[<no_argument>],dnl +pushdef([<__GETOPT_LONG_TAG>]) +pushdef([<__GETOPT_SHORT_TAG>]) +pushdef([<__GETOPT_SELECTOR>]) +pushdef([<__GETOPT_ARGNAME>],[<$3>]) +pushdef([<__GETOPT_HIDDEN>],ifelse([<$4>],,1,0)) +pushdef([<__GETOPT_DOCSTRING>],[<__getopt_prep([<$4>])>]) +pushdef([<__GETOPT_ARGTYPE>],[<ifelse([<$3>],,[<no_argument>],dnl patsubst([<$3>],[<\[.*\]>]),,[<optional_argument>],dnl [<required_argument>])>]) __GATHER_OPTIONS($@) >]) dnl ALIAS(long-opt, short-opt) @@ -213,45 +215,45 @@ __GATHER_OPTIONS($1,$2) dnl BEGIN dnl Start an action associated with the declared option. Must follow OPTION dnl statement, with optional ALIAS statements in between. dnl define([<BEGIN>],[< -ifelse(HIDDEN,1,,[< +ifelse(__GETOPT_HIDDEN,1,,[< divert(3) { #ifdef HAVE_GETOPT_LONG "translit(dnl -ifelse(SHORT_TAG,,LONG_TAG,[<SHORT_TAG[<>]ifelse(LONG_TAG,,,; LONG_TAG)>]), +ifelse(__GETOPT_SHORT_TAG,,__GETOPT_LONG_TAG,[<__GETOPT_SHORT_TAG[<>]ifelse(__GETOPT_LONG_TAG,,,; __GETOPT_LONG_TAG)>]), [<;>],[<,>])", #else - "translit(SHORT_TAG, [<;>],[<,>])", + "translit(__GETOPT_SHORT_TAG, [<;>],[<,>])", #endif - ifelse(ARGNAME,,[<NULL, 0>], -[<ifelse(ARGTYPE,[<optional_argument>], -[<N_(>]"[<patsubst(ARGNAME,[<\[\(.*\)\]>],[<\1>])>][<"), 1>],[<N_("ARGNAME"), 0>])>]), N_("DOCSTRING") }, + ifelse(__GETOPT_ARGNAME,,[<NULL, 0>], +[<ifelse(__GETOPT_ARGTYPE,[<optional_argument>], +[<N_(>]"[<patsubst(__GETOPT_ARGNAME,[<\[\(.*\)\]>],[<\1>])>][<"), 1>],[<N_("__GETOPT_ARGNAME"), 0>])>]), N_("__GETOPT_DOCSTRING") }, divert(-1)>]) -popdef([<ARGTYPE>]) -popdef([<ARGNAME>]) -popdef([<DOCSTRING>]) -popdef([<HIDDEN>]) +popdef([<__GETOPT_ARGTYPE>]) +popdef([<__GETOPT_ARGNAME>]) +popdef([<__GETOPT_DOCSTRING>]) +popdef([<__GETOPT_HIDDEN>]) divert(4)dnl -popdef([<LONG_TAG>])dnl -popdef([<SHORT_TAG>])dnl - SELECTOR +popdef([<__GETOPT_LONG_TAG>])dnl +popdef([<__GETOPT_SHORT_TAG>])dnl + __GETOPT_SELECTOR { >]) dnl END dnl Finish the associated action dnl define([<END>],[< break; } divert(-1) -undefine([<SELECTOR>])>]) +popdef([<__GETOPT_SELECTOR>])>]) dnl OPTNODE(name, value) define([<OPTNODE>],[<do { struct grecs_node *node = grecs_node_from_path($1, $2); if (!cmdline_tree) cmdline_tree = node; @@ -272,16 +274,16 @@ dnl define([<GETOPT>],[< { int c; optind = 0; #ifdef HAVE_GETOPT_LONG - while ((c = getopt_long($1, $2, "SHORT_OPTS", + while ((c = getopt_long($1, $2, "__GETOPT_SHORT_OPTS", long_options, NULL)) != EOF) #else - while ((c = getopt($1, $2, "SHORT_OPTS")) != EOF) + while ((c = getopt($1, $2, "__GETOPT_SHORT_OPTS")) != EOF) #endif { switch (c) { default: ifelse([<$4>],,,[<$4;>])dnl diff --git a/src/format.c b/src/format.c index 6c13ac4..aaad65a 100644 --- a/src/format.c +++ b/src/format.c @@ -1,8 +1,8 @@ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2012, 2015 Sergey Poznyakoff + Copyright (C) 2007-2015 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. @@ -185,12 +185,14 @@ grecs_print_statement_array(struct grecs_keyword *kwp, FILE *stream) { if (!kwp) { return; } for (; kwp->ident; kwp++, n++) { + if (kwp->flags & GRECS_HIDDEN) + continue; if (n) fputc('\n', stream); if (kwp->type == grecs_type_section) grecs_print_block_statement(kwp, level, stream); else grecs_print_simple_statement(kwp, level, stream); @@ -239,12 +241,17 @@ grecs_format_locus(grecs_locus_t *locus, struct grecs_format_closure *clos) void grecs_format_node_path(struct grecs_node *node, int flags, struct grecs_format_closure *clos) { char delim[2] = "."; + if (!node) { + clos->fmtfun("NULL", clos->data); + return; + } + if (node->up) grecs_format_node_path(node->up, flags, clos); if (node->type == grecs_node_root) return; if (flags & _GRECS_NODE_MASK_DELIM) delim[0] = flags & _GRECS_NODE_MASK_DELIM; @@ -318,12 +325,17 @@ grecs_format_node(struct grecs_node *node, int flags, if (!(flags & _GRECS_NODE_MASK_OUTPUT)) { errno = EINVAL; return 1; } + if (!node) { + clos->fmtfun("NULL", clos->data); + return 0; + } + switch (node->type) { case grecs_node_root: case grecs_node_block: if (flags & GRECS_NODE_FLAG_DESCEND) { for (node = node->down; node; node = node->next) { grecs_format_node(node, flags, clos); diff --git a/src/grecs-lex.l b/src/grecs-lex.l index 15d5e9b..29a511e 100644 --- a/src/grecs-lex.l +++ b/src/grecs-lex.l @@ -380,13 +380,14 @@ grecs_parse_line_directive(char *text, grecs_locus_t *ploc, struct grecs_locus_point *ppoint, size_t *pxlines) { int rc = 1; struct wordsplit ws; if (wordsplit(text, &ws, WRDSF_DEFFLAGS)) - grecs_error(ploc, 0, _("cannot parse #line line")); + grecs_error(ploc, 0, _("cannot parse #line line: %s"), + wordsplit_strerror(&ws)); else { if (ws.ws_wordc == 2) rc = assign_locus(ppoint, NULL, ws.ws_wordv[1], pxlines); else if (ws.ws_wordc == 3) rc = assign_locus(ppoint, ws.ws_wordv[2], @@ -416,13 +417,14 @@ grecs_parse_line_directive_cpp(char *text, grecs_locus_t *ploc, struct grecs_locus_point *ppoint, size_t *pxlines) { struct wordsplit ws; if (wordsplit(text, &ws, WRDSF_DEFFLAGS)) { - grecs_error(ploc, 0, _("cannot parse #line line")); + grecs_error(ploc, 0, _("cannot parse #line line: %s"), + wordsplit_strerror(&ws)); return; } else if (ws.ws_wordc < 3) grecs_error(ploc, 0, _("invalid #line statement")); else { if (assign_locus(ppoint, ws.ws_wordv[2], ws.ws_wordv[1], pxlines)) diff --git a/src/grecs.hin b/src/grecs.hin index 6e3f54c..c01c175 100644 --- a/src/grecs.hin +++ b/src/grecs.hin @@ -99,12 +99,13 @@ enum grecs_data_type { #define GRECS_DFLT 0x00 #define GRECS_AGGR 0x01 #define GRECS_MULT 0x02 #define GRECS_INAC 0x04 #define GRECS_LIST 0x08 +#define GRECS_HIDDEN 0x10 enum grecs_callback_command { grecs_callback_section_begin, grecs_callback_section_end, grecs_callback_set_value }; diff --git a/src/preproc.c b/src/preproc.c index 2753b40..bdf4d40 100644 --- a/src/preproc.c +++ b/src/preproc.c @@ -603,14 +603,13 @@ parse_include(const char *text, int once) len = strlen (p); if (p[0] == '<' && p[len - 1] == '>') { allow_cwd = 0; p[len - 1] = 0; p++; - } - else + } else allow_cwd = 1; if (isglob(p)) { switch (glob(p, 0, NULL, &include_glob)) { case 0: include_pos = 0; |