BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file ncd_parser_test.c
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29  
30 #include <stddef.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <inttypes.h>
35  
36 #include <misc/debug.h>
37 #include <misc/expstring.h>
38 #include <base/BLog.h>
39 #include <ncd/NCDConfigParser.h>
40 #include <ncd/NCDValGenerator.h>
41 #include <ncd/NCDSugar.h>
42  
43 static int generate_val (NCDValue *value, ExpString *out_str)
44 {
45 switch (NCDValue_Type(value)) {
46 case NCDVALUE_STRING: {
47 const char *str = NCDValue_StringValue(value);
48 size_t len = NCDValue_StringLength(value);
49  
50 if (!ExpString_AppendChar(out_str, '"')) {
51 goto fail;
52 }
53  
54 for (size_t i = 0; i < len; i++) {
55 if (str[i] == '\0') {
56 char buf[5];
57 snprintf(buf, sizeof(buf), "\\x%02"PRIx8, (uint8_t)str[i]);
58  
59 if (!ExpString_Append(out_str, buf)) {
60 goto fail;
61 }
62  
63 continue;
64 }
65  
66 if (str[i] == '"' || str[i] == '\\') {
67 if (!ExpString_AppendChar(out_str, '\\')) {
68 goto fail;
69 }
70 }
71  
72 if (!ExpString_AppendChar(out_str, str[i])) {
73 goto fail;
74 }
75 }
76  
77 if (!ExpString_AppendChar(out_str, '"')) {
78 goto fail;
79 }
80 } break;
81  
82 case NCDVALUE_LIST: {
83 if (!ExpString_AppendChar(out_str, '{')) {
84 goto fail;
85 }
86  
87 int is_first = 1;
88  
89 for (NCDValue *e = NCDValue_ListFirst(value); e; e = NCDValue_ListNext(value, e)) {
90 if (!is_first) {
91 if (!ExpString_Append(out_str, ", ")) {
92 goto fail;
93 }
94 }
95  
96 if (!generate_val(e, out_str)) {
97 goto fail;
98 }
99  
100 is_first = 0;
101 }
102  
103 if (!ExpString_AppendChar(out_str, '}')) {
104 goto fail;
105 }
106 } break;
107  
108 case NCDVALUE_MAP: {
109 if (!ExpString_AppendChar(out_str, '[')) {
110 goto fail;
111 }
112  
113 int is_first = 1;
114  
115 for (NCDValue *ekey = NCDValue_MapFirstKey(value); ekey; ekey = NCDValue_MapNextKey(value, ekey)) {
116 NCDValue *eval = NCDValue_MapKeyValue(value, ekey);
117  
118 if (!is_first) {
119 if (!ExpString_Append(out_str, ", ")) {
120 goto fail;
121 }
122 }
123  
124 if (!generate_val(ekey, out_str)) {
125 goto fail;
126 }
127  
128 if (!ExpString_AppendChar(out_str, ':')) {
129 goto fail;
130 }
131  
132 if (!generate_val(eval, out_str)) {
133 goto fail;
134 }
135  
136 is_first = 0;
137 }
138  
139 if (!ExpString_AppendChar(out_str, ']')) {
140 goto fail;
141 }
142 } break;
143  
144 case NCDVALUE_VAR: {
145 if (!ExpString_Append(out_str, NCDValue_VarName(value))) {
146 goto fail;
147 }
148 } break;
149  
150 case NCDVALUE_INVOC: {
151 if (!generate_val(NCDValue_InvocFunc(value), out_str)) {
152 goto fail;
153 }
154  
155 if (!ExpString_AppendChar(out_str, '(')) {
156 goto fail;
157 }
158  
159 if (!generate_val(NCDValue_InvocArg(value), out_str)) {
160 goto fail;
161 }
162  
163 if (!ExpString_AppendChar(out_str, ')')) {
164 goto fail;
165 }
166 } break;
167  
168 default: ASSERT(0);
169 }
170  
171 return 1;
172  
173 fail:
174 return 0;
175 }
176  
177 static void print_indent (unsigned int indent)
178 {
179 while (indent > 0) {
180 printf(" ");
181 indent--;
182 }
183 }
184  
185 static void print_value (NCDValue *v, unsigned int indent)
186 {
187 ExpString estr;
188 if (!ExpString_Init(&estr)) {
189 DEBUG("ExpString_Init failed");
190 exit(1);
191 }
192  
193 if (!generate_val(v, &estr)) {
194 DEBUG("generate_val failed");
195 exit(1);
196 }
197  
198 print_indent(indent);
199 printf("%s\n", ExpString_Get(&estr));
200  
201 ExpString_Free(&estr);
202 }
203  
204 static void print_block (NCDBlock *block, unsigned int indent)
205 {
206 for (NCDStatement *st = NCDBlock_FirstStatement(block); st; st = NCDBlock_NextStatement(block, st)) {
207 const char *name = NCDStatement_Name(st) ? NCDStatement_Name(st) : "";
208  
209 switch (NCDStatement_Type(st)) {
210 case NCDSTATEMENT_REG: {
211 const char *objname = NCDStatement_RegObjName(st) ? NCDStatement_RegObjName(st) : "";
212 const char *cmdname = NCDStatement_RegCmdName(st);
213  
214 print_indent(indent);
215 printf("reg name=%s objname=%s cmdname=%s args:\n", name, objname, cmdname);
216  
217 print_value(NCDStatement_RegArgs(st), indent + 2);
218 } break;
219  
220 case NCDSTATEMENT_IF: {
221 print_indent(indent);
222 printf("if name=%s\n", name);
223  
224 NCDIfBlock *ifb = NCDStatement_IfBlock(st);
225  
226 for (NCDIf *ifc = NCDIfBlock_FirstIf(ifb); ifc; ifc = NCDIfBlock_NextIf(ifb, ifc)) {
227 print_indent(indent + 2);
228 printf("if\n");
229  
230 print_value(NCDIf_Cond(ifc), indent + 4);
231  
232 print_indent(indent + 2);
233 printf("then\n");
234  
235 print_block(NCDIf_Block(ifc), indent + 4);
236 }
237  
238 if (NCDStatement_IfElse(st)) {
239 print_indent(indent + 2);
240 printf("else\n");
241  
242 print_block(NCDStatement_IfElse(st), indent + 4);
243 }
244 } break;
245  
246 case NCDSTATEMENT_FOREACH: {
247 const char *name1 = NCDStatement_ForeachName1(st);
248 const char *name2 = NCDStatement_ForeachName2(st) ? NCDStatement_ForeachName2(st) : "";
249  
250 print_indent(indent);
251 printf("foreach name=%s name1=%s name2=%s\n", name, name1, name2);
252  
253 print_block(NCDStatement_ForeachBlock(st), indent + 2);
254 } break;
255  
256 case NCDSTATEMENT_BLOCK: {
257 print_indent(indent);
258 printf("block name=%s\n", name);
259  
260 print_block(NCDStatement_BlockBlock(st), indent + 2);
261 } break;
262  
263 default: {
264 print_indent(indent);
265 printf("unknown_statement_type name=%s\n", name);
266 } break;
267 }
268 }
269 }
270  
271 int main (int argc, char **argv)
272 {
273 int res = 1;
274  
275 if (argc != 3) {
276 printf("Usage: %s <desugar=0/1> <string>\n", (argc > 0 ? argv[0] : ""));
277 goto fail0;
278 }
279  
280 int desugar = atoi(argv[1]);
281 char *text = argv[2];
282  
283 BLog_InitStdout();
284  
285 // parse
286 NCDProgram prog;
287 if (!NCDConfigParser_Parse(text, strlen(text), &prog)) {
288 DEBUG("NCDConfigParser_Parse failed");
289 goto fail1;
290 }
291  
292 // desugar
293 if (desugar) {
294 if (!NCDSugar_Desugar(&prog)) {
295 DEBUG("NCDSugar_Desugar failed");
296 goto fail2;
297 }
298 }
299  
300 // print
301 for (NCDProgramElem *elem = NCDProgram_FirstElem(&prog); elem; elem = NCDProgram_NextElem(&prog, elem)) {
302 switch (NCDProgramElem_Type(elem)) {
303 case NCDPROGRAMELEM_PROCESS: {
304 NCDProcess *p = NCDProgramElem_Process(elem);
305 printf("process name=%s is_template=%d\n", NCDProcess_Name(p), NCDProcess_IsTemplate(p));
306 print_block(NCDProcess_Block(p), 2);
307 } break;
308  
309 case NCDPROGRAMELEM_INCLUDE: {
310 printf("include path=%s\n", NCDProgramElem_IncludePathData(elem));
311 } break;
312  
313 case NCDPROGRAMELEM_INCLUDE_GUARD: {
314 printf("include_guard id=%s\n", NCDProgramElem_IncludeGuardIdData(elem));
315 } break;
316  
317 default: ASSERT(0);
318 }
319 }
320  
321 res = 0;
322 fail2:
323 NCDProgram_Free(&prog);
324 fail1:
325 BLog_Free();
326 fail0:
327 return res;
328 }