]> mj.ucw.cz Git - libucw.git/blob - ucw/opt-conf.c
d306db98dc4dab6322e7e96b5200c58ef7b39d04
[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 #include <stdbool.h>
21
22 static void opt_conf_end_of_options(struct cf_context *cc) {
23   cf_load_default(cc);
24   if (cc->postpone_commit && cf_close_group())
25     opt_failure("Loading of configuration failed");
26 }
27
28 void opt_handle_config(struct opt_item * opt UNUSED, const char * value, void * data UNUSED)
29 {
30   if (cf_load(value))
31     exit(1);            // Error message is already printed by cf_load()
32 }
33
34 void opt_handle_set(struct opt_item * opt UNUSED, const char * value, void * data UNUSED)
35 {
36   struct cf_context *cc = cf_get_context();
37   cf_load_default(cc);
38   if (cf_set(value))
39     opt_failure("Cannot set %s", value);
40 }
41
42 void opt_handle_dumpconfig(struct opt_item * opt UNUSED, const char * value UNUSED, void * data UNUSED)
43 {
44   struct cf_context *cc = cf_get_context();
45   opt_conf_end_of_options(cc);
46   struct fastbuf *b = bfdopen(1, 4096);
47   cf_dump_sections(b);
48   bclose(b);
49   exit(0);
50 }
51
52 void opt_conf_hook_internal(struct opt_item * opt, const char * value UNUSED, void * data UNUSED) {
53   static enum {
54     OPT_CONF_HOOK_BEGIN,
55     OPT_CONF_HOOK_CONFIG,
56     OPT_CONF_HOOK_OTHERS
57   } state = OPT_CONF_HOOK_BEGIN;
58
59   bool confopt = opt->flags & OPT_BEFORE_CONFIG;
60
61   switch (state) {
62     case OPT_CONF_HOOK_BEGIN:
63       if (confopt)
64         state = OPT_CONF_HOOK_CONFIG;
65       else {
66         opt_conf_end_of_options(cf_get_context());
67         state = OPT_CONF_HOOK_OTHERS;
68       }
69       break;
70     case OPT_CONF_HOOK_CONFIG:
71       if (!confopt) {
72         opt_conf_end_of_options(cf_get_context());
73         state = OPT_CONF_HOOK_OTHERS;
74       }
75       break;
76     case OPT_CONF_HOOK_OTHERS:
77       if (confopt)
78         opt_failure("Config options must stand before other options.");
79       break;
80     default:
81       ASSERT(0);
82   }
83 }