[esnacc-dev] [RFC] compiler/core: Support basic AUTOMATIC tags

Aaron Conole aconole at bytheb.org
Thu Jul 7 02:08:33 UTC 2016


This commit brings about a partially working AUTOMATIC tag facility to
the esnacc compiler.

With this change, RRC v7 is compilable to C / C++ code.  There has been no
testing, and no validation that the code is correct.  This is a preliminary
implementation for review and evaluation.

TODOS:
  - The non-recursive type lists probably need some adjusting
  - This needs to be tested, ideally against a working AUTOMATIC impl. like
    asn1c (or oss/nokalva if someone has a license).

Signed-off-by: Aaron Conole <aconole at bytheb.org>
---
 compiler/core/snacc-util.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++
 compiler/core/snacc-util.h | 10 ++++--
 compiler/core/y.tab.y      | 31 +++++++++++--------
 3 files changed, 102 insertions(+), 16 deletions(-)

diff --git a/compiler/core/snacc-util.c b/compiler/core/snacc-util.c
index 05c456e..be1c6b3 100644
--- a/compiler/core/snacc-util.c
+++ b/compiler/core/snacc-util.c
@@ -1625,5 +1625,82 @@ AppendSubtype PARAMS ((s, newSubtype, op),
 
 }  /* AppendSubtype */
 
+static int
+TagCodeFound(AsnList *tags, AsnInt startingTag)
+{
+    Tag *tag;
+    FOR_EACH_LIST_ELMT(tag, tags) {
+        if (tag->code == startingTag)
+            return 1;
+    }
+    return 0;
+}
+
+void
+AutomaticTagNamed PARAMS ((l),
+    NamedTypeList *l)
+{
+    AsnList *need_tags;
+    AsnList *used_tag;
+    NamedType *e;
+    void *lcurr;
+    AsnInt startingTag = 0;
 
+    if (l == NULL) {
+        fprintf(errFileG, "AutomaticTagNamed - NULL tag list.\n");
+    }
 
+    /* Two passes */
+    need_tags = AsnListNew(sizeof(void*));
+    used_tag = AsnListNew(sizeof(void*));
+    /* First pass, identify all the tags, and all the elements which
+       need tags */
+    lcurr = l->curr;
+    FOR_EACH_LIST_ELMT(e, l) {
+        if ((e->type->optional) && (e->type->tags == NULL)) {
+            APPEND(e, need_tags);
+        } else if (e->type->optional) {
+            Tag *t;
+            int f = 0;
+            void *curr = e->type->tags->curr;
+            FOR_EACH_LIST_ELMT(t, e->type->tags) {
+                if (t->tclass == CNTX) {
+                    f = 1;
+                }
+            }
+            if (!f) {
+                APPEND(e, need_tags);
+            }
+        } else if (e->type->tags != NULL) {
+            Tag *t;
+            void *curr = e->type->tags->curr;
+            FOR_EACH_LIST_ELMT(t, e->type->tags) {
+                if (t->tclass == CNTX) {
+                    fprintf(errFileG, "Code: %d", t->code);
+                    if (t->valueRef) {
+                        fprintf(errFileG, ", ValueRef!");
+                    }
+                    fprintf(errFileG, "\n");
+                    APPEND(t, used_tag);
+                    break;
+                }
+            }
+            e->type->tags->curr = curr;
+        }
+    }
+    FOR_EACH_LIST_ELMT(e, l) {
+        Tag *newTag = Malloc(sizeof(Tag));
+        newTag->tclass = CNTX;
+        newTag->form = CONS;
+        newTag->valueRef = NULL;
+        e->type->tags = AsnListNew(sizeof(void *));
+        APPEND(newTag, e->type->tags);
+        while(TagCodeFound(used_tag, startingTag))
+            startingTag++;
+        newTag->code = startingTag++;
+    }
+    l->curr = lcurr;
+    
+    AsnListFree(need_tags);
+    AsnListFree(used_tag);
+}
diff --git a/compiler/core/snacc-util.h b/compiler/core/snacc-util.h
index fbb98c8..bf812be 100644
--- a/compiler/core/snacc-util.h
+++ b/compiler/core/snacc-util.h
@@ -106,12 +106,16 @@
 
 BasicValue * GetLastNamedNumberValue PROTO ((NamedNumberList *valueList));
 
-void SetupType PROTO ((Type **t, enum BasicTypeChoiceId typeId, unsigned long lineNum));
+void SetupType PROTO ((Type **t, enum BasicTypeChoiceId typeId,
+                       unsigned long lineNum));
 
