refactoring
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@216 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index eaac644..4948016 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -19,8 +19,6 @@
static int _fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no);
static int _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no);
-static int _expr_elements_count(arg_t *arg, asn1p_expr_t *expr);
-static int _emit_member_table(arg_t *arg, asn1p_expr_t *expr);
static int asn1c_lang_C_type_SEQUENCE_def(arg_t *arg);
static int asn1c_lang_C_type_SET_def(arg_t *arg);
@@ -28,9 +26,23 @@
static int asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of);
static int _print_tag(arg_t *arg, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag_p);
static int check_if_extensible(asn1p_expr_t *expr);
+static int expr_elements_count(arg_t *arg, asn1p_expr_t *expr);
+static int emit_member_table(arg_t *arg, asn1p_expr_t *expr);
static int emit_tags_vector(arg_t *arg, asn1p_expr_t *expr, int *tags_impl_skip, int choice_mode);
static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count);
+enum etd_cp {
+ ETD_CP_UNKNOWN = -2,
+ ETD_CP_EITHER = -1,
+ ETD_CP_PRIMITIVE = 0,
+ ETD_CP_CONSTRUCTED = 1,
+};
+enum etd_spec {
+ ETD_NO_SPECIFICS,
+ ETD_HAS_SPECIFICS
+};
+static int emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, int tags_count, int tags_impl_skip, int elements_count, enum etd_cp, enum etd_spec);
+
#define C99_MODE (!(arg->flags & A1C_NO_C99))
#define UNNAMED_UNIONS (arg->flags & A1C_UNNAMED_UNIONS)
@@ -193,7 +205,7 @@
continue;
}
elements++;
- _emit_member_table(arg, v);
+ emit_member_table(arg, v);
});
OUT("};\n");
@@ -220,32 +232,12 @@
(ext_stop<ext_start)?elements+1:ext_stop, ext_stop);
);
OUT("};\n");
- OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
- INDENTED(
- OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
- OUT("SEQUENCE_constraint,\n");
- OUT("SEQUENCE_decode_ber,\n");
- OUT("SEQUENCE_encode_der,\n");
- OUT("SEQUENCE_print,\n");
- OUT("SEQUENCE_free,\n");
- OUT("0,\t/* Use generic outmost tag fetcher */\n");
- if(tags_count) {
- OUT("asn1_DEF_%s_tags,\n", p);
- OUT("sizeof(asn1_DEF_%s_tags)\n", p);
- OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
- p, tags_count);
- } else {
- OUT("0,\t/* No explicit tags (pointer) */\n");
- OUT("0,\t/* No explicit tags (count) */\n");
- }
- OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
- OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
- OUT("asn1_MBR_%s,\n", p);
- OUT("%d,\t/* Elements count */\n", elements);
- OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
- );
- OUT("};\n");
- OUT("\n");
+
+ /*
+ * Emit asn1_DEF_xxx table.
+ */
+ emit_type_DEF(arg, expr, tags_count, tags_impl_skip, elements,
+ ETD_CP_CONSTRUCTED, ETD_HAS_SPECIFICS);
REDIR(OT_TYPE_DECLS);
@@ -360,7 +352,7 @@
continue;
}
elements++;
- _emit_member_table(arg, v);
+ emit_member_table(arg, v);
});
OUT("};\n");
@@ -417,32 +409,12 @@
OUT("(unsigned int *)asn1_DEF_%s_mmap\t/* Mandatory elements map */\n", p);
);
OUT("};\n");
- OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
- INDENTED(
- OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
- OUT("SET_constraint,\n");
- OUT("SET_decode_ber,\n");
- OUT("SET_encode_der,\n");
- OUT("SET_print,\n");
- OUT("SET_free,\n");
- OUT("0,\t/* Use generic outmost tag fetcher */\n");
- if(tags_count) {
- OUT("asn1_DEF_%s_tags,\n", p);
- OUT("sizeof(asn1_DEF_%s_tags)\n", p);
- OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
- p, tags_count);
- } else {
- OUT("0,\t/* No explicit tags (pointer) */\n");
- OUT("0,\t/* No explicit tags (count) */\n");
- }
- OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
- OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
- OUT("asn1_MBR_%s,\n", p);
- OUT("%d,\t/* Elements count */\n", elements);
- OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
- );
- OUT("};\n");
- OUT("\n");
+
+ /*
+ * Emit asn1_DEF_xxx table.
+ */
+ emit_type_DEF(arg, expr, tags_count, tags_impl_skip, elements,
+ ETD_CP_CONSTRUCTED, ETD_HAS_SPECIFICS);
REDIR(OT_TYPE_DECLS);
@@ -531,7 +503,7 @@
INDENTED(
v = TQ_FIRST(&(expr->members));
- _emit_member_table(arg, v);
+ emit_member_table(arg, v);
);
OUT("};\n");
@@ -547,40 +519,12 @@
OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
);
OUT("};\n");
- OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
- INDENTED(
- OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
- if(seq_of) {
- OUT("SEQUENCE_OF_constraint,\n");
- OUT("SEQUENCE_OF_decode_ber,\n");
- OUT("SEQUENCE_OF_encode_der,\n");
- OUT("SEQUENCE_OF_print,\n");
- OUT("SEQUENCE_OF_free,\n");
- } else {
- OUT("SET_OF_constraint,\n");
- OUT("SET_OF_decode_ber,\n");
- OUT("SET_OF_encode_der,\n");
- OUT("SET_OF_print,\n");
- OUT("SET_OF_free,\n");
- }
- OUT("0,\t/* Use generic outmost tag fetcher */\n");
- if(tags_count) {
- OUT("asn1_DEF_%s_tags,\n", p);
- OUT("sizeof(asn1_DEF_%s_tags)\n", p);
- OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
- p, tags_count);
- } else {
- OUT("0,\t/* No explicit tags (pointer) */\n");
- OUT("0,\t/* No explicit tags (count) */\n");
- }
- OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
- OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
- OUT("asn1_MBR_%s,\n", p);
- OUT("1,\t/* Single element */\n");
- OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
- );
- OUT("};\n");
- OUT("\n");
+
+ /*
+ * Emit asn1_DEF_xxx table.
+ */
+ emit_type_DEF(arg, expr, tags_count, tags_impl_skip, 1,
+ ETD_CP_CONSTRUCTED, ETD_HAS_SPECIFICS);
REDIR(OT_TYPE_DECLS);
@@ -684,7 +628,7 @@
continue;
}
elements++;
- _emit_member_table(arg, v);
+ emit_member_table(arg, v);
});
OUT("};\n");
@@ -716,32 +660,12 @@
check_if_extensible(expr));
);
OUT("};\n");
- OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
- INDENTED(
- OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
- OUT("CHOICE_constraint,\n");
- OUT("CHOICE_decode_ber,\n");
- OUT("CHOICE_encode_der,\n");
- OUT("CHOICE_print,\n");
- OUT("CHOICE_free,\n");
- OUT("CHOICE_outmost_tag,\n");
- if(tags_count) {
- OUT("asn1_DEF_%s_tags,\n", p);
- OUT("sizeof(asn1_DEF_%s_tags)\n", p);
- OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
- p, tags_count);
- } else {
- OUT("0,\t/* No explicit tags (pointer) */\n");
- OUT("0,\t/* No explicit tags (count) */\n");
- }
- OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
- OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
- OUT("asn1_MBR_%s,\n", p);
- OUT("%d,\t/* Elements count */\n", elements);
- OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
- );
- OUT("};\n");
- OUT("\n");
+
+ /*
+ * Emit asn1_DEF_xxx table.
+ */
+ emit_type_DEF(arg, expr, tags_count, tags_impl_skip, elements,
+ ETD_CP_CONSTRUCTED /*either?!*/, ETD_HAS_SPECIFICS);
REDIR(OT_TYPE_DECLS);
@@ -829,35 +753,8 @@
*/
tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
- p = MKID(expr->Identifier);
- OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
- INDENTED(
- 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);
- OUT("%s_print,\n", p);
- OUT("%s_free,\n", p);
- OUT("0,\t/* Use generic outmost tag fetcher */\n");
- if(tags_count) {
- OUT("asn1_DEF_%s_tags,\n", p);
- OUT("sizeof(asn1_DEF_%s_tags)\n", p);
- OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
- p, tags_count);
- } else {
- OUT("0,\t/* No explicit tags (pointer) */\n");
- OUT("0,\t/* No explicit tags (count) */\n");
- }
- OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
- OUT("-0,\t/* Unknown yet */\n");
- if(_expr_elements_count(arg, expr))
- OUT("0, 0,\t/* Defined elsewhere */\n");
- else
- OUT("0, 0,\t/* No members */\n");
- OUT("0\t/* No specifics */\n");
- );
- OUT("};\n");
- OUT("\n");
+ emit_type_DEF(arg, expr, tags_count, tags_impl_skip, 0,
+ ETD_CP_UNKNOWN, ETD_NO_SPECIFICS);
REDIR(OT_CODE);
@@ -1264,7 +1161,7 @@
}
static int
-_expr_elements_count(arg_t *arg, asn1p_expr_t *expr) {
+expr_elements_count(arg_t *arg, asn1p_expr_t *expr) {
asn1p_expr_t *topmost_parent;
asn1p_expr_t *v;
int elements = 0;
@@ -1284,7 +1181,7 @@
}
static int
-_emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
+emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
static int global_memb_unique;
int save_target;
arg_t tmp_arg;
@@ -1332,16 +1229,19 @@
|| arg->expr->expr_type == ASN_CONSTR_SET_OF)) {
OUT("(void *)&asn1_DEF_%s_member,\n",
MKID(arg->expr->Identifier));
+ } else if(expr->expr_type & ASN_CONSTR_MASK) {
+ OUT("(void *)&asn1_DEF_%s,\n",
+ MKID(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);
+ char *id = MKID(expr->Identifier);
if(!expr->Identifier)
- p = asn1c_type_name(arg, expr, TNF_SAFE);
- OUT("memb_%s_%d_constraint,\n", p,
+ id = asn1c_type_name(arg, expr, TNF_SAFE);
+ OUT("memb_%s_%d_constraint,\n", id,
++global_memb_unique);
} else {
OUT("0,\t/* Defer to actual type */\n");
@@ -1379,3 +1279,86 @@
return 0;
}
+
+static int
+emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, int tags_count, int tags_impl_skip, int elements_count, enum etd_cp cp, enum etd_spec spec) {
+ char *p;
+
+ p = MKID(expr->Identifier);
+ OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
+ INDENTED(
+ OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
+
+ if(expr->expr_type & ASN_CONSTR_MASK) {
+ p = asn1c_type_name(arg, arg->expr, TNF_SAFE);
+ }
+
+ OUT("%s_constraint,\n", p);
+ OUT("%s_decode_ber,\n", p);
+ OUT("%s_encode_der,\n", p);
+ OUT("%s_print,\n", p);
+ OUT("%s_free,\n", p);
+
+ p = MKID(expr->Identifier);
+
+ if(expr->expr_type == ASN_CONSTR_CHOICE) {
+ OUT("CHOICE_outmost_tag,\n");
+ } else {
+ OUT("0,\t/* Use generic outmost tag fetcher */\n");
+ }
+
+ if(tags_count) {
+ OUT("asn1_DEF_%s_tags,\n", p);
+ OUT("sizeof(asn1_DEF_%s_tags)\n", p);
+ OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
+ p, tags_count);
+ } else {
+ OUT("0,\t/* No explicit tags (pointer) */\n");
+ OUT("0,\t/* No explicit tags (count) */\n");
+ }
+
+ OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
+ switch(cp) {
+ case ETD_CP_UNKNOWN:
+ OUT("-0,\t/* Unknown yet */\n");
+ break;
+ case ETD_CP_EITHER:
+ OUT("-1,\t/* Primitive or constructed */\n");
+ case ETD_CP_PRIMITIVE:
+ OUT("0,\t/* Primitive */\n");
+ break;
+ case ETD_CP_CONSTRUCTED:
+ OUT("1,\t/* Whether CONSTRUCTED */\n");
+ break;
+ }
+
+ if(elements_count) {
+ OUT("asn1_MBR_%s,\n", p);
+ if(expr->expr_type == ASN_CONSTR_SEQUENCE_OF
+ || expr->expr_type == ASN_CONSTR_SET_OF) {
+ OUT("%d,\t/* Single element */\n",
+ elements_count);
+ assert(elements_count == 1);
+ } else {
+ OUT("%d,\t/* Elements count */\n",
+ elements_count);
+ }
+ } else {
+ //if(expr->meta_type == AMT_TYPEREF)
+ if(expr_elements_count(arg, expr))
+ OUT("0, 0,\t/* Defined elsewhere */\n");
+ else
+ OUT("0, 0,\t/* No members */\n");
+ }
+
+ switch(spec) {
+ case ETD_NO_SPECIFICS:
+ OUT("0\t/* No specifics */\n");
+ break;
+ case ETD_HAS_SPECIFICS:
+ OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
+ }
+ );
+ OUT("};\n");
+ OUT("\n");
+}