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