diff options
author | Lev Walkin <vlm@lionet.info> | 2004-09-10 15:49:15 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2004-09-10 15:49:15 +0000 |
commit | 906654e1d7553fdc4c4eec40c13d87e5b610cbb5 (patch) | |
tree | b0d6bd9c91b2251cc22e6071d5de1c9f59dc0bd4 /libasn1fix | |
parent | fa30126db68138de5e8e62af8b8d04e30f1cf2b8 (diff) |
refactored tagging support
Diffstat (limited to 'libasn1fix')
-rw-r--r-- | libasn1fix/asn1fix_internal.h | 2 | ||||
-rw-r--r-- | libasn1fix/asn1fix_tags.c | 38 | ||||
-rw-r--r-- | libasn1fix/asn1fix_tags.h | 1 |
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 |