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