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,
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,8 +457,12 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell,
free(mivr);
return -1;
} else {
mod = TQ_FIRST(&(asn->modules));
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);
......
......@@ -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
......
......@@ -28,34 +28,43 @@ 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) {
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;
}
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;
}
......
......@@ -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 "
......
#include <stdlib.h>
#include <string.h>
#include <genhash.h>
#include "asn1parser.h"
......@@ -15,6 +16,9 @@ asn1p_module_new() {
TQ_INIT(&(mod->exports));
TQ_INIT(&(mod->imports));
TQ_INIT(&(mod->members));
mod->members_hash = genhash_new(cmpf_string, hashf_string, NULL, NULL);
assert(mod->members_hash);
}
return mod;
}
......@@ -42,6 +46,9 @@ asn1p_module_free(asn1p_module_t *mod) {
while((expr = TQ_REMOVE(&(mod->members), next)))
asn1p_expr_free(expr);
genhash_destroy(mod->members_hash);
mod->members_hash = NULL;
free(mod);
}
}
......@@ -66,3 +73,26 @@ asn1p_delete(asn1p_t *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 {
asn1p_t *asn1p_new(void);
void asn1p_delete(asn1p_t *asn);
struct genhash_s; /* Forward declaration */
/*
* Flags specific to a module.
*/
......@@ -75,7 +77,8 @@ typedef struct asn1p_module_s {
/*
* 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.
......@@ -100,4 +103,8 @@ typedef struct asn1p_module_s {
asn1p_module_t *asn1p_module_new(void);
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 */
......@@ -13,7 +13,7 @@ asn1p_xports_new() {
xp = calloc(1, sizeof *xp);
if(xp) {
TQ_INIT(&(xp->members));
TQ_INIT(&(xp->xp_members));
}
return xp;
......@@ -30,7 +30,7 @@ asn1p_xports_free(asn1p_xports_t *xp) {
free(xp->fromModuleName);
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);
free(xp);
......
......@@ -26,7 +26,7 @@ typedef struct asn1p_xports_s {
/*
* 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.
......
This diff is collapsed.
......@@ -262,7 +262,7 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 116 "asn1p_y.y"
#line 115 "asn1p_y.y"
{
asn1p_t *a_grammar;
asn1p_module_flags_e a_module_flags;
......
......@@ -95,12 +95,11 @@ static asn1p_module_t *currentModule;
#ifdef AL_IMPORT
#error AL_IMPORT DEFINED ELSEWHERE!
#endif
#define AL_IMPORT(to,where,from,field) do { \
#define AL_IMPORT(to, where, from, field) \
do { \
if(!(from)) break; \
while(TQ_FIRST(&((from)->where))) { \
TQ_ADD(&((to)->where), \
TQ_REMOVE(&((from)->where), field), \
field); \
TQ_ADD(&((to)->where), TQ_REMOVE(&((from)->where), field), field); \
} \
assert(TQ_FIRST(&((from)->where)) == 0); \
} while(0)
......@@ -589,7 +588,7 @@ ModuleBody:
$$ = asn1p_module_new();
AL_IMPORT($$, exports, $1, 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($2);
......@@ -608,7 +607,7 @@ AssignmentList:
$$ = $2;
break;
}
AL_IMPORT($$, members, $2, next);
asn1p_module_move_members($$, $2);
asn1p_module_free($2);
}
;
......@@ -623,14 +622,14 @@ Assignment:
checkmem($$);
assert($1->expr_type != A1TC_INVALID);
assert($1->meta_type != AMT_INVALID);
TQ_ADD(&($$->members), $1, next);
asn1p_module_member_add($$, $1);
}
| ValueAssignment {
$$ = asn1p_module_new();
checkmem($$);
assert($1->expr_type != A1TC_INVALID);
assert($1->meta_type != AMT_INVALID);
TQ_ADD(&($$->members), $1, next);
asn1p_module_member_add($$, $1);
}
/*
* Value set definition
......@@ -644,7 +643,7 @@ Assignment:
checkmem($$);
assert($1->expr_type != A1TC_INVALID);
assert($1->meta_type != AMT_INVALID);
TQ_ADD(&($$->members), $1, next);
asn1p_module_member_add($$, $1);
}
| TOK_ENCODING_CONTROL TOK_capitalreference
{ asn1p_lexer_hack_push_encoding_control(); }
......@@ -728,11 +727,11 @@ ImportsList:
ImportsElement {
$$ = asn1p_xports_new();
checkmem($$);
TQ_ADD(&($$->members), $1, next);
TQ_ADD(&($$->xp_members), $1, next);
}
| ImportsList ',' ImportsElement {
$$ = $1;
TQ_ADD(&($$->members), $3, next);
TQ_ADD(&($$->xp_members), $3, next);
}
;
......@@ -789,11 +788,11 @@ ExportsBody:
ExportsElement {
$$ = asn1p_xports_new();
assert($$);
TQ_ADD(&($$->members), $1, next);
TQ_ADD(&($$->xp_members), $1, next);
}
| ExportsBody ',' ExportsElement {
$$ = $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