]> mj.ucw.cz Git - libucw.git/blob - ucw/opt-conf.c
Let <ucw/lib.h> include <stdbool.h> automatically
[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_handle_config(struct opt_item * opt UNUSED, const char * value, void * data UNUSED)
28 {
29   if (cf_load(value))
30     exit(1);            // Error message is already printed by cf_load()
31 }
32
33 void opt_handle_set(struct opt_item * opt UNUSED, const char * value, void * data UNUSED)
34 {
35   struct cf_context *cc = cf_get_context();
36   cf_load_default(cc);
37   if (cf_set(value))
38     opt_failure("Cannot set %s", value);
39 }
40
41 void opt_handle_dumpconfig(struct opt_item * opt UNUSED, const char * value UNUSED, void * data UNUSED)
42 {
43   struct cf_context *cc = cf_get_context();
44   opt_conf_end_of_options(cc);
45   struct fastbuf *b = bfdopen(1, 4096);
46   cf_dump_sections(b);
47   bclose(b);
48   exit(0);
49 }
50
51 void opt_conf_hook_internal(struct opt_item * opt, uns event, 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   struct cf_context *cc = cf_get_context();
58
59   if (event == OPT_HOOK_FINAL) {
60       opt_conf_end_of_options(cc);
61       return;
62   }
63
64   ASSERT(event == OPT_HOOK_BEFORE_VALUE);
65
66   bool confopt = opt->flags & OPT_BEFORE_CONFIG;
67
68   switch (state) {
69     case OPT_CONF_HOOK_BEGIN:
70       if (confopt)
71         state = OPT_CONF_HOOK_CONFIG;
72       else {
73         opt_conf_end_of_options(cc);
74         state = OPT_CONF_HOOK_OTHERS;
75       }
76       break;
77     case OPT_CONF_HOOK_CONFIG:
78       if (!confopt) {
79         opt_conf_end_of_options(cc);
80         state = OPT_CONF_HOOK_OTHERS;
81       }
82       break;
83     case OPT_CONF_HOOK_OTHERS:
84       if (confopt)
85         opt_failure("Config options must stand before other options.");
86       break;
87     default:
88       ASSERT(0);
89   }
90 }