introduce namespaces

This commit is contained in:
Lev Walkin 2017-08-22 01:48:23 -07:00
parent 9772177803
commit c0e03b946e
34 changed files with 653 additions and 700 deletions

View File

@ -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);
}
/*

View File

@ -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;

View File

@ -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;
}

View File

@ -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) \

View File

@ -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;

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -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++;
}
/*
* 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));
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;
}

View File

@ -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) {

View File

@ -1,7 +1,7 @@
#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);

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);
}
}
void
asn1f_use_standard_namespaces(asn1p_t *asn) {
asn1f_ssn_asn_ = asn;
asn1_namespace_add_standard_namespaces_callback(_add_standard_namespaces);
}
asn1p_module_t *
asn1f_lookup_module_ex(asn1p_t *asn, const char *module_name,
const asn1p_oid_t *oid) {
arg_t arg;
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,
asn1p_expr_t *expr,
const asn1p_ref_t *ref) {
arg_t arg;
asn1f_lookup_symbol_ex(asn1p_t *asn, asn1_namespace_t *ns, asn1p_expr_t *expr,
const asn1p_ref_t *ref) {
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_lookup_symbol(&arg, expr->module, expr->rhs_pspecs, ref);
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 *

View File

@ -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();

View File

@ -1,6 +1,7 @@
#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 */

View File

@ -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 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) { \
arg->eh(code, fmt " in %s", ##args, \
arg->mod->source_file_name); \
} \
errno = _save_errno; \
} 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) { \
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)

View File

@ -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 */

View File

