aboutsummaryrefslogtreecommitdiffstats
path: root/libasn1fix
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2017-11-06 00:07:00 -0800
committerLev Walkin <vlm@lionet.info>2017-11-06 00:07:53 -0800
commit1a49ced90eb525b1516c02484e166c54b379cd65 (patch)
treeaf6ec648c40a233994d09de99f6c828a862a1265 /libasn1fix
parenta67d11061eef998454464466eae72d6199f1f80c (diff)
use hash for name lookup
Diffstat (limited to 'libasn1fix')
-rw-r--r--libasn1fix/asn1fix_cws.c11
-rw-r--r--libasn1fix/asn1fix_internal.h1
-rw-r--r--libasn1fix/asn1fix_retrieve.c67
-rw-r--r--libasn1fix/check_fixer.c7
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 "