]> mj.ucw.cz Git - libucw.git/blob - lib/shell/config.c
The shell config helper now knows how to parse multiple-valued entries
[libucw.git] / lib / shell / config.c
1 /*
2  *      Sherlock Library -- Shell Interface to Configuration Files
3  *
4  *      (c) 2002 Martin Mares <mj@ucw.cz>
5  *
6  *      Once we were using this beautiful Shell version, but it turned out
7  *      that it doesn't work with nested config files:
8  *
9  *              eval `sed <cf/sherlock '/^#/d;/^ *$/d;s/ \+$//;
10  *              h;s@[^  ]*@@;x;s@[      ].*@@;y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/;G;s/\n//;
11  *              /^\[SECTION\]/,/^\[/ {; /^[A-Z]/ { s/^\([^      ]\+\)[  ]*\(.*\)$/SH_\1="\2"/; p; }; };
12  *              d;'`
13  *
14  *      This software may be freely distributed and used according to the terms
15  *      of the GNU Lesser General Public License.
16  */
17
18 #include "lib/lib.h"
19 #include "lib/conf.h"
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 static struct cfitem *items;
26 static byte *flags;
27
28 static void
29 help(void)
30 {
31   die("Usage: config [-C<configfile>] [-S<section>.<option>=<value>] <section> [@]<item>[=<default>] <item2> ... [*]");
32 }
33
34 static byte *
35 report(struct cfitem *item, byte *value)
36 {
37   if (flags[item-items])
38     printf("CF_%s[${#CF_%s[*]}]='", item->name, item->name);
39   else
40     printf("CF_%s='", item->name);
41   while (*value)
42     {
43       if (*value == '\'')
44         die("Apostrophes are not supported in config of scripts");
45       putchar(*value++);
46     }
47   puts("'");
48   return NULL;
49 }
50
51 int main(int argc, char **argv)
52 {
53   int i = 1;
54   int start;
55   struct cfitem *c;
56
57   log_init("config");
58   while (i < argc && argv[i][0] == '-')
59     i++;
60   if (i + 1 >= argc)
61     help();
62   start = i;
63   c = items = alloca(sizeof(struct cfitem) * (argc-i+1));
64   flags = alloca(argc);
65   bzero(flags, argc);
66   c->name = argv[i];
67   c->type = CT_SECTION;
68   c->var = NULL;
69   c++;
70   while (++i < argc)
71     {
72       if (!strcmp(argv[i], "*"))
73         items->type = CT_INCOMPLETE_SECTION;
74       else
75         {
76           char *e = strchr(argv[i], '=');
77           c->name = argv[i];
78           c->type = CT_FUNCTION;
79           c->var = report;
80           if (e)
81             *e++ = 0;
82           if (*c->name == '@')
83             {
84               c->name++;
85               printf("declare -a CF_%s ; CF_%s=()\n", c->name, c->name);
86               flags[c-items] = 1;
87             }
88           if (e)
89             report(c, e);
90           c++;
91         }
92     }
93   c->type = CT_STOP;
94   cf_register(items);
95   if (cf_getopt(start, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) != -1)
96     help();
97   return 0;
98 }