]> mj.ucw.cz Git - libucw.git/blob - lib/conf2-test.c
99b9b0a846f230e912c1f3ec376876d426d5cb11
[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 byte *
28 init_sec_1(struct sub_sect_1 *s)
29 {
30   s->name = "unknown";
31   s->level = "default";
32   s->confidence[0] = 5;
33   s->confidence[1] = 6;
34   // leave s->list==NULL
35   return NULL;
36 }
37
38 static byte *
39 commit_sec_1(struct sub_sect_1 *s)
40 {
41   if (s->confidence[0] < 0 || s->confidence[0] > 10)
42     return "Well, this can't be";
43   return NULL;
44 }
45
46 static struct cf_section cf_sec_1 = {
47   CF_TYPE(struct sub_sect_1),
48   CF_INIT(init_sec_1),
49   CF_COMMIT(commit_sec_1),
50 #define F(x)    PTR_TO(struct sub_sect_1, x)
51   CF_ITEMS {
52     CF_STRING("name", F(name)),
53     CF_STRING("level", F(level)),
54     CF_INT_ARY("confidence", F(confidence[0]), 2),              // XXX: the [0] is needed for the sake of type checking
55     CF_DOUBLE_DYN("list", F(list), 100),
56     CF_END
57   }
58 #undef F
59 };
60
61 static uns nr1 = 15;
62 static int *nrs1 = DYN_ALLOC(int, 5, 5, 4, 3, 2, 1);
63 static int nrs2[5];
64 static byte *str1 = "no worries";
65 static byte **str2 = DYN_ALLOC(byte *, 2, "Alice", "Bob");
66 static u64 u1 = 0xCafeBeefDeadC00ll;
67 static double d1 = -1.1;
68 static struct sub_sect_1 sec1 = { {}, "Charlie", "WBAFC", { 0, -1} };
69 static struct clist secs;
70 static time_t t1, t2;
71 static u32 ip;
72
73 static byte *
74 init_top(void *ptr UNUSED)
75 {
76   for (uns i=0; i<5; i++)
77   {
78     struct sub_sect_1 *s = cf_malloc(sizeof(struct sub_sect_1));
79     cf_init_section("slaves", &cf_sec_1, s);
80     s->confidence[1] = i;
81     clist_add_tail(&secs, &s->n);
82   }
83   return NULL;
84 }
85
86 static byte *
87 commit_top(void *ptr UNUSED)
88 {
89   if (nr1 != 15)
90     return "Don't touch my variable!";
91   return NULL;
92 }
93
94 static byte *
95 time_parser(uns number, byte **pars, time_t *ptr)
96 {
97   *ptr = number ? atoi(pars[0]) : time(NULL);
98   return NULL;
99 }
100
101 static struct cf_section cf_top = {
102   CF_COMMIT(init_top),
103   CF_COMMIT(commit_top),
104   CF_ITEMS {
105     CF_UNS("nr1", &nr1),
106     CF_INT_DYN("nrs1", &nrs1, 1000),
107     CF_INT_ARY("nrs2", nrs2, 5),
108     CF_STRING("str1", &str1),
109     CF_STRING_DYN("str2", &str2, 20),
110     CF_U64("u1", &u1),
111     CF_DOUBLE("d1", &d1),
112     CF_PARSER("FirstTime", &t1, time_parser, -1),
113     CF_PARSER("SecondTime", &t2, time_parser, 1),
114     CF_SECTION("master", &sec1, &cf_sec_1),
115     CF_LIST("slaves", &secs, &cf_sec_1),
116     CF_IP("ip", &ip),
117     CF_END
118   }
119 };
120
121 static byte short_opts[] = CF_SHORT_OPTS "v";
122 static struct option long_opts[] = {
123         CF_LONG_OPTS
124         {"verbose",     0, 0, 'v'},
125         {NULL,          0, 0, 0}
126 };
127
128 static char *help = "\
129 Usage: conf2-test <options>\n\
130 \n\
131 Options:\n"
132 CF_USAGE
133 "-v\t\tBe verbose\n\
134 ";
135
136 static void NONRET
137 usage(void)
138 {
139         fputs(help, stderr);
140         exit(1);
141 }
142
143 int
144 main(int argc, char *argv[])
145 {
146   log_init(argv[0]);
147   cf_declare_section("top", &cf_top, 0);
148   cf_def_file = "lib/conf2.t";
149
150   int opt;
151   while ((opt = cf_get_opt(argc, argv, short_opts, long_opts, NULL)) >= 0)
152     switch (opt) {
153       case 'v': verbose++; break;
154       default: usage();
155     }
156   if (optind < argc)
157     usage();
158
159   struct fastbuf *out = bfdopen(1, 1<<14);
160   cf_dump_sections(out);
161   bclose(out);
162
163   return 0;
164 }