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_variables.c (11074B)


      1 /*
      2  * 
      3  * 
      4  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      5  * 
      6  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      7  * 
      8  * File:        cint_variables.c
      9  * Purpose:     CINT variable functions
     10  */
     11 
     12 #include "cint_config.h"
     13 #include "cint_variables.h"
     14 #include "cint_porting.h"
     15 #include "cint_debug.h"
     16 #include "cint_interpreter.h"
     17 
     18 /*******************************************************************************
     19  * 
     20  * Global Static Data Variables
     21  */
     22 
     23 typedef struct lscope_list_s {
     24     struct lscope_list_s* next;     
     25     cint_variable_t* vlist; 
     26     cint_variable_t* autolist; 
     27 } lscope_list_t; 
     28 
     29 typedef struct vscope_list_s {
     30     struct vscope_list_s* next; 
     31     lscope_list_t* lscopes; 
     32 } vscope_list_t; 
     33 
     34 /*
     35  * Global variable scope. 
     36  *
     37  * This scope is available at all times. 
     38  */
     39 static vscope_list_t _global_scope = { NULL, NULL }; 
     40 
     41 
     42 /*
     43  * This is the list of all variable scopes. 
     44  */
     45 static vscope_list_t* _scopes = NULL; 
     46 
     47 /*
     48  * Mutex to protect all list operations
     49  */
     50 sal_mutex_t cint_variables_mutex = NULL;
     51 
     52 static void
     53 __cint_variables_mutex_create(void)
     54 {
     55     if (!cint_variables_mutex) {
     56 
     57         SAL_GLOBAL_LOCK;
     58 
     59         if (!cint_variables_mutex) {
     60 
     61             cint_variables_mutex = sal_mutex_create("cint_variables_mutex");
     62             if (!cint_variables_mutex) {
     63                 /* should probably just assert here */
     64                 cint_internal_error(__FILE__, __LINE__, "Failed to create cint_variables_mutex");
     65             }
     66         }
     67 
     68         SAL_GLOBAL_UNLOCK;
     69     }
     70 }
     71 
     72 int 
     73 cint_variable_init(void)
     74 {
     75     __cint_variables_mutex_create();
     76 
     77     /* Destroy any previous scopes */
     78     while(cint_variable_scope_pop("") != CINT_E_NOT_FOUND); 
     79 
     80     /* Initialize the global scope */
     81     _scopes = &_global_scope; 
     82     cint_variable_lscope_push("global"); 
     83     return 0; 
     84 }
     85 
     86 static int
     87 __destroy_vlist(cint_variable_t* vlist, int force)
     88 {
     89     cint_variable_t* v; 
     90     for(v = vlist; v;) {
     91         cint_variable_t* next = v->next;
     92         if (force) {
     93             v->flags &= ~CINT_VARIABLE_F_NODESTROY;
     94         }
     95         cint_variable_free(v); 
     96         v = next; 
     97     }
     98 
     99     return CINT_E_NONE; 
    100 }
    101 
    102 
    103 int 
    104 cint_variable_scope_push(const char* msg)
    105 {
    106     vscope_list_t* vscope = CINT_MALLOC(sizeof(*vscope)); 
    107 
    108     if(vscope == NULL) {
    109         return CINT_E_MEMORY; 
    110     }
    111 
    112     CINT_VARIABLES_LOCK;
    113 
    114     vscope->lscopes = NULL; 
    115     vscope->next = _scopes; 
    116     _scopes = vscope; 
    117 
    118     CINT_VARIABLES_UNLOCK;
    119     
    120     CINT_DTRACE(("scope_push(%s)=%p", msg, (void *)vscope)); 
    121     return cint_variable_lscope_push(msg); 
    122 }
    123 
    124 int
    125 cint_variable_scope_pop(const char* msg)
    126 {
    127     vscope_list_t* vscope;
    128 
    129     CINT_VARIABLES_LOCK;
    130 
    131     vscope = _scopes; 
    132     
    133     if(vscope) {
    134         while(cint_variable_lscope_pop(msg) != CINT_E_NOT_FOUND); 
    135         _scopes = vscope->next;     
    136         CINT_DTRACE(("scope_pop(%s)=%p", msg, (void *)vscope));
    137         if (vscope != &_global_scope) {
    138             CINT_FREE(vscope);
    139         }
    140 
    141         CINT_VARIABLES_UNLOCK;
    142 
    143         return CINT_E_NONE; 
    144     }   
    145     else {
    146 
    147         CINT_VARIABLES_UNLOCK;
    148 
    149         return CINT_E_NOT_FOUND; 
    150     }   
    151 }
    152 
    153 void *
    154 cint_variable_scope_global_set(const char *msg)
    155 {
    156     vscope_list_t *vscope;
    157 
    158     CINT_VARIABLES_LOCK;
    159 
    160     vscope = _scopes;
    161     _scopes = &_global_scope;
    162 
    163     CINT_VARIABLES_UNLOCK;
    164 
    165     CINT_DTRACE(("scope_global_set(%s)=%p (prev %p)", msg, _scopes, vscope)); 
    166 
    167     return vscope;
    168 }
    169 
    170 void *
    171 cint_variable_scope_set(const char *msg, void *vscope)
    172 {
    173     vscope_list_t *c_scope;
    174 
    175     CINT_VARIABLES_LOCK;
    176 
    177     c_scope = _scopes;
    178     _scopes = vscope;
    179 
    180     CINT_VARIABLES_UNLOCK;
    181 
    182     CINT_DTRACE(("scope_set(%s)=%p (prev %p)", msg, _scopes, c_scope)); 
    183 
    184     return c_scope;
    185 }
    186 
    187 
    188 int
    189 cint_variable_lscope_push(const char* msg)
    190 {
    191     lscope_list_t* lscope;
    192 
    193     if (!_scopes) {
    194         CINT_DTRACE(("lscope_push(%s) no scope", msg));
    195         return CINT_E_NONE;
    196     }
    197 
    198     lscope = CINT_MALLOC(sizeof(*lscope));
    199 
    200     if(lscope == NULL) {
    201         return CINT_E_MEMORY; 
    202     }
    203 
    204     lscope->vlist = NULL; 
    205     lscope->autolist = NULL; 
    206 
    207     CINT_VARIABLES_LOCK;
    208 
    209     lscope->next = _scopes->lscopes; 
    210     _scopes->lscopes = lscope;
    211 
    212     CINT_VARIABLES_UNLOCK;
    213     
    214     CINT_DTRACE(("lscope_push(%s)", msg)); 
    215     return CINT_E_NONE; 
    216 }
    217     
    218 int
    219 cint_variable_lscope_pop(const char* msg)
    220 {
    221     lscope_list_t* lscope;
    222 
    223     CINT_VARIABLES_LOCK;
    224 
    225     lscope = _scopes->lscopes; 
    226     if (!lscope) {
    227         CINT_VARIABLES_UNLOCK;
    228         return CINT_E_NOT_FOUND;
    229     }
    230 
    231     _scopes->lscopes = lscope->next; 
    232     __destroy_vlist(lscope->vlist, 0); 
    233     __destroy_vlist(lscope->autolist, 0); 
    234 
    235     CINT_VARIABLES_UNLOCK;
    236 
    237     CINT_FREE(lscope); 
    238     CINT_DTRACE(("lscope_pop(%s)", msg)); 
    239     return CINT_E_NONE;     
    240 }        
    241 
    242     
    243 cint_variable_t*
    244 cint_variable_alloc(void)
    245 {
    246     cint_variable_t* v = (cint_variable_t*)CINT_MALLOC(sizeof(cint_variable_t));
    247     if (v) {
    248         CINT_MEMSET(v, 0, sizeof(*v));
    249     }
    250     return v; 
    251 }
    252 
    253 int
    254 cint_variable_free(cint_variable_t* v)
    255 {
    256     if(v) {
    257         
    258         if(v->flags & CINT_VARIABLE_F_NODESTROY){
    259             return 0; 
    260         }
    261         /*CINT_PRINTF("free variable '%s' flags=0x%x name=%p data=%p\n", 
    262           v->name, v->flags, v->name, v->data);*/
    263         if(v->name && !(v->flags & CINT_VARIABLE_F_SNAME)) {
    264             CINT_FREE(v->name); 
    265         }
    266         if(v->data && !(v->flags & CINT_VARIABLE_F_SDATA)) {
    267             if(v->flags & CINT_VARIABLE_F_CSTRING) {
    268                 char **sptr = (char **)v->data;
    269                 if (sptr) {
    270                     CINT_FREE(*sptr);
    271                 }
    272             }
    273             CINT_FREE(v->data); 
    274         }
    275         CINT_FREE(v); 
    276     }   
    277     return 0; 
    278 }
    279 
    280 /* Find a variable on a variable list */
    281 static cint_variable_t*
    282 _variable_find_list(cint_variable_t* vlist, const char* name)
    283 {
    284     cint_variable_t* v; 
    285     for(v = vlist; v; v = v->next) {
    286         if(!CINT_STRCMP(v->name, name)) {
    287             return v; 
    288         }
    289     }
    290     return NULL; 
    291 }
    292 
    293 /* Find a variable within a scope on manual and auto lists */
    294 static cint_variable_t*
    295 _variable_find_scope(lscope_list_t* lscope, const char* name)
    296 {
    297     cint_variable_t* rv = NULL;
    298 
    299     rv = _variable_find_list(lscope->vlist, name); 
    300 
    301     if (rv == NULL) {
    302         rv = _variable_find_list(lscope->autolist, name);
    303     }
    304 
    305     return rv;
    306 }
    307 
    308 /* Find a variable within a set of scopes on manual and auto lists */
    309 static cint_variable_t*
    310 _variable_find_scopes(lscope_list_t* lscope, const char* name)
    311 {
    312     lscope_list_t* s; 
    313     cint_variable_t* rv = NULL;
    314 
    315     for (s = lscope; s; s = s->next) {
    316         if ((rv = _variable_find_scope(s, name)) != NULL) {
    317             break; 
    318         }
    319     }       
    320 
    321     return rv;
    322 }
    323 
    324 cint_variable_t* 
    325 cint_variable_find(const char* name, int current_scope_only)
    326 {
    327     cint_variable_t* rv = NULL; 
    328 
    329     CINT_VARIABLES_LOCK;
    330     
    331     if(_scopes && _scopes->lscopes) {
    332         if(current_scope_only) {
    333             rv = _variable_find_scope(_scopes->lscopes, name); 
    334             CINT_VARIABLES_UNLOCK;
    335             return rv; 
    336         } else {
    337             rv = _variable_find_scopes(_scopes->lscopes, name);
    338         }   
    339     }
    340 
    341     if(rv == NULL) {
    342         rv = _variable_find_scopes(_global_scope.lscopes, name); 
    343     }
    344 
    345     CINT_VARIABLES_UNLOCK;
    346 
    347     return rv; 
    348 }
    349 
    350 int
    351 cint_variable_add(cint_variable_t* v)
    352 {
    353     int is_global = 0;
    354     v->prev = NULL; 
    355 
    356     CINT_VARIABLES_LOCK;
    357 
    358     if(v->flags & CINT_VARIABLE_F_AUTO) {
    359         v->next = _scopes->lscopes->autolist; 
    360         _scopes->lscopes->autolist = v; 
    361     }   
    362     else {
    363         v->next = _scopes->lscopes->vlist; 
    364         _scopes->lscopes->vlist = v;
    365         if (_scopes == &_global_scope) {
    366             is_global = 1;
    367         }
    368     }   
    369     
    370     if(v->next) {
    371         v->next->prev = v; 
    372     }
    373 
    374     CINT_VARIABLES_UNLOCK;
    375 
    376     if (is_global) {
    377         cint_interpreter_event(cintEventGlobalVariableAdded); 
    378     }
    379 
    380     return CINT_E_NONE; 
    381 }
    382 
    383 int
    384 cint_variable_rename(cint_variable_t* v, const char *name)
    385 {
    386     if (name) {
    387         if (v->name) {
    388             CINT_FREE(v->name);
    389         }
    390         v->name = CINT_STRDUP(name);
    391     }
    392 
    393     return CINT_E_NONE; 
    394 }
    395 
    396 int
    397 cint_variable_list_remove(cint_variable_t* v)
    398 {
    399     if(v == NULL) {
    400         return 0; 
    401     }   
    402 
    403     CINT_VARIABLES_LOCK;
    404         
    405     if(v->prev) {
    406         v->prev->next = v->next; 
    407     }
    408 
    409     if (v->next) {
    410         v->next->prev = v->prev;
    411     }
    412 
    413     if(v == _scopes->lscopes->autolist) {
    414         _scopes->lscopes->autolist = v->next; 
    415     }       
    416     else if(v == _scopes->lscopes->vlist) {
    417         _scopes->lscopes->vlist = v->next; 
    418     }       
    419 
    420     CINT_VARIABLES_UNLOCK;
    421         
    422     return 0; 
    423 }
    424 
    425 
    426 int
    427 cint_variable_auto_clear(void)
    428 {
    429     CINT_VARIABLES_LOCK;
    430 
    431     /* Clear all autovars from the current scope */
    432     __destroy_vlist(_scopes->lscopes->autolist, 0); 
    433     _scopes->lscopes->autolist = NULL; 
    434 
    435     CINT_VARIABLES_UNLOCK;
    436     return 0;
    437 }
    438 
    439 int
    440 cint_variable_auto_save(cint_variable_t* v)
    441 {
    442     /*
    443      * Move this autovar from the auto list to variable list
    444      */
    445     if(v && (v->flags & CINT_VARIABLE_F_AUTO)) {
    446         
    447         /* Remove it from it's auto list */
    448         cint_variable_list_remove(v); 
    449 
    450         v->flags &= ~CINT_VARIABLE_F_AUTO; 
    451         cint_variable_add(v); 
    452     }   
    453     return 0; 
    454 }       
    455         
    456  
    457 
    458 
    459 int 
    460 cint_variable_delete(const char* name) 
    461 {
    462     cint_variable_t* v = cint_variable_find(name, 1); 
    463     if(v) {
    464         cint_variable_list_remove(v);
    465         cint_variable_free(v); 
    466     }
    467     return 0; 
    468 }
    469 
    470 
    471 int
    472 cint_variable_show(const char* var)
    473 {
    474     return CINT_E_NONE; 
    475 }       
    476 
    477 
    478 int
    479 cint_variable_dump(void)
    480 {
    481     int l, v; 
    482     cint_variable_t* var; 
    483 
    484     CINT_VARIABLES_LOCK;
    485 
    486     if(_scopes) {
    487         vscope_list_t* vscopes; 
    488         for(v = 0, vscopes = _scopes; vscopes; vscopes = vscopes->next, v++) {
    489             lscope_list_t* lscopes; 
    490             for(l = 0, lscopes = vscopes->lscopes; lscopes; lscopes = lscopes->next, l++) {
    491                 for(var = lscopes->vlist; var; var = var->next) {
    492                     if(!CINT_STRCMP(var->name, "NULL")) continue; 
    493                     CINT_PRINTF("V %d L %d: %s\n", v, l, var->name); 
    494                 }       
    495                 for(var = lscopes->autolist; var; var = var->next) {
    496                     CINT_PRINTF("A %d L %d: %s\n", v, l, var->name); 
    497                 }       
    498             }
    499         }
    500     }
    501     
    502     CINT_VARIABLES_UNLOCK;
    503 
    504     return CINT_E_NONE; 
    505 }       
    506 
    507 
    508 
    509 int
    510 cint_variable_clear(void)
    511 {
    512     vscope_list_t* vscopes; 
    513    
    514     __cint_variables_mutex_create();
    515 
    516     CINT_VARIABLES_LOCK;
    517 
    518     for (vscopes = _scopes; vscopes; vscopes = vscopes->next) {
    519         lscope_list_t* lscopes; 
    520         for (lscopes = vscopes->lscopes; lscopes; lscopes = lscopes->next) {
    521             __destroy_vlist(lscopes->vlist, 1); 
    522             __destroy_vlist(lscopes->autolist, 1);
    523             lscopes->vlist = NULL;
    524             lscopes->autolist = NULL;
    525         }
    526     }
    527     _scopes = NULL;
    528     
    529     CINT_VARIABLES_UNLOCK;
    530 
    531     return CINT_E_NONE; 
    532 }