]> mj.ucw.cz Git - libucw.git/blob - ucw/opt-conf.c
Opt: Split to three separate modules
[libucw.git] / ucw / opt-conf.c
1 /*
2  *      UCW Library -- Interface between command-line options and configuration
3  *
4  *      (c) 2013 Jan Moskyto Matejka <mq@ucw.cz>
5  *      (c) 2014 Martin Mares <mj@ucw.cz>
6  *
7  *      This software may be freely distributed and used according to the terms
8  *      of the GNU Lesser General Public License.
9  */
10
11 #include <ucw/lib.h>
12 #include <ucw/opt.h>
13 #include <ucw/opt-internal.h>
14 #include <ucw/conf.h>
15 #include <ucw/conf-internal.h>
16 #include <ucw/fastbuf.h>
17
18 #include <alloca.h>
19 #include <math.h>
20
21 static void opt_conf_end_of_options(struct cf_context *cc) {
22   cf_load_default(cc);
23   if (cc->postpone_commit && cf_close_group())
24     opt_failure("Loading of configuration failed");
25 }
26
27 void opt_conf_internal(struct opt_item * opt, const char * value, void * data UNUSED) {
28   struct cf_context *cc = cf_get_context();
29   switch (opt->letter) {
30     case 'S':
31       cf_load_default(cc);
32       if (cf_set(value))
33         opt_failure("Cannot set %s", value);
34       break;
35     case 'C':
36       if (cf_load(value))
37         opt_failure("Cannot load config file %s", value);
38       break;
39 #ifdef CONFIG_UCW_DEBUG
40     case '0':
41       opt_conf_end_of_options(cc);
42       struct fastbuf *b = bfdopen(1, 4096);
43       cf_dump_sections(b);
44       bclose(b);
45       exit(0);
46       break;
47 #endif
48   }
49 }
50
51 void opt_conf_hook_internal(struct opt_item * opt, const char * value UNUSED, void * data UNUSED) {
52   static enum {
53     OPT_CONF_HOOK_BEGIN,
54     OPT_CONF_HOOK_CONFIG,
55     OPT_CONF_HOOK_OTHERS
56   } state = OPT_CONF_HOOK_BEGIN;
57
58   int confopt = 0;
59
60   if (opt->letter == 'S' || opt->letter == 'C' || (opt->name && !strcmp(opt->name, "dumpconfig")))
61     confopt = 1;
62
63   switch (state) {
64     case OPT_CONF_HOOK_BEGIN:
65       if (confopt)
66         state = OPT_CONF_HOOK_CONFIG;
67       else {
68         opt_conf_end_of_options(cf_get_context());
69         state = OPT_CONF_HOOK_OTHERS;
70       }
71       break;
72     case OPT_CONF_HOOK_CONFIG:
73       if (!confopt) {
74         opt_conf_end_of_options(cf_get_context());
75         state = OPT_CONF_HOOK_OTHERS;
76       }
77       break;
78     case OPT_CONF_HOOK_OTHERS:
79       if (confopt)
80         opt_failure("Config options (-C, -S) must stand before other options.");
81       break;
82     default:
83       ASSERT(0);
84   }
85 }