@ -147,12 +147,19 @@ asn1f_lookup_module(arg_t *arg, const char *module_name, const asn1p_oid_t *oid)
}
static asn1p_expr_t *
asn1f_lookup_symbol_impl(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t *ref, int recursion_depth) {
asn1p_expr_t *ref_tc; /* Referenced tc */
asn1f_lookup_symbol_impl(arg_t *arg, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t *ref, int recursion_depth) {
asn1_namespace_t *initial_namespace = arg->ns;
asn1p_ref_t tmp_ref;
asn1p_module_t *imports_from;
char *modulename;
char *identifier;
if(ref->module && arg->mod != ref->module) {
return WITH_MODULE(
ref->module,
asn1f_lookup_symbol_impl(arg, rhs_pspecs, ref, recursion_depth));
}
/*
* First of all, a reference to a symbol may be specified
* using several possible forms:
@ -165,17 +172,18 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspe
* All other forms are not implemented at this moment.
*/
DEBUG("(%s) in %s for line %d",
DEBUG("Lookup (%s) in %s for line %d",
asn1f_printable_reference(ref),
mod->ModuleName,
asn1_namespace_string(initial_namespace),
ref->_lineno);
if(recursion_depth++ > 30 /* Arbitrary constant */) {
FATAL("Excessive circular referencing detected in module %s for %s at line %d",
mod->ModuleName,
asn1f_printable_reference(ref),
ref->_lineno);
errno = ETOOMANYREFS;
FATAL(
"Excessive circular referencing detected in namespace %s for %s at "
"line %d",
asn1_namespace_string(initial_namespace),
asn1f_printable_reference(ref), ref->_lineno);
errno = ETOOMANYREFS;
return NULL;
}
@ -194,7 +202,7 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspe
* This is a reference to a CLASS-related stuff.
* Employ a separate function for that.
*/
extract = asn1f_class_access(arg, mod, rhs_pspecs, ref);
extract = asn1f_class_access(arg, rhs_pspecs, ref);
return extract;
} else {
@ -203,162 +211,199 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspe
return NULL;
}
/*
* If module name is specified explicitly
* OR the current module's IMPORTS clause contains the identifier,
* fetch that module.
*/
if(modulename) {
imports_from = asn1f_lookup_module(arg, modulename, 0);
if(imports_from == NULL) {
FATAL("Module \"%s\" "
"mentioned at line %d is not found",
modulename, ref->_lineno);
return NULL;
}
if(modulename) {
/*
* The modulename is specified inside this reference.
* To avoid recursion, reformat the reference
* as it were local to that module.
*/
tmp_ref = *ref;
tmp_ref.components++; /* Hide the first element */
tmp_ref.comp_count--;
assert(tmp_ref.comp_count > 0);
ref = &tmp_ref;
}
/*
* Check that the EXPORTS section of this module contains
* the symbol we care about, or it is EXPORTS ALL.
*/
if(asn1f_compatible_with_exports(arg,imports_from,identifier)) {
errno = EPERM;
return NULL;
}
} else {
/* Search inside the IMPORTS section of the current module */
imports_from = asn1f_lookup_in_imports(arg, mod, identifier);
if(imports_from == NULL && errno != ESRCH) {
/*
* Return only of the name was not found.
* If module was not found or more serious error
* encountered, just return preserving the errno.
*/
return NULL;
}
}
asn1_namespace_t *my_namespace = initial_namespace;
/*
* The symbol is being imported from another module.
*/
importing:
if(imports_from) {
asn1p_ref_t tmpref = *ref;
asn1p_expr_t *expr;
if(modulename) {
/*
* The modulename is specified inside this reference.
* To avoid recursion, reformat the reference
* as it were local to that module.
*/
tmpref.components++; /* Hide the first element */
tmpref.comp_count--;
assert(tmpref.comp_count > 0);
}
#define DISPOSE_OF_MY_NAMESPACE() \
do { \
int tmp_errno = errno; \
if(my_namespace != initial_namespace) { \
asn1_namespace_free(my_namespace); \
my_namespace = NULL; \
} \
errno = tmp_errno; \
} while(0)
expr = asn1f_lookup_symbol_impl(arg, imports_from,
rhs_pspecs, &tmpref, recursion_depth);
if(!expr && !(arg->expr->_mark & TM_BROKEN)
&& !(imports_from->_tags & MT_STANDARD_MODULE)) {
arg->expr->_mark |= TM_BROKEN;
if(modulename) {
FATAL("Module %s referred by %s in module %s "
"does not contain the requested symbol",
imports_from->ModuleName,
asn1f_printable_reference(ref),
mod->ModuleName);
} else {
FATAL("Module %s referred in IMPORTS section "
"for %s of module %s does not contain "
"the requested symbol",
imports_from->ModuleName,
asn1f_printable_reference(ref),
mod->ModuleName);
}
}
return expr;
}
/*
* If module name is specified explicitly
* OR the current module's IMPORTS clause contains the identifier,
* switch namespace to that module.
*/
if(modulename) {
imports_from = asn1f_lookup_module(arg, modulename, 0);
if(imports_from == NULL) {
FATAL(
"Module \"%s\" "
"mentioned at line %d is not found",
modulename, ref->_lineno);
return NULL;
}
/*
* Now we know where to search for a value: in the current module.
*/
TQ_FOR(ref_tc, &(mod->members), next) {
if(ref_tc->Identifier)
if(strcmp(ref_tc->Identifier, identifier) == 0)
break;
}
if(ref_tc) {
/* It is acceptable that we don't use input parameters */
if(rhs_pspecs && !ref_tc->lhs_params) {
WARNING("Parameterized type %s expected "
"for %s at line %d",
ref_tc->Identifier,
asn1f_printable_reference(ref),
ref->_lineno);
}
if(!rhs_pspecs && ref_tc->lhs_params) {
FATAL("Type %s expects specialization "
"from %s at line %d",
ref_tc->Identifier,
asn1f_printable_reference(ref),
ref->_lineno);
errno = EPERM;
return NULL;
}
if(rhs_pspecs && ref_tc->lhs_params) {
/* Specialize the target */
ref_tc = asn1f_parameterization_fork(arg,
ref_tc, rhs_pspecs);
}
/*
* Check that the EXPORTS section of this module contains
* the symbol we care about, or it is EXPORTS ALL.
*/
if(asn1f_compatible_with_exports(arg, imports_from, identifier)) {
errno = EPERM;
return NULL;
}
return ref_tc;
}
my_namespace = asn1_namespace_new_from_module(imports_from, 1);
DEBUG("Lookup (%s) in %s for line %d", asn1f_printable_reference(ref),
asn1_namespace_string(my_namespace), ref->_lineno);
}
/*
* Not found in the current module.
* Search in our default standard module.
*/
{
/* Search inside standard module */
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 }
};
size_t namespace_switches = 0;
if(!imports_from) {
uioc_oid = asn1p_oid_construct(arcs,
sizeof(arcs)/sizeof(arcs[0]));
/*
* Search through all layers of the namespace.
*/
for(ssize_t ns_item = my_namespace->elements_count - 1; ns_item >= 0;
ns_item--) {
struct asn1_namespace_element_s *ns_el =
&my_namespace->elements[ns_item];
asn1p_expr_t *ref_tc; /* Referenced tc */
if(!mod->module_oid
|| asn1p_oid_compare(mod->module_oid, uioc_oid))
imports_from = asn1f_lookup_module(arg,
"ASN1C-UsefulInformationObjectClasses",
uioc_oid);
switch(ns_el->selector) {
case NAM_SYMBOL:
if(modulename) {
/*
* Trying to match a fully specified "Module.Symbol"
* against the "Symbol" parameter. Doesn't match.
*/
continue;
}
if(strcmp(ns_el->u.symbol.identifier, identifier) != 0) {
continue;
} else {
DEBUG("Lookup (%s) in %s for line %d => found as parameter",
asn1f_printable_reference(ref),
asn1_namespace_string(my_namespace), ref->_lineno);
DISPOSE_OF_MY_NAMESPACE();
return ns_el->u.symbol.resolution;
}
case NAM_SPACE:
/*
* 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) {
/* It is acceptable that we don't use input parameters */
if(rhs_pspecs && !ref_tc->lhs_params) {
WARNING(
"Parameterized type %s expected "
"for %s at line %d",
ref_tc->Identifier, asn1f_printable_reference(ref),
ref->_lineno);
}
if(!rhs_pspecs && ref_tc->lhs_params) {
FATAL(
"Type %s expects specialization "
"from %s at line %d",
ref_tc->Identifier, asn1f_printable_reference(ref),
ref->_lineno);
errno = EPERM;
return NULL;
}
if(rhs_pspecs && ref_tc->lhs_params) {
/* Specialize the target */
ref_tc =
asn1f_parameterization_fork(arg, ref_tc, rhs_pspecs);
}
asn1p_oid_free(uioc_oid);
if(imports_from) goto importing;
}
}
DISPOSE_OF_MY_NAMESPACE();
return ref_tc;
}
DEBUG("Module \"%s\" does not contain \"%s\" "
"mentioned at line %d: %s",
mod->ModuleName,
identifier,
ref->_lineno,
strerror(errno));
/*
if(!expr && !(arg->expr->_mark & TM_BROKEN)
&& !(imports_from->_tags & MT_STANDARD_MODULE)) {
arg->expr->_mark |= TM_BROKEN;
if(modulename) {
} else {
FATAL(
"Module %s referred in IMPORTS section "
"for %s of module %s does not contain "
"the requested symbol",
imports_from->ModuleName,
asn1f_printable_reference(ref), mod->ModuleName);
}
}
*/
if(asn1f_check_known_external_type(identifier) == 0) {
/* Search inside the IMPORTS section of the given module */
imports_from =
asn1f_lookup_in_imports(arg, ns_el->u.space.module, identifier);
if(imports_from) {
if(namespace_switches++ > 10 /* Arbitrary constant */) {
FATAL(
"Excessive circular referencing detected in namespace "
"%s for %s at "
"line %d",
asn1_namespace_string(arg->ns),
asn1f_printable_reference(ref), ref->_lineno);
errno = ETOOMANYREFS;
return NULL;
}
/* Switch namespace */
DISPOSE_OF_MY_NAMESPACE();
my_namespace = asn1_namespace_new_from_module(imports_from, 1);
DEBUG("Lookup (%s) in %s for line %d",
asn1f_printable_reference(ref),
asn1_namespace_string(my_namespace), ref->_lineno);
ns_item = my_namespace->elements_count;
continue;
} else if(errno != ESRCH) {
/*
* Return only if the name was not found.
* If module was not found or more serious error
* encountered, just return preserving the errno.
*/
DISPOSE_OF_MY_NAMESPACE();
return NULL;
}
if(modulename) {
FATAL(
"Module %s referred by %s in module %s "
"does not contain the requested symbol",
ns_el->u.space.module->ModuleName,
asn1f_printable_reference(ref), modulename);
break;
}
/* Search failed in the given namespace */
continue;
}
}
DEBUG(
"Namespace %s does not contain \"%s\" "
"mentioned at line %d: %s",
asn1_namespace_string(my_namespace), identifier, ref->_lineno,
strerror(errno));
DISPOSE_OF_MY_NAMESPACE();
if(asn1f_check_known_external_type(identifier) == 0) {
errno = EEXIST; /* Exists somewhere */
} else {
errno = ESRCH;
@ -368,9 +413,9 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspe
asn1p_expr_t *
asn1f_lookup_symbol(arg_t *arg,
asn1p_module_t *mod, asn1p_expr_t *rhs_pspecs, const asn1p_ref_t *ref) {
return asn1f_lookup_symbol_impl(arg, mod, rhs_pspecs, ref, 0);
asn1f_lookup_symbol(arg_t *arg, asn1p_expr_t *rhs_pspecs,
const asn1p_ref_t *ref) {
return asn1f_lookup_symbol_impl(arg, rhs_pspecs, ref, 0);
}
asn1p_expr_t *
@ -393,23 +438,30 @@ asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, enum ftt_what what) {
asn1p_ref_t *ref = 0;
asn1p_expr_t *tc;
switch(what) {
case FTT_TYPE:
case FTT_CONSTR_TYPE:
/* Expression may be a terminal type itself */
if(expr->expr_type != A1TC_REFERENCE)
return expr;
ref = expr->reference;
break;
case FTT_VALUE:
assert(expr->meta_type == AMT_VALUE);
assert(expr->value);
/* Expression may be a terminal type itself */
if(expr->value->type != ATV_REFERENCED)
return expr;
ref = expr->value->value.reference;
break;
}
if(arg->mod != expr->module) {
return WITH_MODULE(expr->module,
asn1f_find_terminal_thing(arg, expr, what));
}
switch(what) {
case FTT_TYPE:
case FTT_CONSTR_TYPE:
/* Expression may be a terminal type itself */
if(expr->expr_type != A1TC_REFERENCE) {
return expr;
}
ref = expr->reference;
break;
case FTT_VALUE:
assert(expr->meta_type == AMT_VALUE);
assert(expr->value);
/* Expression may be a terminal type itself */
if(expr->value->type != ATV_REFERENCED) {
return expr;
}
ref = expr->value->value.reference;
break;
}
DEBUG("%s(%s->%s) for line %d",
(what == FTT_VALUE)?"VALUE":"TYPE",
@ -424,11 +476,13 @@ asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, enum ftt_what what) {
if(what == FTT_VALUE) {
asn1p_expr_t *val_type_tc;
val_type_tc = asn1f_find_terminal_type(arg, expr);
if(val_type_tc
&& asn1f_look_value_in_type(arg, val_type_tc, expr))
return NULL;
if(val_type_tc
&& WITH_MODULE(val_type_tc->module,
asn1f_look_value_in_type(arg, val_type_tc, expr))) {
return expr;
}
if(expr->value->type != ATV_REFERENCED) {
return expr;
return expr;
}
assert(ref == expr->value->value.reference);
ref = expr->value->value.reference;
@ -437,41 +491,42 @@ asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, enum ftt_what what) {
/*
* Lookup inside the default module and its IMPORTS section.
*/
tc = asn1f_lookup_symbol(arg, expr->module, expr->rhs_pspecs, ref);
if(tc == NULL) {
tc = asn1f_lookup_symbol(arg, expr->rhs_pspecs, ref);
if(tc == NULL) {
/*
* Lookup inside the ref's module and its IMPORTS section.
*/
tc = asn1f_lookup_symbol(arg, ref->module, expr->rhs_pspecs, ref);
if(tc == NULL) {
tc = WITH_MODULE(ref->module,
asn1f_lookup_symbol(arg, expr->rhs_pspecs, ref));
if(tc == NULL) {
DEBUG("\tSymbol \"%s\" not found: %s",
asn1f_printable_reference(ref),
strerror(errno));
return NULL;
return NULL;
}
}
/*
* Recursive loops detection.
*/
if(tc->_mark & TM_RECURSION) {
DEBUG("Recursion loop detected for %s at line %d",
asn1f_printable_reference(ref), ref->_lineno);
errno = EPERM;
return NULL;
}
if(tc->_mark & TM_RECURSION) {
DEBUG("Recursion loop detected for %s at line %d",
asn1f_printable_reference(ref), ref->_lineno);
errno = EPERM;
return NULL;
}
tc->_type_referenced = 1;
tc->_type_referenced = 1;
if((what == FTT_CONSTR_TYPE) && (tc->constraints))
return tc;
if((what == FTT_CONSTR_TYPE) && (tc->constraints)) {
return tc;
}
tc->_mark |= TM_RECURSION;
WITH_MODULE(tc->module,
expr = asn1f_find_terminal_thing(arg, tc, what));
tc->_mark &= ~TM_RECURSION;
tc->_mark |= TM_RECURSION;
expr = WITH_MODULE(tc->module, asn1f_find_terminal_thing(arg, tc, what));
tc->_mark &= ~TM_RECURSION;
return expr;
return expr;
}

View File

@ -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.

View File

@ -1,4 +1,5 @@
#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;

View File

@ -1,6 +1,8 @@
#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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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 {

View File

@ -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);
}

View File

@ -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);

View File

@ -42,16 +42,16 @@ typedef enum asn1p_module_flags {
*/
typedef struct asn1p_module_s {
/*
* Human-readable module reference.
*/
char *ModuleName; /* Must be the first field */
/*
* Name of the source file.
*/
char *source_file_name;
/*
* Human-readable module reference.
*/
char *ModuleName;
/*
* Unique module identifier, OID.
*/

View File

@ -1,191 +0,0 @@
#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;
}

View File

@ -1,77 +0,0 @@
/*
* 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 */

View File

@ -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 */

View File

@ -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;