openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

cint_eval_ast_cint.c (12973B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        cint_eval_ast_cint.c
      8  * Purpose:     CINT AST node evaluators
      9  */
     10 
     11 #include "cint_eval_ast_cint.h"
     12 #include "cint_porting.h"
     13 #include "cint_interpreter.h"
     14 #include "cint_internal.h"
     15 #include "cint_eval_asts.h"
     16 
     17 /*
     18  * Command Handlers
     19  */
     20 
     21 #define CCINT_PRINTF CINT_PRINTF("cint> "); CINT_PRINTF
     22 
     23 
     24 #if CINT_CONFIG_INCLUDE_CINT_LOAD == 1
     25 #include <dlfcn.h>
     26 
     27 void
     28 cint_ast_cint_cmd_unload(void *handle)
     29 {
     30     if (handle && dlclose(handle)) {
     31         CCINT_PRINTF("%s", dlerror()); 
     32     }
     33 }
     34 #endif
     35 
     36 cint_variable_t* 
     37 __cint_ast_cint_cmd_load(cint_ast_t* ast, const char* argv[])
     38 {
     39 #if CINT_CONFIG_INCLUDE_CINT_LOAD == 0
     40     cint_ast_error(ast, CINT_E_UNSUPPORTED, "dynamic library loading support was not compiled in."); 
     41 #else
     42     void* handle;
     43     const char** s = NULL; 
     44 
     45     for(s = argv; *s; s++) {
     46 
     47         if((handle = dlopen(*s, RTLD_NOW)) == NULL) {
     48             cint_ast_error(ast, CINT_E_BAD_AST, "loading library '%s': %s", *s, dlerror()); 
     49         }
     50         else {
     51 #define STRINGIFY0(x) #x
     52 #define STRINGIFY(x) STRINGIFY0(x)
     53             void* data;             
     54             char *sym = STRINGIFY(CINT_LOAD_DATA_SYMBOL);
     55 
     56             if((data = dlsym(handle, sym)) == NULL) {
     57                 cint_ast_error(ast, CINT_E_BAD_AST, "%s", dlerror()); 
     58                 dlclose(handle); 
     59                 return NULL; 
     60             }       
     61             else {
     62                 cint_interpreter_add_data(*(cint_data_t**)data, handle); 
     63             }
     64         }
     65     }
     66 #endif /* CINT_CONFIG_INCLUDE_CINT_LOAD */
     67 
     68     return NULL; 
     69 }
     70 
     71 cint_variable_t*
     72 __cint_ast_cint_cmd_typecheck(cint_ast_t* ast, const char* argv[])
     73 {
     74     cint_datatype_checkall(1); 
     75     return NULL; 
     76 }
     77 
     78 cint_variable_t*
     79 __cint_ast_cint_cmd_var(cint_ast_t* ast, const char* argv[])
     80 {
     81     cint_variable_t* v = NULL; 
     82     char _rstr[CINT_CONFIG_MAX_STACK_PRINT_BUFFER] = {0};
     83 
     84     if(*argv == NULL) {
     85         CCINT_PRINTF("no variable specified"); 
     86         return NULL; 
     87     }
     88 
     89     v = cint_variable_find(*argv, 0); 
     90 
     91     if(v) {
     92         CCINT_PRINTF("variable '%s' is type '%s' @ %p size=%d\n", v->name, cint_datatype_format(&v->dt,_rstr,0), v->data, v->size);  
     93     }
     94     else {        
     95         CCINT_PRINTF("variable '%s' not found\n", *argv); 
     96     }
     97     return NULL; 
     98 }       
     99 
    100 
    101 static int
    102 __cint_list_datatype_traverse(void* cookie, const cint_datatype_t* dt)
    103 {
    104     const char* substr = (const char*)cookie; 
    105     int flags = dt->flags;
    106     char _rstr[256] = {0};
    107 
    108     if(flags & CINT_DATATYPE_F_TYPEDEF) {
    109         if(substr && CINT_STRSTR(dt->type, substr) == NULL) {
    110             /* No Match */
    111             return 0; 
    112         }
    113         CINT_PRINTF("%s typedef for %s ", dt->type, cint_datatype_format_pd(&dt->desc,_rstr, 0)); 
    114         flags &= ~CINT_DATATYPE_F_TYPEDEF; 
    115     }
    116     else if (flags & CINT_DATATYPE_F_CONSTANT) {
    117         if(substr && CINT_STRSTR(dt->basetype.cp->name, substr) == NULL) {
    118             /* No Match */
    119             return 0; 
    120         }
    121     }   
    122     else {
    123         if(substr && CINT_STRSTR(dt->desc.basetype, substr) == NULL) {
    124             /* No Match */
    125             return 0; 
    126         }
    127         CINT_PRINTF("%s ", dt->desc.basetype); 
    128     }
    129 
    130     switch(flags) 
    131         {
    132         case CINT_DATATYPE_F_ATOMIC: CINT_PRINTF("(atomic)"); break; 
    133         case CINT_DATATYPE_F_STRUCT: CINT_PRINTF("(struct)"); break; 
    134         case CINT_DATATYPE_F_ENUM:     CINT_PRINTF("(enum)"); break; 
    135         case CINT_DATATYPE_F_FUNC_DYNAMIC:     
    136         case CINT_DATATYPE_F_FUNC:   CINT_PRINTF("(function)"); break; 
    137         case CINT_DATATYPE_F_CONSTANT: CINT_PRINTF("%s (constant)", dt->basetype.cp->name); break; 
    138         case CINT_DATATYPE_F_FUNC_POINTER: CINT_PRINTF("(function pointer)"); break; 
    139         case CINT_DATATYPE_F_MACRO: CINT_PRINTF("(macro)"); break; 
    140         case CINT_DATATYPE_F_ITERATOR: CINT_PRINTF("(iterator)"); break; 
    141         default:  CINT_PRINTF("(unknown datatype flags 0x%x)", flags); break; 
    142         }
    143     
    144     CINT_PRINTF("\n"); 
    145     return 0; 
    146 }
    147 
    148 cint_variable_t*
    149 __cint_ast_cint_cmd_list(cint_ast_t* ast, const char* argv[])
    150 {
    151     const char** arg = argv; 
    152     unsigned dtflags = 0; 
    153     const char* str = NULL; 
    154 
    155     for(arg = argv; *arg; arg++) {
    156         if(!CINT_STRCMP(*arg, "atomic")) {
    157             dtflags |= CINT_DATATYPE_F_ATOMIC; 
    158         }
    159         else if(!CINT_STRCMP(*arg, "struct")) {
    160             dtflags |= CINT_DATATYPE_F_STRUCT;
    161         }
    162         else if(!CINT_STRCMP(*arg, "enum")) {
    163             dtflags |= CINT_DATATYPE_F_ENUM; 
    164         }       
    165         else if(!CINT_STRCMP(*arg, "fp")) {
    166             dtflags |= CINT_DATATYPE_F_FUNC_POINTER; 
    167         }       
    168         else if(!CINT_STRCMP(*arg, "function")) {
    169             dtflags |= CINT_DATATYPE_F_FUNC|CINT_DATATYPE_F_FUNC_DYNAMIC; 
    170         }
    171         else if(!CINT_STRCMP(*arg, "constant")) {
    172             dtflags |= CINT_DATATYPE_F_CONSTANT; 
    173         }
    174         else if(!CINT_STRCMP(*arg, "macro")) {
    175             dtflags |= CINT_DATATYPE_F_MACRO; 
    176         }
    177         else if(!CINT_STRCMP(*arg, "iterator")) {
    178             dtflags |= CINT_DATATYPE_F_ITERATOR; 
    179         }
    180         else {
    181             if(str != NULL) {
    182                 cint_ast_error(ast, CINT_E_BAD_AST, "only one search substring may be specified"); 
    183                 return NULL; 
    184             }
    185             else {
    186                 str = *arg; 
    187             }
    188         }
    189     }
    190     
    191     /* 
    192      * Traverse all datatypes 
    193      */
    194     cint_datatype_traverse(dtflags, __cint_list_datatype_traverse, (void*)str); 
    195     
    196     return NULL; 
    197 }
    198 
    199 #if CINT_CONFIG_YAPI
    200 
    201 typedef struct yapi_data_s {
    202     int level;
    203     unsigned int flags;
    204 } yapi_data_t;
    205 
    206 #define NULLSTR(s) ((s) ? (s) : "NULL")
    207 
    208 static void
    209 _yapi_indent(int level)
    210 {
    211     while (level-- > 0) {
    212         CINT_PRINTF("  ");
    213     }
    214 }
    215 
    216 static int
    217 _yapi_desc(const cint_parameter_desc_t *desc, int level)
    218 {
    219     int dim_index;
    220     _yapi_indent(level);
    221     CINT_PRINTF("basetype: %s\n", NULLSTR(desc->basetype));
    222     _yapi_indent(level);
    223     CINT_PRINTF("pcount: %d\n", desc->pcount);
    224     _yapi_indent(level);
    225     CINT_PRINTF("name: %s\n", NULLSTR(desc->name));
    226     _yapi_indent(level);
    227     CINT_PRINTF(
    228         "arrayDimensions: %d\n", 
    229         desc->utype.declaration.arrayDimensions);
    230     for(dim_index = 0; 
    231         dim_index < desc->utype.declaration.arrayDimensions;
    232         ++dim_index) {
    233         _yapi_indent(level);
    234         CINT_PRINTF(
    235             "dimensions[%d]: %d\n",
    236             dim_index,
    237             desc->dimensions[dim_index]);
    238     }
    239     _yapi_indent(level);
    240     CINT_PRINTF("flags: %d\n", desc->flags);
    241 
    242     return 0;
    243 }
    244 
    245 static void
    246 _yapi_func(const char *name, const cint_parameter_desc_t *param, int *level)
    247 {
    248     int idx;
    249     _yapi_indent(*level);
    250     CINT_PRINTF("%s:\n", name);
    251     *level += 1;
    252     if (param) {
    253         for (idx=0; param->name; idx++, param++) {
    254             if (idx == 0) {
    255                 _yapi_indent(*level);
    256                 CINT_PRINTF("return:\n");
    257             } else if (idx == 1) {
    258                 _yapi_indent(*level);
    259                 CINT_PRINTF("arg:\n");
    260             }
    261             if (idx > 0) {
    262                 _yapi_indent(*level+1);
    263                 CINT_PRINTF("-\n");
    264                 _yapi_desc(param, *level+2);
    265             } else {
    266                 _yapi_desc(param, *level+1);
    267             }
    268         }
    269     } else {
    270         _yapi_indent(*level);
    271         CINT_PRINTF("vararg: 1\n");
    272     }
    273 }
    274 
    275 static int
    276 _yapi_show(const cint_datatype_t *dt, yapi_data_t *data)
    277 {
    278     int show_desc = 0;
    279     int level = data->level;
    280 
    281     if (level > 5) {
    282         _yapi_indent(level);
    283         CINT_PRINTF("error: DEPTH\n");
    284         return -1;
    285     }
    286 
    287     if (dt == NULL) {
    288         _yapi_indent(level);
    289         CINT_PRINTF("error: NULLDT\n");
    290         return -1;
    291     }
    292     
    293     /* consistency check */
    294     if (dt->flags == CINT_DATATYPE_F_ATOMIC && dt->flags == data->flags) {
    295         _yapi_indent(level);
    296         CINT_PRINTF("%s:\n", dt->desc.basetype);
    297         show_desc = 1;
    298         level += 1;
    299     }
    300     if (dt->flags & CINT_DATATYPE_F_STRUCT) {
    301         const cint_parameter_desc_t *m;
    302         show_desc = 1;
    303         _yapi_indent(level);
    304         CINT_PRINTF("%s:\n", dt->desc.basetype);
    305         level += 1;
    306         _yapi_indent(level);
    307         CINT_PRINTF("members:\n");
    308         for (m=dt->basetype.sp->struct_members; m->basetype; m++) {
    309             _yapi_indent(level+1);
    310             CINT_PRINTF("-\n");
    311             _yapi_desc(m, level+2);
    312         }
    313     }
    314 
    315     if (dt->flags & CINT_DATATYPE_F_ENUM) {
    316         cint_enum_type_t* ep = dt->basetype.ep;
    317         cint_enum_map_t* enum_map;
    318 
    319         _yapi_indent(level);
    320         CINT_PRINTF("%s:\n", dt->desc.basetype);
    321         level += 1;
    322 
    323         for (enum_map = ep->enum_map; enum_map->name; enum_map++) {
    324             _yapi_indent(level);
    325             printf("%s: %d\n", enum_map->name, enum_map->value);
    326         }
    327     }
    328     if (dt->flags & CINT_DATATYPE_F_FUNC) {
    329         show_desc = 1;
    330         _yapi_func(dt->desc.basetype, dt->basetype.fp->params, &level);
    331     }
    332     if (dt->flags & CINT_DATATYPE_F_CONSTANT) {
    333         _yapi_indent(level);
    334         printf("%s: %d\n", dt->basetype.cp->name, dt->basetype.cp->value);
    335     }
    336     if (dt->flags & CINT_DATATYPE_F_FUNC_DYNAMIC) {
    337         show_desc = 1;
    338         _yapi_indent(level);
    339         CINT_PRINTF("dynamic_function: 1\n");
    340     }
    341     if (dt->flags & CINT_DATATYPE_F_FUNC_POINTER) {
    342         show_desc = 1;
    343         _yapi_func(dt->desc.basetype, dt->basetype.fpp->params, &level);
    344     }
    345     if (dt->flags & CINT_DATATYPE_F_ITERATOR) {
    346         _yapi_indent(level);
    347         CINT_PRINTF("%s:\n", dt->basetype.ip->name);
    348     }
    349     if (dt->flags & CINT_DATATYPE_F_MACRO) {
    350         _yapi_indent(level);
    351         CINT_PRINTF("%s:\n", dt->basetype.mp->name);
    352     }
    353     if (dt->flags & CINT_DATATYPE_F_FUNC_VARARG) {
    354         show_desc = 1;
    355         _yapi_indent(level);
    356         CINT_PRINTF("%s:\n", dt->desc.basetype);
    357     }
    358     if (dt->flags & CINT_DATATYPE_F_TYPEDEF) {
    359         show_desc = 1;
    360         _yapi_indent(level);
    361         CINT_PRINTF("%s:\n", dt->desc.name);
    362         level += 1;
    363         _yapi_indent(level);
    364         CINT_PRINTF("typedef:\n");
    365         if (dt->flags & CINT_DATATYPE_F_ATOMIC) {
    366             _yapi_indent(level);
    367             CINT_PRINTF("atomic:\n");
    368         }
    369     }
    370 
    371     if (show_desc) {
    372         _yapi_desc(&dt->desc, level);
    373     }
    374 
    375     return 0;
    376 }
    377 
    378 
    379 static int
    380 __yapi(void* cookie, const cint_datatype_t* dt)
    381 {
    382     yapi_data_t *data = (yapi_data_t *)cookie;
    383 
    384     (void)_yapi_show(dt, data);
    385 
    386     return 0;
    387 }
    388 
    389 static void _yapi_trav(const char *name, unsigned int flags)
    390 {
    391     yapi_data_t data;
    392 
    393     CINT_PRINTF("%s:\n", name);
    394     data.level = 1;
    395     data.flags = flags;
    396     cint_datatype_traverse(data.flags, __yapi, &data);
    397 }
    398 
    399 static void
    400 _yapi(void)
    401 {
    402     CINT_PRINTF("---\n");
    403     _yapi_trav("ATOMIC", CINT_DATATYPE_F_ATOMIC);
    404     _yapi_trav("STRUCT", CINT_DATATYPE_F_STRUCT);
    405     _yapi_trav("ENUM", CINT_DATATYPE_F_ENUM);
    406     _yapi_trav("CONSTANT", CINT_DATATYPE_F_CONSTANT);
    407     _yapi_trav("FUNC", CINT_DATATYPE_F_FUNC);
    408     _yapi_trav("MACRO", CINT_DATATYPE_F_MACRO);
    409     _yapi_trav("ITERATOR", CINT_DATATYPE_F_ITERATOR);
    410     _yapi_trav("TYPEDEF", CINT_DATATYPE_F_TYPEDEF);
    411     _yapi_trav("FUNC_POINTER", CINT_DATATYPE_F_FUNC_POINTER);
    412     CINT_PRINTF("\n");
    413 }
    414 #endif
    415 
    416 cint_variable_t*
    417 __cint_ast_cint_cmd_yapi(cint_ast_t* ast, const char* argv[])
    418 {
    419 #if CINT_CONFIG_YAPI == 0
    420     cint_ast_error(ast, CINT_E_UNSUPPORTED, "YAML emitter not compiled in."); 
    421 #else
    422     _yapi();
    423 #endif /* CINT_CONFIG_YAPI */
    424 
    425     return NULL; 
    426 }
    427 
    428 
    429 
    430 /*
    431  * Command Handler Dispatch
    432  */
    433 struct {
    434     const char* cmd; 
    435     cint_variable_t* (*handler)(cint_ast_t* ast, const char* args[]); 
    436 } __handler_table[] = {
    437 
    438 #define CINT_AST_CINT_CMD_ENTRY(_e) { #_e, __cint_ast_cint_cmd_##_e }, 
    439 #include "cint_eval_ast_cint.h"
    440     { NULL }
    441 }; 
    442 
    443 cint_variable_t* 
    444 cint_eval_ast_Cint(cint_ast_t* ast)
    445 {
    446     int i; 
    447     cint_ast_t* cmd; 
    448     cint_ast_t* args;    
    449     const char* argv[64] = { NULL }; 
    450         
    451     if(ast == NULL) {
    452         return NULL; 
    453     }   
    454     
    455     cmd = ast->utype.cint.arguments; 
    456     
    457     if(cmd == NULL) {
    458         return NULL; 
    459     }
    460     
    461     /* Process string arguments */
    462     for(i = 0, args = cmd->next; args; args = args->next, i++) {
    463         switch(args->ntype)
    464             {
    465             case cintAstIdentifier:     argv[i] = args->utype.identifier.s; break; 
    466             case cintAstString:         argv[i] = args->utype.string.s; break; 
    467             case cintAstType:           argv[i] = args->utype.type.s; break; 
    468             default: break; 
    469             }   
    470     }   
    471     argv[i] = NULL; 
    472     
    473     for(i = 0; __handler_table[i].cmd; i++) {
    474         if(!CINT_STRCMP(cmd->utype.identifier.s, __handler_table[i].cmd)) {
    475             return __handler_table[i].handler(cmd, argv); 
    476         }
    477     }   
    478 
    479     return NULL; 
    480 }