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 }