aboutsummaryrefslogtreecommitdiffstats
path: root/libasn1fix
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2004-09-10 15:49:15 +0000
committerLev Walkin <vlm@lionet.info>2004-09-10 15:49:15 +0000
commit906654e1d7553fdc4c4eec40c13d87e5b610cbb5 (patch)
treeb0d6bd9c91b2251cc22e6071d5de1c9f59dc0bd4 /libasn1fix
parentfa30126db68138de5e8e62af8b8d04e30f1cf2b8 (diff)
refactored tagging support
Diffstat (limited to 'libasn1fix')
-rw-r--r--libasn1fix/asn1fix_internal.h2
-rw-r--r--libasn1fix/asn1fix_tags.c38
-rw-r--r--libasn1fix/asn1fix_tags.h1
3 files changed, 34 insertions, 7 deletions
diff --git a/libasn1fix/asn1fix_internal.h b/libasn1fix/asn1fix_internal.h
index c3739633..040750df 100644
--- a/libasn1fix/asn1fix_internal.h
+++ b/libasn1fix/asn1fix_internal.h
@@ -89,7 +89,7 @@ typedef struct arg_s {
if(code < 0) { \
if(arg->debug) \
arg->debug(code, fmt, ##args); \
- } else { \
+ } else if(arg->eh) { \
arg->eh(code, fmt " in %s", ##args, \
arg->mod->source_file_name); \
} \
diff --git a/libasn1fix/asn1fix_tags.c b/libasn1fix/asn1fix_tags.c
index 20066e6d..6d887980 100644
--- a/libasn1fix/asn1fix_tags.c
+++ b/libasn1fix/asn1fix_tags.c
@@ -2,14 +2,20 @@
#define ADD_TAG(skip, newtag) do { \
void *__p; \
- if(skip) { skip--; break; } \
+ if(skip) { \
+ if(newtag.tag_mode != TM_IMPLICIT) \
+ skip--; \
+ break; \
+ } else { \
+ if(newtag.tag_mode == TM_IMPLICIT) \
+ skip++; \
+ } \
__p = realloc((*tags), \
sizeof(struct asn1p_type_tag_s) * (count + 1)); \
if(!__p) return -1; \
*tags = __p; \
(*tags)[count++] = newtag; \
if((flags & AFT_FETCH_OUTMOST)) return count; \
- if(newtag.tag_mode == TM_IMPLICIT) skip++; \
} while(0)
static int
@@ -46,11 +52,33 @@ asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int
}
if(expr->meta_type == AMT_TYPEREF) {
- expr = asn1f_lookup_symbol(arg, expr->module, expr->reference);
- if(expr == NULL) return -1;
+ asn1p_expr_t *nexpr;
+ nexpr = asn1f_lookup_symbol(arg, expr->module, expr->reference);
+ if(nexpr == NULL) {
+ if(errno != EEXIST) /* -fknown-extern-type */
+ return -1;
+ if(!count)
+ return 0; /* OK */
+ if((*tags)[count-1].tag_mode == TM_IMPLICIT) {
+ WARNING("Tagging mode for %s "
+ "is IMPLICIT, assuming %s "
+ "has exactly one tag",
+ expr->Identifier,
+ asn1f_printable_reference(expr->reference)
+ );
+ return count;
+ }
+ FATAL("Tagging mode %s -> %s "
+ "dangerously incompatible",
+ expr->Identifier,
+ asn1f_printable_reference(expr->reference)
+ );
+ return -1;
+ } else {
+ arg->expr = nexpr;
+ }
if(expr->_mark & TM_RECURSION)
return -1;
- arg->expr = expr;
expr->_mark |= TM_RECURSION;
count = asn1f_fetch_tags_impl(arg, tags, count, skip, flags);
expr->_mark &= ~TM_RECURSION;
diff --git a/libasn1fix/asn1fix_tags.h b/libasn1fix/asn1fix_tags.h
index 8dd622b7..394c3e84 100644
--- a/libasn1fix/asn1fix_tags.h
+++ b/libasn1fix/asn1fix_tags.h
@@ -6,7 +6,6 @@ enum asn1f_aft_flags_e {
AFT_FETCH_OUTMOST = 0x02, /* Fetch only outmost tag */
};
-
/*
* Allocate and return an array of tags for the given type.
* Type1 ::= [2] EXPLICIT Type2