Commit 993eca85 authored by Lev Walkin's avatar Lev Walkin Committed by GitHub

Merge pull request #154 from...

Merge pull request #154 from brchiu/vlm_master_merge_pr99_mouse_2c8d366b_solve_prob_for_s1ap_nbap_dsrc

Merge PR99 and its fixes to support parsing Information Object and Information Object Set
parents 4021e4ba f1e29c8a
......@@ -9,7 +9,6 @@ script:
- autoreconf -iv
- ./configure --enable-Werror --enable-code-coverage
- make -j8
- make check
- make distcheck
after_success:
- test "x$CC" = "xgcc" -o "x$CC" = "xclang" && make code-coverage-capture && coveralls-lcov asn1c-*-coverage.info
......@@ -4,7 +4,19 @@ SUBDIRS = check-src
dist_check_SCRIPTS = check-assembly.sh
TESTS_ENVIRONMENT= CC="${CC}" CFLAGS="${TESTSUITE_CFLAGS} ${CFLAGS}" CXXFLAGS="${CXXFLAGS}" srcdir=${srcdir} abs_top_srcdir=${abs_top_srcdir} abs_top_builddir=${abs_top_builddir} ${srcdir}/check-assembly.sh
#Filter out the coverage options from CFLAGS as we don't need
#code coverage data for the tests executables
CFLAGS = $(filter-out $(CODE_COVERAGE_CFLAGS), @CFLAGS@)
TESTS_ENVIRONMENT= \
CC="${CC}" \
CFLAGS="${TESTSUITE_CFLAGS} ${CFLAGS}" \
CXXFLAGS="${CXXFLAGS}" \
LDFLAGS="${LDFLAGS}" \
srcdir=${srcdir} \
abs_top_srcdir=${abs_top_srcdir} \
abs_top_builddir=${abs_top_builddir} \
${srcdir}/check-assembly.sh
TESTS =
TESTS += check-src/check-03.-fwide-types.c
......
......@@ -53,28 +53,34 @@ asn_module=$(echo "${abs_top_srcdir}/tests/${testno}"-*.asn1)
cat > "$testdir/Makefile" <<EOM
# This file is autogenerated by ../$0
COMMON_FLAGS= -I.
CFLAGS = \${COMMON_FLAGS} ${CFLAGS:-} -g -O0 -I ${abs_top_srcdir}/skeletons
COMMON_FLAGS= -I. -I${abs_top_srcdir}/skeletons
CFLAGS = \${COMMON_FLAGS} ${CFLAGS:-} -g -O0
CPPFLAGS = -DSRCDIR=../${srcdir}
CXXFLAGS = \${COMMON_FLAGS} ${CXXFLAGS}
LDFLAGS = ${LDFLAGS:-}
CC ?= ${CC}
all: check-executable
check-executable: compiled-module *.c*
OBJS=\$(patsubst %.c,%.o,\$(wildcard *.c))
all: compiled-module
\$(MAKE) check-executable
check-executable: \$(OBJS)
@rm -f *.core
\$(CC) \$(CPPFLAGS) \$(CFLAGS) -o check-executable *.c* -L${abs_top_builddir}/skeletons/.libs -lasn1cskeletons -lm
\$(CC) \$(CPPFLAGS) \$(CFLAGS) \$(LDFLAGS) -o check-executable \$(OBJS) -L${abs_top_builddir}/skeletons/.libs -lasn1cskeletons -lm
# Compile the corresponding .asn1 spec.
compiled-module: ${asn_module} ${abs_top_builddir}/asn1c/asn1c
${abs_top_builddir}/asn1c/asn1c \\
-S /tmp/do/not/copy/skeletons \\
-S ${abs_top_srcdir}/skeletons \\
-Wdebug-compiler \\
${AFLAGS} ${asn_module}
rm -f converter-sample.c
@touch compiled-module
check-succeeded: check-executable
check-succeeded: compiled-module
\$(MAKE) check-executable
@rm -f check-succeeded
./check-executable
@touch check-succeeded
......
......@@ -2815,7 +2815,7 @@ asn1c_recurse(arg_t *arg, asn1p_expr_t *expr, int (*callback)(arg_t *arg, void *
int maxret = 0;
int ret;
if(expr->_mark) return 0;
if(expr->_mark & TM_RECURSION) return 0;
expr->_mark |= TM_RECURSION;
/* Invoke callback for every type going into recursion */
......
......@@ -51,9 +51,11 @@ asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
char *str;
char *nextstr;
char *first = 0;
char *second = 0;
ssize_t size;
ssize_t size = 0;
char *p;
char *prefix = NULL;
char *sptr[4], **psptr = &sptr[0];
int sptr_cnt = 0;
if(expr) {
/*
......@@ -61,16 +63,26 @@ asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
*/
if(expr->Identifier == NULL)
return "Member";
size = strlen(expr->Identifier);
/*
* Add MODULE name to resolve clash
*/
if(expr->_mark & TM_NAMECLASH) {
size += strlen(expr->module->ModuleName) + 2;
sptr[sptr_cnt++] = expr->module->ModuleName;
}
sptr[sptr_cnt++] = expr->Identifier;
size += strlen(expr->Identifier);
if(expr->spec_index != -1) {
static char buf[32];
second = buf;
size += 1 + snprintf(buf, sizeof buf, "%dP%d",
expr->_lineno, expr->spec_index);
sptr[sptr_cnt++] = (char *)&buf;
}
} else {
size = -1;
}
sptr[sptr_cnt++] = (char *)0;
va_start(ap, expr);
while((str = va_arg(ap, char *)))
......@@ -78,14 +90,16 @@ asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
va_end(ap);
if(size == -1) return NULL;
if(prefix)
size += 1 + strlen(prefix);
/*
* Make sure we have this amount of storage.
*/
if(storage_size <= size) {
free(storage);
if(storage) free(storage);
storage = malloc(size + 1);
if(storage) {
storage_size = size;
storage_size = size + 1;
} else {
storage_size = 0;
return NULL;
......@@ -97,20 +111,19 @@ asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
*/
va_start(ap, expr);
p = storage;
if(prefix) {
strcpy(storage, prefix);
p += strlen(prefix);
}
nextstr = "";
for(p = storage, str = 0; str || nextstr; str = nextstr) {
for(str = 0; str || nextstr; str = nextstr) {
int subst_made = 0;
nextstr = second ? second : va_arg(ap, char *);
nextstr = *(psptr) ? *(psptr++) : va_arg(ap, char *);
if(str == 0) {
if(expr) {
str = expr->Identifier;
first = str;
second = 0;
} else {
first = nextstr;
continue;
}
str = first = nextstr;
nextstr = *(psptr) ? *(psptr++) : va_arg(ap, char *);
if (!first) continue;
}
if(str[0] == ' ' && str[1] == '\0') {
......@@ -159,7 +172,7 @@ char *
asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
asn1p_expr_t *exprid = 0;
asn1p_expr_t *top_parent;
asn1p_expr_t *terminal;
asn1p_expr_t *terminal = 0;
int stdname = 0;
char *typename;
......@@ -208,7 +221,7 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
}
}
if(terminal && terminal->spec_index != -1) {
if(_format != TNF_RSAFE && terminal && terminal->spec_index != -1) {
exprid = terminal;
typename = 0;
}
......@@ -266,13 +279,14 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
switch(_format) {
case TNF_UNMODIFIED:
return asn1c_make_identifier(AMI_MASK_ONLY_SPACES,
0, exprid ? exprid->Identifier : typename, (char*)0);
return asn1c_make_identifier(AMI_MASK_ONLY_SPACES | AMI_NODELIMITER,
0, MODULE_NAME_OF(exprid), exprid ? exprid->Identifier : typename, (char*)0);
case TNF_INCLUDE:
return asn1c_make_identifier(
AMI_MASK_ONLY_SPACES | AMI_NODELIMITER,
0, ((!stdname || (arg->flags & A1C_INCLUDES_QUOTED))
? "\"" : "<"),
MODULE_NAME_OF(exprid),
exprid ? exprid->Identifier : typename,
((!stdname || (arg->flags & A1C_INCLUDES_QUOTED))
? ".h\"" : ".h>"), (char*)0);
......@@ -282,8 +296,8 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
return asn1c_make_identifier(0, exprid,
exprid?"t":typename, exprid?0:"t", (char*)0);
case TNF_RSAFE: /* Recursion-safe type */
return asn1c_make_identifier(AMI_CHECK_RESERVED, 0,
"struct", " ", typename, (char*)0);
return asn1c_make_identifier(AMI_CHECK_RESERVED | AMI_NODELIMITER, 0,
"struct", " ", MODULE_NAME_OF(exprid), typename, (char*)0);
}
assert(!"unreachable");
......
......@@ -7,9 +7,10 @@
* with safe ones.
*/
enum ami_flags_e {
AMI_MASK_ONLY_SPACES = 1, /* Mask only spaces, everything else's safe */
AMI_CHECK_RESERVED = 2, /* Check against reserved keywords */
AMI_NODELIMITER = 4, /* Do not put delimiter, just concatenate */
AMI_MASK_ONLY_SPACES = 1, /* Mask only spaces, everything else's safe */
AMI_CHECK_RESERVED = 2, /* Check against reserved keywords */
AMI_NODELIMITER = 4, /* Do not put delimiter, just concatenate */
AMI_USE_PREFIX = 8, /* Use Prefix when generating identifier */
};
char *asn1c_make_identifier(enum ami_flags_e, asn1p_expr_t *expr, ...);
......
......@@ -89,7 +89,7 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir,
if(asn1_lang_map[arg->expr->meta_type]
[arg->expr->expr_type].type_cb) {
safe_fprintf(mkf, "\t\\\n\t%s.c",
arg->expr->Identifier);
asn1c_make_identifier(AMI_MASK_ONLY_SPACES, arg->expr, 0));
}
}
}
......@@ -99,7 +99,7 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir,
if(asn1_lang_map[arg->expr->meta_type]
[arg->expr->expr_type].type_cb) {
safe_fprintf(mkf, "\t\\\n\t%s.h",
arg->expr->Identifier);
asn1c_make_identifier(AMI_MASK_ONLY_SPACES, arg->expr, 0));
}
}
}
......@@ -245,6 +245,7 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps, int optc, char **argv) {
char *header_id;
const char *c_retained = "";
const char *h_retained = "";
char *filename;
if(cs == NULL) {
safe_fprintf(stderr, "Cannot compile %s at line %d\n",
......@@ -252,8 +253,9 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps, int optc, char **argv) {
return -1;
}
fp_c = asn1c_open_file(expr->Identifier, ".c", &tmpname_c);
fp_h = asn1c_open_file(expr->Identifier, ".h", &tmpname_h);
filename = strdup(asn1c_make_identifier(AMI_MASK_ONLY_SPACES, expr, (char*)0));
fp_c = asn1c_open_file(filename, ".c", &tmpname_c);
fp_h = asn1c_open_file(filename, ".h", &tmpname_h);
if(fp_c == NULL || fp_h == NULL) {
if(fp_c) { unlink(tmpname_c); free(tmpname_c); fclose(fp_c); }
if(fp_h) { unlink(tmpname_h); free(tmpname_h); fclose(fp_h); }
......@@ -297,7 +299,7 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps, int optc, char **argv) {
safe_fprintf(fp_h, "\n#endif\t/* _%s_H_ */\n", header_id);
HINCLUDE("asn_internal.h");
safe_fprintf(fp_c, "#include \"%s.h\"\n\n", expr->Identifier);
safe_fprintf(fp_c, "#include \"%s.h\"\n\n", filename);
if(arg->flags & A1C_NO_INCLUDE_DEPS)
SAVE_STREAM(fp_c, OT_POST_INCLUDE, "", 1);
TQ_FOR(ot, &(cs->destination[OT_CTABLES].chunks), next)
......@@ -314,9 +316,9 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps, int optc, char **argv) {
fclose(fp_c);
fclose(fp_h);
name_buf = alloca(strlen(expr->Identifier) + 3);
name_buf = alloca(strlen(filename) + 3);
sprintf(name_buf, "%s.c", expr->Identifier);
sprintf(name_buf, "%s.c", filename);
if(identical_files(name_buf, tmpname_c)) {
c_retained = " (contents unchanged)";
unlink(tmpname_c);
......@@ -330,7 +332,7 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps, int optc, char **argv) {
}
}
sprintf(name_buf, "%s.h", expr->Identifier);
sprintf(name_buf, "%s.h", filename);
if(identical_files(name_buf, tmpname_h)) {
h_retained = " (contents unchanged)";
unlink(tmpname_h);
......@@ -348,9 +350,10 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps, int optc, char **argv) {
free(tmpname_h);
safe_fprintf(stderr, "Compiled %s.c%s\n",
expr->Identifier, c_retained);
filename, c_retained);
safe_fprintf(stderr, "Compiled %s.h%s\n",
expr->Identifier, h_retained);
filename, h_retained);
free(filename);
return 0;
}
......
......@@ -247,6 +247,7 @@ asn1f_fix_module__phase_2(arg_t *arg) {
int ret;
TQ_FOR(expr, &(arg->mod->members), next) {
arg->expr = expr;
/*
......@@ -499,6 +500,16 @@ asn1f_check_duplicate(arg_t *arg) {
arg->expr->Identifier))
continue;
/* resolve clash of Identifier in different modules */
int oid_exist = (tmparg.expr->module->module_oid && arg->expr->module->module_oid);
if ((!oid_exist && strcmp(tmparg.expr->module->ModuleName, arg->expr->module->ModuleName)) ||
(oid_exist && !asn1p_oid_compare(tmparg.expr->module->module_oid, arg->expr->module->module_oid))) {
tmparg.expr->_mark |= TM_NAMECLASH;
arg->expr->_mark |= TM_NAMECLASH;
continue;
}
diff_files = strcmp(arg->mod->source_file_name,
tmparg.mod->source_file_name) ? 1 : 0;
......
......@@ -4,6 +4,7 @@
static void _remove_extensions(arg_t *arg, asn1p_constraint_t *ct, int flast);
static int constraint_type_resolve(arg_t *arg, asn1p_constraint_t *ct);
static int constraint_object_resolve(arg_t *arg, asn1p_value_t *value);
static int constraint_value_resolve(arg_t *arg, asn1p_value_t **value, enum asn1p_constraint_type_e real_ctype);
int
......@@ -214,6 +215,10 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_type_e ety
&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.
......@@ -346,3 +351,24 @@ constraint_value_resolve(arg_t *arg,
return rvalue;
}
static int
constraint_object_resolve(arg_t *arg, asn1p_value_t *value) {
asn1p_expr_t tmp_expr = *arg->expr;
asn1p_expr_t *saved_expr = arg->expr;
tmp_expr.meta_type = AMT_VALUE;
tmp_expr.expr_type = A1TC_REFERENCE;
tmp_expr.value = value;
arg->expr = &tmp_expr;
if (asn1f_check_class_object(arg)) {
arg->expr = saved_expr;
FATAL("Parsing ObjectSet %s failed at %d", arg->expr->Identifier,
arg->expr->_lineno);
return -1;
}
arg->expr = saved_expr;
return 0;
}
......@@ -6,6 +6,48 @@ static int _asn1f_parse_class_object_data(arg_t *, asn1p_expr_t *eclass,
uint8_t *buf, const uint8_t *bend,
int optional_mode, uint8_t **newpos);
static int _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_ioc_cell_s *cell, uint8_t *buf, const uint8_t *bend);
static asn1p_wsyntx_chunk_t *asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, uint8_t *buf);
int
asn1f_check_class_object(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *eclass;
asn1p_ioc_row_t *row;
int ret;
if(expr->meta_type != AMT_VALUE
|| expr->expr_type != A1TC_REFERENCE
|| !expr->value
|| expr->value->type != ATV_UNPARSED)
return 0;
eclass = asn1f_find_terminal_type(arg, expr);
if(!eclass
|| eclass->meta_type != AMT_OBJECTCLASS
|| eclass->expr_type != A1TC_CLASSDEF) {
return 0;
}
if(!eclass->with_syntax) {
DEBUG("Can't process classes without %s just yet",
"WITH SYNTAX");
return 0;
}
row = asn1p_ioc_row_new(eclass);
assert(row);
ret = _asn1f_parse_class_object_data(arg, eclass, row,
eclass->with_syntax,
expr->value->value.string.buf + 1,
expr->value->value.string.buf
+ expr->value->value.string.size - 1,
0, 0);
asn1p_ioc_row_delete(row);
return ret;
}
int
asn1f_parse_class_object(arg_t *arg) {
......@@ -102,32 +144,25 @@ _asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
case WC_WHITESPACE: break; /* Ignore whitespace */
case WC_FIELD: {
struct asn1p_ioc_cell_s *cell;
int lbraces = 0;
uint8_t *p;
asn1p_wsyntx_chunk_t *next_literal;
uint8_t *buf_old = buf;
uint8_t *p = 0;
SKIPSPACES;
p = buf;
if(p < bend && *p == '{')
lbraces = 1, p++;
for(; p < bend; p++) {
if(lbraces) {
/* Search the terminating brace */
switch(*p) {
case '}': lbraces--; break;
case '{': lbraces++; break;
}
} else if(isspace(*p)) {
break;
next_literal = asn1f_next_literal_chunk(syntax, chunk, buf);
if(!next_literal) {
p += (bend - p);
} else {
p = (uint8_t *)strstr((char *)buf, (char *)next_literal->content.token);
if(!p) {
if (!optional_mode)
FATAL("Next literal \"%s\" not found !", next_literal->content.token);
if(newpos) *newpos = buf_old;
return -1;
}
}
if(lbraces) {
FATAL("Field reference %s found in class value definition for %s at line %d can not be satisfied by broken value \"%s\"",
chunk->content.token,
arg->expr->Identifier, arg->expr->_lineno, buf);
if(newpos) *newpos = buf;
return -1;
}
cell = asn1p_ioc_row_cell_fetch(row,
chunk->content.token);
if(cell == NULL) {
......@@ -167,10 +202,15 @@ _asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass,
static int
_asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_ioc_cell_s *cell,
uint8_t *buf, const uint8_t *bend) {
asn1p_expr_t *expr;
asn1p_ref_t *ref;
asn1p_expr_t *expr = (asn1p_expr_t *)NULL;
int idLength;
char *p;
int new_ref = 1;
asn1p_t *asn;
asn1p_module_t *mod;
asn1p_expr_t *type_expr = (asn1p_expr_t *)NULL;
int i, ret = 0, psize;
char *pp;
if((bend - buf) <= 0) {
FATAL("Assignment warning: empty string is being assigned into %s for %s at line %d",
......@@ -183,37 +223,89 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_i
assert(p);
memcpy(p, buf, bend - buf);
p[bend - buf] = '\0';
/* remove trailing space */
for (i = bend - buf - 1; (i > 0) && isspace(p[i]); i--)
p[i] = '\0';
if(!isalpha(*p)) {
/* This value 100 should be larger than following formatting string */
psize = bend - buf + 100;
pp = malloc(psize);
if(pp == NULL) {
free(p);
return -1;
}
if(isdigit(*p)) {
asn1c_integer_t value;
if(asn1p_atoi(p, &value)) {
FATAL("Value %s at line %d is too large for this compiler! Contact the asn1c author.\n", p, arg->expr->_lineno);
return -1;
}
expr = asn1p_expr_new(arg->expr->_lineno, arg->expr->module);
expr->Identifier = p;
expr->meta_type = AMT_VALUE;
expr->expr_type = ASN_BASIC_INTEGER;
expr->value = asn1p_value_fromint(value);
if(cell->field->expr_type == A1TC_CLASSFIELD_TFS) {
ret = snprintf(pp, psize,
"M DEFINITIONS ::=\nBEGIN\n"
"V ::= %s\n"
"END\n",
p
);
} else if(cell->field->expr_type == A1TC_CLASSFIELD_FTVFS) {
type_expr = TQ_FIRST(&(cell->field->members));
ret = snprintf(pp, psize,
"M DEFINITIONS ::=\nBEGIN\n"
"v %s ::= %s\n"
"END\n",
type_expr->reference ?
type_expr->reference->components[0].name :
_asn1p_expr_type2string(type_expr->expr_type),
p
);
} else {
WARNING("asn1c only be able to parse TypeFieldSpec and FixedTypeValueFieldSpec. Failed when parsing %s at line %d\n", p, arg->expr->_lineno);
free(p); /* bad idea freeing object you refer to later! */
free(pp);
return -1;
}
DEBUG("ASN.1 :\n\n%s\n", pp);
assert(ret < psize);
psize = ret;
asn = asn1p_parse_buffer(pp, psize, A1P_NOFLAGS);
free(pp);
if(asn == NULL) {
FATAL("Cannot parse Setting token %s "
"at line %d",
p,
arg->expr->_lineno
);
free(p);
return -1;
} else {
mod = TQ_FIRST(&(asn->modules));
assert(mod);
expr = TQ_REMOVE(&(mod->members), next);
assert(expr);
free(expr->Identifier);
expr->module = arg->expr->module;
expr->_lineno = arg->expr->_lineno;
if (expr->reference) {
expr->reference->module = arg->expr->module;
expr->reference->_lineno = arg->expr->_lineno;
expr->Identifier = strdup(expr->reference->components[expr->reference->comp_count - 1].name);
} else {
WARNING("asn1c is not yet able to parse arbitrary direct values; try converting %s at line %d to a reference.", p, arg->expr->_lineno);
free(p);
return 1;
expr->Identifier = p;
}
} else {
ref = asn1p_ref_new(arg->expr->_lineno);
asn1p_ref_add_component(ref, p, RLT_UNKNOWN);
assert(ref);
asn1p_delete(asn);
}
if(expr->reference &&
!asn1f_lookup_symbol(arg, arg->mod, expr->rhs_pspecs, expr->reference)) {
expr = asn1f_lookup_symbol(arg, arg->mod, arg->expr->rhs_pspecs, ref);
if(!expr) {
asn1p_ref_free(expr->reference);
new_ref = 0;
expr->reference = type_expr->reference;
if (asn1f_value_resolve(arg, expr, 0)) {
expr->reference = 0;
asn1p_expr_free(expr);
FATAL("Cannot find %s referenced by %s at line %d",
p, arg->expr->Identifier,
arg->expr->_lineno);
asn1p_ref_free(ref);
free(p);
free(p); /* freeing must happen *after* p was used in FATAL() */
return -1;
}
}
......@@ -222,11 +314,43 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_i
cell->field->Identifier, p, expr->Identifier);
cell->value = expr;
cell->new_ref = new_ref;
idLength = strlen(expr->Identifier);
if(row->max_identifier_length < idLength)
row->max_identifier_length = idLength;
if(expr->Identifier != p)
free(p);
return 0;
}
static asn1p_wsyntx_chunk_t *
asn1f_next_literal_chunk(asn1p_wsyntx_t *syntax, asn1p_wsyntx_chunk_t *chunk, uint8_t *buf)
{
asn1p_wsyntx_chunk_t *next_chunk;
next_chunk = TQ_NEXT(chunk, next);
do {
if(next_chunk == (struct asn1p_wsyntx_chunk_s *)0) {
if(!syntax->parent)
break;
next_chunk = TQ_NEXT(syntax->parent, next);
} else if(next_chunk->type == WC_LITERAL) {
if(strstr((char *)buf, (char *)next_chunk->content.token))
break;
if(!syntax->parent)
break;
next_chunk = TQ_NEXT(syntax->parent, next);
} else if(next_chunk->type == WC_WHITESPACE) {
next_chunk = TQ_NEXT(next_chunk, next);
} else if(next_chunk->type == WC_OPTIONALGROUP) {
syntax = next_chunk->content.syntax;
next_chunk = TQ_FIRST(((&next_chunk->content.syntax->chunks)));
} else
break;
} while (next_chunk);
return next_chunk;
}
......@@ -4,6 +4,7 @@
/*
* Parse class objects
*/
int asn1f_check_class_object(arg_t *arg);
int asn1f_parse_class_object(arg_t *arg);
#endif /* ASN1FIX_CLASS_WITH_SYNTAX_H */
......@@ -48,6 +48,7 @@ asn1f_fix_dereference_defaults(arg_t *arg) {
child->marker.default_value=expr->marker.default_value;
ret = asn1f_fix_dereference_defaults(&tmparg);
expr->marker.default_value = child->marker.default_value;
child->marker.default_value = 0; /* ULB: trying to ensure there isn't another pointer to the same value object */
if(ret == 0) return 0; /* Finished */
}
......
......@@ -18,6 +18,7 @@ asn1f_parameterization_fork(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *rhs_ps
resolver_arg_t rarg; /* resolver argument */
asn1p_expr_t *exc; /* expr clone */
asn1p_expr_t *rpc; /* rhs_pspecs clone */
asn1p_expr_t *m; /* expr members */
void *p;
struct asn1p_pspec_s *pspec;
int npspecs;
......@@ -69,6 +70,17 @@ asn1f_parameterization_fork(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *rhs_ps
pspec->my_clone = exc;
exc->spec_index = npspecs;
/* Passing arguments to members and type references */
exc->rhs_pspecs = expr->rhs_pspecs ? expr->rhs_pspecs : rhs_pspecs;
if(exc->rhs_pspecs)
exc->rhs_pspecs->ref_cnt++;
TQ_FOR(m, &exc->members, next) {
m->rhs_pspecs = exc->rhs_pspecs;
if (exc->rhs_pspecs)
exc->rhs_pspecs->ref_cnt++;
}
DEBUG("Forked new parameterization for %s", expr->Identifier);
/* Commit */
......@@ -86,7 +98,15 @@ compare_specializations(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
if(ac == bc) continue;
if(ac->meta_type != bc->meta_type) break;
if(ac->expr_type != bc->expr_type) break;
/* Maybe different object sets */
if(ac->constraints && bc->constraints
&& ac->constraints->containedSubtype
&& bc->constraints->containedSubtype
&& ac->constraints->containedSubtype->type == ATV_REFERENCED
&& bc->constraints->containedSubtype->type == ATV_REFERENCED
&& strcmp(ac->constraints->containedSubtype->value.reference->components[0].name,
bc->constraints->containedSubtype->value.reference->components[0].name))
break;
if(!ac->reference && !bc->reference)
continue;
......
......@@ -287,14 +287,13 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspe
break;
}
if(ref_tc) {
/* It is acceptable that we don't use input parameters */
if(rhs_pspecs && !ref_tc->lhs_params) {
FATAL("Parameterized type %s expected "
WARNING("Parameterized type %s expected "
"for %s at line %d",
ref_tc->Identifier,
asn1f_printable_reference(ref),
ref->_lineno);
errno = EPERM;
return NULL;
}
if(!rhs_pspecs && ref_tc->lhs_params) {
FATAL("Type %s expects specialization "
......@@ -320,30 +319,33 @@ asn1f_lookup_symbol_impl(arg_t *arg, asn1p_module_t *mod, asn1p_expr_t *rhs_pspe
*/
{
/* Search inside standard module */
static asn1p_oid_t *uioc_oid;
if(!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 }
};
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 }
};
if(!imports_from) {
uioc_oid = asn1p_oid_construct(arcs,
sizeof(arcs)/sizeof(arcs[0]));
}
if(!imports_from && (!mod->module_oid
|| asn1p_oid_compare(mod->module_oid, uioc_oid))) {
imports_from = asn1f_lookup_module(arg,
"ASN1C-UsefulInformationObjectClasses",
uioc_oid);
if(!mod->module_oid
|| asn1p_oid_compare(mod->module_oid, uioc_oid))
imports_from = asn1f_lookup_module(arg,
"ASN1C-UsefulInformationObjectClasses",
uioc_oid);
asn1p_oid_free(uioc_oid);
if(imports_from) goto importing;
}
}
......@@ -430,10 +432,16 @@ asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, enum ftt_what what) {
*/
tc = asn1f_lookup_symbol(arg, expr->module, expr->rhs_pspecs, ref);
if(tc == NULL) {
DEBUG("\tSymbol \"%s\" not found: %s",
asn1f_printable_reference(ref),
strerror(errno));
return 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) {
DEBUG("\tSymbol \"%s\" not found: %s",
asn1f_printable_reference(ref),
strerror(errno));
return NULL;
}
}
/*
......
......@@ -199,8 +199,28 @@ asn1f_look_value_in_type(arg_t *arg,
: "<not found>"
);
if(child_expr && child_expr->value) {
if(_asn1f_copy_value(arg, value_expr, child_expr))
if(child_expr) {
/* Maybe hasn't been fixed yet. */
if (!child_expr->value) {
asn1p_expr_t *saved_expr = arg->expr;
arg->expr = type_expr;
switch (type_expr->expr_type) {
case ASN_BASIC_INTEGER:
asn1f_fix_integer(arg);
break;
case ASN_BASIC_ENUMERATED:
asn1f_fix_enum(arg);
break;
default:
WARNING("Unexpected type %s for %s",
type_expr->expr_type,
type_expr->Identifier);
return -1;
}
arg->expr = saved_expr;
}
if(child_expr->value && _asn1f_copy_value(arg,
value_expr, child_expr))
return -1;
/* Fall through */
}
......
......@@ -42,8 +42,20 @@ asn1p_ioc_row_new(asn1p_expr_t *oclass) {
void
asn1p_ioc_row_delete(asn1p_ioc_row_t *row) {
int i;
if(row) {
if(row->column) {
for(i = 0; i < row->columns; i++) {
if(!row->column[i].new_ref && row->column[i].value) {
/*
* Field 'reference' comes from asn1fix_cws.c :
* TQ_FIRST(&cell->field->members)->reference
* so it should not be freed here.
*/
row->column[i].value->reference = NULL;
}
asn1p_expr_free(row->column[i].value);
}
free(row->column);
}
free(row);
......@@ -182,6 +194,7 @@ asn1p_wsyntx_chunk_fromsyntax(asn1p_wsyntx_t *syntax) {
if(wc) {
wc->type = WC_OPTIONALGROUP;
wc->content.syntax = syntax;
syntax->parent = wc;
}
return wc;
......
......@@ -12,6 +12,7 @@ typedef struct asn1p_ioc_row_s {
struct asn1p_ioc_cell_s {
struct asn1p_expr_s *field; /* may never be NULL */
struct asn1p_expr_s *value; /* may be left uninitialized */
int new_ref;
} *column;
int columns;
int max_identifier_length;
......@@ -48,6 +49,8 @@ typedef struct asn1p_wsyntx_chunk_s {
typedef struct asn1p_wsyntx_s {
struct asn1p_wsyntx_chunk_s *parent;
TQ_HEAD(struct asn1p_wsyntx_chunk_s) chunks;
} asn1p_wsyntx_t;
......
......@@ -7,12 +7,13 @@
#include "asn1parser.h"
asn1p_constraint_t *
asn1p_constraint_new(int _lineno) {
asn1p_constraint_new(int _lineno, asn1p_module_t *mod) {
asn1p_constraint_t *ct;
ct = calloc(1, sizeof(*ct));
if(ct) {
ct->_lineno = _lineno;
ct->module = mod;
}
return ct;
......@@ -58,7 +59,7 @@ asn1p_constraint_clone_with_resolver(asn1p_constraint_t *src,
} \
} } while(0)
clone = asn1p_constraint_new(src->_lineno);
clone = asn1p_constraint_new(src->_lineno, src->module);
if(clone) {
unsigned int i;
......@@ -117,6 +118,7 @@ asn1p_constraint_insert(asn1p_constraint_t *into, asn1p_constraint_t *what) {
return -1;
into->elements[into->el_count++] = what;
what->parent_ct = into;
return 0;
}
......@@ -134,6 +136,7 @@ asn1p_constraint_prepend(asn1p_constraint_t *before, asn1p_constraint_t *what) {
before->elements[0] = what;
before->el_count++;
what->parent_ct = before;
return 0;
}
......
......@@ -47,6 +47,8 @@ typedef struct asn1p_constraint_s {
ACPRES_OPTIONAL,
} presence;
struct asn1p_constraint_s *parent_ct; /* optional */
/*
* Separate types and values.
*/
......@@ -62,6 +64,7 @@ typedef struct asn1p_constraint_s {
unsigned int el_count; /* Number of meaningful elements */
unsigned int el_size; /* Size of the allocated (elements) */
struct asn1p_module_s *module; /* Defined in module */
int _lineno; /* Position in a source file */
} asn1p_constraint_t;
......@@ -71,7 +74,7 @@ char *asn1p_constraint_type2str(enum asn1p_constraint_type_e);
/*
* Constructors and a recursive destructor.
*/
asn1p_constraint_t *asn1p_constraint_new(int _lineno);
asn1p_constraint_t *asn1p_constraint_new(int _lineno, asn1p_module_t *mod);
void asn1p_constraint_free(asn1p_constraint_t *);
/*
......
......@@ -252,6 +252,7 @@ typedef struct asn1p_expr_s {
TM_RECURSION = (1<<0), /* Used to break recursion */
TM_BROKEN = (1<<1), /* A warning was already issued */
TM_PERFROMCT = (1<<2), /* PER FROM() constraint tables emitted */
TM_NAMECLASH = (1<<3) /* Name clash found, need to add module name to resolve */
} _mark;
/*
......@@ -285,4 +286,11 @@ void asn1p_expr_free(asn1p_expr_t *expr);
#define TAG2STRING_BUFFER_SIZE 64 /* buf should be at least this big */
char *asn1p_tag2string(struct asn1p_type_tag_s *tag, char *opt_buf);
#define MODULE_NAME_OF(expr) \
((!expr) ? "" : \
(!(expr->_mark & TM_NAMECLASH) ? "" : \
(!expr->module ? "" : expr->module->ModuleName))), \
((!expr) ? "" : \
(!(expr->_mark & TM_NAMECLASH) ? "" : "_"))
#endif /* ASN1_PARSER_EXPR_H */
......@@ -2707,7 +2707,7 @@ YY_RULE_SETUP
#line 210 "asn1p_l.l"
{
/* " \t\r\n" weren't allowed in ASN.1:1990. */
asn1p_lval.tv_str = asn1p_text;
asn1p_lval.tv_str = strdup(asn1p_text);
return TOK_hstring;
}
YY_BREAK
......
......@@ -10,12 +10,13 @@
* Construct a new empty reference.
*/
asn1p_ref_t *
asn1p_ref_new(int _lineno) {
asn1p_ref_new(int _lineno, asn1p_module_t *mod) {
asn1p_ref_t *ref;
ref = calloc(1, sizeof *ref);
if(ref) {
ref->_lineno = _lineno;
ref->module = mod;
}
return ref;
......@@ -118,7 +119,7 @@ asn1p_ref_t *
asn1p_ref_clone(asn1p_ref_t *ref) {
asn1p_ref_t *newref;
newref = asn1p_ref_new(ref->_lineno);
newref = asn1p_ref_new(ref->_lineno, ref->module);
if(newref) {
int i;
for(i = 0; i < ref->comp_count; i++) {
......
......@@ -37,13 +37,14 @@ typedef struct asn1p_ref_s {
int comp_count; /* Number of the components in the reference name. */
int 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_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);
......
......@@ -83,6 +83,7 @@ asn1p_value_frombits(uint8_t *bits, int size_in_bits, int do_copy) {
return NULL;
}
}
asn1p_value_t *
asn1p_value_frombuf(char *buffer, int size, int do_copy) {
if(buffer) {
......
This diff is collapsed.
This diff is collapsed.
......@@ -40,12 +40,12 @@ typedef intmax_t asn1c_integer_t;
#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 */
#include "asn1p_xports.h" /* IMports/EXports */
#include "asn1p_module.h" /* ASN.1 definition module */
#include "asn1p_class.h" /* CLASS-related stuff */
#include "asn1p_expr.h" /* A single ASN.1 expression */
......
......@@ -21,7 +21,7 @@
# Test also for gcov program and create GCOV variable that could be
# substituted.
#
# Note that all optimisation flags in CFLAGS must be disabled when code
# Note that all optimization flags in CFLAGS must be disabled when code
# coverage is enabled.
#
# Usage example:
......@@ -45,11 +45,6 @@
# (`make check`) and build a code coverage report detailing the code which
# was touched, then print the URI for the report.
#
# In earlier versions of this macro, CODE_COVERAGE_LDFLAGS was defined
# instead of CODE_COVERAGE_LIBS. They are both still defined, but use of
# CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is
# deprecated. They have the same value.
#
# This code was derived from Makefile.decl in GLib, originally licenced
# under LGPLv2.1+.
#
......@@ -75,7 +70,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#serial 21
#serial 23
AC_DEFUN([AX_CODE_COVERAGE],[
dnl Check for --enable-code-coverage
......@@ -123,12 +118,19 @@ AC_DEFUN([AX_CODE_COVERAGE],[
])
dnl Build the code coverage flags
dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility
CODE_COVERAGE_CPPFLAGS="-DNDEBUG"
CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
CODE_COVERAGE_LIBS="-lgcov"
CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS"
AX_CHECK_COMPILE_FLAG([-coverage], [
CODE_COVERAGE_CFLAGS="-O0 -g -coverage"
CODE_COVERAGE_CXXFLAGS="-O0 -g -coverage"
CODE_COVERAGE_LDFLAGS="-coverage"
CODE_COVERAGE_LIBS=""
], [
CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
CODE_COVERAGE_LIBS="-lgcov"
dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility
CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS"
])
AC_SUBST([CODE_COVERAGE_CPPFLAGS])
AC_SUBST([CODE_COVERAGE_CFLAGS])
......@@ -218,7 +220,7 @@ CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\
$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS)
CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
CODE_COVERAGE_IGNORE_PATTERN ?=
code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
......
SUBDIRS = . tests
CFLAGS = $(filter-out $(CODE_COVERAGE_CFLAGS), @CFLAGS@)
dist_pkgdata_DATA = \
${srcdir}/README \
......
......@@ -14,6 +14,9 @@ check_PROGRAMS = \
check-PER \
check-PER-INTEGER
#Filter out the coverage options from CFLAGS as we don't need
#code coverage data for the tests executables
CFLAGS = $(filter-out $(CODE_COVERAGE_CFLAGS), @CFLAGS@)
AM_CPPFLAGS = -I$(top_srcdir)/skeletons $(TESTSUITE_CFLAGS)
AM_LDFLAGS = $(top_builddir)/skeletons/libasn1cskeletons.la
LDADD = -lm
......
ModuleClassSample { iso org(3) dod(6) internet(1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 100 }
DEFINITIONS ::=
BEGIN
REF-ID ::= TYPE-IDENTIFIER
RefID ::= SEQUENCE {
field REF-ID.&id,
params REF-ID.&Type
}
SupportedReferences REF-ID ::= {...}
END
ModuleTestClass { iso org(3) dod(6) internet(1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 18 }
DEFINITIONS ::=
BEGIN
AlphaNumeric ::= IA5String (FROM("A".."Z" | "a".."z" | "0".."9"))
FUNCTION ::= CLASS {
&code INTEGER (0..MAX) UNIQUE,
&Alphabet IA5String DEFAULT {AlphaNumeric},
&ArgType ,
&SupportedArguments &ArgType OPTIONAL,
&ResultType DEFAULT NULL,
&result-if-error &ResultType DEFAULT NULL,
&associated-function FUNCTION OPTIONAL
}
operator-plus FUNCTION ::= {
&ArgType Pair,
&SupportedArguments { PosPair | NegPair }
&ResultType INTEGER,
&result-if-error 0,
&code 1
}
FunctionCodeType ::= FUNCTION.&code
END
ModuleAttributeClass { iso org(3) dod(6) internet(1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 98 }
DEFINITIONS ::=
BEGIN
ATTRIBUTE ::= CLASS {
&id RELATIVE-OID UNIQUE
} WITH SYNTAX { ID &id }
Attribute ::= SEQUENCE {
identifier ATTRIBUTE.&id ({Attributes}),
siAttributeValue IA5String
}
Attributes ATTRIBUTE ::= {Names}
Names ATTRIBUTE ::= {{ ID raf } | { ID rcf }}
rafService ATTRIBUTE ::= { ID raf }
rcfService ATTRIBUTE ::= { ID rcf }
raf RELATIVE-OID ::= {3 2 1}
rcf RELATIVE-OID ::= {3 2 2}
END
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