Commit 1a49ced9 authored by Lev Walkin's avatar Lev Walkin

use hash for name lookup

parent a67d1106
...@@ -389,7 +389,6 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell, ...@@ -389,7 +389,6 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell,
char *mivr; /* Most Immediate Value Representation */ char *mivr; /* Most Immediate Value Representation */
int new_ref = 1; int new_ref = 1;
asn1p_t *asn; asn1p_t *asn;
asn1p_module_t *mod;
asn1p_expr_t *type_expr = (asn1p_expr_t *)NULL; asn1p_expr_t *type_expr = (asn1p_expr_t *)NULL;
int i, ret = 0, psize; int i, ret = 0, psize;
char *pp; char *pp;
...@@ -458,9 +457,13 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell, ...@@ -458,9 +457,13 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell,
free(mivr); free(mivr);
return -1; return -1;
} else { } else {
mod = TQ_FIRST(&(asn->modules)); asn1p_module_t *mod = TQ_FIRST(&(asn->modules));
assert(mod); assert(mod);
expr = TQ_REMOVE(&(mod->members), next);
/* 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); assert(expr);
expr->parent_expr = NULL; expr->parent_expr = NULL;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <asn1parser.h> /* Our lovely ASN.1 parser module */ #include <asn1parser.h> /* Our lovely ASN.1 parser module */
#include <asn1_namespace.h> #include <asn1_namespace.h>
#include <genhash.h>
#include "asn1fix.h" #include "asn1fix.h"
#ifdef _WIN32 #ifdef _WIN32
......
...@@ -28,35 +28,44 @@ asn1f_lookup_child(asn1p_expr_t *tc, const char *name) { ...@@ -28,35 +28,44 @@ asn1f_lookup_child(asn1p_expr_t *tc, const char *name) {
return NULL; 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 * asn1p_module_t *
asn1f_lookup_in_imports(arg_t *arg, asn1p_module_t *mod, const char *name) { asn1f_lookup_in_imports(arg_t *arg, asn1p_module_t *mod, const char *name) {
asn1p_xports_t *xp; 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. * Search in which exactly module this name is defined.
*/ */
TQ_FOR(xp, &(mod->imports), xp_next) { TQ_FOR(xp, &(mod->imports), xp_next) {
fromModule = asn1f_lookup_module(arg, xp->fromModuleName, NULL); asn1p_module_t *fromModule =
TQ_FOR(tc, &(xp->members), next) { asn1f_lookup_module(arg, xp->fromModuleName, NULL);
if(strcmp(name, tc->Identifier) == 0) asn1p_expr_t *tc = (asn1p_expr_t *)0;
TQ_FOR(tc, &(xp->xp_members), next) {
if(strcmp(name, tc->Identifier) == 0)
break; break;
if(!fromModule) if(!fromModule)
continue; continue;
TQ_FOR(memb, &(fromModule->members), next) { asn1p_expr_t *v = v =
if((memb->expr_type != ASN_BASIC_ENUMERATED) || asn1f_lookup_in_module(fromModule, tc->Identifier);
(strcmp(memb->Identifier, tc->Identifier) != 0)) if(v) break;
continue;
v = asn1f_lookup_child(memb, name);
if (v) break;
}
if(v) break;
} }
if(tc) break; if(tc) break;
} }
...@@ -291,8 +300,6 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t ...@@ -291,8 +300,6 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t
ns_item--) { ns_item--) {
struct asn1_namespace_element_s *ns_el = struct asn1_namespace_element_s *ns_el =
&my_namespace->elements[ns_item]; &my_namespace->elements[ns_item];
asn1p_expr_t *ref_tc; /* Referenced tc */
asn1p_expr_t *v = (asn1p_expr_t *)0;
switch(ns_el->selector) { switch(ns_el->selector) {
case NAM_SYMBOL: case NAM_SYMBOL:
...@@ -312,22 +319,12 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t ...@@ -312,22 +319,12 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t
DISPOSE_OF_MY_NAMESPACE(); DISPOSE_OF_MY_NAMESPACE();
return ns_el->u.symbol.resolution; 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. * Do a direct symbol search in the given module.
*/ */
TQ_FOR(ref_tc, &(ns_el->u.space.module->members), next) { ref_tc = asn1f_lookup_in_module(ns_el->u.space.module, identifier);
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;
}
}
}
if(ref_tc) { if(ref_tc) {
/* It is acceptable that we don't use input parameters */ /* It is acceptable that we don't use input parameters */
if(rhs_pspecs && !ref_tc->lhs_params) { 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 ...@@ -355,6 +352,7 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t
DISPOSE_OF_MY_NAMESPACE(); DISPOSE_OF_MY_NAMESPACE();
return ref_tc; return ref_tc;
} }
}
/* /*
if(!expr && !(arg->expr->_mark & TM_BROKEN) 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) { ...@@ -479,6 +477,11 @@ asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, enum ftt_what what) {
ref = expr->reference; ref = expr->reference;
break; break;
case FTT_VALUE: 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->meta_type == AMT_VALUE);
assert(expr->value); assert(expr->value);
/* Expression may be a terminal type itself */ /* 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) ...@@ -574,7 +577,7 @@ asn1f_compatible_with_exports(arg_t *arg, asn1p_module_t *mod, const char *name)
return 0; return 0;
} }
TQ_FOR(item, &(exports->members), next) { TQ_FOR(item, &(exports->xp_members), next) {
if(strcmp(item->Identifier, name) == 0) if(strcmp(item->Identifier, name) == 0)
return 0; return 0;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <errno.h> #include <errno.h>
#include <libgen.h> #include <libgen.h>
#include "genhash.h"
#include "asn1fix.h" #include "asn1fix.h"
#include "asn1_buffer.h" #include "asn1_buffer.h"
#include "asn1_namespace.h" #include "asn1_namespace.h"
...@@ -340,11 +341,7 @@ post_fix_check_element(asn1p_module_t *mod, asn1p_expr_t *check_expr) { ...@@ -340,11 +341,7 @@ post_fix_check_element(asn1p_module_t *mod, asn1p_expr_t *check_expr) {
/* /*
* Scan in search for the original. * Scan in search for the original.
*/ */
TQ_FOR(expr, &(mod->members), next) { expr = genhash_get(mod->members_hash, name);
if(strcmp(expr->Identifier, name) == 0)
break;
}
if(expr == NULL) { if(expr == NULL) {
fprintf(stderr, fprintf(stderr,
"CHECKER: Value \"%s\" requested by " "CHECKER: Value \"%s\" requested by "
......
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <genhash.h>
#include "asn1parser.h" #include "asn1parser.h"
...@@ -15,7 +16,10 @@ asn1p_module_new() { ...@@ -15,7 +16,10 @@ asn1p_module_new() {
TQ_INIT(&(mod->exports)); TQ_INIT(&(mod->exports));
TQ_INIT(&(mod->imports)); TQ_INIT(&(mod->imports));
TQ_INIT(&(mod->members)); TQ_INIT(&(mod->members));
}
mod->members_hash = genhash_new(cmpf_string, hashf_string, NULL, NULL);
assert(mod->members_hash);
}
return mod; return mod;
} }
...@@ -42,6 +46,9 @@ asn1p_module_free(asn1p_module_t *mod) { ...@@ -42,6 +46,9 @@ asn1p_module_free(asn1p_module_t *mod) {
while((expr = TQ_REMOVE(&(mod->members), next))) while((expr = TQ_REMOVE(&(mod->members), next)))
asn1p_expr_free(expr); asn1p_expr_free(expr);
genhash_destroy(mod->members_hash);
mod->members_hash = NULL;
free(mod); free(mod);
} }
} }
...@@ -66,3 +73,26 @@ asn1p_delete(asn1p_t *asn) { ...@@ -66,3 +73,26 @@ asn1p_delete(asn1p_t *asn) {
free(asn); free(asn);
} }
} }
void
asn1p_module_move_members(asn1p_module_t *to, asn1p_module_t *from) {
if(from) {
while(TQ_FIRST(&(from->members))) {
asn1p_expr_t *expr = TQ_REMOVE(&from->members, next);
TQ_ADD(&to->members, expr, next);
genhash_add(to->members_hash, expr->Identifier, expr);
}
assert(TQ_FIRST(&from->members) == 0);
genhash_empty(from->members_hash, 0, 0);
}
}
void
asn1p_module_member_add(asn1p_module_t *mod, asn1p_expr_t *expr) {
if(expr) {
TQ_ADD(&mod->members, expr, next);
genhash_add(mod->members_hash, expr->Identifier, expr);
}
}
...@@ -16,6 +16,8 @@ typedef struct asn1p_s { ...@@ -16,6 +16,8 @@ typedef struct asn1p_s {
asn1p_t *asn1p_new(void); asn1p_t *asn1p_new(void);
void asn1p_delete(asn1p_t *asn); void asn1p_delete(asn1p_t *asn);
struct genhash_s; /* Forward declaration */
/* /*
* Flags specific to a module. * Flags specific to a module.
*/ */
...@@ -75,7 +77,8 @@ typedef struct asn1p_module_s { ...@@ -75,7 +77,8 @@ typedef struct asn1p_module_s {
/* /*
* List of everything that this module defines itself. * List of everything that this module defines itself.
*/ */
TQ_HEAD(struct asn1p_expr_s) members; TQ_HEAD(struct asn1p_expr_s) members; /* Do not access directly */
struct genhash_s *members_hash;
/* /*
* Next module in the list. * Next module in the list.
...@@ -100,4 +103,8 @@ typedef struct asn1p_module_s { ...@@ -100,4 +103,8 @@ typedef struct asn1p_module_s {
asn1p_module_t *asn1p_module_new(void); asn1p_module_t *asn1p_module_new(void);
void asn1p_module_free(asn1p_module_t *mod); void asn1p_module_free(asn1p_module_t *mod);
void asn1p_module_move_members(asn1p_module_t *to, asn1p_module_t *from);
void asn1p_module_member_add(asn1p_module_t *mod, struct asn1p_expr_s *expr);
#endif /* ASN1_PARSER_MODULE_H */ #endif /* ASN1_PARSER_MODULE_H */
...@@ -13,7 +13,7 @@ asn1p_xports_new() { ...@@ -13,7 +13,7 @@ asn1p_xports_new() {
xp = calloc(1, sizeof *xp); xp = calloc(1, sizeof *xp);
if(xp) { if(xp) {
TQ_INIT(&(xp->members)); TQ_INIT(&(xp->xp_members));
} }
return xp; return xp;
...@@ -30,7 +30,7 @@ asn1p_xports_free(asn1p_xports_t *xp) { ...@@ -30,7 +30,7 @@ asn1p_xports_free(asn1p_xports_t *xp) {
free(xp->fromModuleName); free(xp->fromModuleName);
asn1p_oid_free(xp->identifier.oid); asn1p_oid_free(xp->identifier.oid);
while((expr = TQ_REMOVE(&(xp->members), next))) while((expr = TQ_REMOVE(&(xp->xp_members), next)))
asn1p_expr_free(expr); asn1p_expr_free(expr);
free(xp); free(xp);
......
...@@ -26,7 +26,7 @@ typedef struct asn1p_xports_s { ...@@ -26,7 +26,7 @@ typedef struct asn1p_xports_s {
/* /*
* Number of entities to import. * Number of entities to import.
*/ */
TQ_HEAD(struct asn1p_expr_s) members; TQ_HEAD(struct asn1p_expr_s) xp_members;
/* /*
* Pointer to the next xports structure in whatever list. * Pointer to the next xports structure in whatever list.
......
This diff is collapsed.
...@@ -262,7 +262,7 @@ ...@@ -262,7 +262,7 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE typedef union YYSTYPE
#line 116 "asn1p_y.y" #line 115 "asn1p_y.y"
{ {
asn1p_t *a_grammar; asn1p_t *a_grammar;
asn1p_module_flags_e a_module_flags; asn1p_module_flags_e a_module_flags;
......
...@@ -95,15 +95,14 @@ static asn1p_module_t *currentModule; ...@@ -95,15 +95,14 @@ static asn1p_module_t *currentModule;
#ifdef AL_IMPORT #ifdef AL_IMPORT
#error AL_IMPORT DEFINED ELSEWHERE! #error AL_IMPORT DEFINED ELSEWHERE!
#endif #endif
#define AL_IMPORT(to,where,from,field) do { \ #define AL_IMPORT(to, where, from, field) \
if(!(from)) break; \ do { \
while(TQ_FIRST(&((from)->where))) { \ if(!(from)) break; \
TQ_ADD(&((to)->where), \ while(TQ_FIRST(&((from)->where))) { \
TQ_REMOVE(&((from)->where), field), \ TQ_ADD(&((to)->where), TQ_REMOVE(&((from)->where), field), field); \
field); \ } \
} \ assert(TQ_FIRST(&((from)->where)) == 0); \
assert(TQ_FIRST(&((from)->where)) == 0); \ } while(0)
} while(0)
%} %}
...@@ -589,7 +588,7 @@ ModuleBody: ...@@ -589,7 +588,7 @@ ModuleBody:
$$ = asn1p_module_new(); $$ = asn1p_module_new();
AL_IMPORT($$, exports, $1, xp_next); AL_IMPORT($$, exports, $1, xp_next);
AL_IMPORT($$, imports, $2, xp_next); AL_IMPORT($$, imports, $2, xp_next);
AL_IMPORT($$, members, $3, next); asn1p_module_move_members($$, $3);
asn1p_module_free($1); asn1p_module_free($1);
asn1p_module_free($2); asn1p_module_free($2);
...@@ -608,7 +607,7 @@ AssignmentList: ...@@ -608,7 +607,7 @@ AssignmentList:
$$ = $2; $$ = $2;
break; break;
} }
AL_IMPORT($$, members, $2, next); asn1p_module_move_members($$, $2);
asn1p_module_free($2); asn1p_module_free($2);
} }
; ;
...@@ -623,14 +622,14 @@ Assignment: ...@@ -623,14 +622,14 @@ Assignment:
checkmem($$); checkmem($$);
assert($1->expr_type != A1TC_INVALID); assert($1->expr_type != A1TC_INVALID);
assert($1->meta_type != AMT_INVALID); assert($1->meta_type != AMT_INVALID);
TQ_ADD(&($$->members), $1, next); asn1p_module_member_add($$, $1);
} }
| ValueAssignment { | ValueAssignment {
$$ = asn1p_module_new(); $$ = asn1p_module_new();
checkmem($$); checkmem($$);
assert($1->expr_type != A1TC_INVALID); assert($1->expr_type != A1TC_INVALID);
assert($1->meta_type != AMT_INVALID); assert($1->meta_type != AMT_INVALID);
TQ_ADD(&($$->members), $1, next); asn1p_module_member_add($$, $1);
} }
/* /*
* Value set definition * Value set definition
...@@ -644,7 +643,7 @@ Assignment: ...@@ -644,7 +643,7 @@ Assignment:
checkmem($$); checkmem($$);
assert($1->expr_type != A1TC_INVALID); assert($1->expr_type != A1TC_INVALID);
assert($1->meta_type != AMT_INVALID); assert($1->meta_type != AMT_INVALID);
TQ_ADD(&($$->members), $1, next); asn1p_module_member_add($$, $1);
} }
| TOK_ENCODING_CONTROL TOK_capitalreference | TOK_ENCODING_CONTROL TOK_capitalreference
{ asn1p_lexer_hack_push_encoding_control(); } { asn1p_lexer_hack_push_encoding_control(); }
...@@ -728,11 +727,11 @@ ImportsList: ...@@ -728,11 +727,11 @@ ImportsList:
ImportsElement { ImportsElement {
$$ = asn1p_xports_new(); $$ = asn1p_xports_new();
checkmem($$); checkmem($$);
TQ_ADD(&($$->members), $1, next); TQ_ADD(&($$->xp_members), $1, next);
} }
| ImportsList ',' ImportsElement { | ImportsList ',' ImportsElement {
$$ = $1; $$ = $1;
TQ_ADD(&($$->members), $3, next); TQ_ADD(&($$->xp_members), $3, next);
} }
; ;
...@@ -789,11 +788,11 @@ ExportsBody: ...@@ -789,11 +788,11 @@ ExportsBody:
ExportsElement { ExportsElement {
$$ = asn1p_xports_new(); $$ = asn1p_xports_new();
assert($$); assert($$);
TQ_ADD(&($$->members), $1, next); TQ_ADD(&($$->xp_members), $1, next);
} }
| ExportsBody ',' ExportsElement { | ExportsBody ',' ExportsElement {
$$ = $1; $$ = $1;
TQ_ADD(&($$->members), $3, next); TQ_ADD(&($$->xp_members), $3, next);
} }
; ;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment