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.
20 #include "lib/conf2.h"
40 Usage: config [-C<configfile>] [-S<section>.<option>=<value>] <section> [@]<item><type>[=<default>] <item2> ... [*]\n\
44 #\t\t32-bit integer\n\
45 ##\t\t64-bit integer\n\
46 $\t\tFloating point number\n\
49 @\t\tMultiple occurences of the item are passed as an array (otherwise the last one wins)\n\
50 *\t\tIgnore unknown items instead of reporting them as errors\n\
56 report(uns num, byte **pars, struct cf_item *item)
59 for (uns i=0; i<num; i++)
62 byte *err, *value = buf;
63 switch (f & F_TYPE_MASK) {
69 if (err = cf_parse_int(pars[i], &val))
71 sprintf(buf, "%d", val);
75 if (err = cf_parse_u64(pars[i], &val64))
77 sprintf(buf, "%Lu", val64);
81 if (err = cf_parse_double(pars[i], &valf))
83 sprintf(buf, "%g", valf);
90 printf("CF_%s[${#CF_%s[*]}]='", item->name, item->name);
92 printf("CF_%s='", item->name);
95 die("Apostrophes are not supported in config of scripts");
103 int main(int argc, char **argv)
109 while (i < argc && argv[i][0] == '-')
115 byte *sec_name = argv[i++];
116 uns allow_unknown = 0;
117 struct cf_section *sec = xmalloc_zero(sizeof(struct cf_section));
118 struct cf_item *c = sec->cfg = xmalloc_zero(sizeof(struct cf_item) * (argc-i+1));
122 byte *arg = xstrdup(argv[i]);
123 if (!strcmp(arg, "*"))
127 byte *e = strchr(arg, '=');
131 byte *t = arg + strlen(arg) - 1;
137 if (t > arg && *t == '#')
155 printf("declare -a CF_%s ; CF_%s=()\n", arg, arg);
161 c->number = (c->type & F_ARRAY) ? CF_ANY_NUM : 1;
163 c->u.par = (cf_parser*) report;
165 byte *err = report(1, &e, c);
167 die("Cannot parse the default value #%d: %s", c-sec->cfg, err);
173 cf_declare_section(sec_name, sec, allow_unknown);
174 if (cf_get_opt(start, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) != -1)