Line data Source code
1 : /*
2 : * sandesh_gen.c -- parse the sandesh file and generate code that takes
3 : * the xml node and assigns the value to the corresponding member of
4 : * the structure
5 : *
6 : * Copyright (c) 2015, Juniper Networks, Inc.
7 : * Copyright Contributors to the OpenSDN project
8 : * All rights reserved
9 : */
10 : #include <stdio.h>
11 : #include <string.h>
12 : #include <errno.h>
13 : #include <stdbool.h>
14 : #include <ctype.h>
15 :
16 : #define CHARS 80
17 :
18 : static char line[CHARS];
19 : static char nest[] = " ";
20 :
21 : static char header[] = {"\
22 : /*\n\
23 : * Auto generated file\n\
24 : */\n"
25 : };
26 :
27 : static char includes[] = {"\
28 : #include <string.h>\n\n\
29 : #include <stdbool.h>\n\n\
30 : \
31 : #include <libxml/xmlmemory.h>\n\
32 : #include <libxml/parser.h>\n\n\
33 : \
34 : #include <vr_types.h>\n\
35 : #include <vt_gen_lib.h>\n\
36 : #include <vtest.h>\n\n"
37 : };
38 :
39 : static char message_gen_foo[] = "#include <";
40 :
41 : static char message_gen[] = {"\
42 : vt_gen_message_modules.h>\n\n\
43 : struct vt_message_module vt_message_modules[] = {\n\
44 : "};
45 :
46 : static char vt_message_module_gen[] = {"\
47 : struct vt_message_module {\n\
48 : char *vmm_name;\n\
49 : void *(*vmm_node)(xmlNodePtr, struct vtest *);\n\
50 : bool (*vmm_expect)(xmlNodePtr, struct vtest *, void *);\n\
51 : unsigned int vmm_size;\n\
52 : };\n\n"
53 : };
54 :
55 : static char part_gen[] = {"\
56 : req = calloc(sizeof(*req), 1);\n\
57 : if (!req)\n\
58 : return NULL;\n\n\
59 : node = node->xmlChildrenNode;\n\
60 : while (node) {\n\
61 : if (node->type == XML_TEXT_NODE) {\n\
62 : node = node->next;\n\
63 : continue;\n\
64 : }\n\n\
65 : "
66 : };
67 :
68 : static char expect_gen[] = {"\
69 : node = node->xmlChildrenNode;\n\
70 : while (node) {\n\
71 : if (node->type == XML_TEXT_NODE) {\n\
72 : node = node->next;\n\
73 : continue;\n\
74 : }\n\n\
75 : "
76 : };
77 :
78 : static unsigned char *
79 1061 : gen_skip_space(unsigned char *string)
80 : {
81 1061 : unsigned int i = 0, len;
82 :
83 1061 : if (!string)
84 0 : return string;
85 :
86 1061 : len = strlen(string);
87 1061 : if (!len)
88 0 : return NULL;
89 :
90 6698 : while ((i < len) && isspace(string[i])) {
91 5637 : i++;
92 : }
93 :
94 1061 : if (i == len)
95 0 : return NULL;
96 :
97 1061 : return &string[i];
98 : }
99 :
100 : static unsigned char *
101 1124 : gen_reach_char(unsigned char *string, unsigned char c)
102 : {
103 1124 : unsigned int i = 0, len;
104 :
105 1124 : if (!string)
106 0 : return string;
107 :
108 1124 : len = strlen(string);
109 1124 : if (!len)
110 0 : return string;
111 :
112 11264 : while ((i < len) && (string[i] != c)) {
113 10140 : i++;
114 : }
115 :
116 1124 : return &string[i];
117 : }
118 :
119 : static unsigned char *
120 573 : gen_reach_space(unsigned char *string)
121 : {
122 573 : return gen_reach_char(string, ' ');
123 : }
124 :
125 :
126 : static void
127 16280 : gen_write(FILE *ofp, unsigned int nesting, unsigned char *string)
128 : {
129 : unsigned int i;
130 :
131 37388 : for (i = 0; i < nesting; i++)
132 21108 : fwrite(nest, 1, strlen(nest), ofp);
133 :
134 16280 : fwrite(string, 1, strlen(string), ofp);
135 16280 : return;
136 : }
137 :
138 : static void
139 2871 : gen_raw_write(FILE *ofp, unsigned int nesting,
140 : unsigned char *string, unsigned int len)
141 : {
142 : unsigned int i;
143 :
144 3003 : for (i = 0; i < nesting; i++)
145 132 : fwrite(nest, 1, strlen(nest), ofp);
146 :
147 2871 : fwrite(string, 1, len, ofp);
148 2871 : return;
149 : }
150 :
151 : static void
152 2 : gen_close(FILE *fp, bool header_file)
153 : {
154 2 : if (header_file) {
155 1 : gen_write(fp, 0, "\n#endif\n");
156 : }
157 :
158 2 : fclose(fp);
159 2 : return;
160 : }
161 :
162 : static FILE *
163 4 : gen_open(unsigned char *name, bool header_file)
164 : {
165 : unsigned char c[105];
166 4 : unsigned int i = 0, j = 0;
167 : FILE *fp;
168 :
169 4 : if (header_file && (strlen(name) >= 100)) {
170 0 : perror(name);
171 0 : return NULL;
172 : }
173 :
174 4 : fp = fopen(name, "w+");
175 4 : if (!fp)
176 0 : return fp;
177 :
178 4 : gen_write(fp, 0, header);
179 :
180 4 : if (header_file) {
181 1 : gen_write(fp, 0, "#ifndef ");
182 1 : c[i++] = '_';
183 1 : c[i++] = '_';
184 25 : while ((c[i] = name[j]) != '\0') {
185 24 : if (c[i] == '.') {
186 1 : c[i] = '_';
187 : } else {
188 23 : c[i] = toupper(c[i]);
189 : }
190 24 : i++, j++;
191 : }
192 1 : c[i++] = '_';
193 1 : c[i++] = '_';
194 :
195 1 : c[i] = '\0';
196 :
197 1 : gen_write(fp, 0, c);
198 1 : gen_write(fp, 0, "\n");
199 1 : gen_write(fp, 0, "#define ");
200 1 : gen_write(fp, 0, c);
201 1 : gen_write(fp, 0, "\n\n");
202 : }
203 :
204 4 : gen_write(fp, 0, includes);
205 :
206 4 : return fp;
207 : }
208 :
209 : static int
210 1 : gen(FILE *fp)
211 : {
212 1 : bool need_else = false;
213 :
214 1 : unsigned int len, start = 0, end = 0;
215 1 : unsigned int type_len, sub_type_len = 0, var_len;
216 1 : unsigned int nesting = 0;
217 1 : unsigned int sub_type_size = 0;
218 :
219 1 : char *marker, *type, *var, *sub_type = NULL;
220 : FILE *ofp, *fp_expect, *fp_message, *fp_message_hdr;
221 :
222 1 : ofp = gen_open("vt_gen_sandesh.c", false);
223 1 : if (!ofp) {
224 0 : perror("vt_gen_sandesh.c");
225 0 : return errno;
226 : }
227 :
228 1 : fp_expect = gen_open("vt_gen_sandesh_expect.c", false);
229 1 : if (!fp_expect) {
230 0 : perror("vt_gen_sandesh_expect.c");
231 0 : return errno;
232 : }
233 :
234 1 : fp_message = gen_open("vt_gen_message_modules.c", false);
235 1 : if (!fp_message) {
236 0 : perror("vt_message_modules.c");
237 0 : return errno;
238 : }
239 1 : gen_write(fp_message, 0, message_gen_foo);
240 1 : gen_write(fp_message, 0, message_gen);
241 :
242 1 : fp_message_hdr = gen_open("vt_gen_message_modules.h", true);
243 1 : if (!fp_message_hdr) {
244 0 : perror("vt_gen_message_modules.h");
245 0 : return errno;
246 : }
247 1 : gen_write(fp_message_hdr, 0, vt_message_module_gen);
248 :
249 585 : while (fgets(line, sizeof(line), fp)) {
250 584 : if (!strncmp("buffer sandesh", line, strlen("buffer sandesh"))) {
251 22 : len = strlen("buffer sandesh");
252 22 : marker = gen_skip_space(&line[len]);
253 22 : if (!marker)
254 0 : break;
255 :
256 22 : start = marker - line;
257 22 : marker = gen_reach_space(marker);
258 22 : end = marker - line;
259 :
260 22 : gen_write(fp_message, 1, "{\n");
261 22 : gen_write(fp_message, 2, ".vmm_name");
262 22 : gen_write(fp_message, 2, "=");
263 22 : gen_write(fp_message, 2, "\"");
264 22 : gen_raw_write(fp_message, 0, &line[start], end - start);
265 22 : gen_write(fp_message, 0, "\",\n");
266 :
267 22 : gen_write(fp_message, 2, ".vmm_node");
268 22 : gen_write(fp_message, 2, "=");
269 22 : gen_raw_write(fp_message, 2, &line[start], end - start);
270 22 : gen_write(fp_message, 0, "_node,\n");
271 :
272 22 : gen_write(fp_message, 2, ".vmm_expect");
273 22 : gen_write(fp_message, 2, "=");
274 22 : gen_raw_write(fp_message, 2, &line[start], end - start);
275 22 : gen_write(fp_message, 0, "_expect,\n");
276 :
277 22 : gen_write(fp_message, 2, ".vmm_size");
278 22 : gen_write(fp_message, 2, "=");
279 22 : gen_write(fp_message, 2, "sizeof(");
280 22 : gen_raw_write(fp_message, 0, &line[start], end - start);
281 22 : gen_write(fp_message, 0, "),\n");
282 22 : gen_write(fp_message, 1, "},\n");
283 :
284 22 : gen_write(fp_message_hdr, 0, "extern void *");
285 22 : gen_raw_write(fp_message_hdr, 0, &line[start], end - start);
286 22 : gen_write(fp_message_hdr, 0, "_node(xmlNodePtr, struct vtest *);\n");
287 :
288 22 : gen_write(ofp, nesting, "void *\n");
289 22 : gen_raw_write(ofp, nesting, &line[start], end - start);
290 22 : gen_write(ofp, nesting, "_node(xmlNodePtr node, struct vtest *test)\n");
291 22 : gen_write(ofp, nesting, "{\n");
292 :
293 22 : gen_write(fp_message_hdr, 0, "extern bool ");
294 22 : gen_raw_write(fp_message_hdr, 0, &line[start], end - start);
295 22 : gen_write(fp_message_hdr, 0, "_expect(xmlNodePtr, struct vtest *, void *);\n");
296 :
297 22 : gen_write(fp_expect, nesting, "bool\n");
298 22 : gen_raw_write(fp_expect, nesting, &line[start], end - start);
299 22 : gen_write(fp_expect, nesting, "_expect(xmlNodePtr node, struct vtest *test, void *buf)\n");
300 22 : gen_write(fp_expect, nesting, "{\n");
301 :
302 22 : gen_write(ofp, ++nesting, "unsigned int list_size;\n");
303 22 : gen_write(ofp, nesting, "xmlNodePtr elemptr = NULL;\n");
304 22 : gen_write(ofp, nesting, "xmlNodePtr tmpnode = NULL;\n");
305 22 : gen_write(ofp, nesting, "xmlNodePtr listnode = NULL;\n");
306 22 : gen_write(ofp, nesting, "int elem_count = 0;\n");
307 22 : gen_write(ofp, nesting, "int has_list = 0;\n");
308 :
309 22 : gen_raw_write(ofp, nesting, &line[start], end - start);
310 22 : gen_write(ofp, 0, " *req;\n\n");
311 22 : gen_write(ofp, 0, part_gen);
312 :
313 22 : gen_write(fp_expect, nesting, "bool result = true;\n");
314 22 : gen_write(fp_expect, nesting, "unsigned int list_size;\n");
315 22 : gen_raw_write(fp_expect, nesting, &line[start], end - start);
316 22 : gen_write(fp_expect, 0, " *req = (");
317 22 : gen_raw_write(fp_expect, 0, &line[start], end - start);
318 22 : gen_write(fp_expect, 0, " *)buf;\n\n");
319 22 : gen_write(fp_expect, 0, expect_gen);
320 :
321 : /* account for nesting inside part_gen */
322 22 : nesting++;
323 22 : continue;
324 : }
325 :
326 562 : if (start) {
327 510 : if (!strncmp("}", line, strlen("}"))) {
328 22 : start = end = 0;
329 22 : gen_write(ofp, 0, "\n");
330 22 : gen_write(ofp, nesting, "node = node->next;\n");
331 :
332 22 : gen_write(fp_expect, 0, "\n\n");
333 22 : gen_write(fp_expect, nesting, "if (!result)\n");
334 22 : gen_write(fp_expect, nesting + 1, "return result;\n\n");
335 22 : gen_write(fp_expect, nesting, "node = node->next;\n");
336 :
337 22 : gen_write(ofp, --nesting, "}\n\n");
338 22 : gen_write(ofp, nesting, "return (void *)req;\n}\n\n");
339 :
340 22 : gen_write(fp_expect, nesting, "}\n\n");
341 22 : gen_write(fp_expect, nesting, "return result;\n}\n\n");
342 :
343 22 : --nesting;
344 22 : need_else = false;
345 22 : continue;
346 : }
347 :
348 488 : marker = strchr(line, ':');
349 488 : if (!marker) {
350 0 : return EINVAL;
351 : }
352 :
353 488 : marker = gen_skip_space(++marker);
354 488 : if (!marker) {
355 0 : return EINVAL;
356 : }
357 :
358 488 : type = marker;
359 488 : marker = gen_reach_space(marker);
360 488 : if (!marker) {
361 0 : return EINVAL;
362 : }
363 488 : type_len = marker - type;
364 :
365 488 : if (!strncmp(type, "list", strlen("list"))) {
366 63 : marker = type + strlen("list");;
367 63 : marker = gen_skip_space(marker);
368 63 : if (!marker) {
369 0 : return EINVAL;
370 : }
371 :
372 63 : if (*marker != '<') {
373 0 : return EINVAL;
374 : }
375 :
376 63 : sub_type = ++marker;
377 63 : marker = gen_reach_char(marker, '>');
378 63 : if (!marker) {
379 0 : return EINVAL;
380 : }
381 63 : sub_type_len = marker - sub_type;
382 63 : marker = gen_reach_space(marker);
383 63 : if (!marker) {
384 0 : return EINVAL;
385 : }
386 : }
387 :
388 488 : marker = gen_skip_space(marker);
389 488 : if (!marker) {
390 0 : return EINVAL;
391 : }
392 :
393 488 : var = marker;
394 488 : marker = gen_reach_char(marker, ';');
395 488 : if (!marker) {
396 0 : return EINVAL;
397 : }
398 488 : var_len = marker - var;
399 :
400 488 : if (need_else) {
401 466 : gen_write(ofp, 0, " else ");
402 466 : gen_write(fp_expect, 0, " else ");
403 : } else {
404 22 : gen_write(ofp, nesting, "");
405 22 : gen_write(fp_expect, nesting, "");
406 : }
407 :
408 488 : gen_write(ofp, 0, "if (!strncmp(node->name, ");
409 488 : gen_write(ofp, 0, "\"");
410 488 : gen_raw_write(ofp, 0, var, var_len);
411 488 : gen_write(ofp, 0, "\"");
412 488 : gen_write(ofp, 0, ", sizeof(");
413 488 : gen_write(ofp, 0, "\"");
414 488 : gen_raw_write(ofp, 0, var, var_len);
415 488 : gen_write(ofp, 0, "\"");
416 488 : gen_write(ofp, 0, "))) {\n");
417 :
418 488 : gen_write(fp_expect, 0, "if (!strncmp(node->name, ");
419 488 : gen_write(fp_expect, 0, "\"");
420 488 : gen_raw_write(fp_expect, 0, var, var_len);
421 488 : gen_write(fp_expect, 0, "\"");
422 488 : gen_write(fp_expect, 0, ", strlen(node->name))) {\n");
423 :
424 488 : if (strncmp(type, "list", strlen("list")) != 0) {
425 425 : gen_write(ofp, nesting, "if (node->children && node->children->content)\n");
426 425 : gen_write(ofp, ++nesting, "req->");
427 425 : gen_raw_write(ofp, 0, var, var_len);
428 425 : gen_write(ofp, 0, " = ");
429 : }
430 488 : gen_write(fp_expect, nesting, "");
431 :
432 488 : if (!strncmp(type, "i32", strlen("i32"))) {
433 88 : gen_write(ofp, 0, "strtoul(node->children->content, NULL, 0);\n");
434 :
435 88 : gen_write(fp_expect, 0, "result = vt_gen_int_compare(");
436 88 : gen_write(fp_expect, 0, "req->");
437 88 : gen_raw_write(fp_expect, 0, var, var_len);
438 88 : gen_write(fp_expect, 0, ",\n");
439 88 : gen_write(fp_expect, nesting + 4, "strtoul(node->children->content, NULL, 0)");
440 88 : gen_write(fp_expect, 0, ");\n");
441 :
442 400 : } else if (!strncmp(type, "u32", strlen("u32"))) {
443 32 : gen_write(ofp, 0, "strtoul(node->children->content, NULL, 0);\n");
444 :
445 32 : gen_write(fp_expect, 0, "result = vt_gen_int_compare(");
446 32 : gen_write(fp_expect, 0, "req->");
447 32 : gen_raw_write(fp_expect, 0, var, var_len);
448 32 : gen_write(fp_expect, 0, ",\n");
449 32 : gen_write(fp_expect, nesting + 4, "strtoul(node->children->content, NULL, 0)");
450 32 : gen_write(fp_expect, 0, ");\n");
451 :
452 368 : } else if ((!strncmp(type, "i64", strlen("i64"))) ||
453 193 : (!strncmp(type, "u64", strlen("u64")))) {
454 192 : gen_write(ofp, 0, "strtoull(node->children->content, NULL, 0);\n");
455 :
456 192 : gen_write(fp_expect, 0, "result = vt_gen_int64_compare(");
457 192 : gen_write(fp_expect, 0, "req->");
458 192 : gen_raw_write(fp_expect, 0, var, var_len);
459 192 : gen_write(fp_expect, 0, ",\n");
460 192 : gen_write(fp_expect, nesting + 4, "strtoul(node->children->content, NULL, 0)");
461 192 : gen_write(fp_expect, 0, ");\n");
462 :
463 176 : } else if ((!strncmp(type, "i16", strlen("i16"))) ||
464 130 : (!strncmp(type, "u16", strlen("u16")))) {
465 67 : gen_write(ofp, 0, "strtoul(node->children->content, NULL, 0);\n");
466 :
467 67 : gen_write(fp_expect, 0, "result = vt_gen_short_compare(");
468 67 : gen_write(fp_expect, 0, "req->");
469 67 : gen_raw_write(fp_expect, 0, var, var_len);
470 67 : gen_write(fp_expect, 0, ",\n");
471 67 : gen_write(fp_expect, nesting + 4, "strtoul(node->children->content, NULL, 0));\n");
472 :
473 109 : } else if (!strncmp(type, "byte", strlen("byte"))) {
474 20 : gen_write(ofp, 0, "strtoul(node->children->content, NULL, 0);\n");
475 :
476 20 : gen_write(fp_expect, 0, "result = vt_gen_byte_compare(");
477 20 : gen_write(fp_expect, 0, "req->");
478 20 : gen_raw_write(fp_expect, 0, var, var_len);
479 20 : gen_write(fp_expect, 0, ",\n");
480 20 : gen_write(fp_expect, nesting + 4, "strtoul(node->children->content, NULL, 0)");
481 20 : gen_write(fp_expect, 0, ");\n");
482 :
483 89 : } else if (!strncmp(type, "sandesh_op", strlen("sandesh_op"))) {
484 19 : gen_write(ofp, 0, "vt_gen_op(node->children->content);\n");
485 :
486 19 : gen_write(fp_expect, 0, "result = vt_gen_op_compare(");
487 19 : gen_write(fp_expect, 0, "req->");
488 19 : gen_raw_write(fp_expect, 0, var, var_len);
489 19 : gen_write(fp_expect, 0, ", node->children->content);\n");
490 :
491 70 : } else if (!strncmp(type, "flow_op", strlen("flow_op"))) {
492 3 : gen_write(ofp, 0, "vt_gen_flow_op(node->children->content);\n");
493 :
494 3 : gen_write(fp_expect, 0, "result = vt_gen_flow_op_compare(");
495 3 : gen_write(fp_expect, 0, "req->");
496 3 : gen_raw_write(fp_expect, 0, var, var_len);
497 3 : gen_write(fp_expect, 0, ", node->content);\n");
498 :
499 67 : } else if (!strncmp(type, "list", strlen("list"))) {
500 63 : char* size = NULL;
501 63 : if (!strncmp(sub_type, "byte", strlen("byte"))) {
502 38 : size = "8";
503 38 : sub_type_size = 1;
504 25 : } else if (!strncmp(sub_type, "i16", strlen("i16")) ||
505 23 : !strncmp(sub_type, "u16", strlen("u16"))) {
506 3 : size = "16";
507 3 : sub_type_size = 2;
508 22 : } else if (!strncmp(sub_type, "i32", strlen("i32")) ||
509 13 : !strncmp(sub_type, "u32", strlen("u32"))) {
510 13 : size = "32";
511 13 : sub_type_size = 4;
512 9 : } else if (!strncmp(sub_type, "i64", strlen("i64")) ||
513 8 : !strncmp(sub_type, "u64", strlen("u64"))) {
514 9 : size = "64";
515 9 : sub_type_size = 8;
516 : }
517 :
518 : /*
519 : * Add support for parsing both the list formats
520 : * old format:-
521 : * <vifr_mac>de:ad:be:ef:00:01</vifr_mac>
522 : *
523 : * Format used by pysandesh:-
524 : * <vifr_mac type="list" identifier="38">
525 : * <list type="byte" size="6">
526 : * <element>-34</element>
527 : * <element>-83</element>
528 : * <element>-66</element>
529 : * <element>-17</element>
530 : * <element>0</element>
531 : * <element>2</element>
532 : * </list>
533 : * </vifr_mac>
534 : *
535 : * Logic:
536 : * If the list has children of type "list",
537 : * then it is assumed to be in pysandesh format, else
538 : * it is assumed to be in the old format
539 : */
540 63 : gen_write(ofp, nesting, "has_list = 0;\n");
541 63 : gen_write(ofp, nesting, "tmpnode = node->children;\n");
542 63 : gen_write(ofp, nesting, "listnode = NULL;\n");
543 63 : gen_write(ofp, nesting, "while (tmpnode != NULL) {\n");
544 63 : gen_write(ofp, nesting+1, "if (!strncmp(tmpnode->name, "
545 : "\"list\", sizeof(\"list\"))) {\n");
546 63 : gen_write(ofp, nesting+2, "has_list = 1;\n");
547 63 : gen_write(ofp, nesting+2, "listnode = tmpnode;\n");
548 63 : gen_write(ofp, nesting+2, "break;\n");
549 63 : gen_write(ofp, nesting+1, "}\n");
550 63 : gen_write(ofp, nesting+1, "tmpnode = tmpnode->next;\n");
551 63 : gen_write(ofp, nesting, "}\n");
552 :
553 : /* Parse old format list (has_list == 0) */
554 63 : gen_write(ofp, nesting, "if (node->children && node->children->content && !has_list)\n");
555 63 : gen_write(ofp, ++nesting, "req->");
556 63 : gen_raw_write(ofp, 0, var, var_len);
557 63 : gen_write(ofp, 0, " = ");
558 63 : gen_write(ofp, 0, "vt_gen_list(node->children->content, GEN_TYPE_U");
559 63 : gen_write(ofp, 0, size);
560 63 : gen_write(ofp, 0, ", &list_size);\n");
561 :
562 63 : gen_write(fp_expect, 0, "result = vt_gen_list_compare(");
563 63 : gen_write(fp_expect, 0, "req->");
564 63 : gen_raw_write(fp_expect, 0, var, var_len);
565 63 : gen_write(fp_expect, 0, ",\n");
566 63 : gen_write(fp_expect, nesting + 2, "req->");
567 63 : gen_raw_write(fp_expect, 0, var, var_len);
568 63 : gen_write(fp_expect, 0, "_size");
569 63 : gen_write(fp_expect, 0, ", node->children->content, GEN_TYPE_U");
570 63 : gen_write(fp_expect, 0, size);
571 63 : gen_write(fp_expect, 0, ");\n");
572 :
573 : /* Parse list in pysandesh format */
574 63 : gen_write(ofp, nesting,
575 : "if (node->children && has_list) {\n");
576 63 : gen_write(ofp, nesting+1, "elemptr = listnode->children;\n");
577 63 : gen_write(ofp, nesting+1, "elem_count = 0;\n");
578 63 : gen_write(ofp, nesting+1, "while (elemptr) {\n");
579 63 : gen_write(ofp, nesting+2, "if (!strncmp(elemptr->name, "
580 : "\"element\", sizeof(\"element\"))) {\n");
581 63 : gen_write(ofp, nesting+3, "elem_count++;\n");
582 63 : gen_write(ofp, nesting+2, "}\n");
583 63 : gen_write(ofp, nesting+2, "elemptr = elemptr->next;\n");
584 63 : gen_write(ofp, nesting+1, "}\n");
585 63 : gen_write(ofp, nesting+1, "list_size = elem_count;\n");
586 63 : gen_write(ofp, nesting+1, "if (elem_count) {\n");
587 63 : gen_write(ofp, nesting+2, "uint8_t *tmp_list = NULL;\n");
588 63 : switch (sub_type_size) {
589 38 : case 1:
590 38 : gen_write(ofp, nesting+2,
591 : "uint8_t *list_index = NULL;\n");
592 38 : gen_write(ofp, nesting+2,
593 : "tmp_list = (uint8_t*) calloc(elem_count, 1);\n");
594 38 : gen_write(ofp, nesting+2, "if (!tmp_list) {\n");
595 38 : gen_write(ofp, nesting+3, "return NULL;\n");
596 38 : gen_write(ofp, nesting+2, "}\n");
597 38 : gen_write(ofp, nesting+2, "list_index = tmp_list;\n");
598 38 : break;
599 3 : case 2:
600 3 : gen_write(ofp, nesting+2,
601 : "uint16_t *list_index = NULL;\n");
602 3 : gen_write(ofp, nesting+2,
603 : "tmp_list = (uint8_t*) calloc(elem_count, 2);\n");
604 3 : gen_write(ofp, nesting+2, "if (!tmp_list) {\n");
605 3 : gen_write(ofp, nesting+3, "return NULL;\n");
606 3 : gen_write(ofp, nesting+2, "}\n");
607 3 : gen_write(ofp, nesting+2, "list_index = (uint16_t *)tmp_list;\n");
608 3 : break;
609 13 : case 4:
610 13 : gen_write(ofp, nesting+2,
611 : "uint32_t *list_index = NULL;\n");
612 13 : gen_write(ofp, nesting+2,
613 : "tmp_list = (uint8_t*) calloc(elem_count, 4);\n");
614 13 : gen_write(ofp, nesting+2, "if (!tmp_list) {\n");
615 13 : gen_write(ofp, nesting+3, "return NULL;\n");
616 13 : gen_write(ofp, nesting+2, "}\n");
617 13 : gen_write(ofp, nesting+2, "list_index = (uint32_t *)tmp_list;\n");
618 13 : break;
619 9 : case 8:
620 9 : gen_write(ofp, nesting+2,
621 : "uint64_t *list_index = NULL;\n");
622 9 : gen_write(ofp, nesting+2,
623 : "tmp_list = (uint8_t*) calloc(elem_count, 8);\n");
624 9 : gen_write(ofp, nesting+2, "if (!tmp_list) {\n");
625 9 : gen_write(ofp, nesting+3, "return NULL;\n");
626 9 : gen_write(ofp, nesting+2, "}\n");
627 9 : gen_write(ofp, nesting+2, "list_index = (uint64_t *)tmp_list;\n");
628 9 : break;
629 0 : default:
630 0 : return EINVAL;
631 : }
632 63 : gen_write(ofp, nesting+2, "elemptr = listnode->children;\n");
633 63 : gen_write(ofp, nesting+2, "while (elemptr) {\n");
634 63 : gen_write(ofp, nesting+3, "if (!strncmp(elemptr->name, "
635 : "\"element\", sizeof(\"element\"))) {\n");
636 63 : switch (sub_type_size) {
637 38 : case 1:
638 38 : gen_write(ofp, nesting+4,
639 : "*list_index = "
640 : " (uint8_t) strtoul(elemptr->children->content, NULL, 0);\n");
641 38 : break;
642 3 : case 2:
643 3 : gen_write(ofp, nesting+4,
644 : "*list_index = "
645 : " (uint16_t) strtoul(elemptr->children->content, NULL, 0);\n");
646 3 : break;
647 13 : case 4:
648 13 : gen_write(ofp, nesting+4,
649 : "*list_index = "
650 : " (uint32_t) strtoul(elemptr->children->content, NULL, 0);\n");
651 13 : break;
652 9 : case 8:
653 9 : gen_write(ofp, nesting+4,
654 : "*list_index = "
655 : " (uint64_t) strtoull(elemptr->children->content, NULL, 0);\n");
656 9 : break;
657 0 : default:
658 0 : return EINVAL;
659 : }
660 63 : gen_write(ofp, nesting+4, "list_index++;\n");
661 63 : gen_write(ofp, nesting+3, "}\n");
662 63 : gen_write(ofp, nesting+3, "elemptr = elemptr->next;\n");
663 63 : gen_write(ofp, nesting+2, "}\n");
664 :
665 63 : gen_write(ofp, nesting+2, "req->");
666 63 : gen_raw_write(ofp, 0, var, var_len);
667 63 : gen_write(ofp, 0, " = ");
668 63 : gen_write(ofp, 0, "(void *) tmp_list;\n");
669 :
670 63 : gen_write(ofp, nesting+1, "}\n");
671 63 : gen_write(ofp, nesting, "}\n");
672 :
673 63 : gen_write(ofp, nesting, "req->");
674 63 : gen_raw_write(ofp, 0, var, var_len);
675 63 : gen_write(ofp, 0, "_size = list_size;\n");
676 4 : } else if (!strncmp(type, "string", strlen("string"))) {
677 4 : gen_write(ofp, 0, "vt_gen_string(node->children->content);\n");
678 :
679 4 : gen_write(fp_expect, 0, "result = !strcmp(");
680 4 : gen_write(fp_expect, 0, "req->");
681 4 : gen_raw_write(fp_expect, 0, var, var_len);
682 4 : gen_write(fp_expect, 0, ", node->children->content);\n");
683 :
684 : }
685 :
686 488 : gen_write(ofp, --nesting, "}");
687 488 : gen_write(fp_expect, nesting, "}");
688 488 : need_else = true;
689 : }
690 : }
691 :
692 1 : gen_write(fp_message, 1, "{\n");
693 1 : gen_write(fp_message, 2, ".vmm_name");
694 1 : gen_write(fp_message, 2, "=");
695 1 : gen_write(fp_message, 2, "\"return\",\n");
696 1 : gen_write(fp_message, 2, ".vmm_node");
697 1 : gen_write(fp_message, 2, "=");
698 1 : gen_write(fp_message, 2, "vt_return_node,\n");
699 1 : gen_write(fp_message, 2, ".vmm_size");
700 1 : gen_write(fp_message, 2, "=");
701 1 : gen_write(fp_message, 2, "0,\n");
702 1 : gen_write(fp_message, 1, "},\n");
703 1 : gen_write(fp_message_hdr, 0, "extern void *");
704 1 : gen_write(fp_message_hdr, 0, "vt_return_node(xmlNodePtr, struct vtest *);\n");
705 :
706 1 : gen_write(fp_message, 0, "};\n\n");
707 1 : gen_write(fp_message, 0,
708 : "unsigned int vt_message_modules_num = \n");
709 1 : gen_write(fp_message, 2, "sizeof(vt_message_modules) / sizeof(vt_message_modules[0]);\n\n");
710 1 : gen_close(fp_message, false);
711 1 : gen_close(fp_message_hdr, true);
712 :
713 1 : return 0;
714 : }
715 :
716 : static void
717 0 : Usage(void)
718 : {
719 0 : printf("Usage: sandesh_gen <file name>\n");
720 0 : return;
721 : }
722 :
723 : int
724 1 : main(int argc, char *argv[])
725 : {
726 : int ret;
727 : FILE *fp;
728 :
729 1 : if (argc != 2) {
730 0 : Usage();
731 0 : return EINVAL;
732 : }
733 :
734 1 : fp = fopen(argv[1], "r");
735 1 : if (!fp) {
736 0 : perror(argv[1]);
737 0 : return errno;
738 : }
739 :
740 1 : ret = gen(fp);
741 1 : return ret;
742 : }
|