]> mj.ucw.cz Git - libucw.git/blob - lib/conf2-test.c
Fixed operator priorities in cf_parse_ip().
[libucw.git] / lib / conf2-test.c
1 /*
2  *      Insane tester of reading configuration files
3  *
4  *      (c) 2006 Robert Spalek <robert@ucw.cz>
5  */
6
7 #include "lib/lib.h"
8 #include "lib/conf2.h"
9 #include "lib/clists.h"
10 #include "lib/fastbuf.h"
11
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <time.h>
15 #include <getopt.h>
16
17 static int verbose;
18
19 struct sub_sect_1 {
20   struct cnode n;
21   byte *name;
22   byte *level;
23   int confidence[2];
24   double *list;
25 };
26
27 static struct sub_sect_1 sec1 = { {}, "Charlie", "WBAFC", { 0, -1}, DARY_ALLOC(double, 3, 1e4, -1e-4, 8) };
28
29 static byte *
30 init_sec_1(struct sub_sect_1 *s)
31 {
32   if (s == &sec1) {                     // this is a static variable; skip clearing
33     DARY_LEN(sec1.list) = 3;            // XXX: fix for the bug in DARY_ALLOC()
34     return NULL;
35   }
36   s->name = "unknown";
37   s->level = "default";
38   s->confidence[0] = 5;
39   s->confidence[1] = 6;
40   // leave s->list==NULL
41   return NULL;
42 }
43
44 static byte *
45 commit_sec_1(struct sub_sect_1 *s)
46 {
47   if (s->confidence[0] < 0 || s->confidence[0] > 10)
48     return "Well, this can't be";
49   return NULL;
50 }
51
52 static struct cf_section cf_sec_1 = {
53   CF_TYPE(struct sub_sect_1),
54   CF_INIT(init_sec_1),
55   CF_COMMIT(commit_sec_1),
56 #define F(x)    PTR_TO(struct sub_sect_1, x)
57   CF_ITEMS {
58     CF_STRING("name", F(name)),
59     CF_STRING("level", F(level)),
60     CF_INT_ARY("confidence", F(confidence[0]), 2),              // XXX: the [0] is needed for the sake of type checking
61     CF_DOUBLE_DYN("list", F(list), 100),
62     CF_END
63   }
64 #undef F
65 };
66
67 static uns nr1 = 15;
68 static int *nrs1 = DARY_ALLOC(int, 5, 5, 4, 3, 2, 1);
69 static int nrs2[5];
70 static byte *str1 = "no worries";
71 static byte **str2 = DARY_ALLOC(byte *, 2, "Alice", "Bob");
72 static u64 u1 = 0xCafeBeefDeadC00ll;
73 static double d1 = -1.1;
74 static struct clist secs;
75 static time_t t1, t2;
76 static u32 ip;
77 static int look[2] = {2, 1};
78
79 static byte *
80 init_top(void *ptr UNUSED)
81 {
82   for (uns i=0; i<5; i++)
83   {
84     struct sub_sect_1 *s = xmalloc(sizeof(struct sub_sect_1));  // XXX: cannot by cf_malloc(), because it's deleted when cf_reload()'ed
85     cf_init_section("slaves", &cf_sec_1, s, 1);
86     s->confidence[1] = i;
87     clist_add_tail(&secs, &s->n);
88   }
89   return NULL;
90 }
91
92 static byte *
93 commit_top(void *ptr UNUSED)
94 {
95   if (nr1 != 15)
96     return "Don't touch my variable!";
97   return NULL;
98 }
99
100 static byte *
101 time_parser(uns number, byte **pars, time_t *ptr)
102 {
103   *ptr = number ? atoi(pars[0]) : time(NULL);
104   return NULL;
105 }
106
107 static char *alphabet[] = { "alpha", "beta", "gamma", "delta", NULL };
108 static struct cf_section cf_top = {
109   CF_INIT(init_top),
110   CF_COMMIT(commit_top),
111   CF_ITEMS {
112     CF_UNS("nr1", &nr1),
113     CF_INT_DYN("nrs1", &nrs1, 1000),
114     CF_INT_ARY("nrs2", nrs2, 5),
115     CF_STRING("str1", &str1),
116     CF_STRING_DYN("str2", &str2, 20),
117     CF_U64("u1", &u1),
118     CF_DOUBLE("d1", &d1),
119     CF_PARSER("FirstTime", &t1, time_parser, -1),
120     CF_PARSER("SecondTime", &t2, time_parser, 1),
121     CF_SECTION("master", &sec1, &cf_sec_1),
122     CF_LIST("slaves", &secs, &cf_sec_1),
123     CF_IP("ip", &ip),
124     CF_LOOKUP_ARY("look", look, alphabet, 2),
125     CF_END
126   }
127 };
128
129 static byte short_opts[] = CF_SHORT_OPTS "v";
130 static struct option long_opts[] = {
131         CF_LONG_OPTS
132         {"verbose",     0, 0, 'v'},
133         {NULL,          0, 0, 0}
134 };
135
136 static char *help = "\
137 Usage: conf2-test <options>\n\
138 \n\
139 Options:\n"
140 CF_USAGE
141 "-v\t\t\tBe verbose\n\
142 ";
143
144 static void NONRET
145 usage(byte *msg, ...)
146 {
147   va_list va;
148   va_start(va, msg);
149   if (msg)
150     vfprintf(stderr, msg, va);
151   fputs(help, stderr);
152   exit(1);
153 }
154
155 int
156 main(int argc, char *argv[])
157 {
158   log_init(argv[0]);
159   cf_declare_section("top", &cf_top, 0);
160   cf_def_file = "lib/conf2.t";
161
162   int opt;
163   while ((opt = cf_get_opt(argc, argv, short_opts, long_opts, NULL)) >= 0)
164     switch (opt) {
165       case 'v': verbose++; break;
166       default: usage("unknown option %c\n", opt);
167     }
168   if (optind < argc)
169     usage("too many parameters (%d more)\n", argc-optind);
170
171   /*
172   cf_load("non-existent file");
173   //cf_reload("non-existent file");
174   cf_load("non-existent file");
175   cf_set("top.d1 -1.1; top.master b");
176   */
177
178   struct fastbuf *out = bfdopen(1, 1<<14);
179   cf_dump_sections(out);
180   bclose(out);
181
182   return 0;
183 }