COMPONENTS OF support
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@189 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/ChangeLog b/ChangeLog
index 6ddf842..6c7e05a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,12 @@
-0.9: 2004-Aug-20
+0.9: 2004-Aug-21
* Reworked subtype constraints handling, aiming at PER-applicability.
* BOOLEAN and NULL are now implemented in terms of native int type.
* Compiler now links in only necessary skeleton files.
* -t option added to asn1c to ease manual BER/CER/DER decoding.
+ * Added support COMPONENTS OF construct.
+ * Numerous parser fixes and enhancements.
0.8.19: 2004-Aug-18
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index f54d2d5..eaac644 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -40,11 +40,13 @@
OUT("ber_dec_ctx_t _ber_dec_ctx;\n"));
#define DEPENDENCIES do { \
- TQ_FOR(v, &(expr->members), next) { \
- if((!(v->expr_type & ASN_CONSTR_MASK) \
- && v->expr_type > ASN_CONSTR_MASK) \
- || v->meta_type == AMT_TYPEREF) { \
- GEN_INCLUDE(asn1c_type_name(arg, v, TNF_INCLUDE));\
+ asn1p_expr_t *__m; \
+ TQ_FOR(__m, &(expr->members), next) { \
+ if((!(__m->expr_type & ASN_CONSTR_MASK) \
+ && __m->expr_type > ASN_CONSTR_MASK) \
+ || __m->meta_type == AMT_TYPEREF) { \
+ GEN_INCLUDE(asn1c_type_name(arg, \
+ __m, TNF_INCLUDE)); \
} \
} \
if(expr->expr_type == ASN_CONSTR_SET_OF) \
@@ -124,8 +126,7 @@
DEPENDENCIES;
if(arg->embed) {
- OUT("struct %s {\n",
- MKID(expr->Identifier));
+ OUT("struct %s {\n", MKID(expr->Identifier));
} else {
OUT("typedef struct %s {\n",
MKID(expr->Identifier));
@@ -141,9 +142,9 @@
}
PCTX_DEF;
- OUT("} %s%s", expr->marker?"*":"",
- MKID(expr->Identifier));
- if(arg->embed) OUT(";\n"); else OUT("_t;\n");
+ OUT("} %s%s%s", expr->marker?"*":"",
+ expr->_anonymous_type ? "" : MKID(expr->Identifier),
+ arg->embed ? "" : "_t");
return asn1c_lang_C_type_SEQUENCE_def(arg);
}
@@ -221,7 +222,7 @@
OUT("};\n");
OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
INDENTED(
- OUT("\"%s\",\n", expr->Identifier);
+ OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
OUT("SEQUENCE_constraint,\n");
OUT("SEQUENCE_decode_ber,\n");
OUT("SEQUENCE_encode_der,\n");
@@ -252,34 +253,6 @@
}
int
-asn1c_lang_C_type_SEQUENCE_OF(arg_t *arg) {
- asn1p_expr_t *expr = arg->expr;
- asn1p_expr_t *v;
-
- DEPENDENCIES;
-
- if(arg->embed) {
- OUT("struct %s {\n", MKID(expr->Identifier));
- } else {
- OUT("typedef struct %s {\n", MKID(expr->Identifier));
- }
-
- TQ_FOR(v, &(expr->members), next) {
- INDENTED(OUT("A_SEQUENCE_OF(%s) list;\n",
- asn1c_type_name(arg, v, TNF_RSAFE)));
- }
-
- PCTX_DEF;
- OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
- if(arg->embed) OUT(";\n"); else OUT("_t;\n");
-
- /*
- * SET OF/SEQUENCE OF definition, SEQUENCE OF mode.
- */
- return asn1c_lang_C_type_SEx_OF_def(arg, 1);
-}
-
-int
asn1c_lang_C_type_SET(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
@@ -338,8 +311,9 @@
);
PCTX_DEF;
- OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
- if(arg->embed) OUT(";\n"); else OUT("_t;\n");
+ OUT("} %s%s%s", expr->marker?"*":"",
+ expr->_anonymous_type ? "" : MKID(expr->Identifier),
+ arg->embed ? "" : "_t");
return asn1c_lang_C_type_SET_def(arg);
}
@@ -445,7 +419,7 @@
OUT("};\n");
OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
INDENTED(
- OUT("\"%s\",\n", expr->Identifier);
+ OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
OUT("SET_constraint,\n");
OUT("SET_decode_ber,\n");
OUT("SET_encode_der,\n");
@@ -476,32 +450,56 @@
}
int
-asn1c_lang_C_type_SET_OF(arg_t *arg) {
+asn1c_lang_C_type_SEx_OF(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
- asn1p_expr_t *v;
+ asn1p_expr_t *memb;
DEPENDENCIES;
if(arg->embed) {
OUT("struct %s {\n", MKID(expr->Identifier));
} else {
- OUT("typedef struct %s {\n",
- MKID(expr->Identifier));
+ OUT("typedef struct %s {\n", MKID(expr->Identifier));
}
- TQ_FOR(v, &(expr->members), next) {
- INDENTED(OUT("A_SET_OF(%s) list;\n",
- asn1c_type_name(arg, v, TNF_RSAFE)));
+ memb = TQ_FIRST(&expr->members);
+
+ INDENT(+1);
+ OUT("A_%s_OF(",
+ (arg->expr->expr_type == ASN_CONSTR_SET_OF)
+ ? "SET" : "SEQUENCE");
+ if(memb->expr_type & ASN_CONSTR_MASK) {
+ arg_t tmp;
+ asn1p_expr_t tmp_memb;
+ arg->embed++;
+ tmp = *arg;
+ tmp.expr = &tmp_memb;
+ tmp_memb = *memb;
+ tmp_memb._anonymous_type = 1;
+ tmp_memb.Identifier = strdup(
+ asn1c_make_identifier(0,
+ expr->Identifier, "member", 0));
+ assert(tmp_memb.Identifier);
+ tmp.default_cb(&tmp);
+ free(tmp_memb.Identifier);
+ arg->embed--;
+ assert(arg->target->target == OT_TYPE_DECLS);
+ } else {
+ OUT("%s", asn1c_type_name(arg, memb, TNF_RSAFE));
}
+ OUT(") list;\n");
+ INDENT(-1);
PCTX_DEF;
- OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
- if(arg->embed) OUT(";\n"); else OUT("_t;\n");
+ OUT("} %s%s%s", expr->marker?"*":"",
+ expr->_anonymous_type ? "" : MKID(expr->Identifier),
+ arg->embed ? "" : "_t");
/*
- * SET OF/SEQUENCE OF definition, SET OF mode.
+ * SET OF/SEQUENCE OF definition
*/
- return asn1c_lang_C_type_SEx_OF_def(arg, 0);
+ return asn1c_lang_C_type_SEx_OF_def(arg,
+ (arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF));
}
static int
@@ -551,7 +549,7 @@
OUT("};\n");
OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
INDENTED(
- OUT("\"%s\",\n", expr->Identifier);
+ OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
if(seq_of) {
OUT("SEQUENCE_OF_constraint,\n");
OUT("SEQUENCE_OF_decode_ber,\n");
@@ -593,43 +591,42 @@
asn1c_lang_C_type_CHOICE(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
- char *p;
+ char *id;
DEPENDENCIES;
REDIR(OT_DEPS);
- p = MKID(expr->Identifier);
- OUT("typedef enum %s_PR {\n", p);
+ id = MKID(expr->Identifier);
+ OUT("typedef enum %s_PR {\n", id);
INDENTED(
- p = MKID(expr->Identifier);
OUT("%s_PR_NOTHING,\t"
- "/* No components present */\n", p);
+ "/* No components present */\n", id);
TQ_FOR(v, &(expr->members), next) {
if(v->expr_type == A1TC_EXTENSIBLE) {
OUT("/* Extensions may appear below */\n");
continue;
}
- p = MKID(expr->Identifier);
- OUT("%s_PR_", p);
- p = MKID(v->Identifier);
- OUT("%s,\n", p, p);
+ id = MKID(expr->Identifier);
+ OUT("%s_PR_", id);
+ id = MKID(v->Identifier);
+ OUT("%s,\n", id, id);
}
);
- p = MKID(expr->Identifier);
- OUT("} %s_PR;\n", p);
+ id = MKID(expr->Identifier);
+ OUT("} %s_PR;\n", id);
REDIR(OT_TYPE_DECLS);
if(arg->embed) {
- OUT("struct %s {\n", p);
+ OUT("struct %s {\n", id);
} else {
- OUT("typedef struct %s {\n", p);
+ OUT("typedef struct %s {\n", id);
}
INDENTED(
- OUT("%s_PR present;\n", p);
- OUT("union {\n", p);
+ OUT("%s_PR present;\n", id);
+ OUT("union {\n", id);
TQ_FOR(v, &(expr->members), next) {
EMBED(v);
}
@@ -638,8 +635,9 @@
);
PCTX_DEF;
- OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
- if(arg->embed) OUT(";\n"); else OUT("_t;\n");
+ OUT("} %s%s%s", expr->marker?"*":"",
+ expr->_anonymous_type ? "" : MKID(expr->Identifier),
+ arg->embed ? "" : "_t");
return asn1c_lang_C_type_CHOICE_def(arg);
}
@@ -720,7 +718,7 @@
OUT("};\n");
OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
INDENTED(
- OUT("\"%s\",\n", expr->Identifier);
+ OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
OUT("CHOICE_constraint,\n");
OUT("CHOICE_decode_ber,\n");
OUT("CHOICE_encode_der,\n");
@@ -756,17 +754,16 @@
ref = arg->expr->reference;
if(ref->components[ref->comp_count-1].name[0] == '&') {
- asn1p_module_t *mod;
asn1p_expr_t *extract;
arg_t tmp;
int ret;
- extract = asn1f_class_access_ex(arg->asn, arg->mod, arg->expr,
- ref, &mod);
+ extract = asn1f_class_access_ex(arg->asn, arg->mod,
+ arg->expr, ref);
if(extract == NULL)
return -1;
- extract = asn1p_expr_clone(extract);
+ extract = asn1p_expr_clone(extract, 0);
if(extract) {
if(extract->Identifier)
free(extract->Identifier);
@@ -781,7 +778,7 @@
tmp = *arg;
tmp.asn = arg->asn;
- tmp.mod = mod;
+ tmp.mod = extract->module;
tmp.expr = extract;
ret = arg->default_cb(&tmp);
@@ -808,10 +805,9 @@
OUT("%s\t", asn1c_type_name(arg, arg->expr,
expr->marker?TNF_RSAFE:TNF_CTYPE));
OUT("%s", expr->marker?"*":" ");
- OUT("%s;", MKID(expr->Identifier));
+ OUT("%s", MKID(expr->Identifier));
if(expr->marker) OUT("\t/* %s */",
(expr->marker==EM_OPTIONAL)?"OPTIONAL":"DEFAULT");
- OUT("\n");
REDIR(OT_TYPE_DECLS);
return 0;
@@ -824,8 +820,7 @@
OUT("typedef %s\t", asn1c_type_name(arg, arg->expr, TNF_CTYPE));
OUT("%s", expr->marker?"*":" ");
- OUT("%s_t;\n", MKID(expr->Identifier));
- OUT("\n");
+ OUT("%s_t", MKID(expr->Identifier));
REDIR(OT_STAT_DEFS);
@@ -837,7 +832,7 @@
p = MKID(expr->Identifier);
OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
INDENTED(
- OUT("\"%s\",\n", expr->Identifier);
+ OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
OUT("%s_constraint,\n", p);
OUT("%s_decode_ber,\n", p);
OUT("%s_encode_der,\n", p);
@@ -1167,9 +1162,10 @@
if(arg->expr->expr_type == A1TC_REFERENCE) {
arg_t tmp = *arg;
asn1p_expr_t *expr;
- expr = asn1f_lookup_symbol_ex(tmp.asn, &tmp.mod, tmp.expr,
+ expr = asn1f_lookup_symbol_ex(tmp.asn, tmp.mod, tmp.expr,
arg->expr->reference);
if(expr) {
+ tmp.mod = expr->module;
tmp.expr = expr;
return _add_tag2el_member(&tmp, tag2el, count, el_no);
} else {
@@ -1273,8 +1269,7 @@
asn1p_expr_t *v;
int elements = 0;
- topmost_parent = asn1f_find_terminal_type_ex(arg->asn,
- arg->mod, expr, 0);
+ topmost_parent = asn1f_find_terminal_type_ex(arg->asn, arg->mod, expr);
if(!topmost_parent) return 0;
if(!(topmost_parent->expr_type & ASN_CONSTR_MASK))
@@ -1290,6 +1285,7 @@
static int
_emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
+ static int global_memb_unique;
int save_target;
arg_t tmp_arg;
char *p;
@@ -1331,14 +1327,22 @@
OUT("0,\n");
}
if(C99_MODE) OUT(".type = ");
- OUT("(void *)&asn1_DEF_%s,\n",
- asn1c_type_name(arg, expr, TNF_SAFE));
+ if((expr->expr_type & ASN_CONSTR_MASK)
+ && (arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF
+ || arg->expr->expr_type == ASN_CONSTR_SET_OF)) {
+ OUT("(void *)&asn1_DEF_%s_member,\n",
+ MKID(arg->expr->Identifier));
+ } else {
+ OUT("(void *)&asn1_DEF_%s,\n",
+ asn1c_type_name(arg, expr, TNF_SAFE));
+ }
if(C99_MODE) OUT(".memb_constraints = ");
if(expr->constraints) {
p = MKID(expr->Identifier);
if(!expr->Identifier)
p = asn1c_type_name(arg, expr, TNF_SAFE);
- OUT("memb_%s_constraint,\n", p);
+ OUT("memb_%s_%d_constraint,\n", p,
+ ++global_memb_unique);
} else {
OUT("0,\t/* Defer to actual type */\n");
}
@@ -1358,7 +1362,7 @@
else
p = asn1c_type_name(arg, expr, TNF_SAFE);
OUT("static int\n");
- OUT("memb_%s_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,\n", p);
+ OUT("memb_%s_%d_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,\n", p, global_memb_unique);
INDENT(+1);
OUT("\t\tasn_app_consume_bytes_f *app_errlog, void *app_key) {\n");
tmp_arg = *arg;
diff --git a/libasn1compiler/asn1c_C.h b/libasn1compiler/asn1c_C.h
index 643d629..6349306 100644
--- a/libasn1compiler/asn1c_C.h
+++ b/libasn1compiler/asn1c_C.h
@@ -7,9 +7,8 @@
int asn1c_lang_C_type_EXTENSIBLE(arg_t *);
int asn1c_lang_C_type_SEQUENCE(arg_t *);
-int asn1c_lang_C_type_SEQUENCE_OF(arg_t *);
int asn1c_lang_C_type_SET(arg_t *);
-int asn1c_lang_C_type_SET_OF(arg_t *);
+int asn1c_lang_C_type_SEx_OF(arg_t *); /* SET OF or SEQUENCE OF */
int asn1c_lang_C_type_CHOICE(arg_t *);
int asn1c_lang_C_type_INTEGER(arg_t *);
@@ -24,11 +23,11 @@
* Constructed types
*/
{ AMT_TYPE, ASN_CONSTR_SEQUENCE, asn1c_lang_C_type_SEQUENCE },
- { AMT_TYPE, ASN_CONSTR_SEQUENCE_OF, asn1c_lang_C_type_SEQUENCE_OF },
- { AMT_TYPEREF, ASN_CONSTR_SEQUENCE_OF, asn1c_lang_C_type_SEQUENCE_OF },
+ { AMT_TYPE, ASN_CONSTR_SEQUENCE_OF, asn1c_lang_C_type_SEx_OF, },
+ { AMT_TYPEREF, ASN_CONSTR_SEQUENCE_OF, asn1c_lang_C_type_SEx_OF },
{ AMT_TYPE, ASN_CONSTR_SET, asn1c_lang_C_type_SET },
- { AMT_TYPE, ASN_CONSTR_SET_OF, asn1c_lang_C_type_SET_OF },
- { AMT_TYPEREF, ASN_CONSTR_SET_OF, asn1c_lang_C_type_SET_OF },
+ { AMT_TYPE, ASN_CONSTR_SET_OF, asn1c_lang_C_type_SEx_OF },
+ { AMT_TYPEREF, ASN_CONSTR_SET_OF, asn1c_lang_C_type_SEx_OF },
{ AMT_TYPE, ASN_CONSTR_CHOICE, asn1c_lang_C_type_CHOICE },
/*
* Basic types