X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Frmr%2Fcommon%2Fsrc%2Fsymtab.c;h=18cf60adf1aab9067d8c564b8a6c81d225413851;hb=9c923bcc9322c22220b574671c7b46f10008c614;hp=e96af03ade4f30bb1408be31852a7f9a2fe77828;hpb=68c1ab2191d9959fde0bd275a560f7c9cf6df485;p=ric-plt%2Flib%2Frmr.git diff --git a/src/rmr/common/src/symtab.c b/src/rmr/common/src/symtab.c index e96af03..18cf60a 100644 --- a/src/rmr/common/src/symtab.c +++ b/src/rmr/common/src/symtab.c @@ -1,8 +1,8 @@ // : vi ts=4 sw=4 noet : /* ================================================================================== - Copyright (c) 2019 Nokia - Copyright (c) 2018-2019 AT&T Intellectual Property. + Copyright (c) 2019-2020 Nokia + Copyright (c) 2018-2020 AT&T Intellectual Property. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -33,6 +33,10 @@ Abstract: Symbol table -- slightly streamlined from it's original 2000 version incorporated into the RIC msg routing library and will be available to user applications. + There is NO logging from this module! The caller is asusmed to + report any failures as it might handle them making any error messages + generated here misleading if not incorrect. + Date: 11 Feb 2000 Author: E. Scott Daniels @@ -42,6 +46,7 @@ Mod: 2016 23 Feb - converted Symtab refs so that caller need only a ------------------------------------------------------------------------------ */ +#include #include #include #include @@ -91,7 +96,10 @@ static int sym_hash( const char *n, long size ) return (int ) (t % size); } -/* delete element pointed to by eptr at hash loc hv */ +/* + Delete element pointed to by eptr which is assumed to be + a member of the list at symtab[i]. +*/ static void del_ele( Sym_tab *table, int hv, Sym_ele *eptr ) { Sym_ele **sym_tab; @@ -119,6 +127,39 @@ static void del_ele( Sym_tab *table, int hv, Sym_ele *eptr ) } } +/* + Delete the head element from table[i]. This isn't really + needed, but keeps code analysers from claiming that memory + is being used after it is freed. +*/ +static void del_head_ele( Sym_tab *table, int hv ) { + Sym_ele **sym_tab; + Sym_ele *eptr; // first in list + + + if( hv < 0 || hv >= table->size ) { + return; + } + + sym_tab = table->symlist; + if( (eptr = sym_tab[hv]) != NULL ) // not an empty element; yank it off + { + if( (sym_tab[hv] = eptr->next) != NULL ) { // bump list to next if not the only thing here + sym_tab[hv]->prev = NULL; // new head + } + eptr->next = NULL; // take no chances + + if( eptr->class && eptr->name ) { // class 0 entries are numeric, so name is NOT a pointer + free( (void *) eptr->name ); + } + + free( eptr ); + + table->deaths++; + table->inhabitants--; + } +} + /* Determine if these are the same. */ @@ -161,7 +202,7 @@ static int putin( Sym_tab *table, const char *name, unsigned int class, void *va eptr = (Sym_ele *) malloc( sizeof( Sym_ele) ); if( ! eptr ) { - fprintf( stderr, "[FAIL] symtab/putin: out of memory\n" ); + errno = ENOMEM; return -1; } @@ -200,9 +241,11 @@ extern void rmr_sym_clear( void *vtable ) table = (Sym_tab *) vtable; sym_tab = table->symlist; - for( i = 0; i < table->size; i++ ) - while( sym_tab[i] ) - del_ele( table, i, sym_tab[i] ); + for( i = 0; i < table->size; i++ ) { + while( sym_tab[i] ) { + del_head_ele( table, i ); // delete the head element (and keep bloody sonar from claiming use after free) + } + } } /* @@ -237,9 +280,9 @@ extern void rmr_sym_dump( void *vtable ) for( eptr = sym_tab[i]; eptr; eptr = eptr->next ) { if( eptr->val && eptr->class ) { - fprintf( stderr, "key=%s val@=%p\n", eptr->name, eptr->val ); + fprintf( stderr, "symtab dump: key=%s val@=%p\n", eptr->name, eptr->val ); } else { - fprintf( stderr, "nkey=%lu val@=%p\n", (unsigned long) eptr->nkey, eptr->val ); + fprintf( stderr, "symtab dump: nkey=%lu val@=%p\n", (unsigned long) eptr->nkey, eptr->val ); } } } @@ -259,7 +302,7 @@ extern void *rmr_sym_alloc( int size ) if( (table = (Sym_tab *) malloc( sizeof( Sym_tab ))) == NULL ) { - fprintf( stderr, "rmr_sym_alloc: unable to get memory for symtable (%d elements)", size ); + errno = ENOMEM; return NULL; } @@ -272,7 +315,7 @@ extern void *rmr_sym_alloc( int size ) } else { - fprintf( stderr, "sym_alloc: unable to get memory for %d elements", size ); + errno = ENOMEM; return NULL; } @@ -308,7 +351,7 @@ extern void rmr_sym_del( void *vtable, const char *name, unsigned int class ) /* Delete element by numberic key. */ -extern void *rmr_sym_ndel( void *vtable, uint64_t key ) { +extern void rmr_sym_ndel( void *vtable, uint64_t key ) { rmr_sym_del( vtable, (const char *) &key, 0 ); } @@ -321,7 +364,10 @@ extern void *rmr_sym_get( void *vtable, const char *name, unsigned int class ) int hv; // hash value of key uint64_t nkey; // numeric key if class 0 - table = (Sym_tab *) vtable; + if( (table = (Sym_tab *) vtable) == NULL ) { + return NULL; + } + sym_tab = table->symlist; if( class ) { @@ -407,9 +453,9 @@ extern void rmr_sym_stats( void *vtable, int level ) ch_count++; if( level > 3 ) { if( eptr->class ) { // a string key - fprintf( stderr, "sym: (%d) key=%s val@=%p ref=%ld mod=%lu\n", i, eptr->name, eptr->val, eptr->rcount, eptr->mcount ); + fprintf( stderr, " symtab stats: sym: (%d) key=%s val@=%p ref=%ld mod=%lu\n", i, eptr->name, eptr->val, eptr->rcount, eptr->mcount ); } else { - fprintf( stderr, "sym: (%d) key=%lu val@=%p ref=%ld mod=%lu\n", i, (unsigned long) eptr->nkey, eptr->val, eptr->rcount, eptr->mcount ); + fprintf( stderr, "symtab stats: sym: (%d) key=%lu val@=%p ref=%ld mod=%lu\n", i, (unsigned long) eptr->nkey, eptr->val, eptr->rcount, eptr->mcount ); } } } @@ -426,12 +472,12 @@ extern void rmr_sym_stats( void *vtable, int level ) twoper++; if( level > 2 ) - fprintf( stderr, "sym: (%d) chained=%ld\n", i, ch_count ); + fprintf( stderr, "symtab stats: sym: (%d) chained=%ld\n", i, ch_count ); } if( level > 1 ) { - fprintf( stderr, "sym: longest chain: idx=%d has %ld elsements):\n", maxi, max_chain ); + fprintf( stderr, "symtab stats: sym: longest chain: idx=%d has %ld elsements):\n", maxi, max_chain ); for( eptr = sym_tab[maxi]; eptr; eptr = eptr->next ) { if( eptr->class ) { fprintf( stderr, "\t%s\n", eptr->name ); @@ -441,7 +487,7 @@ extern void rmr_sym_stats( void *vtable, int level ) } } - fprintf( stderr, "sym:%ld(size) %ld(inhab) %ld(occupied) %ld(dead) %ld(maxch) %d(>2per)\n", + fprintf( stderr, "symtab stats: sym:%ld(size) %ld(inhab) %ld(occupied) %ld(dead) %ld(maxch) %d(>2per)\n", table->size, table->inhabitants, table->size - empty, table->deaths, max_chain, twoper ); } @@ -460,13 +506,16 @@ extern void rmr_sym_foreach_class( void *vst, unsigned int class, void (* user_f st = (Sym_tab *) vst; - if( st && (list = st->symlist) != NULL && user_fun != NULL ) - for( i = 0; i < st->size; i++ ) - for( se = list[i]; se; se = next ) /* using next allows user to delet via this */ - { - next = se->next; + if( st && (list = st->symlist) != NULL && user_fun != NULL ) { + for( i = 0; i < st->size; i++ ) { + se = list[i]; + while( se ) { + next = se->next; // allow callback to delete from the list w/o borking us if( class == se->class ) { user_fun( st, se, se->name, se->val, user_data ); } + se = next; } + } + } }