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-11-09 02:10:49 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             :  * 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             : }

Generated by: LCOV version 1.14