aboutsummaryrefslogtreecommitdiffstats
path: root/libasn1compiler
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2004-06-06 07:20:17 +0000
committerLev Walkin <vlm@lionet.info>2004-06-06 07:20:17 +0000
commitfd171ef359bc5842686d2ae01dbbc01c8d0eb6f9 (patch)
tree962433fd5dcc413c58203bde2499b12b7f66d6ad /libasn1compiler
parent4c36e308bbc8e4132a67ecc184e56afed183cb58 (diff)
tag2member map required for SEQUENCE
Diffstat (limited to 'libasn1compiler')
-rw-r--r--libasn1compiler/asn1c_C.c195
1 files changed, 87 insertions, 108 deletions
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index 9fb4f23c..54bd847e 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -6,11 +6,21 @@
#include "asn1c_C.h"
#include <asn1fix_export.h> /* exportable stuff from libasn1fix */
+typedef struct tag2el_s {
+ struct asn1p_type_tag_s el_tag;
+ int el_no;
+ asn1p_expr_t *from_expr;
+} tag2el_t;
+
+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 asn1c_lang_C_type_SEQUENCE_def(arg_t *arg);
static int asn1c_lang_C_type_SET_def(arg_t *arg);
static int asn1c_lang_C_type_CHOICE_def(arg_t *arg);
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 emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count);
static int emit_constraint_checking_code(arg_t *arg);
static int emit_single_constraint_check(arg_t *arg, asn1p_constraint_t *ct, int mode);
static int emit_alphabet_tables(arg_t *arg, asn1p_constraint_t *ct, int *table);
@@ -23,15 +33,6 @@ static long compute_min_size(arg_t *arg);
static long compute_max_size(arg_t *arg);
static long compute_xxx_size(arg_t *arg, int _max);
-typedef struct tag2el_s {
- struct asn1p_type_tag_s el_tag;
- int el_no;
- asn1p_expr_t *from_expr;
-} tag2el_t;
-
-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);
-
#define C99_MODE (arg->flags & A1C_NO_C99)
#define UNNAMED_UNIONS (arg->flags & A1C_UNNAMED_UNIONS)
@@ -170,8 +171,18 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) {
int comp_mode = 0; /* {root,ext=1,root,root,...} */
int ext_start = -1;
int ext_stop = -1;
+ tag2el_t *tag2el = NULL;
+ int tag2el_count = 0;
char *p;
+ /*
+ * Fetch every inner tag from the tag to elements map.
+ */
+ if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1)) {
+ if(tag2el) free(tag2el);
+ return -1;
+ }
+
REDIR(OT_STAT_DEFS);
OUT("#include <constr_SEQUENCE.h>\n");
@@ -255,12 +266,19 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) {
);
OUT("};\n");
+ /*
+ * Tags to elements map.
+ */
+ emit_tag2member_map(arg, tag2el, tag2el_count);
+
OUT("static asn1_SEQUENCE_specifics_t asn1_DEF_%s_specs = {\n", p);
INDENTED(
OUT("sizeof(struct %s),\n", p);
OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
OUT("asn1_DEF_%s_elements,\n", p);
OUT("%d,\t/* Elements count */\n", elements);
+ OUT("asn1_DEF_%s_tag2el,\n", p);
+ OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
OUT("%d,\t/* Start extensions */\n",
ext_start);
OUT("%d\t/* Stop extensions */\n",
@@ -388,61 +406,6 @@ asn1c_lang_C_type_SET(arg_t *arg) {
return asn1c_lang_C_type_SET_def(arg);
}
-/*
- * Compare tags according to their canonical order.
- * Canonical order: [UNIVERSAL] [APPLICATION] [] [PRIVATE]
- * As you see, the class is encoded using the two lowest bits.
- */
-static arg_t *_ctc_arg;
-static int _canonical_tags_cmp(const void *ap, const void *bp)
- __attribute__ ((unused));
-static int
-_canonical_tags_cmp(const void *ap, const void *bp) {
- asn1p_expr_t *a, *b;
- struct asn1p_type_tag_s ta, tb;
-
- (const asn1p_expr_t *)a = *(const asn1p_expr_t * const *)ap;
- (const asn1p_expr_t *)b = *(const asn1p_expr_t * const *)bp;
-
- if(asn1f_fetch_tag(_ctc_arg->asn, _ctc_arg->mod, a, &ta)
- || asn1f_fetch_tag(_ctc_arg->asn, _ctc_arg->mod, b, &tb))
- return 0;
-
- if(ta.tag_class == tb.tag_class) {
- if(ta.tag_value == tb.tag_value)
- return 0;
- else if(ta.tag_value < tb.tag_value)
- return -1;
- else
- return 1;
- } else if(ta.tag_class < tb.tag_class) {
- return -1;
- } else {
- return 1;
- }
-}
-
-static int
-_tag2el_cmp(const void *ap, const void *bp) {
- const tag2el_t *a = ap;
- const tag2el_t *b = bp;
- const struct asn1p_type_tag_s *ta = &a->el_tag;
- const struct asn1p_type_tag_s *tb = &b->el_tag;
-
- if(ta->tag_class == tb->tag_class) {
- if(ta->tag_value == tb->tag_value)
- return 0;
- else if(ta->tag_value < tb->tag_value)
- return -1;
- else
- return 1;
- } else if(ta->tag_class < tb->tag_class) {
- return -1;
- } else {
- return 1;
- }
-}
-
static int
asn1c_lang_C_type_SET_def(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
@@ -461,12 +424,6 @@ asn1c_lang_C_type_SET_def(arg_t *arg) {
if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1)) {
if(tag2el) free(tag2el);
return -1;
- } else {
- /*
- * Sort the map according to canonical order of their tags.
- */
- _ctc_arg = arg;
- qsort(tag2el, tag2el_count, sizeof(*tag2el), _tag2el_cmp);
}
@@ -550,22 +507,7 @@ asn1c_lang_C_type_SET_def(arg_t *arg) {
/*
* Tags to elements map.
*/
- p = MKID(expr->Identifier);
- OUT("static asn1_SET_tag2member_t asn1_DEF_%s_tag2el[] = {\n", p);
- if(tag2el_count) {
- int i;
- for(i = 0; i < tag2el_count; i++) {
- OUT(" { ");
- _print_tag(arg, expr, &tag2el[i].el_tag);
- OUT(", ");
- OUT("%d ", tag2el[i].el_no);
- OUT("}, /* %s at %d */\n",
- tag2el[i].from_expr->Identifier,
- tag2el[i].from_expr->_lineno
- );
- }
- }
- OUT("};\n");
+ emit_tag2member_map(arg, tag2el, tag2el_count);
/*
* Emit a map of mandatory elements.
@@ -836,12 +778,6 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1)) {
if(tag2el) free(tag2el);
return -1;
- } else {
- /*
- * Sort the map according to canonical order of their tags.
- */
- _ctc_arg = arg;
- qsort(tag2el, tag2el_count, sizeof(*tag2el), _tag2el_cmp);
}
REDIR(OT_STAT_DEFS);
@@ -920,22 +856,7 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
/*
* Tags to elements map.
*/
- p = MKID(expr->Identifier);
- OUT("static asn1_CHOICE_tag2member_t asn1_DEF_%s_tag2el[] = {\n", p);
- if(tag2el_count) {
- int i;
- for(i = 0; i < tag2el_count; i++) {
- OUT(" { ");
- _print_tag(arg, expr, &tag2el[i].el_tag);
- OUT(", ");
- OUT("%d ", tag2el[i].el_no);
- OUT("}, /* %s at %d */\n",
- tag2el[i].from_expr->Identifier,
- tag2el[i].from_expr->_lineno
- );
- }
- }
- OUT("};\n");
+ emit_tag2member_map(arg, tag2el, tag2el_count);
OUT("static asn1_CHOICE_specifics_t asn1_DEF_%s_specs = {\n", p);
INDENTED(
@@ -1252,6 +1173,35 @@ _print_tag(arg_t *arg, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag_p) {
return 0;
}
+
+static int
+_tag2el_cmp(const void *ap, const void *bp) {
+ const tag2el_t *a = ap;
+ const tag2el_t *b = bp;
+ const struct asn1p_type_tag_s *ta = &a->el_tag;
+ const struct asn1p_type_tag_s *tb = &b->el_tag;
+
+ if(ta->tag_class == tb->tag_class) {
+ if(ta->tag_value == tb->tag_value) {
+ /*
+ * Sort by their respective positions.
+ */
+ if(a->el_no < b->el_no)
+ return -1;
+ else if(a->el_no > b->el_no)
+ return 1;
+ return 0;
+ } else if(ta->tag_value < tb->tag_value)
+ return -1;
+ else
+ return 1;
+ } else if(ta->tag_class < tb->tag_class) {
+ return -1;
+ } else {
+ return 1;
+ }
+}
+
/*
* For constructed types, number of external tags may be greater than
* number of elements in the type because of CHOICE type.
@@ -1285,6 +1235,11 @@ _fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no) {
element++;
}
+ /*
+ * Sort the map according to canonical order of their tags.
+ */
+ qsort(*tag2el, *count, sizeof(**tag2el), _tag2el_cmp);
+
return 0;
}
@@ -1349,6 +1304,30 @@ _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no) {
}
static int
+emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count) {
+ asn1p_expr_t *expr = arg->expr;
+
+ OUT("static asn1_TYPE_tag2member_t asn1_DEF_%s_tag2el[] = {\n",
+ MKID(expr->Identifier));
+ if(tag2el_count) {
+ int i;
+ for(i = 0; i < tag2el_count; i++) {
+ OUT(" { ");
+ _print_tag(arg, expr, &tag2el[i].el_tag);
+ OUT(", ");
+ OUT("%d ", tag2el[i].el_no);
+ OUT("}, /* %s at %d */\n",
+ tag2el[i].from_expr->Identifier,
+ tag2el[i].from_expr->_lineno
+ );
+ }
+ }
+ OUT("};\n");
+
+ return 0;;
+}
+
+static int
emit_constraint_checking_code(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_type_e etype;