diff options
author | Lev Walkin <vlm@lionet.info> | 2017-11-06 00:07:00 -0800 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2017-11-06 00:07:53 -0800 |
commit | 1a49ced90eb525b1516c02484e166c54b379cd65 (patch) | |
tree | af6ec648c40a233994d09de99f6c828a862a1265 /libasn1fix | |
parent | a67d11061eef998454464466eae72d6199f1f80c (diff) |
use hash for name lookup
Diffstat (limited to 'libasn1fix')
-rw-r--r-- | libasn1fix/asn1fix_cws.c | 11 | ||||
-rw-r--r-- | libasn1fix/asn1fix_internal.h | 1 | ||||
-rw-r--r-- | libasn1fix/asn1fix_retrieve.c | 67 | ||||
-rw-r--r-- | libasn1fix/check_fixer.c | 7 |
4 files changed, 45 insertions, 41 deletions
diff --git a/libasn1fix/asn1fix_cws.c b/libasn1fix/asn1fix_cws.c index 948c6277..e54eaa70 100644 --- a/libasn1fix/asn1fix_cws.c +++ b/libasn1fix/asn1fix_cws.c @@ -389,7 +389,6 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell, char *mivr; /* Most Immediate Value Representation */ int new_ref = 1; asn1p_t *asn; - asn1p_module_t *mod; asn1p_expr_t *type_expr = (asn1p_expr_t *)NULL; int i, ret = 0, psize; char *pp; @@ -458,9 +457,13 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell, free(mivr); return -1; } else { - mod = TQ_FIRST(&(asn->modules)); - assert(mod); - expr = TQ_REMOVE(&(mod->members), next); + asn1p_module_t *mod = TQ_FIRST(&(asn->modules)); + assert(mod); + + /* This member removal is safe with respect to members hash since the + * entire asn module will be deleted down below. + */ + expr = TQ_REMOVE(&(mod->members), next); assert(expr); expr->parent_expr = NULL; diff --git a/libasn1fix/asn1fix_internal.h b/libasn1fix/asn1fix_internal.h index 5fd7e768..c429730f 100644 --- a/libasn1fix/asn1fix_internal.h +++ b/libasn1fix/asn1fix_internal.h @@ -22,6 +22,7 @@ #include <asn1parser.h> /* Our lovely ASN.1 parser module */ #include <asn1_namespace.h> +#include <genhash.h> #include "asn1fix.h" #ifdef _WIN32 diff --git a/libasn1fix/asn1fix_retrieve.c b/libasn1fix/asn1fix_retrieve.c index 536f5020..40acbe5a 100644 --- a/libasn1fix/asn1fix_retrieve.c +++ b/libasn1fix/asn1fix_retrieve.c @@ -28,35 +28,44 @@ asn1f_lookup_child(asn1p_expr_t *tc, const char *name) { return NULL; } +static asn1p_expr_t * +asn1f_lookup_in_module(asn1p_module_t *mod, const char *name) { + asn1p_expr_t *expr = genhash_get(mod->members_hash, name); + if(!expr) { + asn1p_expr_t *memb; + TQ_FOR(memb, &mod->members, next) { + if(memb->expr_type == ASN_BASIC_ENUMERATED) { + asn1p_expr_t *v = asn1f_lookup_child(memb, name); + if(v) return v; + } + } + } + + return expr; +} + asn1p_module_t * asn1f_lookup_in_imports(arg_t *arg, asn1p_module_t *mod, const char *name) { asn1p_xports_t *xp; - asn1p_module_t *fromModule; - asn1p_expr_t *tc = (asn1p_expr_t *)0; - asn1p_expr_t *memb = (asn1p_expr_t *)0; - asn1p_expr_t *v = (asn1p_expr_t *)0; /* * Search in which exactly module this name is defined. */ TQ_FOR(xp, &(mod->imports), xp_next) { - fromModule = asn1f_lookup_module(arg, xp->fromModuleName, NULL); - TQ_FOR(tc, &(xp->members), next) { - if(strcmp(name, tc->Identifier) == 0) + asn1p_module_t *fromModule = + asn1f_lookup_module(arg, xp->fromModuleName, NULL); + asn1p_expr_t *tc = (asn1p_expr_t *)0; + + TQ_FOR(tc, &(xp->xp_members), next) { + if(strcmp(name, tc->Identifier) == 0) break; if(!fromModule) continue; - TQ_FOR(memb, &(fromModule->members), next) { - if((memb->expr_type != ASN_BASIC_ENUMERATED) || - (strcmp(memb->Identifier, tc->Identifier) != 0)) - continue; - - v = asn1f_lookup_child(memb, name); - if (v) break; - } - if(v) break; + asn1p_expr_t *v = v = + asn1f_lookup_in_module(fromModule, tc->Identifier); + if(v) break; } if(tc) break; } @@ -291,8 +300,6 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t ns_item--) { struct asn1_namespace_element_s *ns_el = &my_namespace->elements[ns_item]; - asn1p_expr_t *ref_tc; /* Referenced tc */ - asn1p_expr_t *v = (asn1p_expr_t *)0; switch(ns_el->selector) { case NAM_SYMBOL: @@ -312,22 +319,12 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t DISPOSE_OF_MY_NAMESPACE(); return ns_el->u.symbol.resolution; } - case NAM_SPACE: + case NAM_SPACE: { + asn1p_expr_t *ref_tc; /* Referenced tc */ /* * Do a direct symbol search in the given module. */ - TQ_FOR(ref_tc, &(ns_el->u.space.module->members), next) { - if(ref_tc->Identifier) - if(strcmp(ref_tc->Identifier, identifier) == 0) break; - - if(ref_tc->expr_type == ASN_BASIC_ENUMERATED) { - v = asn1f_lookup_child(ref_tc, identifier); - if(v) { - ref_tc = v; - break; - } - } - } + ref_tc = asn1f_lookup_in_module(ns_el->u.space.module, identifier); if(ref_tc) { /* It is acceptable that we don't use input parameters */ if(rhs_pspecs && !ref_tc->lhs_params) { @@ -355,6 +352,7 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t DISPOSE_OF_MY_NAMESPACE(); return ref_tc; } + } /* if(!expr && !(arg->expr->_mark & TM_BROKEN) @@ -479,6 +477,11 @@ asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, enum ftt_what what) { ref = expr->reference; break; case FTT_VALUE: + + DEBUG("%s(%s->%s) meta %d for line %d", + "VALUE", expr->Identifier, asn1f_printable_reference(ref), + expr->meta_type, expr->_lineno); + assert(expr->meta_type == AMT_VALUE); assert(expr->value); /* Expression may be a terminal type itself */ @@ -574,7 +577,7 @@ asn1f_compatible_with_exports(arg_t *arg, asn1p_module_t *mod, const char *name) return 0; } - TQ_FOR(item, &(exports->members), next) { + TQ_FOR(item, &(exports->xp_members), next) { if(strcmp(item->Identifier, name) == 0) return 0; } diff --git a/libasn1fix/check_fixer.c b/libasn1fix/check_fixer.c index 6f5f25e6..b71a8c9e 100644 --- a/libasn1fix/check_fixer.c +++ b/libasn1fix/check_fixer.c @@ -12,6 +12,7 @@ #include <errno.h> #include <libgen.h> +#include "genhash.h" #include "asn1fix.h" #include "asn1_buffer.h" #include "asn1_namespace.h" @@ -340,11 +341,7 @@ post_fix_check_element(asn1p_module_t *mod, asn1p_expr_t *check_expr) { /* * Scan in search for the original. */ - TQ_FOR(expr, &(mod->members), next) { - if(strcmp(expr->Identifier, name) == 0) - break; - } - + expr = genhash_get(mod->members_hash, name); if(expr == NULL) { fprintf(stderr, "CHECKER: Value \"%s\" requested by " |