-void SetupMacroType PROTO ((Type **t, enum MacroTypeChoiceId macroTypeId, unsigned long lineNum));
+void SetupMacroType PROTO ((Type **t, enum MacroTypeChoiceId macroTypeId,
+                            unsigned long lineNum));
 
-void SetupValue PROTO ((Value **v, enum BasicValueChoiceId valId, unsigned long lineNum));
+void SetupValue PROTO ((Value **v, enum BasicValueChoiceId valId,
+                        unsigned long lineNum));
 
+void AutomaticTagNamed PROTO ((NamedTypeList *l));
 
 void AddPrivateImportElmt PROTO ((Module *m, char *name, char *refModuleName, long lineNo));
 
diff --git a/compiler/core/y.tab.y b/compiler/core/y.tab.y
index dfc48c0..8d1a39b 100644
--- a/compiler/core/y.tab.y
+++ b/compiler/core/y.tab.y
@@ -517,10 +517,7 @@ TagDefault:
   | IMPLICIT_SYM TAGS_SYM { $$ = IMPLICIT_TAGS; }
   | AUTOMATIC_SYM TAGS_SYM
     {
-        printf("Automatic Tags are not properly supported.\n");
-        printf("%s(%ld). Using Explicit tags.\n", modulePtrG->asn1SrcFileName,
-               myLineNoG);
-        $$ = EXPLICIT_TAGS;
+        $$ = AUTOMATIC_TAGS;
     }
   | empty
     {
@@ -1093,14 +1090,17 @@ SequenceType:
 
         SetupType (&$$, BASICTYPE_SEQUENCE, $1);
 
-        if (AsnListCount ((AsnList*)$2) != 0)
-        {
+        if (AsnListCount ((AsnList*)$2) != 0) {
             n = (NamedType*) FIRST_LIST_ELMT ((AsnList*)$2);
             n->type->lineNo = $1;
         }
 
         $$->basicType->a.sequence = $2;
 
+        if (modulePtrG->tagDefault == AUTOMATIC_TAGS) {
+            AutomaticTagNamed($$->basicType->a.sequence);
+        }
+
     }
   | SequenceOpening RIGHTBRACE_SYM
     {
@@ -1324,6 +1324,9 @@ SetType:
             n->type->lineNo = $1;
         }
         $$->basicType->a.set = $2;
+        if (modulePtrG->tagDefault == AUTOMATIC_TAGS) {
+            AutomaticTagNamed($$->basicType->a.set);
+        }
     }
   | SetOpening RIGHTBRACE_SYM
     {
@@ -1368,6 +1371,10 @@ ChoiceType:
             n = (NamedType*)FIRST_LIST_ELMT ($4);
             n->type->lineNo = $2;
         }
+
+        if (modulePtrG->tagDefault == AUTOMATIC_TAGS) {
+            AutomaticTagNamed($$->basicType->a.choice);
+        }
     }
 ;
 
@@ -1498,11 +1505,10 @@ TaggedType:
         Tag *tag;
 
         /* remove next tag if any  && IMPLICIT_TAGS */
- 	if ((modulePtrG->tagDefault == IMPLICIT_TAGS) &&
-            ($2->tags != NULL) && !LIST_EMPTY ($2->tags))
-        {
+        if ((modulePtrG->tagDefault == IMPLICIT_TAGS) &&
+            ($2->tags != NULL) && !LIST_EMPTY ($2->tags)) {
             tag = (Tag*)FIRST_LIST_ELMT ($2->tags); /* set curr to first */
-	    AsnListFirst ($2->tags); /* set curr to first elmt */
+            AsnListFirst ($2->tags); /* set curr to first elmt */
             AsnListRemove ($2->tags);      /* remove first elmt */
 
             /*
@@ -1523,10 +1529,9 @@ TaggedType:
         Tag *tag;
 
         /* remove next tag if any */
- 	if (($3->tags != NULL) && !LIST_EMPTY ($3->tags))
-        {
+        if (($3->tags != NULL) && !LIST_EMPTY ($3->tags)) {
             tag = (Tag*)FIRST_LIST_ELMT ($3->tags); /* set curr to first */
-	    AsnListFirst ($3->tags); /* set curr to first elmt */
+            AsnListFirst ($3->tags); /* set curr to first elmt */
             AsnListRemove ($3->tags);      /* remove first elmt */
 
             if (tag->tclass == UNIV)
-- 
2.5.5



More information about the dev mailing list