LCOV - code coverage report
Current view: top level - root/contrail/vrouter/utils/vtest - sandesh_gen.c (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 409 446 91.7 %
Date: 2026-08-03 02:19:58 Functions: 9 10 90.0 %
Legend: Lines: hit not hit

          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             : }

Generated by: LCOV version 1.14