Commit c0e03b94 authored by Lev Walkin's avatar Lev Walkin

introduce namespaces

parent 97721778
......@@ -38,6 +38,7 @@
#include <asn1fix.h> /* Fix the ASN.1 tree */
#include <asn1print.h> /* Print the ASN.1 tree */
#include <asn1compiler.h> /* Compile the ASN.1 tree */
#include <asn1fix_export.h>
#include <asn1c_compat.h> /* Portable basename(3) and dirname(3) */
......@@ -312,6 +313,8 @@ main(int ac, char **av) {
exit_code = EX_DATAERR;
goto cleanup;
}
} else {
asn1f_use_standard_namespaces(asn);
}
/*
......
......@@ -1260,9 +1260,11 @@ asn1c_lang_C_type_REFERENCE(arg_t *arg) {
arg_t tmp;
int ret;
extract = asn1f_class_access_ex(arg->asn, arg->expr->module,
arg->expr, arg->expr->rhs_pspecs, ref);
if(extract == NULL)
extract = WITH_MODULE_NAMESPACE(
arg->expr->module, expr_ns,
asn1f_class_access_ex(arg->asn, arg->expr->module, expr_ns,
arg->expr, arg->expr->rhs_pspecs, ref));
if(extract == NULL)
return -1;
extract = asn1p_expr_clone(extract, 0);
......@@ -1455,7 +1457,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
MKID(expr), expr->_type_unique_index);
INDENT(+1);
{
asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, asn->ns, expr);
char *type_name = asn1c_type_name(arg, expr, TNF_SAFE);
OUT("td->free_struct = asn_DEF_%s.free_struct;\n", type_name);
OUT("td->print_struct = asn_DEF_%s.print_struct;\n", type_name);
......@@ -1676,9 +1678,11 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
"asn_SPC_%s_specs_%d;\n", p, expr->_type_unique_index);
}
} else {
asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
asn1p_expr_t *terminal = WITH_MODULE_NAMESPACE(
expr->module, expr_ns,
asn1f_find_terminal_type_ex(arg->asn, expr_ns, expr));
OUT("extern asn_%s_specifics_t ", asn1c_type_name(arg, terminal, TNF_SAFE));
OUT("extern asn_%s_specifics_t ", asn1c_type_name(arg, terminal, TNF_SAFE));
OUT("asn_SPC_%s_specs_%d;\n", MKID(expr), expr->_type_unique_index);
}
}
......@@ -1868,9 +1872,11 @@ _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e f
assert(el_no >= 0);
ret = asn1f_fetch_outmost_tag(arg->asn, arg->expr->module,
arg->expr, &tag, AFT_IMAGINARY_ANY);
if(ret == 0) {
ret = WITH_MODULE_NAMESPACE(
arg->expr->module, expr_ns,
asn1f_fetch_outmost_tag(arg->asn, expr_ns, arg->expr->module, arg->expr,
&tag, AFT_IMAGINARY_ANY));
if(ret == 0) {
tag2el_t *te;
int new_count = (*count) + 1;
void *p;
......@@ -1914,9 +1920,11 @@ _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e f
if(arg->expr->expr_type == A1TC_REFERENCE) {
arg_t tmp = *arg;
asn1p_expr_t *expr;
expr = asn1f_lookup_symbol_ex(tmp.asn, tmp.expr,
arg->expr->reference);
if(expr) {
expr = WITH_MODULE_NAMESPACE(
tmp.expr->module, expr_ns,
asn1f_lookup_symbol_ex(tmp.asn, expr_ns, tmp.expr,
arg->expr->reference));
if(expr) {
tmp.expr = expr;
return _add_tag2el_member(&tmp, tag2el, count, el_no, flags);
} else {
......@@ -1977,16 +1985,20 @@ emit_tags_vectors(arg_t *arg, asn1p_expr_t *expr, int *tags_count_r, int *all_ta
*all_tags_count_r = 0;
/* Fetch a chain of tags */
tags_count = asn1f_fetch_tags(arg->asn, expr->module, expr, &tags, 0);
if(tags_count < 0) {
tags_count = WITH_MODULE_NAMESPACE(
expr->module, expr_ns,
asn1f_fetch_tags(arg->asn, expr_ns, expr->module, expr, &tags, 0));
if(tags_count < 0) {
DEBUG("fail to fetch tags for %s", expr->Identifier);
return -1;
}
/* Fetch a chain of tags */
all_tags_count = asn1f_fetch_tags(arg->asn, expr->module, expr,
&all_tags, AFT_FULL_COLLECT);
if(all_tags_count < 0) {
all_tags_count = WITH_MODULE_NAMESPACE(
expr->module, expr_ns,
asn1f_fetch_tags(arg->asn, expr_ns, expr->module, expr, &all_tags,
AFT_FULL_COLLECT));
if(all_tags_count < 0) {
free(tags);
DEBUG("fail to fetch tags chain for %s", expr->Identifier);
return -1;
......@@ -2051,8 +2063,10 @@ expr_elements_count(arg_t *arg, asn1p_expr_t *expr) {
asn1p_expr_t *v;
int elements = 0;
topmost_parent = asn1f_find_terminal_type_ex(arg->asn, expr);
if(!topmost_parent) return 0;
topmost_parent = WITH_MODULE_NAMESPACE(
expr->module, expr_ns,
asn1f_find_terminal_type_ex(arg->asn, expr_ns, expr));
if(!topmost_parent) return 0;
if(!(topmost_parent->expr_type & ASN_CONSTR_MASK)
&& !(topmost_parent->expr_type == ASN_BASIC_INTEGER)
......@@ -2071,7 +2085,7 @@ expr_elements_count(arg_t *arg, asn1p_expr_t *expr) {
static asn1p_expr_type_e
expr_get_type(arg_t *arg, asn1p_expr_t *expr) {
asn1p_expr_t *terminal;
terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
terminal = asn1f_find_terminal_type_ex(arg->asn, arg->ns, expr);
if(terminal) return terminal->expr_type;
return A1TC_INVALID;
}
......@@ -2410,7 +2424,7 @@ emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
int extensible = 0;
int eidx = -1;
expr = asn1f_find_terminal_type_ex(arg->asn, expr);
expr = asn1f_find_terminal_type_ex(arg->asn, arg->ns, expr);
assert(expr);
TQ_FOR(v, &(expr->members), next) {
......@@ -2899,10 +2913,11 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *
int complex_contents;
char *p;
if(asn1f_fetch_outmost_tag(arg->asn,
expr->module, expr, &outmost_tag_s,
AFT_IMAGINARY_ANY)) {
outmost_tag = 0;
if(WITH_MODULE_NAMESPACE(
expr->module, expr_ns,
asn1f_fetch_outmost_tag(arg->asn, expr_ns, expr->module, expr,
&outmost_tag_s, AFT_IMAGINARY_ANY))) {
outmost_tag = 0;
} else {
outmost_tag = &outmost_tag_s;
}
......@@ -3096,7 +3111,7 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_
char *p = MKID(expr);
char *p2 = (char *)0;
terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
terminal = asn1f_find_terminal_type_ex(arg->asn, arg->ns, expr);
if(emit_member_OER_constraints(arg, expr, "type"))
return -1;
......@@ -3476,8 +3491,9 @@ expr_break_recursion(arg_t *arg, asn1p_expr_t *expr) {
*/
static asn1p_expr_t *
terminal_structable(arg_t *arg, asn1p_expr_t *expr) {
asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
if(terminal
asn1p_expr_t *terminal =
asn1f_find_terminal_type_ex(arg->asn, arg->ns, expr);
if(terminal
&& !terminal->parent_expr
&& (terminal->expr_type & ASN_CONSTR_MASK)) {
return terminal;
......@@ -3612,13 +3628,17 @@ static int compar_cameo(const void *ap, const void *bp) {
struct asn1p_type_tag_s atag, btag;
arg_t *arg = cameo_arg;
if(asn1f_fetch_outmost_tag(arg->asn, a->expr->module, a->expr,
&atag, AFT_IMAGINARY_ANY | AFT_CANON_CHOICE))
return 1;
if(WITH_MODULE_NAMESPACE(a->expr->module, expr_ns,
asn1f_fetch_outmost_tag(
arg->asn, expr_ns, a->expr->module, a->expr,
&atag, AFT_IMAGINARY_ANY | AFT_CANON_CHOICE)))
return 1;
if(asn1f_fetch_outmost_tag(arg->asn, b->expr->module, b->expr,
&btag, AFT_IMAGINARY_ANY | AFT_CANON_CHOICE))
return -1;
if(WITH_MODULE_NAMESPACE(b->expr->module, expr_ns,
asn1f_fetch_outmost_tag(
arg->asn, expr_ns, b->expr->module, b->expr,
&btag, AFT_IMAGINARY_ANY | AFT_CANON_CHOICE)))
return -1;
if(atag.tag_class < btag.tag_class)
return -1;
......
......@@ -429,7 +429,7 @@ emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range) {
asn1p_expr_t *terminal;
char *tname;
terminal = asn1f_find_terminal_type_ex(arg->asn, arg->expr);
terminal = asn1f_find_terminal_type_ex(arg->asn, arg->ns, arg->expr);
if(terminal) {
OUT("/* The underlying type is %s */\n",
ASN_EXPR_TYPE2STR(terminal->expr_type));
......@@ -704,7 +704,7 @@ emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_rang
static asn1p_expr_type_e
_find_terminal_type(arg_t *arg) {
asn1p_expr_t *expr;
expr = asn1f_find_terminal_type_ex(arg->asn, arg->expr);
expr = asn1f_find_terminal_type_ex(arg->asn, arg->ns, arg->expr);
if(expr) return expr->expr_type;
return A1TC_INVALID;
}
......
......@@ -40,6 +40,7 @@
#endif
#include "asn1compiler.h"
#include "asn1_namespace.h"
struct asn1c_ioc_table_and_objset_s;
......@@ -53,17 +54,18 @@ typedef struct arg_s {
struct compiler_streams *target;
asn1p_t *asn;
asn1p_expr_t *expr;
asn1p_t *asn;
asn1_namespace_t *ns;
asn1p_expr_t *expr;
int embed;
int embed;
} arg_t;
/*
* Logging.
*/
#define LOG(ll, fmt, args...) do { \
arg->logger_cb(ll, fmt, ##args); \
arg->logger_cb(ll, fmt " @ line %d", ##args, __LINE__); \
} while(0)
#define DEBUG(fmt, args...) do { \
if(arg->flags & A1C_DEBUG) \
......
......@@ -80,7 +80,9 @@ asn1c_get_ioc_table(arg_t *arg) {
return safe_ioc_tao;
}
objset = asn1f_lookup_symbol_ex(arg->asn, arg->expr, objset_ref);
objset = WITH_MODULE_NAMESPACE(
arg->expr->module, expr_ns,
asn1f_lookup_symbol_ex(arg->asn, expr_ns, arg->expr, objset_ref));
if(!objset) {
FATAL("Cannot found %s", asn1p_ref_string(objset_ref));
return failed_ioc_tao;
......@@ -97,7 +99,7 @@ emit_ioc_value(arg_t *arg, struct asn1p_ioc_cell_s *cell) {
int primitive_representation = 0;
asn1p_expr_t *cv_type =
asn1f_find_terminal_type_ex(arg->asn, cell->value);
asn1f_find_terminal_type_ex(arg->asn, arg->ns, cell->value);
switch(cv_type->expr_type) {
case ASN_BASIC_INTEGER:
......@@ -137,8 +139,10 @@ emit_ioc_value(arg_t *arg, struct asn1p_ioc_cell_s *cell) {
asn1p_expr_t *expr_value = cell->value;
while(expr_value->value->type == ATV_REFERENCED) {
expr_value = asn1f_lookup_symbol_ex(
arg->asn, expr_value, expr_value->value->value.reference);
expr_value = WITH_MODULE_NAMESPACE(
expr_value->module, expr_ns,
asn1f_lookup_symbol_ex(arg->asn, expr_ns, expr_value,
expr_value->value->value.reference));
if(!expr_value) {
FATAL("Unrecognized value type for %s", MKID(cell->value));
return -1;
......
......@@ -195,16 +195,21 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
* This is a reference to a type defined in a class.
* Resolve it and use instead.
*/
tmp.expr = asn1f_class_access_ex(arg->asn,
arg->expr->module, arg->expr, expr->rhs_pspecs, expr->reference);
if(!tmp.expr) return NULL;
tmp.expr = WITH_MODULE_NAMESPACE(
arg->expr->module, expr_ns,
asn1f_class_access_ex(arg->asn, arg->expr->module, expr_ns,
arg->expr, expr->rhs_pspecs,
expr->reference));
if(!tmp.expr) return NULL;
return asn1c_type_name(&tmp, tmp.expr, _format);
}
terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
terminal = WITH_MODULE_NAMESPACE(
expr->module, expr_ns,
asn1f_find_terminal_type_ex(arg->asn, expr_ns, expr));
if(_format == TNF_RSAFE) {
if(_format == TNF_RSAFE) {
if(terminal && terminal->expr_type & ASN_CONSTR_MASK) {
typename = terminal->Identifier;
}
......@@ -327,8 +332,10 @@ asn1c_type_fits_long(arg_t *arg, asn1p_expr_t *expr) {
#define LEFTMIN (-RIGHTMAX-1) /* of 32-bit integer type */
/* Descend to the terminal type */
expr = asn1f_find_terminal_type_ex(arg->asn, expr);
if(expr == 0) return FL_NOTFIT;
expr = WITH_MODULE_NAMESPACE(
expr->module, expr_ns,
asn1f_find_terminal_type_ex(arg->asn, expr_ns, expr));
if(expr == 0) return FL_NOTFIT;
/* The "fits into long" operation is relevant only for integer types */
switch(expr->expr_type) {
......
......@@ -34,6 +34,8 @@ asn1_compile(asn1p_t *asn, const char *datadir, enum asn1c_flags flags,
*/
TQ_FOR(mod, &(asn->modules), mod_next) {
TQ_FOR(arg->expr, &(mod->members), next) {
arg->ns = asn1_namespace_new_from_module(mod, 0);
compiler_streams_t *cs = NULL;
if(asn1c_attach_streams(arg->expr))
......@@ -52,6 +54,9 @@ asn1_compile(asn1p_t *asn, const char *datadir, enum asn1c_flags flags,
arg->expr->_lineno);
return ret;
}
asn1_namespace_free(arg->ns);
arg->ns = 0;
}
}
......
......@@ -75,27 +75,33 @@ asn1f_process(asn1p_t *asn, enum asn1f_flags flags,
return -1;
}
/*
* Process each module in the list.
* PHASE I.
*/
TQ_FOR(arg.mod, &(asn->modules), mod_next) {
ret = asn1f_fix_module__phase_1(&arg);
/*
* These lines are used for illustration purposes.
* RET2RVAL() is used everywhere else.
*/
if(ret == -1) fatals++;
if(ret == 1) warnings++;
}
/* PHASE II. */
TQ_FOR(arg.mod, &(asn->modules), mod_next) {
ret = asn1f_fix_module__phase_2(&arg);
if(ret == -1) fatals++;
if(ret == 1) warnings++;
}
memset(&a1f_replace_me_with_proper_interface_arg, 0, sizeof(arg_t));
/*
* Process each module in the list.
* PHASE I.
*/
TQ_FOR(arg.mod, &(asn->modules), mod_next) {
arg.ns = asn1_namespace_new_from_module(arg.mod, 0);
ret = asn1f_fix_module__phase_1(&arg);
/*
* These lines are used for illustration purposes.
* RET2RVAL() is used everywhere else.
*/
if(ret == -1) fatals++;
if(ret == 1) warnings++;
asn1_namespace_free(arg.ns);
arg.ns = 0;
}
/* PHASE II. */
TQ_FOR(arg.mod, &(asn->modules), mod_next) {
arg.ns = asn1_namespace_new_from_module(arg.mod, 0);
ret = asn1f_fix_module__phase_2(&arg);
if(ret == -1) fatals++;
if(ret == 1) warnings++;
asn1_namespace_free(arg.ns);
arg.ns = 0;
}
memset(&a1f_replace_me_with_proper_interface_arg, 0, sizeof(arg_t));
/*
* Compute a return value.
......@@ -418,8 +424,8 @@ asn1f_resolve_constraints(arg_t *arg) {
DEBUG("(%s)", arg->expr->Identifier);
ret = asn1constraint_resolve(arg, arg->expr->constraints, etype, 0);
RET2RVAL(ret, rvalue);
ret = asn1constraint_resolve(arg, arg->expr->constraints, etype, 0);
RET2RVAL(ret, rvalue);
return rvalue;
}
......
......@@ -64,8 +64,8 @@ asn1f_fix_bit_string_type(arg_t *arg) {
return -1;
} else if(v->value->type == ATV_REFERENCED) {
/* Resolve the value */
if(asn1f_value_resolve(arg, v, 0))
return -1;
if(asn1f_value_resolve(arg, v, 0))
return -1;
}
if(v->value->type != ATV_INTEGER
|| v->value->value.v_integer < 0) {
......
#include "asn1fix_internal.h"
asn1p_expr_t *
asn1f_class_access(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t *ref) {
asn1f_class_access(arg_t *arg, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t *ref) {
asn1p_expr_t *ioclass;
asn1p_expr_t *classfield;
asn1p_expr_t *expr;
......@@ -9,9 +9,11 @@ asn1f_class_access(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, co
assert(ref->comp_count > 1);
DEBUG("ClassAccess lookup (%s) for line %d", asn1f_printable_reference(ref), ref->_lineno);
DEBUG("ClassAccess lookup (%s%s) for line %d",
asn1f_printable_reference(ref), rhs_pspecs ? ", parameterized" : "",
ref->_lineno);
/*
/*
* Fetch the first part of the reference (OBJECT or ObjectSet).
* OBJECT.&<something>...
* ObjectSet.&<something>...
......@@ -20,17 +22,18 @@ asn1f_class_access(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, co
tmpref = *ref;
tmpref.comp_count = 1;
ioclass = asn1f_lookup_symbol(arg, mod, rhs_pspecs, &tmpref);
ioclass = asn1f_lookup_symbol(arg, rhs_pspecs, &tmpref);
if(ioclass == NULL) {
errno = ESRCH;
DEBUG("ClassAccess lookup (%s) failed",
asn1f_printable_reference(&tmpref));
errno = ESRCH;
return NULL;
}
if(ioclass->expr_type == A1TC_REFERENCE) {
ioclass = asn1f_lookup_symbol(arg,
ioclass->module,
ioclass->rhs_pspecs,
ioclass->reference);
if(ioclass == NULL) {
ioclass = WITH_MODULE(
ioclass->module,
asn1f_lookup_symbol(arg, ioclass->rhs_pspecs, ioclass->reference));
if(ioclass == NULL) {
errno = ESRCH;
return NULL;
}
......@@ -65,7 +68,7 @@ asn1f_class_access(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, co
if(TQ_FIRST(&classfield->members)) {
/* Already have something */
} else {
expr = asn1p_expr_new(classfield->_lineno, mod);
expr = asn1p_expr_new(classfield->_lineno, arg->mod);
expr->expr_type = ASN_TYPE_ANY;
expr->meta_type = AMT_TYPE;
asn1p_expr_add(classfield, expr);
......
......@@ -4,6 +4,7 @@
/*
* Fetch the element from the class-related stuff (thing) by its reference.
*/
asn1p_expr_t *asn1f_class_access(arg_t *, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t *);
asn1p_expr_t *asn1f_class_access(arg_t *, asn1p_expr_t *rhs_pspecs,
const asn1p_ref_t *);
#endif /* ASN1FIX_CLASS_H */
......@@ -376,7 +376,7 @@ _asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v) {
*/
save_tag = v->tag; /* Save existing tag */
memset(&v->tag, 0, sizeof(v->tag)); /* Remove it temporarily */
ret = asn1f_fetch_outmost_tag(arg->asn, arg->mod, v, &tag, 0);
ret = asn1f_fetch_outmost_tag(arg->asn, arg->ns, arg->mod, v, &tag, 0);
v->tag = save_tag; /* Restore the tag back */
if(ret == 0) return 0; /* If found tag, it's okay */
......@@ -404,9 +404,9 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
int ra, rb;
int ret;
ra = asn1f_fetch_outmost_tag(arg->asn, arg->mod, a,
ra = asn1f_fetch_outmost_tag(arg->asn, arg->ns, arg->mod, a,
&ta, AFT_IMAGINARY_ANY);
rb = asn1f_fetch_outmost_tag(arg->asn, arg->mod, b,
rb = asn1f_fetch_outmost_tag(arg->asn, arg->ns, arg->mod, b,
&tb, AFT_IMAGINARY_ANY);
/*
......@@ -475,12 +475,10 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
DEBUG(" %s is a type reference", a->Identifier);
a = asn1f_lookup_symbol(arg,
a->module, a->rhs_pspecs, a->reference);
if(!a) return 0; /* Already FATAL()'ed somewhere else */
WITH_MODULE(a->module, ret = _asn1f_compare_tags(arg, a, b));
return ret;
}
a = asn1f_lookup_symbol(arg, a->rhs_pspecs, a->reference);
if(!a) return 0; /* Already FATAL()'ed somewhere else */
return WITH_MODULE(a->module, _asn1f_compare_tags(arg, a, b));
}
if(ra && a->expr_type == ASN_CONSTR_CHOICE) {
asn1p_expr_t *v;
......
......@@ -31,8 +31,8 @@ asn1constraint_pullup(arg_t *arg) {
asn1p_expr_t *parent_expr;
assert(ref);
parent_expr = asn1f_lookup_symbol(arg, expr->module, expr->rhs_pspecs, ref);
if(!parent_expr) {
parent_expr = asn1f_lookup_symbol(arg, expr->rhs_pspecs, ref);
if(!parent_expr) {
if(errno != EEXIST) {
DEBUG("\tWhile fetching parent constraints: "
"type \"%s\" not found: %s",
......@@ -57,7 +57,7 @@ asn1constraint_pullup(arg_t *arg) {
ct_parent = parent_expr->combined_constraints;
}
} else {
} else {
ct_parent = 0;
}
......@@ -70,9 +70,9 @@ asn1constraint_pullup(arg_t *arg) {
* Resolve constraints, if not already resolved.
*/
top_parent = asn1f_find_terminal_type(arg, arg->expr);
ret = asn1constraint_resolve(arg, ct_expr,
top_parent ? top_parent->expr_type : A1TC_INVALID, 0);
if(ret) return ret;
ret = asn1constraint_resolve(
arg, ct_expr, top_parent ? top_parent->expr_type : A1TC_INVALID, 0);
if(ret) return ret;
/*
* Copy parent type constraints.
......@@ -201,35 +201,34 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_type_e ety
RET2RVAL(ret, rvalue);
}
if(ct->value && ct->value->type == ATV_REFERENCED) {
ret = constraint_value_resolve(arg,
&ct->value, real_constraint_type);
RET2RVAL(ret, rvalue);
ret = constraint_value_resolve(arg, &ct->value, real_constraint_type);
RET2RVAL(ret, rvalue);
}
if(ct->range_start && ct->range_start->type == ATV_REFERENCED) {
ret = constraint_value_resolve(arg,
&ct->range_start, real_constraint_type);
RET2RVAL(ret, rvalue);
ret = constraint_value_resolve(arg, &ct->range_start,
real_constraint_type);
RET2RVAL(ret, rvalue);
}
if(ct->range_stop && ct->range_stop->type == ATV_REFERENCED) {
ret = constraint_value_resolve(arg,
&ct->range_stop, real_constraint_type);
RET2RVAL(ret, rvalue);
ret = constraint_value_resolve(arg, &ct->range_stop,
real_constraint_type);
RET2RVAL(ret, rvalue);
}
if (ct->value && ct->value->type == ATV_UNPARSED && etype == A1TC_CLASSDEF) {
ret = constraint_object_resolve(arg, ct->value);
RET2RVAL(ret, rvalue);
}
/*
* Proceed recursively.
*/
for(el = 0; el < ct->el_count; el++) {
ret = asn1constraint_resolve(arg, ct->elements[el],
etype, effective_type);
RET2RVAL(ret, rvalue);
}
/*
* Proceed recursively.
*/
for(el = 0; el < ct->el_count; el++) {
ret = asn1constraint_resolve(arg, ct->elements[el], etype,
effective_type);
RET2RVAL(ret, rvalue);
}
return rvalue;
return rvalue;
}
static void
......@@ -272,10 +271,9 @@ constraint_type_resolve(arg_t *arg, asn1p_constraint_t *ct) {
asn1p_expr_t *rtype;
arg_t tmparg;
rtype = asn1f_lookup_symbol(arg, arg->expr->module,
arg->expr->rhs_pspecs,
ct->containedSubtype->value.reference);
if(!rtype) {
rtype = asn1f_lookup_symbol(arg, arg->expr->rhs_pspecs,
ct->containedSubtype->value.reference);
if(!rtype) {
FATAL("Cannot find type \"%s\" in constraints "
"at line %d",
asn1f_printable_value(ct->containedSubtype),
......@@ -326,10 +324,10 @@ constraint_type_resolve(arg_t *arg, asn1p_constraint_t *ct) {
}
static int
constraint_value_resolve(arg_t *arg,
asn1p_value_t **value, enum asn1p_constraint_type_e real_ctype) {
asn1p_expr_t static_expr;
arg_t tmp_arg;
constraint_value_resolve(arg_t *arg, asn1p_value_t **value,
enum asn1p_constraint_type_e real_ctype) {
asn1p_expr_t static_expr;
arg_t tmparg;
int rvalue = 0;
int ret;
......@@ -340,10 +338,10 @@ constraint_value_resolve(arg_t *arg,
static_expr = *arg->expr;
static_expr.value = *value;
static_expr.meta_type = AMT_VALUE;
tmp_arg = *arg;
tmp_arg.mod = arg->expr->module;
tmp_arg.expr = &static_expr;
ret = asn1f_value_resolve(&tmp_arg, &static_expr, &real_ctype);
tmparg = *arg;
tmparg.mod = arg->expr->module;
tmparg.expr = &static_expr;
ret = asn1f_value_resolve(&tmparg, &static_expr, &real_ctype);
RET2RVAL(ret, rvalue);
assert(static_expr.value);
*value = static_expr.value;
......@@ -353,7 +351,7 @@ constraint_value_resolve(arg_t *arg,
static int
constraint_object_resolve(arg_t *arg, asn1p_value_t *value) {
asn1p_expr_t tmp_expr = *arg->expr;
asn1p_expr_t tmp_expr = *arg->expr;
asn1p_expr_t *saved_expr = arg->expr;
tmp_expr.meta_type = AMT_VALUESET;
......
......@@ -4,9 +4,10 @@
/*
* Resolve referenced values inside constraints.
*/
int asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct,
asn1p_expr_type_e topmost_parent_expression_type,
enum asn1p_constraint_type_e effective_constraint_type);
int asn1constraint_resolve(
arg_t *arg, asn1p_constraint_t *ct,
asn1p_expr_type_e topmost_parent_expression_type,
enum asn1p_constraint_type_e effective_constraint_type);
/*
* Collect all subtype constraints from all parents of this type and
......
......@@ -468,7 +468,7 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell,
}
if(expr->reference &&
!asn1f_lookup_symbol(arg, arg->mod, expr->rhs_pspecs, expr->reference)) {
!asn1f_lookup_symbol(arg, expr->rhs_pspecs, expr->reference)) {
asn1p_ref_free(expr->reference);
new_ref = 0;
......
......@@ -3,29 +3,69 @@
extern arg_t a1f_replace_me_with_proper_interface_arg;
static asn1p_t *asn1f_ssn_asn_;
static void
_add_standard_namespaces(asn1_namespace_t *ns) {
asn1p_oid_t *uioc_oid;
asn1p_oid_arc_t arcs[] = {{1, "iso"}, {3, "org"},
{6, "dod"}, {1, "internet"},
{4, "private"}, {1, "enterprise"},
{9363, "spelio"}, {1, "software"},
{5, "asn1c"}, {3, "standard-modules"},
{0, "auto-imported"}, {1, 0}};
uioc_oid = asn1p_oid_construct(arcs, sizeof(arcs) / sizeof(arcs[0]));
asn1p_module_t *module = asn1f_lookup_module_ex(
asn1f_ssn_asn_, "ASN1C-UsefulInformationObjectClasses", uioc_oid);
asn1p_oid_free(uioc_oid);
if(module) {
asn1_namespace_add_module(ns, module, 0);
}
}
asn1p_expr_t *
asn1f_lookup_symbol_ex(
asn1p_t *asn,
asn1p_expr_t *expr,
const asn1p_ref_t *ref) {
arg_t arg;
void
asn1f_use_standard_namespaces(asn1p_t *asn) {
asn1f_ssn_asn_ = asn;
asn1_namespace_add_standard_namespaces_callback(_add_standard_namespaces);
}
memset(&arg, 0, sizeof(arg));
asn1p_module_t *
asn1f_lookup_module_ex(asn1p_t *asn, const char *module_name,
const asn1p_oid_t *oid) {
arg_t arg;
arg.asn = asn;
arg.mod = expr->module;
arg.expr = expr;
arg.eh = a1f_replace_me_with_proper_interface_arg.eh;
arg.debug = a1f_replace_me_with_proper_interface_arg.debug;
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.eh = a1f_replace_me_with_proper_interface_arg.eh;
arg.debug = a1f_replace_me_with_proper_interface_arg.debug;
return asn1f_lookup_module(&arg, module_name, oid);
}
asn1p_expr_t *
asn1f_lookup_symbol_ex(asn1p_t *asn, asn1_namespace_t *ns, asn1p_expr_t *expr,
const asn1p_ref_t *ref) {
arg_t arg;
return asn1f_lookup_symbol(&arg, expr->module, expr->rhs_pspecs, ref);
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.ns = ns;
arg.mod = expr->module;
arg.expr = expr;
arg.eh = a1f_replace_me_with_proper_interface_arg.eh;
arg.debug = a1f_replace_me_with_proper_interface_arg.debug;
return asn1f_lookup_symbol(&arg, expr->rhs_pspecs, ref);
}
asn1p_expr_t *
asn1f_class_access_ex(asn1p_t *asn,
asn1p_module_t *mod,
asn1_namespace_t *ns,
asn1p_expr_t *expr,
asn1p_expr_t *rhs_pspecs,
const asn1p_ref_t *ref) {
......@@ -35,26 +75,29 @@ asn1f_class_access_ex(asn1p_t *asn,
arg.asn = asn;
arg.mod = mod;
arg.ns = ns;
arg.expr = expr;
arg.eh = a1f_replace_me_with_proper_interface_arg.eh;
arg.debug = a1f_replace_me_with_proper_interface_arg.debug;
return asn1f_class_access(&arg, mod, rhs_pspecs, ref);
return asn1f_class_access(&arg, rhs_pspecs, ref);
}
asn1p_expr_t *
asn1f_find_terminal_type_ex(asn1p_t *asn, asn1p_expr_t *expr) {
arg_t arg;
asn1f_find_terminal_type_ex(asn1p_t *asn, asn1_namespace_t *ns,
asn1p_expr_t *expr) {
arg_t arg;
memset(&arg, 0, sizeof(arg));
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.mod = expr->module;
arg.expr = expr;
arg.eh = a1f_replace_me_with_proper_interface_arg.eh;
arg.debug = a1f_replace_me_with_proper_interface_arg.debug;
arg.asn = asn;
arg.ns = ns;
arg.mod = expr->module;
arg.expr = expr;
arg.eh = a1f_replace_me_with_proper_interface_arg.eh;
arg.debug = a1f_replace_me_with_proper_interface_arg.debug;
return asn1f_find_terminal_type(&arg, expr);
return asn1f_find_terminal_type(&arg, expr);
}
asn1p_expr_t *
......
......@@ -7,6 +7,16 @@
#include "asn1fix_tags.h"
struct asn1_namespace_s; /* Forward declaration. */
void asn1f_use_standard_namespaces(asn1p_t *asn);
/*
* Lookup the module by its oid. oid is mandatory.
*/
asn1p_module_t *asn1f_lookup_module_ex(asn1p_t *asn, const char *module_name,
const asn1p_oid_t *oid);
/*
* Create a human-readable representation of a reference and value.
*/
......@@ -18,6 +28,7 @@ char const *asn1f_printable_value(asn1p_value_t *value);
*/
asn1p_expr_t *asn1f_lookup_symbol_ex(
asn1p_t *asn,
struct asn1_namespace_s *ns,
asn1p_expr_t *expr,
const asn1p_ref_t *ref);
......@@ -25,12 +36,17 @@ asn1p_expr_t *asn1f_lookup_symbol_ex(
* Exportable version of an asn1f_class_access().
*/
asn1p_expr_t *asn1f_class_access_ex(asn1p_t *asn, asn1p_module_t *mod,
asn1p_expr_t *expr, asn1p_expr_t *rhs_rspecs, const asn1p_ref_t *);
struct asn1_namespace_s *ns,
asn1p_expr_t *expr,
asn1p_expr_t *rhs_rspecs,
const asn1p_ref_t *);
/*
* Exportable version of asn1f_find_terminal_type().
*/
asn1p_expr_t *asn1f_find_terminal_type_ex(asn1p_t *asn, asn1p_expr_t *tc);
asn1p_expr_t *asn1f_find_terminal_type_ex(asn1p_t *asn,
struct asn1_namespace_s *ns,
asn1p_expr_t *tc);
/*
* Exportable version of asn1f_fix_dereference_values();
......
#ifndef ASN1FIX_INTEGER_H
#define ASN1FIX_INTEGER_H
int asn1f_fix_integer(arg_t *); /* Type1 ::= INTEGER { a(1), b(2) } */
/* Type1 ::= INTEGER { a(1), b(2) } */
int asn1f_fix_integer(arg_t *);
#endif /* ASN1FIX_INTEGER_H */
......@@ -21,6 +21,7 @@
#endif
#include <asn1parser.h> /* Our lovely ASN.1 parser module */
#include <asn1_namespace.h>
#include "asn1fix.h"
#ifdef _WIN32
......@@ -45,13 +46,14 @@ typedef void (*error_logger_f)(int _is_fatal, const char *fmt, ...);
* Universal argument.
*/
typedef struct arg_s {
asn1p_t *asn;
asn1p_module_t *mod;
asn1p_expr_t *expr;
error_logger_f eh;
error_logger_f debug;
void *key; /* The next level key */
enum asn1f_flags flags;
asn1p_t *asn;
asn1_namespace_t *ns;
asn1p_module_t *mod;
asn1p_expr_t *expr;
error_logger_f eh;
error_logger_f debug;
void *key; /* The next level key */
enum asn1f_flags flags;
} arg_t;
/*
......@@ -96,28 +98,38 @@ typedef struct arg_s {
/*
* Temporary substitute module for the purposes of evaluating expression.
*/
#define WITH_MODULE(tmp_mod, expr) do { \
void *_saved_mod = arg->mod; \
arg->mod = tmp_mod; \
do { expr; } while(0); \
arg->mod = _saved_mod; \
} while(0)
#define LOG(code, fmt, args...) do { \
int _save_errno = errno; \
if(code < 0) { \
if(arg->debug) \
arg->debug(code, \
"%s: " fmt " in %s (%s:%d)", \
__func__, ##args, \
arg->mod->source_file_name, \
__FILE__, __LINE__); \
} else if(arg->eh) { \
arg->eh(code, fmt " in %s", ##args, \
arg->mod->source_file_name); \
} \
errno = _save_errno; \
} while(0)
#define WITH_MODULE(tmp_mod, code) \
({ \
void *_saved_mod = arg->mod; \
asn1_namespace_t *_saved_ns = arg->ns; \
arg->mod = tmp_mod; \
arg->ns = asn1_namespace_new_from_module(tmp_mod, 1); \
typeof(code) ret = code; \
arg->ns = _saved_ns; \
arg->mod = _saved_mod; \
ret; \
})
#define LOG(code, fmt, args...) \
do { \
int _save_errno = errno; \
if(code < 0) { \
if(arg->debug) { \
arg->debug(code, "%s: " fmt " in %s (%s:%d)", __func__, \
##args, arg->mod->source_file_name, __FILE__, \
__LINE__); \
} \
} else if(arg->eh) { \
if(arg->debug) { \
arg->eh(code, fmt " in %s (%s:%d)", ##args, \
arg->mod->source_file_name, __FILE__, __LINE__); \
} else { \
arg->eh(code, fmt " in %s", ##args, \
arg->mod->source_file_name); \
} \
errno = _save_errno; \
} \
} while(0)
#define DEBUG(fmt, args...) LOG(-1, fmt, ##args)
#define FATAL(fmt, args...) LOG( 1, fmt, ##args)
......
......@@ -111,17 +111,19 @@ compare_specializations(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
continue;
if(ac->reference) {
ac = asn1f_lookup_symbol(arg,
ac->module, ac->rhs_pspecs, ac->reference);
if(!ac) break;
ac = WITH_MODULE(
ac->module,
asn1f_lookup_symbol(arg, ac->rhs_pspecs, ac->reference));
if(!ac) break;
}
if(bc->reference) {
bc = asn1f_lookup_symbol(arg,
bc->module, bc->rhs_pspecs, bc->reference);
if(!bc) break;
bc = WITH_MODULE(
bc->module,
asn1f_lookup_symbol(arg, bc->rhs_pspecs, bc->reference));
if(!bc) break;
}
goto retry;
}
goto retry;
}
if(ac || bc)
/* Specializations do not match: different size option sets */
......
This diff is collapsed.
......@@ -37,10 +37,8 @@ asn1p_module_t *asn1f_lookup_module(arg_t *arg,
* Return the reference to a destination of the given reference,
* symbol lookup. Not a recursive function.
*/
asn1p_expr_t *asn1f_lookup_symbol(arg_t *arg,
asn1p_module_t *mod,
asn1p_expr_t *rhs_pspecs,
const asn1p_ref_t *ref);
asn1p_expr_t *asn1f_lookup_symbol(arg_t *arg, asn1p_expr_t *rhs_pspecs,
const asn1p_ref_t *ref);
/*
* Recursively find the original type for the given expression.
......
#include "asn1fix_internal.h"
#include <asn1_namespace.h>
#define ADD_TAG(skip, newtag) do { \
void *__p; \
......@@ -66,7 +67,7 @@ asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int
if(expr->meta_type == AMT_TYPEREF) {
asn1p_expr_t *nexpr;
DEBUG("Following the reference %s", expr->Identifier);
nexpr = asn1f_lookup_symbol(arg, expr->module, expr->rhs_pspecs, expr->reference);
nexpr = asn1f_lookup_symbol(arg, expr->rhs_pspecs, expr->reference);
if(nexpr == NULL) {
if(errno != EEXIST) /* -fknown-extern-type */
return -1;
......@@ -139,13 +140,13 @@ asn1f_fetch_minimal_choice_root_tag(arg_t *arg, struct asn1p_type_tag_s *tag, en
}
int
asn1f_fetch_outmost_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, enum asn1f_aft_flags_e flags) {
asn1f_fetch_outmost_tag(asn1p_t *asn, asn1_namespace_t *ns, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, enum asn1f_aft_flags_e flags) {
struct asn1p_type_tag_s *tags;
int count;
flags |= AFT_FETCH_OUTMOST;
count = asn1f_fetch_tags(asn, mod, expr, &tags, flags);
count = asn1f_fetch_tags(asn, ns, mod, expr, &tags, flags);
if(count <= 0) return count;
*tag = tags[0];
......@@ -155,13 +156,14 @@ asn1f_fetch_outmost_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, s
}
int
asn1f_fetch_tags(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s **tags_r, enum asn1f_aft_flags_e flags) {
asn1f_fetch_tags(asn1p_t *asn, asn1_namespace_t *ns, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s **tags_r, enum asn1f_aft_flags_e flags) {
arg_t arg;
struct asn1p_type_tag_s *tags = 0;
int count;
memset(&arg, 0, sizeof(arg));
arg.asn = asn;
arg.ns = ns;
arg.mod = mod;
arg.expr = expr;
......
#ifndef ASN1FIX_TAGS_H
#define ASN1FIX_TAGS_H
struct asn1_namespace_s; /* Forward declaration */
enum asn1f_aft_flags_e {
AFT_IMAGINARY_ANY = 0x01, /* Treat ANY tag as [IMAGINARY ANY] */
AFT_FETCH_OUTMOST = 0x02, /* Fetch only outmost tag */
......@@ -15,8 +17,10 @@ enum asn1f_aft_flags_e {
* Type3 ::= [4] EXPLICIT SEQUENCE { ... }
* Will return [2][3][UNIVERSAL 16] for the Type1.
*/
int asn1f_fetch_tags(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr,
struct asn1p_type_tag_s **tags, enum asn1f_aft_flags_e flags);
int asn1f_fetch_tags(asn1p_t *asn, struct asn1_namespace_s *ns,
asn1p_module_t *mod, asn1p_expr_t *expr,
struct asn1p_type_tag_s **tags,
enum asn1f_aft_flags_e flags);
/*
* Fetch the outmost tag of the given type.
......@@ -25,6 +29,9 @@ int asn1f_fetch_tags(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr,
* Type3 ::= SEQUENCE { ... }
* Will yield [2] for Type1.
*/
int asn1f_fetch_outmost_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, enum asn1f_aft_flags_e);
int asn1f_fetch_outmost_tag(asn1p_t *asn, struct asn1_namespace_s *ns,
asn1p_module_t *mod, asn1p_expr_t *expr,
struct asn1p_type_tag_s *tag,
enum asn1f_aft_flags_e);
#endif /* ASN1FIX_TAGS_H */
......@@ -4,6 +4,8 @@
#ifndef ASN1FIX_VALUE_H
#define ASN1FIX_VALUE_H
struct asn1p_namespace_s; /* Forward declaration */
/*
* Resolve the value given by reference.
* This function also takes a parameter which specifies the desired
......@@ -16,7 +18,7 @@
* -1/ESRCH: Cannot find the terminal reference.
*/
int asn1f_value_resolve(arg_t *arg, asn1p_expr_t *tc,
const enum asn1p_constraint_type_e *opt_constr_type);
const enum asn1p_constraint_type_e *opt_constr_type);
/*
* Check if a value in value_expr refers to the enumeration or integer element
......
......@@ -10,8 +10,11 @@
#include <sysexits.h>
#endif
#include <errno.h>
#include <libgen.h>
#include "asn1fix.h"
#include "asn1_buffer.h"
#include "asn1_namespace.h"
#ifndef TOP_SRCDIR
#define TOP_SRCDIR_S ".."
......@@ -58,13 +61,18 @@ main(int ac, char **av) {
* Go into a directory with tests.
*/
if(ac <= 1) {
const char *asn1_tests_dir = getenv("ASN1_TESTS_DIR");
if(!asn1_tests_dir)
asn1_tests_dir = TOP_SRCDIR_S "/tests/tests-asn1c-compiler";
fprintf(stderr, "Testing in %s...\n", asn1_tests_dir);
ret = chdir(asn1_tests_dir);
abuf *asn1_tests_dirname = abuf_new();
const char *top_srcdir = getenv("top_srcdir");
if(!top_srcdir) top_srcdir = TOP_SRCDIR_S;
abuf_printf(asn1_tests_dirname, "%s/tests/tests-asn1c-compiler",
top_srcdir);
fprintf(stderr, "Testing in %s...\n", top_srcdir);
ret = chdir(asn1_tests_dirname->buffer);
if(ret == -1)
fprintf(stderr, "%s: %s\n", asn1_tests_dir, strerror(errno));
fprintf(stderr, "%s: %s\n", asn1_tests_dirname->buffer,
strerror(errno));
assert(ret == 0);
/* For some reasons, tests could be hidden under extra tests dir. */
#ifdef _WIN32
......@@ -195,17 +203,35 @@ check(const char *fname,
if(!asn) return r_value;
if(r_value == 0) {
char *fname_copy = strdup(fname);
char *test_dir = dirname(fname_copy);
abuf *skeletons_dirname = abuf_new();
asn1p_t *std_asn;
std_asn = asn1p_parse_file("../../skeletons/standard-modules/ASN1C-UsefulInformationObjectClasses.asn1", A1P_NOFLAGS);
if(std_asn) {
abuf_printf(skeletons_dirname,
"%s/../../skeletons/standard-modules/"
"ASN1C-UsefulInformationObjectClasses.asn1",
test_dir);
free(fname_copy);
std_asn = asn1p_parse_file(skeletons_dirname->buffer, A1P_NOFLAGS);
if(std_asn) {
asn1p_module_t *mod;
while((mod = TQ_REMOVE(&(std_asn->modules), mod_next))) {
mod->_tags |= MT_STANDARD_MODULE;
TQ_ADD(&(asn->modules), mod, mod_next);
}
asn1p_delete(std_asn);
}
}
/* Allow referencing imported modules. */
asn1f_use_standard_namespaces(asn);
} else {
fprintf(stderr, "%s: %s\n", skeletons_dirname->buffer,
strerror(errno));
}
abuf_free(skeletons_dirname);
}
/*
* Perform semantical checks and fixes.
......@@ -364,8 +390,6 @@ post_fix_check_element(asn1p_module_t *mod, asn1p_expr_t *check_expr) {
return -1;
}
assert(value->type = ATV_INTEGER);
return 0;
}
......
......@@ -4,8 +4,6 @@
#ifndef ASN1_PARSER_CLASS_H
#define ASN1_PARSER_CLASS_H
#include "asn1p_ref.h"
struct asn1p_expr_s; /* Forward declaration */
typedef struct asn1p_ioc_row_s {
......
......@@ -393,3 +393,10 @@ char *asn1p_tag2string(struct asn1p_type_tag_s *tag, char *buf) {
return start;
}
asn1p_paramlist_t *
asn1p_get_namespace(asn1p_expr_t *expr) {
if(!expr) return NULL;
if(expr->lhs_params) return expr->lhs_params;
return asn1p_get_namespace(expr->parent_expr);
}
......@@ -283,6 +283,7 @@ int asn1p_expr_compare(const asn1p_expr_t *, const asn1p_expr_t *);
void asn1p_expr_free(asn1p_expr_t *expr);
void asn1p_expr_set_source(asn1p_expr_t *, asn1p_module_t *, int lineno);
asn1p_paramlist_t *asn1p_get_namespace(asn1p_expr_t *);
#define TAG2STRING_BUFFER_SIZE 64 /* buf should be at least this big */
char *asn1p_tag2string(struct asn1p_type_tag_s *tag, char *opt_buf);
......
......@@ -43,14 +43,14 @@ typedef enum asn1p_module_flags {
typedef struct asn1p_module_s {
/*
* Name of the source file.
* Human-readable module reference.
*/
char *source_file_name;
char *ModuleName; /* Must be the first field */
/*
* Human-readable module reference.
* Name of the source file.
*/
char *ModuleName;
char *source_file_name;
/*
* Unique module identifier, OID.
......
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "asn1parser.h"
/*
* Construct a new empty reference.
*/
asn1p_ref_t *
asn1p_ref_new(int _lineno, asn1p_module_t *mod) {
asn1p_ref_t *ref;
ref = calloc(1, sizeof *ref);
assert(ref);
asn1p_ref_set_source(ref, mod, _lineno);
return ref;
}
void
asn1p_ref_free(asn1p_ref_t *ref) {
if(ref) {
if(ref->components) {
size_t i = ref->comp_count;
while(i--) {
free(ref->components[i].name);
ref->components[i].name = 0;
}
free(ref->components);
ref->components = 0;
}
free(ref);
}
}
void
asn1p_ref_set_source(asn1p_ref_t *ref, asn1p_module_t *module, int lineno) {
if(ref) {
ref->module = module;
ref->_lineno = lineno;
}
}
static enum asn1p_ref_lex_type_e
asn1p_ref_name2lextype(const char *name) {
enum asn1p_ref_lex_type_e lex_type;
int has_lowercase = 0;
if(*name == '&') {
if(name[1] >= 'A' && name[1] <= 'Z') {
lex_type = RLT_AmpUppercase;
} else {
lex_type = RLT_Amplowercase;
}
} else if(*name >= 'A' && *name <= 'Z') {
const char *p;
for(p = name; *p; p++) {
if(*p >= 'a' && *p <= 'z') {
has_lowercase = 1;
break;
}
}
if(has_lowercase) {
lex_type = RLT_Uppercase;
} else {
lex_type = RLT_CAPITALS;
}
} else if(*name == '@') {
if(name[1] == '.')
lex_type = RLT_AtDotlowercase;
else
lex_type = RLT_Atlowercase;
} else {
lex_type = RLT_lowercase;
}
return lex_type;
}
int
asn1p_ref_add_component(asn1p_ref_t *ref, const char *name, enum asn1p_ref_lex_type_e lex_type) {
if(!ref || !name
|| (int)lex_type < RLT_UNKNOWN || lex_type >= RLT_MAX) {
errno = EINVAL;
return -1;
}
if(ref->comp_count == ref->comp_size) {
int newsize = ref->comp_size?(ref->comp_size<<2):4;
void *p = realloc(ref->components,
newsize * sizeof(ref->components[0]));
if(p) {
ref->components = p;
ref->comp_size = newsize;
} else {
return -1;
}
}
if(lex_type == RLT_UNKNOWN) {
lex_type = asn1p_ref_name2lextype(name);
} else {
assert(lex_type == asn1p_ref_name2lextype(name));
}
ref->components[ref->comp_count].name = strdup(name);
ref->components[ref->comp_count].lex_type = lex_type;
if(ref->components[ref->comp_count].name) {
ref->comp_count++;
return 0;
} else {
return -1;
}
}
asn1p_ref_t *
asn1p_ref_clone(asn1p_ref_t *ref) {
asn1p_ref_t *newref;
newref = asn1p_ref_new(ref->_lineno, ref->module);
if(newref) {
for(size_t i = 0; i < ref->comp_count; i++) {
if(asn1p_ref_add_component(newref,
ref->components[i].name,
ref->components[i].lex_type
)) {
asn1p_ref_free(newref);
newref = NULL;
break;
}
}
}
return newref;
}
int
asn1p_ref_compare(const asn1p_ref_t *a, const asn1p_ref_t *b) {
if(a->comp_count != b->comp_count)
return -1;
if(a->module != b->module)
return -1;
for(size_t i = 0; i < a->comp_count; i++) {
if(a->components[i].lex_type != b->components[i].lex_type
|| strcmp(a->components[i].name, b->components[i].name) != 0) {
return -1;
}
}
return 0;
}
const char *
asn1p_ref_string(const asn1p_ref_t *ref) {
static char static_buf[32];
static char *buf = static_buf;
static size_t buf_size = sizeof(static_buf);
char *p = buf;
for(size_t i = 0; i < ref->comp_count; i++) {
size_t space = buf_size - (p - buf);
int ret =
snprintf(p, space, "%s%s", i ? "." : "", ref->components[i].name);
if(ret < 0 || (size_t)ret >= space) {
i--;
char *tmp = malloc(buf_size * 2 + 1);
assert(tmp);
size_t p_offset = p - buf;
memcpy(tmp, buf, (p - buf));
if(buf != static_buf) free(buf);
buf_size *= 2;
buf = tmp;
p = tmp + p_offset;
} else {
p += ret;
}
}
*p = '\0';
return buf;
}
/*
* Generic reference to the yet unknown type defined elsewhere.
*/
#ifndef ASN1_PARSER_REFERENCE_H
#define ASN1_PARSER_REFERENCE_H
typedef struct asn1p_ref_s {
/*
* A set of reference name components.
* A reference name consists of several components separated by dots:
* "OBJECT-CLASS.&Algorithm.&id"
*/
struct asn1p_ref_component_s {
enum asn1p_ref_lex_type_e {
RLT_UNKNOWN, /* Invalid? */
/*
* Object class reference "OCLASS1",
* type reference "Type1",
* value reference "id",
* type field reference "&Type1",
* value field reference "&id",
* "OBJECT-CLASS"
*/
RLT_CAPITALS,
RLT_Uppercase,
RLT_lowercase,
RLT_AmpUppercase,
RLT_Amplowercase,
RLT_Atlowercase,
RLT_AtDotlowercase,
RLT_MAX
} lex_type; /* Inferred lexical type of the identifier */
char *name; /* An identifier */
} *components;
size_t comp_count; /* Number of the components in the reference name. */
size_t comp_size; /* Number of allocated structures */
struct asn1p_module_s *module; /* Defined in module */
int _lineno; /* Number of line in the file */
} asn1p_ref_t;
/*
* Constructor and destructor.
*/
asn1p_ref_t *asn1p_ref_new(int _lineno, asn1p_module_t *mod);
void asn1p_ref_free(asn1p_ref_t *);
asn1p_ref_t *asn1p_ref_clone(asn1p_ref_t *ref);
void asn1p_ref_set_source(asn1p_ref_t *, asn1p_module_t *module, int lineno);
/*
* Lexicographically compare references.
*/
int asn1p_ref_compare(const asn1p_ref_t *, const asn1p_ref_t *);
/*
* Return a pointer to a statically allocated buffer representing the
* complete reference.
*/
const char *asn1p_ref_string(const asn1p_ref_t *);
/*
* Add a new reference component to the existing reference structure.
*
* RETURN VALUES:
* 0: All clear.
* -1/EINVAL: Invalid arguments
* -1/ENOMEM: Memory allocation failed
*/
int asn1p_ref_add_component(asn1p_ref_t *,
const char *name, enum asn1p_ref_lex_type_e);
#endif /* ASN1_PARSER_REFERENCE_H */
......@@ -8,11 +8,14 @@
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "asn1_ref.h"
#include "asn1_buffer.h"
#include "asn1_namespace.h"
#include "asn1p_integer.h"
#include "asn1p_list.h"
#include "asn1p_oid.h" /* Object identifiers (OIDs) */
#include "asn1p_module.h" /* ASN.1 definition module */
#include "asn1p_ref.h" /* References to custom types */
#include "asn1p_value.h" /* Value definition */
#include "asn1p_param.h" /* Parameterization */
#include "asn1p_constr.h" /* Type Constraints */
......
......@@ -4,6 +4,7 @@
#include <errno.h>
#include <assert.h>
#include <asn1_namespace.h>
#include <asn1parser.h>
#include <asn1fix_export.h>
#include <asn1fix_crange.h>
......@@ -753,8 +754,9 @@ asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1pri
asn1print_constraint(tc->combined_constraints, flags);
}
top_parent = asn1f_find_terminal_type_ex(asn, tc);
if(top_parent) {
top_parent = WITH_MODULE_NAMESPACE(
tc->module, tc_ns, asn1f_find_terminal_type_ex(asn, tc_ns, tc));
if(top_parent) {
safe_printf("\n-- Practical constraints (%s): ",
top_parent->Identifier);
asn1print_constraint_explain(top_parent->Identifier,
......@@ -859,7 +861,7 @@ asn1print_expr_dtd(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, enum a
INDENT("<!ELEMENT %s", expr->Identifier);
if(expr->expr_type == A1TC_REFERENCE) {
se = asn1f_find_terminal_type_ex(asn, expr);
se = WITH_MODULE_NAMESPACE(expr->module, expr_ns, asn1f_find_terminal_type_ex(asn, expr_ns, expr));
if(!se) {
safe_printf(" (ANY)");
return 0;
......
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