2 * UCW Library -- Shell Interface to Configuration Files
4 * (c) 2002--2005 Martin Mares <mj@ucw.cz>
5 * (c) 2006 Robert Spalek <robert@ucw.cz>
7 * Once we were using this beautiful Shell version, but it turned out
8 * that it doesn't work with nested config files:
10 * eval `sed <cf/sherlock '/^#/d;/^ *$/d;s/ \+$//;
11 * h;s@[^ ]*@@;x;s@[ ].*@@;y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/;G;s/\n//;
12 * /^\[SECTION\]/,/^\[/ {; /^[A-Z]/ { s/^\([^ ]\+\)[ ]*\(.*\)$/SH_\1="\2"/; p; }; };
15 * This software may be freely distributed and used according to the terms
16 * of the GNU Lesser General Public License.
21 #include "lib/getopt.h"
41 Usage: config [-C<configfile>] [-S<section>.<option>=<value>] <section> [@]<item><type>[=<default>] <item2> ... [*]\n\
45 #\t\t32-bit integer\n\
46 ##\t\t64-bit integer\n\
47 $\t\tFloating point number\n\
50 @\t\tMultiple occurences of the item are passed as an array (otherwise the last one wins)\n\
51 *\t\tIgnore unknown items instead of reporting them as errors\n\
57 report(uns num, byte **pars, struct cf_item *item)
60 for (uns i=0; i<num; i++)
63 byte *err, *value = buf;
64 switch (f & F_TYPE_MASK) {
70 if (err = cf_parse_int(pars[i], &val))
72 sprintf(buf, "%d", val);
76 if (err = cf_parse_u64(pars[i], &val64))
78 sprintf(buf, "%Lu", val64);
82 if (err = cf_parse_double(pars[i], &valf))
84 sprintf(buf, "%g", valf);
91 printf("CF_%s[${#CF_%s[*]}]='", item->name, item->name);
93 printf("CF_%s='", item->name);
96 die("Apostrophes are not supported in config of scripts");
104 int main(int argc, char **argv)
110 while (i < argc && argv[i][0] == '-')
116 byte *sec_name = argv[i++];
117 uns allow_unknown = 0;
118 struct cf_section *sec = xmalloc_zero(sizeof(struct cf_section));
119 struct cf_item *c = sec->cfg = xmalloc_zero(sizeof(struct cf_item) * (argc-i+1));
123 byte *arg = xstrdup(argv[i]);
124 if (!strcmp(arg, "*"))
128 byte *e = strchr(arg, '=');
132 byte *t = arg + strlen(arg) - 1;
138 if (t > arg && *t == '#')
156 printf("declare -a CF_%s ; CF_%s=()\n", arg, arg);
162 c->number = (c->type & F_ARRAY) ? CF_ANY_NUM : 1;
164 c->u.par = (cf_parser*) report;
166 byte *err = report(1, &e, c);
168 die("Cannot parse the default value #%d: %s", c-sec->cfg, err);
174 cf_declare_section(sec_name, sec, allow_unknown);
175 if (cf_getopt(start, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) != -1)