aboutsummaryrefslogtreecommitdiffstats
path: root/libasn1fix/asn1fix_tags.c
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2004-06-03 03:38:44 +0000
committerLev Walkin <vlm@lionet.info>2004-06-03 03:38:44 +0000
commitf15320bf6b50a0c02636405561ac8323ae901abd (patch)
tree33461d45122896c6dde35f82f5c7d19b62004a6b /libasn1fix/asn1fix_tags.c
parent746cb60bbccf47019563665f4aec4b6c462c4163 (diff)
Initial revision
Diffstat (limited to 'libasn1fix/asn1fix_tags.c')
-rw-r--r--libasn1fix/asn1fix_tags.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/libasn1fix/asn1fix_tags.c b/libasn1fix/asn1fix_tags.c
new file mode 100644
index 00000000..ed8c19f2
--- /dev/null
+++ b/libasn1fix/asn1fix_tags.c
@@ -0,0 +1,47 @@
+#include "asn1fix_internal.h"
+
+int
+asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag) {
+ int ret;
+
+ if(expr->tag.tag_class != TC_NOCLASS) {
+ *tag = expr->tag;
+ return 0;
+ }
+
+ if(expr->expr_type == A1TC_EXTENSIBLE) {
+ memset(tag, 0, sizeof(*tag));
+ tag->tag_class = -1;
+ return 0;
+ }
+
+ if(expr->meta_type == AMT_TYPE) {
+ memset(tag, 0, sizeof(*tag));
+ tag->tag_class = TC_UNIVERSAL;
+ tag->tag_value = expr_type2uclass_value[expr->expr_type];
+ return (tag->tag_value == 0) ? -1 : 0;
+ }
+
+ if(expr->meta_type == AMT_TYPEREF) {
+ arg_t arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.asn = asn;
+ arg.mod = mod;
+ arg.expr = expr;
+
+ expr = asn1f_lookup_symbol(&arg, expr->reference, &mod);
+ if(expr == NULL) return -1;
+
+ if(expr->_mark & TM_RECURSION)
+ return -1;
+
+ expr->_mark |= TM_RECURSION;
+ ret = asn1f_fetch_tag(asn, mod, expr, tag);
+ expr->_mark &= ~TM_RECURSION;
+ return ret;
+ }
+
+ return -1;
+}
+