[esnacc-dev] [RFC 2/2] ENOTREADY: Python backend
Aaron Conole
aconole at bytheb.org
Tue Jan 10 22:15:29 UTC 2017
Here be dragons...
Signed-off-by: Aaron Conole <aconole at bytheb.org>
---
compiler/automake.mk | 5 +
compiler/back-ends/py-gen/gen-any.c | 300 ++++
compiler/back-ends/py-gen/gen-code.c | 2722 ++++++++++++++++++++++++++++++++++
compiler/back-ends/py-gen/rules.c | 569 +++++++
compiler/back-ends/py-gen/rules.h | 36 +
compiler/back-ends/py-gen/types.c | 529 +++++++
compiler/back-ends/str-util.c | 48 +-
compiler/back-ends/str-util.h | 1 +
compiler/core/define.c | 3 +-
compiler/core/snacc.c | 171 ++-
10 files changed, 4341 insertions(+), 43 deletions(-)
create mode 100644 compiler/back-ends/py-gen/gen-any.c
create mode 100644 compiler/back-ends/py-gen/gen-code.c
create mode 100644 compiler/back-ends/py-gen/rules.c
create mode 100644 compiler/back-ends/py-gen/rules.h
create mode 100644 compiler/back-ends/py-gen/types.c
diff --git a/compiler/automake.mk b/compiler/automake.mk
index 7a1f910..b46372f 100644
--- a/compiler/automake.mk
+++ b/compiler/automake.mk
@@ -70,6 +70,11 @@ compiler_esnacc_SOURCES = \
compiler/back-ends/idl-gen/gen-code.c \
compiler/back-ends/idl-gen/types.c \
compiler/back-ends/idl-gen/gen-vals.c \
+ compiler/back-ends/py-gen/gen-any.c \
+ compiler/back-ends/py-gen/gen-code.c \
+ compiler/back-ends/py-gen/rules.c \
+ compiler/back-ends/py-gen/rules.h \
+ compiler/back-ends/py-gen/types.c \
policy.h \
version.h
diff --git a/compiler/back-ends/py-gen/gen-any.c b/compiler/back-ends/py-gen/gen-any.c
new file mode 100644
index 0000000..5d1ce8e
--- /dev/null
+++ b/compiler/back-ends/py-gen/gen-any.c
@@ -0,0 +1,300 @@
+/*
+ * compiler/back-ends/py-gen/gen-any.c - routines for printing python
+ * anytype code
+ *
+ * assumes that the type tree has already been run through the
+ * python type generator (py-gen/types.c).
+ *
+ * Copyright (C) 2016 Aaron Conole
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <string.h>
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "str-util.h"
+#include "rules.h"
+#include "snacc-util.h"
+
+#ifdef WIN32
+#pragma warning( disable : 4100 ) /* IGNORE unreferenced formal parameter */
+#endif
+
+
+void PrintPyAnyEnum PROTO ((FILE *hdr, Module *m));
+void PrintPyAnyHashInitRoutine PROTO ((FILE *src, FILE *hdr,
+ Module *m, PyRules *r));
+void PrintPyOidValue PROTO ((FILE *f, PyRules *r, AsnOid *oid, int parenOrQuote));
+
+static TypeDef* GetTypeDef PROTO ((Type *t));
+
+
+extern int anyEnumValG;
+
+
+void
+PrintPyAnyCode PARAMS ((src, hdr, r, mods, m),
+ FILE *src _AND_
+ FILE *hdr _AND_
+ PyRules *r _AND_
+ ModuleList *mods _AND_
+ Module *m)
+{
+
+ if (!m->hasAnys)
+ return;
+
+ PrintPyAnyEnum(hdr, m);
+ PrintPyAnyHashInitRoutine(src, hdr, m, r);
+
+} /* PrintAnyCode */
+
+
+
+void
+PrintPyAnyEnum PARAMS ((hdr, m),
+ FILE *hdr _AND_
+ Module *m)
+{
+ int firstPrinted = TRUE;
+ char *modName;
+ ValueDef *vd;
+ Type *t;
+ char anyId[512];
+
+ modName = Asn1TypeName2CTypeName (m->modId->name);
+
+ fprintf (hdr,"typedef enum %sAnyId\n", modName);
+ fprintf (hdr,"{\n");
+
+ FOR_EACH_LIST_ELMT (vd, m->valueDefs) {
+ if (vd->value != NULL) {
+ t = vd->value->type;
+ if ((GetBuiltinType(t) == BASICTYPE_MACROTYPE) &&
+ (t->basicType->a.macroType->choiceId ==
+ MACROTYPE_SNMPOBJECTTYPE)) {
+ strcpy(anyId, vd->definedName);
+ Dash2Underscore(anyId, strlen (anyId));
+ strcat(anyId, "_ANY_ID");
+
+ if (!firstPrinted)
+ fprintf (hdr,",\n");
+ fprintf (hdr," %s = %d", anyId, anyEnumValG);
+ anyEnumValG++;
+ firstPrinted = FALSE;
+ }
+ }
+ }
+
+ if (firstPrinted)
+ fprintf (hdr,"/* NO INTEGER or OBJECT IDENTIFIER to ANY type relationships were defined (via MACROs or other mechanism) */\n ??? \n");
+
+ fprintf (hdr,"\n} %sAnyId;\n\n\n", modName);
+ Free (modName);
+
+} /* PrintAnyEnum */
+
+
+void
+PrintPyAnyHashInitRoutine PARAMS ((src, hdr, m, r),
+ FILE *src _AND_
+ FILE *hdr _AND_
+ Module *m _AND_
+ PyRules *r)
+{
+
+ TypeDef *td;
+ int i;
+ int installedSomeHashes=0;
+ struct CxxTDI *cxxtdi;
+ char *modName;
+/* REN -- 5/11/2001 */
+/* AnyRef *ar;
+ AnyRefList *arl;
+ int j; */
+ enum BasicTypeChoiceId typeId;
+ ValueDef *vd;
+ Type *t;
+ BasicValue *bv;
+ char anyId[512];
+ char *typeName = NULL;
+/* REN -- end */
+
+ modName = Asn1TypeName2CTypeName (m->modId->name);
+
+ /* print Any class src file */
+ fprintf (src,"// this class will automatically intialize the any hash tbl\n");
+ fprintf (src,"class InitAny%s\n", modName);
+ fprintf (src,"{\n");
+ fprintf (src," public:\n");
+ fprintf (src," InitAny%s();\n", modName);
+ fprintf (src," /* Do not add a destructor to this class! It could\n");
+ fprintf (src," * cause pre-mature destruction of the ANY tables.\n");
+ fprintf (src," * The ANY tables will be destroyed by the runtime library.\n");
+ fprintf (src," */\n");
+#if 0
+ fprintf (src," ~InitAny%s() { AsnAny::AsnAnyDestroyHashTbls(); }\n",modName);
+#endif
+ fprintf (src,"};\n\n");
+
+ fprintf (src,"static InitAny%s anyInitalizer;\n", modName);
+
+ /* print constructor method that build hash tbl to src file*/
+ fprintf (src,"InitAny%s::InitAny%s()\n", modName, modName);
+ fprintf (src,"{\n");
+
+ /* first print value for OID's */
+ i = 0;
+
+ FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+ {
+ if (vd->value != NULL)
+ {
+ t = vd->value->type;
+ if ((GetBuiltinType(t) == BASICTYPE_MACROTYPE) &&
+ (t->basicType->a.macroType->choiceId ==
+ MACROTYPE_SNMPOBJECTTYPE))
+ {
+ bv = vd->value->basicValue;
+ if (bv != NULL)
+ {
+ installedSomeHashes = TRUE;
+ if (bv->choiceId == BASICVALUE_OID)
+ {
+ fprintf (src," %s oid%d",
+ r->typeConvTbl[BASICTYPE_OID].className, i++);
+#if 0
+ PrintPyOidValue(src, r, bv->a.oid, 1);
+#endif
+ fprintf (src,";\n");
+ }
+ }
+ }
+ }
+ }
+ fprintf (src,"\n\n");
+
+ /* now print hash init calls */
+ i = 0;
+
+ FOR_EACH_LIST_ELMT (vd, m->valueDefs)
+ {
+ if (vd->value != NULL)
+ {
+ t = vd->value->type;
+ if ((GetBuiltinType(t) == BASICTYPE_MACROTYPE) &&
+ (t->basicType->a.macroType->choiceId ==
+ MACROTYPE_SNMPOBJECTTYPE))
+ {
+ bv = vd->value->basicValue;
+ if (bv != NULL)
+ {
+ strcpy (anyId, vd->definedName);
+ Dash2Underscore (anyId, strlen (anyId));
+ strcat (anyId, "_ANY_ID");
+
+ installedSomeHashes = TRUE;
+ t = t->basicType->a.macroType->a.snmpObjectType->syntax;
+
+ /* If the syntax of this any is a basic type, get the
+ class name from the rules table. */
+ typeId = t->basicType->choiceId;
+ if (((typeId >= BASICTYPE_BOOLEAN) &&
+ (typeId <= BASICTYPE_SETOF)) ||
+ ((typeId >= BASICTYPE_NUMERIC_STR) &&
+ (typeId <= BASICTYPE_T61_STR)))
+ {
+ typeName = r->typeConvTbl[typeId].className;
+ }
+ /* Else if the syntax of this any is either a locally
+ defined type or an imported type, get the class name from
+ the this type's ref info. */
+ else
+ {
+ td = GetTypeDef(t);
+ if (td != NULL)
+ {
+ cxxtdi = td->cxxTypeDefInfo;
+ typeName = cxxtdi->className;
+ }
+ else
+ typeName = NULL;
+ }
+
+ if (typeName == NULL)
+ fprintf(src, "*** ERROR *** Unknown ANY\n\n");
+ else
+ {
+ if (bv->choiceId == BASICVALUE_OID)
+ {
+ fprintf (src,
+ " AsnAny::InstallAnyByOid (oid%d, %s, new %s);\n",
+ i++, anyId, typeName);
+ }
+ else if (bv->choiceId == BASICVALUE_INTEGER)
+ {
+ fprintf (src,
+ " AsnAny::InstallAnyByInt (%d, %s, new %s);\n",
+ bv->a.integer, anyId, typeName);
+ }
+ }
+ }
+ }
+ }
+ }
+/* REN -- end */
+
+ if (!installedSomeHashes)
+ {
+ fprintf (src," /* Since no INTEGER/OID to ANY type relations were defined\n");
+ fprintf (src," * (usually done via MACROs) you must manually do the code\n");
+ fprintf (src," * to fill the hash tbl.\n");
+ fprintf (src," * if the ids are INTEGER use the following:\n");
+ fprintf (src," * AsnAny::InstallAnyByInt (3, ??_ANY_ID, new <className>);\n");
+ fprintf (src," * if the ids are OBJECT IDENTIFIERs use the following:\n");
+ fprintf (src," * AsnAny::InstallAnyByOid (OidValue, ??_ANY_ID, new <className>);\n");
+ fprintf (src," * put the ??_ANY_IDs in the AnyId enum.\n\n");
+ fprintf (src," * For example if you have some thing like\n");
+ fprintf (src," * T1 ::= SEQUENCE { id INTEGER, ANY DEFINED BY id }\n");
+ fprintf (src," * and the id 1 maps to the type BOOLEAN use the following:\n");
+ fprintf (src," * AsnAny::InstallAnyByInt (1, SOMEBOOL_ANY_ID, new AsnBool);\n");
+ fprintf (src," */\n ???????\n"); /* generate compile error */
+ }
+
+
+ fprintf (src,"} /* InitAny::InitAny */\n\n\n");
+/* RWC;4/23/01;#endif */
+
+/* RWC;4/23/01; r;m;mods;hdr;src; */ /*AVOIDS warning.*/
+} /* PrintAnyHashInitRoutine */
+
+
+/* REN -- 5/11/2001 -- GetTypeDef() function added to return the type def info
+for the given type. */
+static TypeDef*
+GetTypeDef PARAMS ((t),
+ Type *t)
+{
+ if (t == NULL)
+ return NULL;
+
+ switch (t->basicType->choiceId)
+ {
+ case BASICTYPE_LOCALTYPEREF:
+ case BASICTYPE_IMPORTTYPEREF:
+ return t->basicType->a.localTypeRef->link;
+ break;
+
+ default:
+ return NULL;
+ }
+ /*fprintf (errFileG, "GetTypeDef: ERROR - cannot get type def for unlinked local/import type refs\n");
+ return NULL;*/
+
+} /* GetTypeDef */
+/* REN -- end */
diff --git a/compiler/back-ends/py-gen/gen-code.c b/compiler/back-ends/py-gen/gen-code.c
new file mode 100644
index 0000000..d793f74
--- /dev/null
+++ b/compiler/back-ends/py-gen/gen-code.c
@@ -0,0 +1,2722 @@
+/*
+ * compiler/back-ends/py-gen/gen-code.c - routines for printing python
+ * code from type trees
+ *
+ * assumes that the type tree has already been run through the
+ * python type generator (py-gen/types.c).
+ *
+ * Copyright (C) 2016 Aaron Conole
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include "snacc.h"
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#include <string.h>
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "rules.h"
+#include "snacc-util.h"
+#include "print.h"
+#include "tag-util.h" /* get GetTags/FreeTags/CountTags/TagByteLen */
+
+#if META
+#include "meta.h"
+#endif
+
+
+enum BasicTypeChoiceId ParanoidGetBuiltinType PARAMS ((t),Type *t);
+void PrintPyAnyCode PROTO ((FILE *src, FILE *hdr, PyRules *r,
+ ModuleList *mods, Module *m));
+void PrintPyValueDef PROTO ((FILE *src, PyRules *r, ValueDef *v));
+void PrintPyValueExtern PROTO ((FILE *hdr, PyRules *r, ValueDef *v));
+void PrintPySetTypeByCode(NamedType *defByNamedType, CxxTRI *cxxtri, FILE *src);
+void PrintPyEncodeContaining(Type *t, PyRules *r, FILE *src);
+void PrintPyPEREncodeContaining(Type *t, PyRules *r, FILE *src);
+void PrintPyPERDecodeContaining(Type *t, PyRules *r, FILE *src);
+void PrintPyDecodeContaining(Type *t, PyRules *r, FILE *src);
+static char *
+LookupNamespace PROTO ((Type *t, ModuleList *mods));
+static void PrintPySeqSetPrintFunction(FILE* src, FILE* hdr,
+ MyString className,
+ BasicType *pBasicType);
+static void PrintPyDefCode_PERSort(NamedType ***pppElementNamedType,
+ int **ppElementTag,
+ AsnList *pElementList);
+static void PrintPyDefCode_SetSeqPEREncode(FILE *src, FILE *hdr, PyRules *r,
+ TypeDef *td,
+ NamedType **pSetElementNamedType,
+ int iElementCount);
+static void PrintPyDefCode_SetSeqPERDecode(FILE *src, FILE *hdr,
+ PyRules *r, TypeDef *td,
+ NamedType **pSetElementNamedType,
+ int iElementCount);
+
+
+/* flag to see if constraints were present */
+static int constraints_flag;
+static long lconstraintvar=0;
+
+extern char *bVDAGlobalDLLExport;
+extern int gNO_NAMESPACE;
+extern const char *gAlternateNamespaceString;
+extern int genPERCode;
+//extern short ImportedFilesG;
+
+static const char bufTypeNameG[] = "asn_buffer.AsnBuf";
+static const char lenTypeNameG[] = "AsnLen";
+static const char tagTypeNameG[] = "AsnTag";
+static const char baseClassesG[] = "(asn_base.AsnBase)";
+
+static int printTypesG;
+static int printEncodersG;
+static int printDecodersG;
+static int printPrintersG;
+static int printFreeG;
+
+// normalizeValue
+//
+// strip whitespace and { } from valueNation values.
+//
+static void
+normalizeValue(char **normalized, char *input)
+{
+ int i;
+ while(*input == ' ' || *input == '{' )
+ input++;
+
+ *normalized = strdup(input);
+
+ i = strlen(*normalized) - 1;
+ while ( (*normalized)[i] == ' ' || (*normalized)[i] == '}' )
+ {
+ (*normalized)[i] = 0;
+ i--;
+ }
+}
+
+static char *GetImportFileName (char *Impname, ModuleList *mods)
+{
+ Module *currMod;
+ char *fileName = NULL;
+ FOR_EACH_LIST_ELMT (currMod, mods) {
+ /* Find the import Module in the Modules and
+ * return the header file name
+ */
+ if ((strcmp(Impname, currMod->modId->name) == 0)) {
+ /* Set the file name and break */
+ fileName = currMod->cxxHdrFileName;
+ break;
+ }
+ }
+ return fileName;
+}
+
+static Module *GetImportModuleRef (char *Impname, ModuleList *mods)
+{
+ Module *currMod=NULL;
+ FOR_EACH_LIST_ELMT (currMod, mods) {
+ /* Find the import Module in the Modules and
+ * return the header file name
+ */
+ if ((strcmp(Impname, currMod->modId->name) == 0)) {
+ break;
+ }
+ }
+ return currMod;
+}
+
+static void
+PrintSimpleMeta(FILE *hdr, char *className,int exportMember)
+{
+
+}
+
+static void
+PrintSimpleCheck(FILE *hdr, FILE* src, char *className, int exportMember)
+{
+ fprintf(src, "int %s::checkConstraints(ConstraintFailList* pConstraintFails) const\n{\n",
+ className);
+ fprintf(src, "\treturn checkListConstraints(pConstraintFails);\n");
+ fprintf(src, "}\n");
+}
+
+static void
+PrintSrcComment PARAMS ((src, m),
+ FILE *src _AND_
+ Module *m)
+{
+ time_t now = time (NULL);
+
+ fprintf (src, "# %s - class definitions for ASN.1 module %s\n",
+ m->cxxSrcFileName, m->modId->name);
+ fprintf (src, "#\n");
+ fprintf (src, "# This file was generated by esnacc on %s\n",
+ ctime(&now));
+ fprintf (src, "# NOTE: this is a machine generated file-"
+ "-editing not recommended\n");
+ fprintf (src, "\n");
+
+} /* PrintSrcComment */
+
+
+static void
+PrintSrcIncludes PARAMS ((src), FILE *src)
+{
+ fprintf(src, "from esnacc import asn_base\n");
+ fprintf(src, "from esnacc import asn_bool\n");
+ fprintf(src, "from esnacc import asn_buffer\n");
+ fprintf(src, "from esnacc import asn_ints\n");
+ fprintf(src, "from esnacc import asn_list\n");
+ fprintf(src, "from esnacc import asn_octs\n");
+ fprintf(src, "from esnacc import asn_useful\n");
+ fprintf(src, "\n");
+} /* PrintSrcIncludes */
+
+
+static void
+PrintTypeDecl PARAMS ((f, td),
+ FILE *f _AND_
+ TypeDef *td)
+{
+ switch (td->type->basicType->choiceId)
+ {
+ case BASICTYPE_COMPONENTSOF:
+ case BASICTYPE_SELECTION:
+ case BASICTYPE_UNKNOWN:
+ case BASICTYPE_MACRODEF:
+ case BASICTYPE_MACROTYPE:
+ return; /* do nothing */
+
+ default:
+ if (IsNewType (td->type))
+ fprintf(f, "class %s;\n", td->cxxTypeDefInfo->className);
+ }
+
+} /* PrintTypeDecl */
+
+
+static void
+PrintPyType PARAMS ((hdr, mods, m, r, td, parent, t),
+ FILE *hdr _AND_
+ ModuleList *mods _AND_
+ Module *m _AND_
+ PyRules *r _AND_
+ TypeDef *td _AND_
+ Type *parent _AND_
+ Type *t)
+{
+ char *pszNamespace=NULL;
+ pszNamespace = LookupNamespace(t, mods);
+
+ if (pszNamespace) {
+ fprintf(hdr, "%s::%s ",
+ pszNamespace, t->cxxTypeRefInfo->className);
+ } else {
+ fprintf(hdr, "%s ", t->cxxTypeRefInfo->className);
+ }
+
+ if (t->cxxTypeRefInfo->isPtr)
+ fprintf (hdr, "*");
+
+} /* PrintPyType */
+
+
+
+/*
+ * Uses the Constructor that takes no args.
+ * Assumes file f is positioned inside a class definition.
+ * All Classes get this to support the ANY type.
+ */
+static void
+PrintCloneMethod PARAMS ((hdr, src, td),
+ FILE *hdr _AND_
+ FILE *src _AND_
+ TypeDef *td)
+{
+// fprintf (hdr, " AsnType *Clone() const;\n\n", td->cxxTypeDefInfo->className);
+// fprintf (hdr, " AsnType *Clone() const;\n\n");
+ fprintf (src, "AsnType *%s::Clone() const\n", td->cxxTypeDefInfo->className);
+ fprintf (src, "{\n");
+ fprintf (src, " return new %s(*this);\n", td->cxxTypeDefInfo->className);
+ fprintf (src, "}\n\n");
+
+} /* PrintCloneMethod */
+
+
+/*
+ * prints inline definition of constructors if this class is
+ * derived from a library class.
+ * assumes FILE *f is positioned in the derived class definition (.h)
+ *
+ * 12/92 MS - added overloaded "=" ops for string types.
+ */
+static void
+PrintDerivedConstructors PARAMS ((f, td),
+ FILE *f _AND_
+ TypeDef *td)
+{
+ char *baseClassName = td->type->cxxTypeRefInfo->className;
+ fprintf(f,
+ " def __init__(self, value=None):\n"
+ " %s.__init__(self,value)\n\n", baseClassName);
+} /* PrintDerivedConstructors */
+
+#if DEPRECATED
+static void
+PrintPyEocEncoders PARAMS ((src, td, t, bufVarName),
+ FILE *src _AND_
+ TypeDef *td _AND_
+ Type *t _AND_
+ char *bufVarName)
+{
+ TagList *tl;
+ Tag *tag;
+ int stoleChoiceTags;
+
+ /* get all the tags on this type*/
+ tl = (TagList*) GetTags (t, &stoleChoiceTags);
+ FreeTags (tl);
+ bufVarName=bufVarName;td=td; /*AVOIDS warning.*/
+
+} /* PrintPyEocEncoders */
+#endif
+
+static int
+HasShortLen PARAMS ((t),
+ Type *t)
+{
+ enum BasicTypeChoiceId typesType;
+ /*
+ * efficiency hack - use simple length (1 byte)
+ * encoded for type (almost) guaranteed to have
+ * encoded lengths of 0 <= len <= 127
+ */
+ typesType = GetBuiltinType (t);
+ /*RWC;8/9/01;REMOVED when INTEGER made AsnOcts;return typesType == BASICTYPE_BOOLEAN || typesType == BASICTYPE_INTEGER || typesType == BASICTYPE_NULL || typesType == BASICTYPE_REAL || typesType == BASICTYPE_ENUMERATED; */
+ return typesType == BASICTYPE_BOOLEAN || typesType == BASICTYPE_NULL || typesType == BASICTYPE_REAL || typesType == BASICTYPE_ENUMERATED;
+} /* HasShortLen */
+
+
+/*
+ * prints length encoding code. Primitives always use
+ * definite length and constructors get "ConsLen"
+ * which can be configured at compile to to be indefinite
+ * or definite. Primitives can also be "short" (isShort is true)
+ * in which case a fast macro is used to write the length.
+ * Types for which isShort apply are: boolean, null and
+ * (almost always) integer and reals
+ */
+static void
+PrintPyLenEncodingCode PARAMS ((f, lenVarName, bufVarName, classStr,
+ formStr),
+ FILE *f _AND_
+ char *lenVarName _AND_
+ char *bufVarName _AND_
+ char *classStr _AND_
+ char *formStr)
+{
+ fprintf(f, " %s += asn_buffer.BEncDefLen(%s, %s)\n",
+ lenVarName, bufVarName, lenVarName);
+ fprintf(f, " TAG_CODE = asn_base.BERConsts.MakeTag(asn_base.BERConsts.%s,\n"
+ " self.%s,\n"
+ " self.BER_CODE)\n",
+ classStr, formStr);
+}
+
+/* prints last tag's encoding code first */
+static void
+PrintPyTagAndLenList PARAMS ((src, tagList, lenVarName, bufVarName),
+ FILE *src _AND_
+ TagList *tagList _AND_
+ char *lenVarName _AND_
+ char *bufVarName)
+{
+ char *classStr;
+ char *formStr;
+ Tag *tg;
+ int tagLen;
+
+ if ((tagList == NULL) || LIST_EMPTY (tagList))
+ return;
+
+ /*
+ * since encoding backward encode tags backwards
+ */
+ FOR_EACH_LIST_ELMT_RVS (tg, tagList) {
+ classStr = Class2ClassStr (tg->tclass);
+
+ if (tg->form == CONS) {
+ formStr = Form2FormStr (CONS);
+ } else {
+ formStr = Form2FormStr (PRIM);
+ }
+ PrintPyLenEncodingCode (src, lenVarName, bufVarName,
+ classStr, formStr);
+ fprintf (src, "\n");
+
+ if (tg->tclass == UNIV) {
+ const char* ptr = DetermineCode(tg, &tagLen, 0);
+ fprintf (src, " %s += BEncTag%d (%s, %s, %s, %s);\n", lenVarName, tagLen, bufVarName, classStr, formStr, ptr);
+ } else {
+ const char* ptr = DetermineCode(tg, &tagLen, 1);
+ fprintf(src, " %s += BEncTag%d(%s, %s, %s, %s);\n", lenVarName, tagLen, bufVarName, classStr, formStr, ptr);
+ } //RWC;tg->code);
+ }
+} /* PrintPyTagAndLenList */
+
+/*
+ * Recursively walks through tags, printing lower lvl tags
+ * first (since encoding is done backwards).
+ *
+ */
+static void
+PrintPyTagAndLenEncodingCode PARAMS ((src, t, lenVarName, bufVarName),
+ FILE *src _AND_
+ Type *t _AND_
+ char *lenVarName _AND_
+ char *bufVarName)
+{
+ TagList *tl;
+ int stoleChoiceTags;
+
+ /*
+ * get all the tags on this type
+ */
+ tl = (TagList*) GetTags(t, &stoleChoiceTags);
+
+ /*
+ * leave choice elmt tag enc to encoding routine
+ */
+ if (!stoleChoiceTags)
+ PrintPyTagAndLenList(src, tl, lenVarName, bufVarName);
+
+ FreeTags(tl);
+} /* PrintPyTagAndLenEncodingCode */
+
+
+/*
+ * used to figure out local variables to declare
+ * for decoding tags/len pairs on type t
+ */
+static int
+CxxCountVariableLevels PARAMS ((t),
+ Type *t)
+{
+ if (GetBuiltinType (t) == BASICTYPE_CHOICE)
+ return CountTags (t) +1; /* since must decode 1 internal tag type */
+ else
+ return CountTags (t);
+} /* CxxCountVariableLevels */
+
+
+/*
+ * returns true if elmts curr following
+ * onward are all optional ow. false
+ */
+static int
+RestAreTailOptional PARAMS ((e),
+ NamedTypeList *e)
+{
+ NamedType *elmt;
+ void *tmp;
+ int retVal;
+
+ if (e == NULL)
+ return TRUE;
+
+ tmp = (void*)CURR_LIST_NODE (e);
+ retVal = TRUE;
+ AsnListNext (e);
+ FOR_REST_LIST_ELMT (elmt, e)
+ {
+ if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL)&&(!elmt->type->extensionAddition))
+ {
+ retVal = FALSE;
+ break;
+ }
+ }
+ SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */
+ return retVal;
+}
+
+
+/*
+ * prints typedef or new class given an ASN.1 type def of a primitive type
+ * or typeref. Uses inheritance to cover re-tagging and named elmts.
+ */
+static void
+PrintPySimpleDef PARAMS ((hdr, src, r, td),
+ FILE *hdr _AND_
+ FILE *src _AND_
+ PyRules *r _AND_
+ TypeDef *td)
+{
+ Tag *tag;
+ TagList *tags;
+ char *formStr;
+ char *classStr;
+ int i;
+ CNamedElmt *n;
+ int stoleChoiceTags;
+ int elmtLevel;
+ enum BasicTypeChoiceId typeId;
+
+ if (IsNewType (td->type)) {
+ int hasNamedElmts;
+
+ fprintf(src, "class %s(%s):\n",
+ td->cxxTypeDefInfo->className,
+ td->type->cxxTypeRefInfo->className);
+
+ /*
+ * must explicitly call constructors for base class
+ */
+ PrintDerivedConstructors (src, td);
+ if ((hasNamedElmts = HasNamedElmts (td->type)) != 0) {
+ int count = 0;
+ fprintf(src, " ENUMERATIONS = Enum(");
+ FOR_EACH_LIST_ELMT (n, td->type->cxxTypeRefInfo->namedElmts) {
+ fprintf(src, "%s = %d", n->name, n->value);
+ if (n != (CNamedElmt *)LAST_LIST_ELMT(
+ td->type->cxxTypeRefInfo->namedElmts))
+ fprintf (src, ",");
+ else
+ fprintf (src, ")\n");
+ count++;
+ }
+ }
+
+ fprintf(src, " def typename(self):\n");
+ fprintf(src, " return \"%s\"\n\n",
+ td->cxxTypeDefInfo->className);
+ /*
+ * Re-do BerEncode, BerDeocode, BerDecodePdu and BerDecodePdu
+ * if this type has been re-tagged
+ */
+ if ((IsDefinedByLibraryType(td->type) && !HasDefaultTag(td->type))
+ || (IsTypeRef (td->type) && ((td->type->tags != NULL)
+ && !LIST_EMPTY(td->type->tags)))) {
+
+ int tagLen = 0;
+ tags = GetTags (td->type, &stoleChoiceTags);
+ if (tags->count > 1) {
+ fprintf(src, " # WARNING: only one tag added...\n");
+ }
+ tag = tags->first->data;
+ typeId = GetBuiltinType (td->type);
+ classStr = Class2ClassStr (tag->tclass);
+ formStr = Form2FormStr((tag->form == ANY_FORM) ? PRIM : tag->form);
+ fprintf(src, " BER_FORM = asn_base.BERConsts.%s\n", formStr);
+ fprintf(src, " BER_CLASS = asn_base.BERConsts.%s\n", classStr);
+ fflush(src);
+ if (!stoleChoiceTags) {
+ const char *ptr = DetermineCode(tag, &tagLen, (tag->tclass == UNIV) ? 0 : 1);
+ fprintf(src, " BER_CODE = %s\n", ptr);
+ }
+ FreeTags (tags);
+ fprintf(src, "\n\n");
+ }
+ } else {
+
+
+ /* JKG 7/31/03 */
+ /* The following code enclosed in this if/else statement */
+ /* is constructed for constraint handling capability */
+ /* for primitives found outside of */
+ /* sequences or sets */
+
+ if (td->type->subtypes != NULL) {
+ switch (td->type->subtypes->choiceId) {
+ case SUBTYPE_AND:
+ case SUBTYPE_OR:
+ case SUBTYPE_SINGLE:
+ {
+ struct NamedType temp;
+ NamedType* tmp = &temp;
+ tmp->type=td->type;
+ tmp->type->cxxTypeRefInfo->fieldName=td->definedName;
+ tmp->fieldName=td->definedName;
+#if 0
+ if (!PrintPyMultiConstraintOrHandler(hdr, src, NULL, tmp, 0))
+ PrintTypeDefDefault(hdr, src, td);
+#endif
+ }
+ break;
+ default:
+#if 0
+ PrintTypeDefDefault(hdr, src, td);
+#endif
+ break;
+ }
+ } else {
+#if 0
+ PrintTypeDefDefault(hdr, src, td);
+#endif
+ }
+ }
+
+} /* PrintPySimpleDef */
+
+static void
+PrintPyChoiceDefCode (FILE *src, FILE *hdr, ModuleList *mods, Module *m, PyRules *r ,
+ TypeDef *td,Type *parent, Type *choice, int novolatilefuncs)
+{
+ NamedType *e;
+ char *classStr;
+ char *formStr;
+ char *codeStr;
+ int tagLen=0, i;
+ Tag *tag;
+ TagList *tags;
+ char *varName;
+ CxxTRI *cxxtri;
+ int elmtLevel=0;
+ int varCount, tmpVarCount;
+ int stoleChoiceTags;
+ enum BasicTypeChoiceId tmpTypeId;
+ NamedType *defByNamedType;
+ NamedType **ppElementNamedType;
+ int *pElementTag;
+ int ii;
+ char *ptr=""; /* NOT DLL Exported, or ignored on Unix. */
+ int extensionsExist = FALSE;
+
+ /* put class spec in hdr file */
+
+ if (bVDAGlobalDLLExport != NULL)
+ ptr = bVDAGlobalDLLExport;
+
+ fprintf(src, "class %s %s%s:\n", ptr, td->cxxTypeDefInfo->className, baseClassesG);
+ /* write out choiceId enum type */
+
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) {
+ if(e->type->subtypes != NULL) {
+ switch(e->type->subtypes->choiceId) {
+ case SUBTYPE_AND:
+ case SUBTYPE_OR:
+ case SUBTYPE_SINGLE:
+#if 0
+ PrintPyMultiConstraintOrHandler(hdr, src,
+ td->cxxTypeDefInfo->className,
+ e, 3);
+#endif
+ default:
+ break;
+ }
+ }
+ }
+
+ fprintf(src, " CHOICES_%s = \\\n", r->choiceIdEnumName);
+ fprintf(src, " {\\\n");
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) {
+ fprintf(src, " %s = %d",
+ e->type->cxxTypeRefInfo->choiceIdSymbol,
+ e->type->cxxTypeRefInfo->choiceIdValue);
+ if (e != (NamedType*)LAST_LIST_ELMT (choice->basicType->a.choice))
+ fprintf(src, ",\\\n");
+ else
+ fprintf(src, "\\\n");
+ }
+ fprintf (src, " }\n");
+
+ /* write out the choice element anonymous union */
+ fprintf (src, " union\n");
+ fprintf (src, " {\n");
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) {
+ fprintf (src, " ");
+ PrintPyType(hdr, mods, m, r, td, choice, e->type);
+ fprintf (src, "%s;\n\n", e->type->cxxTypeRefInfo->fieldName);
+ }
+ fprintf (src, " };\n\n");
+
+
+ fprintf (src, "\n");
+
+ /* constructors and destructor */
+ fprintf (src, " %s() {Init();}\n", td->cxxTypeDefInfo->className);
+
+ /* PIERCE 8-22-2001 */
+ PrintSimpleMeta(src,td->cxxTypeDefInfo->className,0);
+
+ /* Init() member function*/
+ fprintf (src, "void %s::Init(void)\n", td->cxxTypeDefInfo->className);
+ fprintf (src, "{\n");
+ fprintf (src, " // initialize choice to no choiceId to first choice and set pointer to NULL\n");
+ e = FIRST_LIST_ELMT (choice->basicType->a.choice);
+ fprintf (src, " choiceId = %sCid;\n", e->type->cxxTypeRefInfo->fieldName);
+ fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+ fprintf (src, "}\n\n");
+ fprintf(src, "\nint %s::checkConstraints(ConstraintFailList* pConstraintFails) const\n{\n",
+ td->cxxTypeDefInfo->className);
+
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+ {
+ if (e->type->cxxTypeRefInfo->isPtr)
+ {
+ fprintf(src, "\tif (%s != NULL)\n",
+ e->type->cxxTypeRefInfo->fieldName);
+ fprintf(src, "\t\t%s->checkConstraints(pConstraintFails);\n\n",
+ e->type->cxxTypeRefInfo->fieldName);
+ }
+ else
+ {
+ fprintf(src, "\t%s.checkConstraints(pConstraintFails);\n\n",
+ e->type->cxxTypeRefInfo->fieldName);
+ }
+ }
+ fprintf(src, "\treturn 0;\n");
+ fprintf(src, "}\n\n\n");
+
+ /* virtual destructor*/
+ fprintf (src, "void %s::Clear()\n", td->cxxTypeDefInfo->className);
+ fprintf (src, "{\n");
+ fprintf (src, " switch (choiceId)\n");
+ fprintf (src, " {\n");
+
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+ {
+ tmpTypeId = GetBuiltinType (e->type);
+
+ fprintf (src, " case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol);
+ if (e->type->cxxTypeRefInfo->isPtr)
+ {
+ fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName);
+ fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName);
+ }
+ else if(!e->type->cxxTypeRefInfo->isPtr &&
+ ((tmpTypeId == BASICTYPE_CHOICE) ||
+ (tmpTypeId == BASICTYPE_SET) ||
+ (tmpTypeId == BASICTYPE_SEQUENCE)) )
+ {
+ fprintf (src, " %s.Clear();\n", e->type->cxxTypeRefInfo->fieldName);
+ }
+ fprintf (src, " break;\n");
+ }
+
+ fprintf (src, " } // end of switch\n");
+ fprintf (src, "} // end of Clear()\n");
+ fprintf (src, "\n");
+
+ /* print clone routine for ANY mgmt */
+ PrintCloneMethod (hdr, src, td);
+
+ fprintf (src, "%s &%s::operator = (const %s &that)\n",
+ td->cxxTypeDefInfo->className,
+ td->cxxTypeDefInfo->className,
+ td->cxxTypeDefInfo->className);
+ fprintf (src, "{\n");
+ fprintf (src, " if (this != &that) {\n");
+ fprintf (src, " Clear();\n");
+
+ e = FIRST_LIST_ELMT (choice->basicType->a.choice);
+ fprintf (src, " if (that.%s != NULL) {\n",
+ e->type->cxxTypeRefInfo->fieldName);
+ fprintf (src, " switch (choiceId = that.choiceId) {\n");
+
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) {
+ fprintf (src, " case %s:\n",
+ e->type->cxxTypeRefInfo->choiceIdSymbol);
+ if (e->type->cxxTypeRefInfo->isPtr) {
+ fprintf (src, " %s = new %s(*that.%s);\n",
+ e->type->cxxTypeRefInfo->fieldName,
+ e->type->cxxTypeRefInfo->className,
+ e->type->cxxTypeRefInfo->fieldName);
+ } else {
+ fprintf (src, " %s = that.%s;\n",
+ e->type->cxxTypeRefInfo->fieldName,
+ e->type->cxxTypeRefInfo->fieldName);
+ }
+ fprintf (src, " break;\n");
+ }
+
+ fprintf (src, " }\n");
+ fprintf (src, " }\n");
+ fprintf (src, " }\n");
+ fprintf (src, "\n");
+ fprintf (src, " return *this;\n");
+ fprintf (src, "}\n\n");
+
+ /* BerEncodeContent */
+ if (printEncodersG)
+ {
+ //fprintf (hdr, " %s B%s (%s &_b) const;\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG);
+
+ fprintf (src, "%s\n", lenTypeNameG);
+ fprintf (src, "%s::B%s (%s &_b) const\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG);
+ fprintf (src, "{\n");
+ fprintf (src, " FUNC(\"%s::B%s (%s &_b)\");\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG);
+
+ /* print local vars */
+ fprintf (src, " %s l=0;\n", lenTypeNameG);
+
+ fprintf (src, " switch (%s)\n", r->choiceIdFieldName);
+ fprintf (src, " {\n");
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+ {
+ cxxtri = e->type->cxxTypeRefInfo;
+ fprintf (src, " case %s:\n", cxxtri->choiceIdSymbol);
+
+ varName = cxxtri->fieldName;
+
+ /* eSNACC 1.5 does not encode indefinite length
+ *
+ * PrintPyEocEncoders (src, td, e->type, "_b");
+ */
+
+ /* encode content */
+ tmpTypeId = GetBuiltinType (e->type);
+ if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+ {
+ defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+ PrintPySetTypeByCode(defByNamedType, cxxtri, src);
+ }
+ else if (tmpTypeId == BASICTYPE_ANY)
+ {
+ fprintf (src, " l = %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "B%s (_b);\n", r->encodeBaseName);
+ }
+ else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) ||
+ (tmpTypeId == BASICTYPE_BITCONTAINING))
+ {
+ PrintPyEncodeContaining(e->type, r, src);
+ }
+ else if ( tmpTypeId == BASICTYPE_EXTENSION )
+ {
+ fprintf (src, " l = %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "B%s (_b);\n", r->encodeBaseName);
+ }
+ else
+ {
+ fprintf (src, " l = %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "B%s (_b);\n", r->encodeContentBaseName);
+ }
+
+ /* encode tag (s) & len (s) */
+ PrintPyTagAndLenEncodingCode(src, e->type, "l", "_b");
+
+ fprintf (src, " break;\n\n");
+ }
+ fprintf (src, " default:\n");
+ fprintf (src, " throw EXCEPT(\"Choice is empty\", ENCODE_ERROR);\n");
+ fprintf (src, " } // end switch\n");
+
+ fprintf (src, " return l;\n");
+ fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName);
+ }
+ /* end of BerEncodeContent method */
+
+ /* BerDecodeContent */
+ if (printDecodersG)
+ {
+ //fprintf (hdr, " void B%s (const %s &_b, %s tag, %s elmtLen, %s &bytesDecoded /*, s env*/);\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG);//, envTypeNameG);
+ fprintf (src, "void %s::B%s (const %s &_b, %s tag, %s elmtLen0, %s &bytesDecoded /*, s env*/)\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG);//, envTypeNameG);
+ fprintf (src, "{\n");
+ fprintf (src, " FUNC(\"%s::B%s()\");\n",td->cxxTypeDefInfo->className, r->decodeContentBaseName);
+ fprintf (src, " Clear();\n");
+ //fprintf (src, " Init();\n");
+ /* print local vars */
+ /* count max number of extra length var nec
+ * by counting tag/len pairs on components of the CHOICE
+ */
+
+ varCount = 0;
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+ {
+ tmpVarCount = CxxCountVariableLevels (e->type);
+ if (tmpVarCount > varCount)
+ varCount = tmpVarCount;
+ }
+ /* write extra length vars - remember choice content
+ * decoders are passed the 'key' tag so need one less
+ * than max var count.
+ */
+ for (i = 1; i < varCount; i++)
+ fprintf (src, " %s elmtLen%d = 0;\n", lenTypeNameG, i);
+
+ /* switch on given tag - choices always have the key tag decoded */
+ fprintf (src, " switch (tag)\n");
+ fprintf (src, " {\n");
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+ {
+ if( e->type->basicType->choiceId == BASICTYPE_EXTENSION )
+ {
+ extensionsExist = TRUE;
+ }
+ else
+ {
+
+ cxxtri = e->type->cxxTypeRefInfo;
+ tags = GetTags (e->type, &stoleChoiceTags);
+
+ if (LIST_EMPTY (tags))
+ {
+ fprintf (src, " // ANY Type?\n");
+ fprintf (src, " case MAKE_TAG_ID (?, ?, ?):\n");
+ }
+ else
+ {
+ tag = (Tag*)FIRST_LIST_ELMT (tags);
+ classStr = Class2ClassStr (tag->tclass);
+ formStr = Form2FormStr (tag->form);
+
+ if (tag->tclass == UNIV)
+ {
+ codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code);
+ }
+ else
+ {
+ codeStr = DetermineCode(tag, NULL, 1);
+ }
+
+ if (tag->form == ANY_FORM)
+ {
+ fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr);
+ fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr);
+ }
+ else
+ {
+ fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr);
+ }
+
+ /* now decode extra tags/length pairs */
+ AsnListFirst (tags);
+ AsnListNext (tags);
+ elmtLevel = 0;
+ if (stoleChoiceTags)
+ {
+ FOR_REST_LIST_ELMT (tag, tags)
+ {
+ classStr = Class2ClassStr (tag->tclass);
+
+ formStr = Form2FormStr (tag->form);
+
+ if (tag->tclass == UNIV)
+ codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code);
+ else
+ codeStr = DetermineCode(tag, NULL, 1);
+
+ if (tag->form == ANY_FORM)
+ {
+ fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr);
+ fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr);
+ }
+ else
+ {
+ fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr);
+ }
+ }
+ }
+ else /* didn't steal nested choice's tags */
+ {
+ FOR_REST_LIST_ELMT (tag, tags)
+ {
+ classStr = Class2ClassStr (tag->tclass);
+ codeStr = DetermineCode(tag, NULL, 0);//RWC;Code2UnivCodeStr (tag->code);
+ formStr = Form2FormStr (tag->form);
+
+ fprintf (src, " tag = BDecTag (_b, bytesDecoded);\n");
+ if (tag->form == ANY_FORM)
+ {
+ if (tag->tclass == UNIV)
+ {
+ fprintf (src, " if ((tag != MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr);
+ fprintf (src, " && (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), codeStr);
+ }
+ else
+ {
+ fprintf (src, " if ((tag != MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), DetermineCode(tag, NULL, 1));//RWC;tag->code);
+ fprintf (src, " && (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code);
+ }
+ }
+ else
+ {
+ if (tag->tclass == UNIV)
+ fprintf (src, " if (tag != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, codeStr);
+ else
+ fprintf (src, " if (tag != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code);
+ }
+
+ fprintf (src, " {\n");
+
+ fprintf (src, " throw InvalidTagException(typeName(), tag, STACK_ENTRY);\n");
+ fprintf (src, " }\n\n");
+
+ fprintf (src, " elmtLen%d = BDecLen (_b, bytesDecoded);\n", ++elmtLevel);
+ }
+ }
+ }
+ /*
+ * if the choices element is another choice &&
+ * we didn't steal its tags then we must grab
+ * the key tag out of the contained CHOICE
+ */
+ if (!stoleChoiceTags && (GetBuiltinType (e->type) == BASICTYPE_CHOICE))
+ {
+ fprintf (src, " tag = BDecTag (_b, bytesDecoded);\n");
+ fprintf (src, " elmtLen%d = BDecLen (_b, bytesDecoded);\n", ++elmtLevel);
+ }
+
+ varName = cxxtri->fieldName;
+ /* set choice id for to this elment */
+ fprintf (src, " %s = %s;\n", r->choiceIdFieldName, cxxtri->choiceIdSymbol);
+
+ /* alloc elmt if nec */
+ if (cxxtri->isPtr)
+ {
+ fprintf (src, " %s = new %s;\n", varName, cxxtri->className);
+ }
+ /* decode content */
+ tmpTypeId = GetBuiltinType (e->type);
+ if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+ {
+ /*
+ * must check for another EOC for ANYs
+ * since the any decode routines decode
+ * their own first tag/len pair
+ */
+ elmtLevel++;
+ defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+ PrintPySetTypeByCode(defByNamedType, cxxtri, src);
+
+ fprintf (src, " %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+ fprintf (src, "B%s (_b, bytesDecoded);\n", r->decodeBaseName);
+ }
+ else if (tmpTypeId == BASICTYPE_ANY)
+ {
+ elmtLevel++;
+ fprintf (src, " %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+ fprintf (src, "B%s (_b, bytesDecoded);\n", r->decodeBaseName);
+ }
+ else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) ||
+ (tmpTypeId == BASICTYPE_BITCONTAINING) )
+ {
+ PrintPyDecodeContaining(e->type, r, src);
+ }
+ else
+ {
+ fprintf (src, " %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "B%s (_b, tag, elmtLen%d, bytesDecoded);\n", r->decodeContentBaseName, elmtLevel);
+ }
+
+ /* decode Eoc (s) */
+ for (i = elmtLevel-1; i >= 0; i--)
+ {
+ fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i);
+ fprintf (src, " BDecEoc (_b, bytesDecoded);\n");
+ }
+
+ fprintf (src, " break;\n\n");
+ FreeTags (tags);
+ }
+ }
+
+ fprintf (src, " default:\n");
+ fprintf (src, " {");
+
+ if(extensionsExist)
+ {
+ fprintf (src, " AsnAny extAny;\n");
+ fprintf (src, " extension = new AsnExtension;\n");
+ fprintf (src, " choiceId = extensionCid;\n");
+ fprintf (src, " extAny.BDecContent(_b, tag, elmtLen0, bytesDecoded);\n");
+ fprintf (src, " extension->extList.insert( extension->extList.end(), extAny );\n");
+ }
+ else
+ {
+ fprintf (src, " throw InvalidTagException(typeName(), tag, STACK_ENTRY);\n");
+ }
+
+ fprintf (src, " break;\n");
+ fprintf (src, " }\n");
+ fprintf (src, " } // end switch\n");
+ fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName);
+ }
+ /* end of code for printing BDecodeContent method */
+
+ /* do BEnc function */
+ if (printEncodersG)
+ {
+ //fprintf (hdr, " %s B%s (%s &_b) const;\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG);
+ fprintf (src, "%s %s::B%s (%s &_b) const\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG);
+ fprintf (src, "{\n");
+ fprintf (src, " %s l=0;\n", lenTypeNameG);
+ fprintf (src, " l = B%s (_b);\n", r->encodeContentBaseName);
+
+ /* encode each tag/len pair if any */
+ FOR_EACH_LIST_ELMT_RVS (tag, choice->tags)
+ {
+ classStr = Class2ClassStr (tag->tclass);
+ formStr = Form2FormStr (CONS); /* choices are constructed */
+ //RWC;tagLen = TagByteLen (tag->code);
+ fprintf (src, " l += BEncConsLen (_b, l);\n");
+
+ if (tag->tclass == UNIV)
+ {
+ const char* ptr = DetermineCode(tag, &tagLen, 1);
+ fprintf (src, " l += BEncTag%d (_b, %s, %s, %s);\n", tagLen, classStr, formStr, ptr);//RWC;Code2UnivCodeStr (tag->code));
+ }
+ else
+ {
+ const char* ptr = DetermineCode(tag, &tagLen, 1);
+ fprintf (src, " l += BEncTag%d (_b, %s, %s, %s);\n", tagLen, classStr, formStr, ptr);//RWC;tag->code);
+ }
+ }
+ fprintf (src, " return l;\n");
+ fprintf (src, "}\n\n");
+ }
+ /* end of BEnc function */
+
+ /* Do BDec function */
+ if (printDecodersG)
+ {
+ //fprintf (hdr, " void B%s (const %s &_b, %s &bytesDecoded);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG);
+ fprintf (src, "void %s::B%s (const %s &_b, %s &bytesDecoded)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG);//, envTypeNameG);
+ fprintf (src, "{\n");
+
+ if (choice->tags->count > 0)
+ fprintf (src, " FUNC(\"%s::B%s\")\n", td->cxxTypeDefInfo->className, r->decodeBaseName);
+
+ fprintf (src, " %s elmtLen = 0;\n", lenTypeNameG);
+ fprintf (src, " %s tag;\n", tagTypeNameG);
+
+ /* print extra locals for redundant lengths */
+ for (i = 1; (choice->tags != NULL) && (i <= LIST_COUNT (choice->tags)); i++)
+ {
+ fprintf (src, " %s extraLen%d = 0;\n", lenTypeNameG, i);
+ }
+ fprintf (src, "\n");
+
+ /* decode tag/length pair (s) */
+ elmtLevel = 0;
+ FOR_EACH_LIST_ELMT (tag, choice->tags)
+ {
+ classStr = Class2ClassStr (tag->tclass);
+ formStr = Form2FormStr (CONS); /* choices are constructed */
+ fprintf (src, " AsnTag tagId = BDecTag (_b, bytesDecoded);\n");
+ fprintf (src, " if (tagId != ");
+ if (tag->tclass == UNIV)
+ {
+ fprintf (src, "MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, DetermineCode(tag, NULL, 0));//RWC;Code2UnivCodeStr (tag->code));
+ }
+ else
+ {
+ fprintf (src, "MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code);
+ }
+ fprintf (src, " {\n");
+ fprintf (src, " throw InvalidTagException(typeName(), tagId, STACK_ENTRY);\n");
+ fprintf (src, " }\n");
+ fprintf (src, " extraLen%d = BDecLen (_b, bytesDecoded);\n", ++elmtLevel);
+ }
+
+ /* decode identifying tag from choice body */
+ fprintf (src, " /* CHOICEs are a special case - grab identifying tag */\n");
+ fprintf (src, " /* this allows easier handling of nested CHOICEs */\n");
+ fprintf (src, " tag = BDecTag (_b, bytesDecoded);\n");
+ fprintf (src, " elmtLen = BDecLen (_b, bytesDecoded);\n");
+ fprintf (src, " B%s (_b, tag, elmtLen, bytesDecoded);\n", r->decodeContentBaseName);
+
+ /* grab any EOCs that match redundant, indef lengths */
+ for (i = elmtLevel; i > 0; i--)
+ {
+ fprintf (src, " if (extraLen%d == INDEFINITE_LEN)\n", i);
+ fprintf (src, " BDecEoc (_b, bytesDecoded);\n");
+ }
+
+ fprintf (src, "}\n\n");
+ }
+ /* end of BDec function */
+
+
+ if(genPERCode)
+ {
+ /* do PER Encode, PEnc function */
+ if (printEncodersG)
+ {
+ /****************************/
+ /*** FIRST, handle index encoding for PER Choice. Taking advantage of
+ * the AsnInt class with constraints for the detailed encoding
+ * details. Declare outside scope of source method for PEnc/PDec. */
+ fprintf (src, "class AsnIntChoice_%s: public AsnInt {\n", td->cxxTypeDefInfo->className);
+ fprintf (src, " public:\n");
+ fprintf (src, " AsnIntChoice_%s(AsnIntType val=0):AsnInt(val){ }\n",
+ td->cxxTypeDefInfo->className);
+ fprintf (src, " ValueRange* ValueRanges(int &sizeVRList)\n");
+ fprintf (src, " {\n");
+ fprintf (src, " static ValueRange INT1_ValueRangeList[] = \n");
+ fprintf (src, " {{ 0, %d, 1 }};\n",
+ choice->basicType->a.choice->count); /* CONSTANT value for this CHOICE. */
+ fprintf (src, " sizeVRList = 1;\n");
+ fprintf (src, " return INT1_ValueRangeList;\n");
+ fprintf (src, " }\n");
+ fprintf (src, "};\n\n");
+
+ //RWC;fprintf (hdr, " AsnLen PEnc(AsnBufBits &_b, bool bAlign = false) const {AsnLen len; len = 1;return len;};\n");
+ //fprintf (hdr, " %s P%s (AsnBufBits &_b) const;\n", lenTypeNameG, r->encodeBaseName);
+ fprintf (src, "%s %s::P%s (AsnBufBits &_b) const\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName);
+ fprintf (src, "{\n");
+ fprintf (src, " %s l=0;\n", lenTypeNameG);
+ fprintf (src, " FUNC(\"%s::P%s (AsnBufBits &_b)\");\n", td->cxxTypeDefInfo->className, r->encodeBaseName);
+
+ /****************************/
+ /*** PERFORM sorting of Choice elements for proper index setting. */
+ PrintPyDefCode_PERSort(&ppElementNamedType, &pElementTag, choice->basicType->a.choice);
+ fprintf (src, " AsnIntChoice_%s TmpAsnIntChoice(%d);\n",
+ td->cxxTypeDefInfo->className,
+ choice->basicType->a.choice->count); /* CONSTANT value for this CHOICE. */
+ for (ii=0; ii < choice->basicType->a.choice->count; ii++)
+ {
+ fprintf (src, " if (%s == %s::%s)\n", r->choiceIdFieldName,
+ td->cxxTypeDefInfo->className,
+ ppElementNamedType[ii]->type->cxxTypeRefInfo->choiceIdSymbol);
+ fprintf (src, " TmpAsnIntChoice.Set(%d); // SORTED index value.\n", ii);
+ } // END FOR ii
+ free(ppElementNamedType);
+ free(pElementTag);
+
+ /*** SETUP specific sorted index value. */
+ fprintf (src, " l = TmpAsnIntChoice.PEnc(_b); // LOAD PER encoded, constrained Choice index value.\n");
+
+ fprintf (src, " switch (%s)\n", r->choiceIdFieldName);
+ fprintf (src, " {\n");
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+ {
+ cxxtri = e->type->cxxTypeRefInfo;
+ fprintf (src, " case %s:\n", cxxtri->choiceIdSymbol);
+
+ varName = cxxtri->fieldName;
+
+ /* encode content */
+ tmpTypeId = GetBuiltinType (e->type);
+ if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+ {
+ defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+ PrintPySetTypeByCode(defByNamedType, cxxtri, src);
+ }
+ else if (tmpTypeId == BASICTYPE_ANY)
+ {
+ fprintf (src, " l += %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "P%s (_b);\n", r->encodeBaseName);
+ }
+ else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) ||
+ (tmpTypeId == BASICTYPE_BITCONTAINING))
+ {
+ PrintPyPEREncodeContaining(e->type, r, src);
+ }
+ else
+ {
+ fprintf (src, " l += %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "P%s (_b);\n", r->encodeBaseName);
+ }
+ fprintf (src, " break;\n\n");
+ }
+ fprintf (src, " default:\n");
+ fprintf (src, " throw EXCEPT(\"Choice is empty\", ENCODE_ERROR);\n");
+ fprintf (src, " } // end switch\n");
+ /****************************/
+
+ fprintf (src, " return l;\n");
+ fprintf (src, "} //%s::P%s(...)\n\n", td->cxxTypeDefInfo->className, r->encodeBaseName);
+ } /* END IF printEncodersG */
+ /* end of PEnc function */
+
+ /* Do PDec function */
+ if (printDecodersG)
+ {
+ //fprintf (hdr, " void P%s (AsnBufBits &_b, %s &bitsDecoded);\n", r->decodeBaseName, lenTypeNameG);
+ fprintf (src, "void %s::P%s (AsnBufBits &_b, %s &bitsDecoded)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, lenTypeNameG);//, envTypeNameG);
+ fprintf (src, "{\n");
+ fprintf (src, "\tClear();\n");
+
+ /* print extra locals for redundant lengths */
+ for (i = 1; (choice->tags != NULL) && (i <= LIST_COUNT (choice->tags)); i++)
+ {
+ //fprintf (src, " %s extraLen%d = 0; \n", lenTypeNameG, i);
+ }
+ fprintf (src, "\n");
+
+ /* decode tag/length pair (s) */
+ elmtLevel = 0;
+
+ /****************************/
+ fprintf (src, " AsnIntChoice_%s TmpAsnIntChoice;\n", td->cxxTypeDefInfo->className);
+
+ /*** SETUP specific sorted index value. */
+ fprintf (src, " TmpAsnIntChoice.PDec(_b, bitsDecoded); // LOAD PER decoded, constrained Choice index value.\n");
+
+ /* decode identifying tag from choice body */
+ fprintf (src, " /* CHOICEs are a special case - grab identifying tag */\n");
+ fprintf (src, " /* this allows easier handling of nested CHOICEs */\n");
+
+ /* print local vars */
+ /* count max number of extra length var nec
+ * by counting tag/len pairs on components of the CHOICE
+ */
+ varCount = 0;
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+ {
+ tmpVarCount = CxxCountVariableLevels (e->type);
+ if (tmpVarCount > varCount)
+ varCount = tmpVarCount;
+ }
+
+ /*** PERFORM sorting of Choice elements for proper index setting, then
+ determine actual Choice chosen by the user. */
+ PrintPyDefCode_PERSort(&ppElementNamedType, &pElementTag, choice->basicType->a.choice);
+ for (ii=0; ii < choice->basicType->a.choice->count; ii++)
+ {
+ fprintf (src, " if (TmpAsnIntChoice == %d)\n", ii);
+ fprintf (src, " {\n");
+ fprintf (src, " %s = %s::%s;\n", r->choiceIdFieldName,
+ td->cxxTypeDefInfo->className,
+ ppElementNamedType[ii]->type->cxxTypeRefInfo->choiceIdSymbol);
+
+ /* Process specific tag - choices always have the key tag decoded */
+ e = ppElementNamedType[ii];
+ cxxtri = e->type->cxxTypeRefInfo;
+
+ varName = cxxtri->fieldName;
+
+ /* alloc elmt if nec */
+ if (cxxtri->isPtr)
+ {
+ fprintf (src, " %s = new %s;\n", varName, cxxtri->className);
+ }
+ /* decode content */
+ tmpTypeId = GetBuiltinType (e->type);
+ if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+ {
+ /*
+ * must check for another EOC for ANYs
+ * since the any decode routines decode
+ * their own first tag/len pair
+ */
+ elmtLevel++;
+
+ defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+ PrintPySetTypeByCode(defByNamedType, cxxtri, src);
+
+ fprintf (src, " %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+ fprintf (src, "P%s (_b, bitsDecoded);\n", r->decodeBaseName);
+ }
+ else if (tmpTypeId == BASICTYPE_ANY)
+ {
+ elmtLevel++;
+ fprintf (src, " %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+ fprintf (src, "P%s (_b, bitsDecoded);\n", r->decodeBaseName);
+ }
+ else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) ||
+ (tmpTypeId == BASICTYPE_BITCONTAINING) )
+ {
+ PrintPyPERDecodeContaining(e->type, r, src);
+ }
+ else
+ {
+ fprintf (src, " %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "P%s (_b, bitsDecoded);\n", r->decodeBaseName);
+ }
+
+
+ fprintf (src, " } // END if this Choice ID chosen\n");
+ } // END FOR ii
+
+ free(ppElementNamedType);
+ free(pElementTag);
+
+ fprintf (src, "} // END %s::P%s(...)\n\n", td->cxxTypeDefInfo->className, r->decodeBaseName);
+ }
+ /* end of PDec function */
+ } /* if genPERCode */
+
+
+ /* ostream printing routine */
+ if (printPrintersG)
+ {
+ fprintf(src, "void %s::Print(std::ostream& os, unsigned short indent) const\n",
+ td->cxxTypeDefInfo->className);
+ fprintf(src, "{\n");
+ fprintf(src, "\tswitch (choiceId)\n");
+ fprintf(src, "\t{\n");
+
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+ {
+ fprintf (src, "\tcase %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol);
+
+ /* value notation so print the choice elmts field name */
+ if (e->fieldName != NULL)
+ fprintf(src, "\t\tos << \"%s \";\n", e->fieldName);
+
+ if (e->type->cxxTypeRefInfo->isPtr)
+ {
+ fprintf(src, "\t\tif (%s)\n", e->type->cxxTypeRefInfo->fieldName);
+ fprintf(src, "\t\t\t%s->Print(os, indent);\n",
+ e->type->cxxTypeRefInfo->fieldName);
+ fprintf(src, "\t\telse\n");
+ fprintf(src, "\t\t\tos << \"<CHOICE value is missing>\\n\";\n");
+ }
+ else
+ {
+ fprintf(src, "\t\t%s.Print(os, indent);\n",
+ e->type->cxxTypeRefInfo->fieldName);
+ }
+
+ fprintf (src, "\t\tbreak;\n\n");
+ }
+ fprintf (src, "\t} // end of switch\n");
+
+ fprintf (src, "} // end of %s::Print()\n\n", td->cxxTypeDefInfo->className);
+
+ //fprintf(hdr, " void PrintXML (std::ostream &os, const char *lpszTitle=NULL) const;\n");
+
+ fprintf(src, "void %s::PrintXML (std::ostream &os, const char *lpszTitle) const\n", td->cxxTypeDefInfo->className);
+ fprintf(src, "{\n");
+ fprintf(src, " const char *tagName = typeName();\n");
+ fprintf(src, " if (lpszTitle)\n");
+ fprintf(src, " tagName = lpszTitle;");
+ fprintf(src, " os << \"<\" << tagName << \">\";\n");
+ fprintf(src, " switch (choiceId) {\n");
+
+ FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice)
+ {
+ fprintf(src, " case %s:\n",
+ e->type->cxxTypeRefInfo->choiceIdSymbol);
+
+ /* value notation so print the choice elmts field name */
+ if (e->type->cxxTypeRefInfo->isPtr)
+ {
+ fprintf(src, " if (%s) {\n",
+ e->type->cxxTypeRefInfo->fieldName);
+ fprintf(src, " %s->PrintXML(os", e->type->cxxTypeRefInfo->fieldName);
+ if (e->fieldName != NULL)
+ fprintf(src, ",\"%s\");\n", e->fieldName);
+ else
+ fprintf(src, ");\n");
+ fprintf(src, " }\n");
+ } else
+ fprintf(src, " %s.PrintXML(os, \"%s\");\n",
+ e->type->cxxTypeRefInfo->fieldName, e->fieldName);
+
+ fprintf(src, " break;\n\n");
+ }
+ fprintf (src, " } // end of switch\n");
+ fprintf (src, " os << \"</\" << tagName << \">\";\n");
+ fprintf (src, "} // %s::PrintXML\n\n", td->cxxTypeDefInfo->className);
+ }
+ /* end of Print Method code */
+} /* PrintPyChoiceDefCode */
+
+static char *
+PyDetermineCode(Tag *tag, int *ptagLen, int bJustIntegerFlag)
+{
+ static char retstring[256];
+ char *codeStr=NULL;
+ int iValue=500; // WILL indicate a problem on source creation...
+ memset(retstring, 0, sizeof(retstring));
+ if (tag->valueRef == NULL) {
+ if (!bJustIntegerFlag) {
+ char *univstr = Code2UnivCodeStr (tag->code);
+ sprintf(retstring, "asn_base.BERConsts.%s", univstr);
+ } else {
+ sprintf(retstring, "%d", tag->code);
+ }
+ codeStr = retstring;
+ if (ptagLen) {
+ *ptagLen = TagByteLen(tag->code);
+ }
+ } else {
+ if (tag->valueRef && tag->valueRef->basicValue &&
+ tag->valueRef->basicValue->choiceId == BASICVALUE_LOCALVALUEREF &&
+ tag->valueRef->basicValue->a.localValueRef &&
+ tag->valueRef->basicValue->a.localValueRef->link &&
+ tag->valueRef->basicValue->a.localValueRef->link->value &&
+ tag->valueRef->basicValue->a.localValueRef->link->value->basicValue)
+ {
+ if (tag->valueRef->basicValue->a.localValueRef->link->value->basicValue->choiceId ==
+ BASICVALUE_INTEGER)
+ {
+ iValue = tag->valueRef->basicValue->a.localValueRef->link->
+ value->basicValue->a.integer;
+ } // IF Integer
+ else if (tag->valueRef->basicValue->a.localValueRef->link->value->basicValue->choiceId ==
+ BASICVALUE_LOCALVALUEREF)
+ {
+ ValueRef *pvalueRef=NULL;
+ if (tag->valueRef->basicValue->a.localValueRef->link->value->basicValue->choiceId == BASICVALUE_LOCALVALUEREF)
+ {
+ pvalueRef = tag->valueRef->basicValue->a.localValueRef->link->value->basicValue->a.localValueRef;
+ if (pvalueRef->link->value && pvalueRef->link->value->basicValue &&
+ pvalueRef->link->value->basicValue->choiceId == BASICVALUE_INTEGER)
+ iValue = pvalueRef->link->value->basicValue->a.integer;
+ }
+ } // END IF Integer/Import
+ else
+ {
+ printf("Tag value type NOT RECOGNIZED; COULD NOT RESOLVE tag integer!\n");
+ }
+ } else if (tag->valueRef->basicValue->choiceId ==
+ BASICVALUE_IMPORTVALUEREF &&
+ tag->valueRef->basicValue->a.importValueRef &&
+ tag->valueRef->basicValue->a.importValueRef->link &&
+ tag->valueRef->basicValue->a.importValueRef->link->value &&
+ tag->valueRef->basicValue->a.importValueRef->link->value->
+ basicValue &&
+ tag->valueRef->basicValue->a.importValueRef->link->value->
+ basicValue->choiceId == BASICVALUE_INTEGER) {
+ iValue = tag->valueRef->basicValue->a.importValueRef->link->
+ value->basicValue->a.integer;
+ }
+ sprintf(retstring, "%d", iValue);
+ codeStr = retstring;
+ if (ptagLen) {
+ *ptagLen = TagByteLen(iValue);
+ }
+ }
+ return(codeStr);
+}
+
+static void
+PrintPySeqOrSetDefCode (FILE *src, FILE *hdr, ModuleList *mods, Module *m,
+ PyRules *r ,TypeDef *td, Type *parent ESNACC_UNUSED,
+ Type *seq, int novolatilefuncs ESNACC_UNUSED,
+ int isSequence)
+{
+ NamedType *e;
+ char *classStr;
+ char *formStr;
+ char *codeStr;
+ int tagLen, i=0;
+ Tag *tag;
+ TagList *tags;
+ char *varName;
+ CxxTRI *cxxtri=NULL;
+ int elmtLevel=0;
+ int varCount, tmpVarCount;
+ int stoleChoiceTags;
+ int inTailOptElmts;
+ enum BasicTypeChoiceId tmpTypeId;
+ NamedType *defByNamedType;
+ NamedType *tmpElmt;
+
+ // DEFINE PER encode/decode tmp vars.
+ NamedType **pSeqElementNamedType=NULL;
+ int ii;
+ int extensionAdditionFound = FALSE;
+
+ fprintf(src, "class %s%s:\n\n", td->cxxTypeDefInfo->className,
+ baseClassesG);
+
+ tag = seq->tags->first->data;
+ classStr = Class2ClassStr (tag->tclass);
+ //formStr = Form2FormStr(CONS);
+ codeStr = PyDetermineCode(tag, NULL, (tag->tclass == UNIV) ? 0 : 1);
+ fprintf(src, " BER_CLASS=asn_base.BERConsts.%s\n", classStr);
+ fprintf(src, " BER_FORM=asn_base.BERConsts.BER_CONSTRUCTED_FORM\n\n");
+ fprintf(src, " BER_TAG=%s\n", codeStr);
+ /* write out the sequence elmts */
+
+ if (!seq->basicType->a.sequence || !seq->basicType->a.sequence->count) {
+ fprintf(stderr, "WARNING: Sequence unknown?\n");
+ }
+
+ /* constructor */
+ fprintf(src, " def __init__(self");
+ FOR_EACH_LIST_ELMT(e, seq->basicType->a.sequence) {
+ fprintf(src, ", %s", e->type->cxxTypeRefInfo->fieldName);
+
+ if (e->type->defaultVal) {
+ Value *defVal = GetValue(e->type->defaultVal->value);
+ switch (ParanoidGetBuiltinType(e->type)) {
+ case BASICTYPE_INTEGER:
+ case BASICTYPE_ENUMERATED:
+ fprintf(src, " = %s(%s)",
+ e->type->cxxTypeRefInfo->className,
+ defVal->basicValue->a.integer);
+ break;
+ case BASICTYPE_BOOLEAN:
+ fprintf(src, " = asn_bool.AsnBool(%s)",
+ defVal->basicValue->a.boolean == 0 ?
+ "\"False\"" : "\"True\"");
+ break;
+ case BASICTYPE_BITSTRING:
+ fprintf(stderr,
+ "WARNING: unsupported default BIT STRING\n");
+ break;
+ default:
+ fprintf(src, " = %s()\n",
+ e->type->cxxTypeRefInfo->className);
+ break;
+ } /* end switch */
+ } else {
+ fprintf(src, " = None");
+ }
+ }
+ fprintf(src, "):\n");
+
+ FOR_EACH_LIST_ELMT(e, seq->basicType->a.sequence) {
+ fprintf(src, " if ");
+ fprintf(src, "%s is not None and ",
+ e->type->cxxTypeRefInfo->fieldName);
+ fprintf(src, "not isinstance(%s, %s):\n",
+ e->type->cxxTypeRefInfo->fieldName,
+ e->type->cxxTypeRefInfo->className);
+ fprintf(src, " raise TypeError(\"Expected %s for %s\")\n",
+ e->type->cxxTypeRefInfo->className,
+ e->type->cxxTypeRefInfo->fieldName);
+ fprintf(src, " else:\n");
+ fprintf(src, " self.%s = %s\n",
+ e->type->cxxTypeRefInfo->fieldName,
+ e->type->cxxTypeRefInfo->fieldName);
+ }
+
+ fprintf(src, "\n\n");
+
+ /* benccontent */
+ fprintf(src, " def BEncContent(self, asnbuf):\n");
+ fprintf(src, " asnlen = 0\n");
+ FOR_EACH_LIST_ELMT(e, seq->basicType->a.sequence) {
+ fprintf(src, " ");
+ if (e->type->cxxTypeRefInfo->isPtr)
+ fprintf(src, "if self.%s is not None:\n ",
+ e->type->cxxTypeRefInfo->fieldName);
+ else
+ fprintf(src, "if self.%s is None:\n "
+ "raise UnboundLocalError('Populate %s before encoding')\n"
+ " ",
+ e->type->cxxTypeRefInfo->fieldName,
+ e->type->cxxTypeRefInfo->fieldName);
+ fprintf(src, "asnlen += self.%s.BEnc(asnbuf)\n",
+ e->type->cxxTypeRefInfo->fieldName);
+ }
+ fprintf(src, " return asnlen\n\n");
+
+ /* bdeccontent */
+ fprintf(src, " def BDecContent(self, asnbuf, length):\n");
+ fprintf(src, " asnlen = 0\n");
+ FOR_EACH_LIST_ELMT(e, seq->basicType->a.sequence) {
+ int i = 0;
+ fprintf(src, " # Total num tags: %d\n", e->type->tags->count);
+ FOR_EACH_LIST_ELMT(tag, e->type->tags) {
+ if (i) {
+ fprintf(src, " bufTag = ord(asnbuf.Buffer()[0])\n");
+ fprintf(src, " if bufTag != TAG_CODE_EXPECTED:\n");
+ fprintf(src, " raise Exception('AHH!')\n");
+ fprintf(src, " asnlen += 1\n"
+ " asnbuf.swallow(1)\n");
+ fprintf(src, " tagTotalLen, totalBytesLen = asn_buffer.BDecDefLen(asnbuf)\n");
+ fprintf(src, " asnlen += tagTotalLen\n");
+ } else {
+ i = 1;
+ }
+ fprintf(src,
+ " TAG_CODE_EXPECTED = asn_base.BERConsts.MakeTag(asn_base.BERConsts.%s, asn_base.BERConsts.%s, %d)\n",
+ Class2ClassStr(tag->tclass), Form2FormStr(tag->form), tag->code);
+ }
+ if (!e->type->tags->count) {
+ fprintf(src,
+ " TAG_CODE_EXPECTED = asn_base.BERConsts.MakeTag(%s.BER_CLASS,\n"
+ " %s.BER_FORM,\n"
+ " %s.BER_TAG)\n",
+ e->type->cxxTypeRefInfo->className,
+ e->type->cxxTypeRefInfo->className,
+ e->type->cxxTypeRefInfo->className);
+ }
+ fprintf(src, " bufTag = ord(asnbuf.Buffer()[0])\n");
+ fprintf(src, " if bufTag != TAG_CODE_EXPECTED:\n");
+ if (!e->type->cxxTypeRefInfo->isPtr)
+ fprintf(src, " raise Exception('Unexpected: %%x; expected: %%x' % (bufTag, TAG_CODE_EXPECTED))\n");
+ else
+ fprintf(src, " pass\n");
+ fprintf(src, " else:\n");
+ fprintf(src, " self.%s = %s()\n",
+ e->type->cxxTypeRefInfo->fieldName,
+ e->type->cxxTypeRefInfo->className);
+ fprintf(src, " asnlen += self.%s.BDec(asnbuf, length)\n",
+ e->type->cxxTypeRefInfo->fieldName);
+ }
+ fprintf(src, " return asnlen\n\n");
+}
+
+
+static void
+PrintPySeqDefCode (FILE *src, FILE *hdr, ModuleList *mods, Module *m,
+ PyRules *r ,TypeDef *td, Type *parent ESNACC_UNUSED,
+ Type *seq, int novolatilefuncs ESNACC_UNUSED)
+{
+
+ PrintPySeqOrSetDefCode (src, hdr, mods, m, r, td, parent, seq,
+ novolatilefuncs, 1);
+
+} /* PrintPySeqDefCode */
+
+
+static void
+PrintPySetDefCode (FILE *src, FILE *hdr, ModuleList *mods, Module *m,
+ PyRules *r, TypeDef *td, Type *parent ESNACC_UNUSED,
+ Type *set, int novolatilefuncs ESNACC_UNUSED)
+{
+ PrintPySeqOrSetDefCode (src, hdr, mods, m, r, td, parent, set,
+ novolatilefuncs, 0);
+
+} /* PrintPySetDefCode */
+
+
+/*
+ * PIERCE added 8-21-2001 template code to handle SET/SEQ OF
+ *
+ */
+static void
+PrintPyListClass(FILE *src, TypeDef *td, Type *lst, Module* m,
+ ModuleList *mods)
+{
+ struct NamedType p_etemp;
+ NamedType* p_e;
+ char typeNameStr[256];
+ char *lcn; /* list class name */
+ char *ecn; /* (list) elmt class name */
+ char pcvarname[100];
+
+ p_e=&p_etemp;
+ p_e->type=lst->basicType->a.setOf;
+
+ ecn = lst->basicType->a.setOf->cxxTypeRefInfo->className;
+ lcn = td->cxxTypeDefInfo->className;
+
+ fprintf(src, "class %s(asn_list.", lcn);
+ switch (lst->basicType->choiceId) {
+ case BASICTYPE_SEQUENCEOF:
+ fprintf(src, "AsnSequenceOf");
+ break;
+ case BASICTYPE_SETOF:
+ fprintf(src, "AsnSetOf");
+ break;
+
+ default:
+ break;
+ }
+ fprintf(src, "):\n");
+ fprintf(src, " def __init__(self, elemts=None, expected=None):\n");
+ fprintf(src, " if expected is None:\n");
+ fprintf(src, " expected = %s\n", ecn);
+ fprintf(src, " asn_list.%s.__init__(self, elemts, expected)\n\n",
+ (lst->basicType->choiceId == BASICTYPE_SEQUENCEOF) ?
+ "AsnSequenceOf" : "AsnSetOf");
+
+ fprintf(src, " def typename(self):\n");
+ fprintf(src, " return \"%s\"\n\n", lcn);
+ // JKG--added functionality for sequence of and set of constraints
+ if (td->type->subtypes != NULL)
+ {
+ /*Subtype* s_type;*/
+ /*s_type = (Subtype*)td->type->subtypes->a.single->a.sizeConstraint->a.or->last->data;*/
+ /* Only single size constraints that are themselves single are supported */
+ if ((td->type->subtypes->choiceId == SUBTYPE_SINGLE) &&
+ (td->type->subtypes->a.single->choiceId == SUBTYPEVALUE_SIZECONSTRAINT) &&
+ (td->type->subtypes->a.single->a.sizeConstraint->choiceId == SUBTYPE_SINGLE))
+ {
+#if 0
+ PrintPySetOfSizeConstraint(src,
+ td->type->subtypes->a.single->a.sizeConstraint->a.single,
+ m, td->type);
+#endif
+ }
+ else
+ {
+ PrintErrLoc(m->asn1SrcFileName, (long)td->type->lineNo);
+ fprintf(errFileG, "ERROR - unsupported constraint\n");
+ }
+ }
+
+}
+
+static void
+PrintPySetOfDefCode PARAMS ((src, mods, m, r, td, parent, setOf, novolatilefuncs),
+ FILE *src _AND_
+ ModuleList *mods _AND_
+ Module *m _AND_
+ PyRules *r _AND_
+ TypeDef *td _AND_
+ Type *parent _AND_
+ Type *setOf _AND_
+ int novolatilefuncs)
+{
+ // Get rid of warnings
+ novolatilefuncs = novolatilefuncs;
+ parent = parent;
+ m = m;
+ r = r;
+ mods = mods;
+ src = src;
+
+ /* do class */
+ PrintPyListClass(src, td, setOf, m, mods);
+
+} /* PrintPySetOfDefCode */
+
+
+static void
+PrintPyTypeDefCode PARAMS ((src, hdr, mods, m, r, td, novolatilefuncs),
+ FILE *src _AND_
+ FILE *hdr _AND_
+ ModuleList *mods _AND_
+ Module *m _AND_
+ PyRules *r _AND_
+ TypeDef *td _AND_
+ int novolatilefuncs)
+{
+ switch (td->type->basicType->choiceId) {
+ case BASICTYPE_BOOLEAN: /* library type */
+ case BASICTYPE_REAL: /* library type */
+ case BASICTYPE_OCTETSTRING: /* library type */
+ case BASICTYPE_NULL: /* library type */
+ case BASICTYPE_EXTERNAL: /* library type */
+ case BASICTYPE_OID: /* library type */
+ case BASICTYPE_RELATIVE_OID:
+ case BASICTYPE_INTEGER: /* library type */
+ case BASICTYPE_BITSTRING: /* library type */
+ case BASICTYPE_ENUMERATED: /* library type */
+ case BASICTYPE_NUMERIC_STR: /* 22 */
+ case BASICTYPE_PRINTABLE_STR: /* 23 */
+ case BASICTYPE_UNIVERSAL_STR: /* 24 */
+ case BASICTYPE_IA5_STR: /* 25 */
+ case BASICTYPE_BMP_STR: /* 26 */
+ case BASICTYPE_UTF8_STR: /* 27 */
+ case BASICTYPE_UTCTIME: /* 28 tag 23 */
+ case BASICTYPE_GENERALIZEDTIME: /* 29 tag 24 */
+ case BASICTYPE_GRAPHIC_STR: /* 30 tag 25 */
+ case BASICTYPE_VISIBLE_STR: /* 31 tag 26 aka ISO646String */
+ case BASICTYPE_GENERAL_STR: /* 32 tag 27 */
+ case BASICTYPE_OBJECTDESCRIPTOR: /* 33 tag 7 */
+ case BASICTYPE_VIDEOTEX_STR: /* 34 tag 21 */
+ case BASICTYPE_T61_STR: /* 35 tag 20 */
+ PrintPySimpleDef(hdr, src, r, td);
+ break;
+ case BASICTYPE_SEQUENCEOF: /* list types */
+ case BASICTYPE_SETOF:
+ PrintPySetOfDefCode(src, mods, m, r, td, NULL, td->type,
+ novolatilefuncs);
+ break;
+ case BASICTYPE_IMPORTTYPEREF: /* type references */
+ case BASICTYPE_LOCALTYPEREF:
+ /*
+ * if this type has been re-tagged then
+ * must create new class instead of using a typedef
+ */
+ PrintPySimpleDef(hdr, src, r, td);
+ break;
+ case BASICTYPE_CHOICE:
+ PrintPyChoiceDefCode (src, hdr, mods, m, r, td, NULL, td->type, novolatilefuncs);
+ break;
+ case BASICTYPE_SET:
+ PrintPySetDefCode (src, hdr, mods, m, r, td, NULL, td->type, novolatilefuncs);
+ break;
+ case BASICTYPE_SEQUENCE:
+ PrintPySeqDefCode (src, hdr, mods, m, r, td, NULL, td->type, novolatilefuncs);
+ break;
+ case BASICTYPE_COMPONENTSOF:
+ case BASICTYPE_SELECTION:
+ case BASICTYPE_UNKNOWN:
+ case BASICTYPE_MACRODEF:
+ case BASICTYPE_MACROTYPE:
+ case BASICTYPE_ANYDEFINEDBY: /* ANY types */
+ case BASICTYPE_ANY:
+ /* do nothing */
+ break;
+ default:
+ /* TBD: print error? */
+ break;
+ }
+} /* PrintPyTypeDefCode */
+
+void
+PrintPyCode PARAMS ((src, hdr, if_META (printMeta COMMA meta COMMA meta_pdus COMMA)
+ mods, m, r, longJmpVal, printTypes, printValues,
+ printEncoders, printDecoders, printPrinters, printFree
+ if_TCL (COMMA printTcl), novolatilefuncs),
+ FILE *src _AND_
+ FILE *hdr _AND_
+ if_META (MetaNameStyle printMeta _AND_)
+ if_META (const Meta *meta _AND_)
+ if_META (MetaPDU *meta_pdus _AND_)
+ ModuleList *mods _AND_
+ Module *m _AND_
+ PyRules *r _AND_
+ long longJmpVal _AND_
+ int printTypes _AND_
+ int printValues _AND_
+ int printEncoders _AND_
+ int printDecoders _AND_
+ int printPrinters _AND_
+ int printFree
+ if_TCL (_AND_ int printTcl) _AND_
+ int novolatilefuncs)
+{
+ Module *currMod;
+ AsnListNode *currModTmp;
+ TypeDef *td;
+ ValueDef *vd;
+
+
+ printTypesG = printTypes;
+ printEncodersG = printEncoders;
+ printDecodersG = printDecoders;
+ printPrintersG = printPrinters;
+ printFreeG = printFree;
+
+#if META
+ printMetaG = printMeta;
+ meta_pdus_G = meta_pdus;
+#if TCL
+ printTclG = printTcl;
+#endif /* TCL */
+#endif /* META */
+
+ PrintSrcComment(src, m);
+ PrintSrcIncludes(src);
+
+ FOR_EACH_LIST_ELMT (currMod, mods) {
+ if (!strcmp(m->cxxHdrFileName, currMod->cxxHdrFileName)) {
+ ImportModuleList *ModLists;
+ ImportModule *impMod;
+ char *ImpFile = NULL;
+ ModLists = currMod->imports;
+ currModTmp = mods->curr;
+ FOR_EACH_LIST_ELMT(impMod, ModLists) {
+ ImpFile = GetImportFileName(impMod->modId->name, mods);
+ if (ImpFile != NULL)
+ fprintf(src, "import %s\n", ImpFile);
+ if (impMod->moduleRef == NULL)
+ impMod->moduleRef = GetImportModuleRef(impMod->modId->name, mods);
+ }
+ mods->curr = currModTmp;
+ }
+ }
+ fprintf(src, "\n");
+
+ if (printValues) {
+ fprintf(src, "# value defs\n\n");
+ FOR_EACH_LIST_ELMT (vd, m->valueDefs) {
+#if 0
+ PrintPyValueDef(src, r, vd);
+#endif
+ }
+ fprintf(src, "\n");
+ }
+
+ fprintf(src, "# class member definitions:\n\n");
+ PrintPyAnyCode (src, hdr, r, mods, m);
+
+ FOR_EACH_LIST_ELMT (td, m->typeDefs) {
+ PrintPyTypeDefCode(src, hdr, mods, m, r, td, novolatilefuncs);
+ }
+
+} /* PrintPyCode */
+
+
+void PrintPyEncodeContaining(Type *t, PyRules *r, FILE *src)
+{
+ fprintf(src, " l += %s", t->cxxTypeRefInfo->fieldName);
+ if (t->cxxTypeRefInfo->isPtr)
+ fprintf(src, "->");
+ else
+ fprintf(src, ".");
+
+ fprintf(src, "B%s(_b);\n", r->encodeBaseName);
+
+ /* If this is a BITSTRING CONTAINING encode a NULL octet for the unused
+ * bits
+ */
+ if (t->basicType->choiceId == BASICTYPE_BITCONTAINING)
+ {
+ fprintf(src," _b.PutByteRvs((char) 0 ); //encode 0 for unused bits\n");
+ fprintf(src," l++;\n");
+ }
+}
+
+void PrintPyDecodeContaining(Type *t, PyRules *r, FILE *src)
+{
+ NamedType *defByNamedType;
+
+ /* Encode Content of contained type */
+ if (t->basicType->a.stringContaining->basicType->choiceId ==
+ BASICTYPE_ANYDEFINEDBY)
+ {
+ defByNamedType =
+ t->basicType->a.stringContaining->basicType->a.anyDefinedBy->link;
+ PrintPySetTypeByCode(defByNamedType, t->cxxTypeRefInfo, src);
+ }
+
+ if (t->basicType->choiceId == BASICTYPE_BITCONTAINING)
+ {
+ fprintf(src,"\n");
+ fprintf(src," // Decode unused bits and make sure it's 0\n");
+ fprintf(src," char unusedBits;\n");
+ fprintf(src," unusedBits = _b.GetByte();\n");
+ fprintf(src," seqBytesDecoded++;\n");
+ fprintf(src," if (unusedBits != '0x0')\n");
+ fprintf(src," throw DecodeException(STACK_ENTRY);\n");
+ fprintf(src,"\n");
+ }
+
+ fprintf (src, " %s", t->cxxTypeRefInfo->fieldName);
+ if (t->cxxTypeRefInfo->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "B%s (_b, seqBytesDecoded);\n", r->decodeBaseName);
+}
+
+
+void PrintPyPEREncodeContaining(Type *t, PyRules *r, FILE *src)
+{
+ fprintf(src, " l += %s", t->cxxTypeRefInfo->fieldName);
+ if (t->cxxTypeRefInfo->isPtr)
+ fprintf(src, "->");
+ else
+ fprintf(src, ".");
+
+ fprintf(src, "P%s(_b);\n", r->encodeBaseName);
+
+ /* If this is a BITSTRING CONTAINING encode a NULL octet for the unused
+ * bits
+ */
+ if (t->basicType->choiceId == BASICTYPE_BITCONTAINING)
+ {
+ fprintf(src," unsigned char _tmp[] = {0x00};\n");
+ fprintf(src," _b.PutBits(tmp , 8); //encode 0 for unused bits\n");
+ fprintf(src," l++;\n");
+ }
+}
+
+void PrintPyPERDecodeContaining(Type *t, PyRules *r, FILE *src)
+{
+ NamedType *defByNamedType;
+
+ /* Encode Content of contained type */
+ if (t->basicType->a.stringContaining->basicType->choiceId ==
+ BASICTYPE_ANYDEFINEDBY)
+ {
+ defByNamedType =
+ t->basicType->a.stringContaining->basicType->a.anyDefinedBy->link;
+ PrintPySetTypeByCode(defByNamedType, t->cxxTypeRefInfo, src);
+ }
+
+ if (t->basicType->choiceId == BASICTYPE_BITCONTAINING)
+ {
+ fprintf(src,"\n");
+ fprintf(src," // Decode unused bits and make sure it's 0\n");
+ fprintf(src," unsigned char* unusedBits;\n");
+ fprintf(src," unusedBits = _b.GetBits(8);\n");
+ fprintf(src," bitsDecoded++;\n");
+ fprintf(src," if (unusedBits[0] != '0x0')\n");
+ fprintf(src," throw DecodeException(STACK_ENTRY);\n");
+ fprintf(src,"\n");
+ }
+
+ fprintf (src, " %s", t->cxxTypeRefInfo->fieldName);
+ if (t->cxxTypeRefInfo->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "P%s (_b, bitsDecoded);\n", r->decodeBaseName);
+}
+
+
+void PrintPySetTypeByCode(NamedType *defByNamedType, CxxTRI *cxxtri, FILE *src)
+{
+ char *varName = cxxtri->fieldName;
+
+ if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID)
+ {
+ fprintf (src, " %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "SetTypeByOid (");
+ if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+ fprintf (src, " *");
+ fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+ }
+ else if (GetBuiltinType (defByNamedType->type) == BASICTYPE_INTEGER)
+ {
+ fprintf (src, " %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "SetTypeByInt (");
+ if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+ fprintf (src, " *");
+ fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+ }
+ else if (GetBuiltinType (defByNamedType->type) == BASICTYPE_CHOICE)
+ {
+ NamedType *nt;
+ Type *t = GetType(defByNamedType->type);
+
+ if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+ fprintf(src, " switch (%s->choiceId)\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+ else
+ fprintf(src, " switch (%s.choiceId)\n", defByNamedType->type->cxxTypeRefInfo->fieldName);
+ fprintf(src, " {\n");
+
+ FOR_EACH_LIST_ELMT(nt, t->basicType->a.choice)
+ {
+ fprintf(src, " case %s::%sCid:\n", defByNamedType->type->cxxTypeRefInfo->className, nt->fieldName);
+ if (nt->type->basicType->choiceId == BASICTYPE_INTEGER ||
+ nt->type->basicType->choiceId == BASICTYPE_ENUMERATED)
+ {
+ fprintf (src, " %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+ fprintf(src, "SetTypeByInt(*%s->%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName, nt->fieldName);
+ else
+ fprintf(src, "SetTypeByInt(*%s.%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName, nt->fieldName);
+ }
+ else
+ {
+ fprintf (src, " %s", varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ if (defByNamedType->type->cxxTypeRefInfo->isPtr)
+ fprintf(src, "SetTypeByOid(*%s->%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName, nt->fieldName);
+ else
+ fprintf(src, "SetTypeByOid(*%s.%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName, nt->fieldName);
+ }
+ fprintf(src, " break;\n");
+
+ }
+ fprintf(src, " }\n");
+ }
+}
+
+
+static char *
+LookupNamespace PARAMS ((t, mods),
+ Type *t _AND_
+ ModuleList *mods)
+{
+ char *pszNamespace=NULL;
+ Module *mTmp=NULL;
+ TypeDef *ptTmp=NULL;
+ BasicType *pbtTmp2=NULL;
+
+ //RWC; HANDLE namespace designations of specific modules on declarations,
+ // if necessary. (May have to lookup module name to get namespace).
+ pbtTmp2 = t->basicType;
+ if (pbtTmp2->choiceId == BASICTYPE_SEQUENCEOF ||
+ pbtTmp2->choiceId == BASICTYPE_SETOF)
+ pbtTmp2 = pbtTmp2->a.sequenceOf->basicType; // Burrow 1 more layer down for SequenceOf/SetOf
+ if (pbtTmp2->choiceId == BASICTYPE_IMPORTTYPEREF)
+ { // RWC; IF IMPORTED, then we need to check for
+ // optional namespace designation (only in .h)
+ FOR_EACH_LIST_ELMT (mTmp, mods)
+ {
+ ptTmp = LookupType(mTmp->typeDefs,
+ pbtTmp2->a.importTypeRef->typeName); //WHAT we are looking for...
+ if (ptTmp != NULL)
+ break; //FOUND the MODULE that contains our defninition...
+ } // END FOR each module.
+ if (ptTmp != NULL && mTmp != NULL && mTmp->namespaceToUse) // FOUND our MODULE...
+ {
+ pszNamespace = mTmp->namespaceToUse; // DO NOT DELETE...
+ }
+ //LookupType PARAMS ((typeDefList, typeName),
+ } // IF BASICTYPE_IMPORTTYPEREF
+
+ return(pszNamespace);
+} /* END LookupNamespace(...)*/
+
+
+void PrintPySeqSetPrintFunction(FILE* src, FILE* hdr, MyString className,
+ BasicType *pBasicType)
+{
+ int allOpt;
+ int inTailOptElmts;
+ NamedTypeList* pElmtList;
+ NamedType *e;
+
+ fprintf(src, "void %s::Print(std::ostream& os, unsigned short indent) const\n",
+ className);
+ fprintf(src, "{\n");
+
+ if (pBasicType->choiceId == BASICTYPE_SEQUENCE)
+ {
+ fprintf(src, "\tos << \"{ -- SEQUENCE --\" << std::endl;\n");
+ pElmtList = pBasicType->a.sequence;
+ }
+ else if (pBasicType->choiceId == BASICTYPE_SET)
+ {
+ fprintf(src, "\tos << \"{ -- SET --\" << std::endl;\n");
+ pElmtList = pBasicType->a.set;
+ }
+ else
+ abort();
+
+ allOpt = AllElmtsOptional(pElmtList);
+ if (allOpt)
+ fprintf(src, "\tint nonePrinted = true;\n");
+
+ fprintf(src, "++indent;\n\n");
+
+ FOR_EACH_LIST_ELMT (e, pElmtList)
+ {
+ inTailOptElmts = IsTailOptional(pElmtList);
+
+ if (e->type->cxxTypeRefInfo->isPtr)
+ {
+ fprintf(src, "\tif (%s (%s))\n",
+ e->type->cxxTypeRefInfo->optTestRoutineName,
+ e->type->cxxTypeRefInfo->fieldName);
+ fprintf (src, "\t{\n");
+
+ if (allOpt)
+ {
+ if (e != FIRST_LIST_ELMT (pElmtList))
+ {
+ fprintf(src, "\t\tif (!nonePrinted)\n");
+ fprintf(src, "\t\t\tos << \",\" << std::endl;\n");
+ }
+ fprintf(src, "\t\tnonePrinted = false;\n");
+ }
+ /* cannot be first elmt ow allOpt is true */
+ else if (inTailOptElmts)
+ fprintf (src, "\t\tos << \",\"<< std::endl;\n");
+
+ fprintf(src, "\t\tIndent(os, indent);\n");
+
+ if (e->fieldName != NULL)
+ fprintf(src, "\t\tos << \"%s \";\n", e->fieldName);
+
+ fprintf(src, "\t\t%s->Print(os, indent);\n",
+ e->type->cxxTypeRefInfo->fieldName);
+
+ fprintf(src, "\t}\n");
+ }
+ else
+ {
+ fprintf(src, "\tIndent(os, indent);\n");
+
+ if (e->fieldName != NULL)
+ fprintf(src, "\tos << \"%s \";\n", e->fieldName);
+
+ fprintf(src, "\t%s.Print(os, indent);\n",
+ e->type->cxxTypeRefInfo->fieldName);
+
+ if (e != LAST_LIST_ELMT (pElmtList))
+ fprintf(src, "\tos << ',' << std::endl;\n");
+ }
+
+ fprintf (src, "\n");
+
+ if (e == LAST_LIST_ELMT (pElmtList))
+ fprintf(src, "\tos << std::endl;\n");
+ }
+
+ fprintf(src, "\t--indent;\n");
+ fprintf(src, "\tIndent(os, indent);\n");
+ fprintf(src, "\tos << \"}\\n\";\n");
+ fprintf (src, "} // end of %s::Print()\n\n", className);
+} /* end of PrintPySeqSetPrintFunction() */
+
+
+/*
+ * RWC; */
+static void
+PrintPyDefCode_SetSeqPEREncode (FILE *src, FILE *hdr, PyRules *r, TypeDef *td,
+ NamedType **pSetElementNamedType,
+ int iElementCount) /* IN, ELEMENT Count to process in array*/
+{
+ NamedType *e;
+ char *varName;
+ CxxTRI *cxxtri=NULL;
+ enum BasicTypeChoiceId tmpTypeId;
+ NamedType *defByNamedType;
+ int extensionsExist = FALSE;
+
+ // DEFINE PER encode/decode tmp vars.
+ int ii=0;
+ long lOptional_Default_ElmtCount=0;
+ const char* tabAndlenVar = "\tl";
+
+ //fprintf(hdr, "\t%s\t\tP%s(AsnBufBits &_b) const;\n", lenTypeNameG,
+ // r->encodeBaseName);
+ /*RWC; {AsnLen len; len = 1;return len;};\n");
+ RWC; MUST sort the results by tag; usually explicit except for
+ RWC; untagged Choices which can be nested. We must determine which
+ RWC; tag can go 1st from any Choice, potentially nested.
+ RWC; (FORWARD ENCODING FOR PER!)*/
+
+ fprintf(src, "%s %s::P%s(AsnBufBits &_b) const\n", lenTypeNameG,
+ td->cxxTypeDefInfo->className, r->encodeBaseName);
+ fprintf(src, "{\n\t%s l = 0;\n", lenTypeNameG);
+
+ /* SECOND, determine ahead of time the bit count for OPTIONAL/DEFAULT values. */
+ for (ii=0; ii < iElementCount; ii++)
+ {
+ e = pSetElementNamedType[ii];
+
+ //RWC; ALSO, count any OPTIONAL/DEFAULT ASN.1 elements.
+ if ( (e->type->optional || e->type->defaultVal != NULL) && (!e->type->extensionAddition))
+ lOptional_Default_ElmtCount++;
+ }
+
+ /* NEXT, decode this number of bits, if any, to determine the
+ presence/absence of OPTIONAL/DEFAULT elements.*/
+ if (lOptional_Default_ElmtCount)
+ { /* NOW, load PER encoding flag to indicate what OPTIONAL/DEFAULT
+ fields are actually present.*/
+ /* FOR PER ENCODING OF Set, we must load a bitfield of length
+ "lOptional_Default_ElmtCount", indicating presence of optional
+ or default field data. */
+ int iOptional_Default_ElementIndex=0;
+ fprintf(src, "\n\t// Build and encode preamble");
+ fprintf(src, "\n\tAsnBits SnaccOptionalDefaultBits(%ld);\n", lOptional_Default_ElmtCount);
+ for (ii=0; ii < iElementCount; ii++)
+ {
+ e = pSetElementNamedType[ii];
+ if ( (e->type->optional || e->type->defaultVal != NULL) && (!e->type->extensionAddition))
+ {
+ fprintf (src, "\tif (%s != NULL)\n",
+ e->type->cxxTypeRefInfo->fieldName);
+ fprintf (src, "\t\tSnaccOptionalDefaultBits.SetBit(%d);\n",
+ iOptional_Default_ElementIndex++);
+ } /* END IF OPTIONAL/DEFAULT */
+ } /* END FOR each element. */
+ fprintf (src, "\t_b.PutBits(SnaccOptionalDefaultBits.data(), %ld);\n",
+ lOptional_Default_ElmtCount);
+ fprintf (src, "\tl += %ld;\n", lOptional_Default_ElmtCount);
+
+ } /* END IF lOptional_Default_ElmtCount */
+
+ /* NEXT, process each element of the Set/Sequence for decoding. */
+ fprintf(src, "\n\t// Encode the elements of the SEQUENCE\n");
+ for (ii=0; ii < iElementCount; ii++)
+ {
+ e = pSetElementNamedType[ii];
+ if(!e->type->extensionAddition)
+ {
+
+
+ if ( (e->type->optional || e->type->defaultVal != NULL) && (!e->type->extensionAddition))
+ {
+ fprintf(src, "\tif (%s != NULL)\t// Optional OR Default\n",
+ e->type->cxxTypeRefInfo->fieldName);
+ tabAndlenVar = "\t\tl";
+ }
+
+ cxxtri = e->type->cxxTypeRefInfo;
+ varName = cxxtri->fieldName;
+
+ /* encode tag(s), not UNIV but APL, CNTX or PRIV tags ONLY for PER */
+
+ /*RWC;TBD; UPDATE to reflect PER encoding rules for encoding length, no tags
+ RWC;TBD; unless explicit (probably need to write a PER version, checking type).*/
+
+ //RWC;NOT FOR PER;PrintPyTagAndLenEncodingCode (src, td, e->type, "l", "(*iBuf)");
+
+ /* encode content */
+ tmpTypeId = GetBuiltinType (e->type);
+ if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+ {
+ //RWC;TBD; we may have to investigate individual types here to
+ //RWC;TBD; restrict which codes are printed for PER...
+ defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+ PrintPySetTypeByCode(defByNamedType, cxxtri, src);
+
+ fprintf(src, "%s += %s", tabAndlenVar, varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+ fprintf (src, "P%s(_b);\n", r->encodeBaseName);
+ }
+ else if (tmpTypeId == BASICTYPE_ANY)
+ {
+ //RWC;NOTE: we will assume here that the ANY buffer is already
+ //RWC;NOTE: properly PER encoder; we have no way of checking.
+ fprintf(src, "%s += %s", tabAndlenVar, varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "P%s(_b);\n", r->encodeBaseName);
+ }
+ else if ( (tmpTypeId == BASICTYPE_OCTETCONTAINING) ||
+ (tmpTypeId == BASICTYPE_BITCONTAINING))
+ {
+ PrintPyPEREncodeContaining(e->type, r, src);
+ //RWC;TBD; THIS CALL WILL NOT UPDATE THE COUNT VALUE PROPERLY; must reflect
+ //RWC;TBD; PER encoding forward, l+=, instead of l=
+ }
+ else
+ {
+ fprintf(src, "%s += %s", tabAndlenVar, varName);
+ if (cxxtri->isPtr)
+ fprintf (src, "->");
+ else
+ fprintf (src, ".");
+
+ fprintf (src, "P%s(_b);\n", r->encodeBaseName);/*RWC;r->encodeContentBaseName);*/
+ }
+ }
+ else
+ {
+ extensionsExist = TRUE;
+ }
+ } /* END FOR iElementCount */
+
+
+ if(extensionsExist)
+ {
+ fprintf (src, " \t/* WARNING: PER does not yet support extensibility */\n");
+ }
+
+ fprintf(src, "\n\treturn l;\n");
+ fprintf(src, "}\t// %s::P%s\n\n\n", td->cxxTypeDefInfo->className,
+ r->encodeBaseName);
+} /* END PrintPyDefCode_SetSeqPEREncode(...) */
+
+
+/*
+ * RWC; This method only handles the entire routine decode operations for both Set and Sequence PER Decode.
+ * element decodes, not the wrapping logic. */
+static void
+PrintPyDefCode_SetSeqPERDecode (FILE *src, FILE *hdr, PyRules *r, TypeDef *td,
+ NamedType **pSetElementNamedType,
+ int iElementCount) /* IN, ELEMENT Count to process in arrays */
+{
+ NamedType *e;
+ char *varName;
+ CxxTRI *cxxtri=NULL;
+ int elmtLevel=0;
+ int varCount, tmpVarCount;
+ enum BasicTypeChoiceId tmpTypeId;
+ NamedType *defByNamedType;
+
+ // DEFINE PER encode/decode tmp vars.
+ int ii=0;
+ int iOptional_Default_ElementIndex=0;
+ long lOptional_Default_ElmtCount=0;
+
+ if (pSetElementNamedType == NULL)
+ {
+ printf("****** PrintPyDefCode_SetSeqPERDecode: MUST HAVE PER Encoders as well as PER Decoders! *****\n");
+ return;
+ }
+
+ /***RWC; PERFORM PDec operations first... */
+ //fprintf(hdr, "\tvoid\t\tP%s(AsnBufBits& _b, %s& bitsDecoded);\n\n",
+ //r->decodeBaseName, lenTypeNameG);
+
+ fprintf(src, "void %s::P%s(AsnBufBits& _b, %s& bitsDecoded)\n",
+ td->cxxTypeDefInfo->className, r->decodeBaseName, lenTypeNameG);
+ fprintf(src, "{\n");
+ fprintf(src, "\tClear();\n");
+
+ /* count max number of extra length var nec */
+ varCount = 0;
+
+ /* decode tag/length pair (s) */
+ elmtLevel = 0;
+
+ for (ii=0; ii < iElementCount; ii++)
+ //FOR_EACH_LIST_ELMT (e, set->basicType->a.set)
+ {
+ e = pSetElementNamedType[ii];
+ tmpVarCount = CxxCountVariableLevels (e->type);
+ if (tmpVarCount > varCount)
+ varCount = tmpVarCount;
+ if ( (e->type->optional || e->type->defaultVal != NULL) && (!e->type->extensionAddition))
+ {
+ lOptional_Default_ElmtCount++;
+ }
+ }
+
+ /* NEXT, decode this number of bits, if any, to determine the
+ presence/absence of OPTIONAL/DEFAULT elements. MUST BE DONE BEFORE
+ TAGs.*/
+ if (lOptional_Default_ElmtCount)
+ {
+ fprintf(src, "\n\t// Decode the preamble\n");
+ fprintf(src, "\tAsnBits SnaccOptionalDefaultBits;\n");
+ fprintf(src, "\tbitsDecoded += _b.GetBits(SnaccOptionalDefaultBits, %ld);\n",
+ lOptional_Default_ElmtCount);
+ }
+
+ //******************
+ /****RWC; PERFORM PDecContent operations here... ***/
+ /* print content local vars */
+ // fprintf (src, " unsigned int mandatoryElmtsDecoded = 0;\n");
+
+ //******************
+ /* write extra length vars */
+ // fprintf (src, "{\n"); // RWC; Temporary until I figure out the local var names from combining PDec with PDecContent
+ // for (i = 1; i <= varCount; i++)
+ // fprintf (src, " %s elmtLen%d = 0; //RWC;default to infinite for now.\n", lenTypeNameG, i);
+ // fprintf (src, "\n");
+
+ /* handle empty set */
+ //RWC;if ((set->basicType->a.set == NULL) || LIST_EMPTY (set->basicType->a.set))
+ if (iElementCount == 0)
+ {
+ // RWC; Allow for "{" editing...
+ /*fprintf (src, " throw EXCEPT(\"Expected an empty sequence\", DECODE_ERROR);\n");
+ fprintf (src, " }\n");*/
+ }
+ else
+ {
+ fprintf(src, "\n\t// Decode each of the elements\n");
+ for (ii=0; ii < iElementCount; ii++)
+ {
+ const char* tabStr = "\t";
+ e = pSetElementNamedType[ii];
+
+ if(!e->type->extensionAddition)
+ {
+ cxxtri = e->type->cxxTypeRefInfo;
+ if (e->type->optional || (e->type->defaultVal != NULL))
+ {
+ tabStr = "\t\t";
+ fprintf(src, "\tif (SnaccOptionalDefaultBits.GetBit(%d))\n",
+ iOptional_Default_ElementIndex++);
+ fprintf(src, "\t{\n");
+ }
+
+ varName = cxxtri->fieldName;
+
+ /* decode content */
+ if (cxxtri->isPtr)
+ {
+ //fprintf(src, "%sif(%s)\n", tabStr, varName);
+ //fprintf(src, "%s%sdelete %s;\n", tabStr, tabStr, varName);
+
+ fprintf(src, "%s%s = new %s;\n", tabStr, varName,
+ cxxtri->className);
+ /* END IF subtypes, PER-Visible */
+ }
+
+ /* decode content */
+ tmpTypeId = GetBuiltinType (e->type);
+ if ((tmpTypeId == BASICTYPE_OCTETCONTAINING) ||
+ (tmpTypeId == BASICTYPE_BITCONTAINING))
+ {
+ PrintPyPERDecodeContaining(e->type, r, src);
+ }
+ else
+ {
+ if (tmpTypeId == BASICTYPE_ANYDEFINEDBY)
+ {
+ elmtLevel++;
+
+ defByNamedType = e->type->basicType->a.anyDefinedBy->link;
+ PrintPySetTypeByCode(defByNamedType, cxxtri, src);
+ }
+ else if (tmpTypeId == BASICTYPE_ANY)
+ {
+ elmtLevel++;
+ }
+
+ if (cxxtri->isPtr)
+ fprintf(src, "%s%s->", tabStr, varName);
+ else
+ fprintf(src, "%s%s.", tabStr, varName);
+ fprintf(src, "P%s(_b, bitsDecoded);\n", r->decodeBaseName);
+ }
+
+ if (e->type->optional || (e->type->defaultVal != NULL))
+ fprintf (src, "\t}\n\n");
+ }
+ } /* for each elmt */
+ } /* if not empty set clause */
+
+ fprintf (src, "} // %s::P%s()\n\n", td->cxxTypeDefInfo->className,
+ r->decodeBaseName);
+
+} /* END PrintPyDefCode_SetSeqPERDecode(...) */
+
+/*** This routine handles sorting of groups of NameType element(s) based on the
+ * Set and Choice sorting rules.
+ */
+static void
+PrintPyDefCode_PERSort (
+ NamedType ***pppElementNamedType, /* OUT, array of sorted NameType(s) */
+ int **ppElementTag, /* OUT, actual tag for sorted. */
+ AsnList *pElementList) /* IN, actual eSNACC defs for NameType(s). */
+{
+ NamedType **pElementNamedType;
+ int *pElementTag;
+ NamedType *e;
+ NamedType *pnamedTypeTmp;
+ Tag *tag;
+ TagList *tags;
+ int tagTmp;
+ int stoleChoiceTags;
+ int ii=0, iii;
+
+ /*
+ * FIRST, determine encode order by looking at each element tag/type.
+ * (careful with untagged Choice elements, may be nested).
+ * If not tagged in the ASN.1 syntax, then we sort based on the IMPLICIT
+ * tag, even though it may not be encoded for PER.
+ * pElementList->count total elements for PER encode sorting.*/
+ pElementTag = *ppElementTag = (int *)calloc(pElementList->count, sizeof(int));
+ pElementNamedType = *pppElementNamedType =
+ (NamedType **)calloc(pElementList->count, sizeof(NamedType *));
+ FOR_EACH_LIST_ELMT (e, pElementList)
+ {
+ /*RWC;SEE tag-utils.c, line 175 for example of looking at nested
+ *RWC; untagged Choice(s). For PER, NEED to return lowest tag
+ *RWC; value in nested untagged Choice for sorting.
+ *RWC; The call to GetTags will only return tags with non-tagged
+ *RWC; "Choice" elements if present (flagged by "stoleChoiceTags").*/
+ tags = GetTags (e->type, &stoleChoiceTags);
+
+ if (LIST_EMPTY (tags))
+ {
+ pElementTag[ii] = 0;
+ /* RWC; IGNORE; for now */
+ } /* END IF (LIST_EMPTY (tags))*/
+ else if (stoleChoiceTags)
+ {
+ /* FOR untagged Choice, determine lowest possible tag for
+ * PER sorting order.*/
+ pElementTag[ii] = 9999;
+ FOR_EACH_LIST_ELMT (tag, tags)
+ {
+ if (tag->code < pElementTag[ii])
+ pElementTag[ii] = tag->code; /* ONLY 1st element for sorting.*/
+ }
+ }
+ else
+ {
+ tag = (Tag*)FIRST_LIST_ELMT (tags);
+ pElementTag[ii] = tag->code; // ONLY 1st element for sorting.
+ }
+ pElementNamedType[ii] = e;
+ ii++;
+ } // END FOR each element.
+
+ // SECOND, sort this group of elements based on these tags.
+ for (ii=0; ii < pElementList->count-1; ii++)
+ {
+ for (iii=ii+1; iii < pElementList->count; iii++)
+ { // LOCATE smallest tag value
+ if (pElementTag[iii] < pElementTag[ii])
+ { // THEN switch them.
+ tagTmp = pElementTag[ii];
+ pnamedTypeTmp = pElementNamedType[ii];
+ pElementTag[ii] = pElementTag[iii];
+ pElementNamedType[ii] = pElementNamedType[iii];
+ pElementTag[iii] = tagTmp;
+ pElementNamedType[iii] = pnamedTypeTmp;
+ }
+ } // END for remaining elements (for sorting)
+ } // END FOR each element
+} /* END PrintPyDefCode_PERSort(...) */
+
+void PrintPySimpleDefMeta_1(FILE * hdr, FILE* src, TypeDef* td, int hasNamedElmts, CNamedElmt *n, Module* m)
+{
+
+}
+
+void PrintPySimpleDefMeta_2(FILE * hdr, FILE* src, TypeDef* td, int hasNamedElmts, CNamedElmt *n, Module* m, PyRules *r)
+{
+
+}
+
+void PrintPyChoiceDefCodeMeta_1(FILE* hdr, FILE* src, TypeDef* td, Type* choice, Module* m, NamedType* e)
+{
+
+}
+
+void PrintPySeqDefCodeMeta_1(FILE* hdr, FILE* src, TypeDef* td, Type* seq, Module* m, NamedType* e)
+{
+
+}
+
+void PrintPySetDefCodeMeta_1(FILE* hdr, FILE* src, TypeDef* td, Type* set, Module* m, NamedType* e)
+{
+
+}
+/* EOF gen-code.c (for back-ends/c++-gen) */
+
diff --git a/compiler/back-ends/py-gen/rules.c b/compiler/back-ends/py-gen/rules.c
new file mode 100644
index 0000000..3c79068
--- /dev/null
+++ b/compiler/back-ends/py-gen/rules.c
@@ -0,0 +1,569 @@
+/*
+ * compiler/back-ends/py-gen/rules.c - initialized rule structure
+ * inits a table that contains info about
+ * converting each ASN.1 type to a python class
+ *
+ * Copyright (C) 2016 Aaron Conole
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "rules.h"
+
+PyRules pyRulesG =
+{
+ 4,
+ "choiceId",
+ "ChoiceIdEnum",
+ "a",
+ "ChoiceUnion",
+ FALSE,
+ "Enc",
+ "Dec",
+ "EncContent",
+ "DecContent",
+ "EncPdu",
+ "DecPdu",
+ {
+ { /* 0 */
+ BASICTYPE_UNKNOWN,
+ "???",
+ FALSE,
+ FALSE,
+ FALSE,
+ TRUE,
+ TRUE,
+ TRUE,
+ TRUE,
+ "None",
+ "unknown"
+ },
+ { /* 1 */
+ BASICTYPE_BOOLEAN, /* 1 */
+ "asn_bool.AsnBool",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "bool"
+ },
+ { /* 2 */
+ BASICTYPE_INTEGER, /* 2 */
+ "asn_ints.AsnInt",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "integer"
+ },
+ { /* 3 */
+ BASICTYPE_BITSTRING,
+ "asn_octs.AsnBits",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "bits"
+ },
+ {/* 4 */
+ BASICTYPE_OCTETSTRING,
+ "asn_octs.AsnOcts",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "octs"
+ },
+ {/* 5 */
+ BASICTYPE_NULL,
+ "asn_base.AsnNull",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "null"
+ },
+ { /* 6 */
+ BASICTYPE_OID,
+ "asn_oid.AsnOid",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "oid"
+ },
+ { /* 7 */
+ BASICTYPE_REAL,
+ "asn_ints.AsnReal",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "real"
+ },
+ {/* 8 */
+ BASICTYPE_ENUMERATED,
+ "asn_ints.AsnEnum",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "enumeration"
+ },
+ {/* 9 */
+ BASICTYPE_SEQUENCE,
+ NULL,
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "seq"
+ },
+ {/* 10 */
+ BASICTYPE_SEQUENCEOF,
+ "asn_list.AsnSequenceOf",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "seqOf"
+ },
+ {/* 11 */
+ BASICTYPE_SET,
+ NULL,
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ FALSE,
+ "None",
+ "set"
+ },
+ {/* 12 */
+ BASICTYPE_SETOF,
+ "asn_list.AsnSetOf",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "setOf"
+ },
+ {/* 13 */
+ BASICTYPE_CHOICE,
+ NULL,
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ FALSE,
+ "None",
+ "choice"
+ },
+ {/* 14 */
+ BASICTYPE_SELECTION,
+ NULL,
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "foo"
+ },
+ {/* 15 */
+ BASICTYPE_COMPONENTSOF,
+ NULL,
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "bar"
+ },
+ {/* 16 */
+ BASICTYPE_ANY,
+ "asn_base.AsnAny",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "any"
+ },
+ {/* 17 */
+ BASICTYPE_ANYDEFINEDBY,
+ "AsnAnyDefinedBy",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "anyDefBy"
+ },
+ {/* 18 */
+ BASICTYPE_LOCALTYPEREF,
+ NULL,
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "foo"
+ },
+ {/* 19 */
+ BASICTYPE_IMPORTTYPEREF,
+ NULL,
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "bar"
+ },
+ {/* 20 */
+ BASICTYPE_MACROTYPE,
+ NULL,
+ FALSE,
+ FALSE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "foo"
+ },
+ {/* 21 */
+ BASICTYPE_MACRODEF,
+ NULL,
+ FALSE,
+ FALSE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "foo"
+ },
+ {/* 22 */
+ BASICTYPE_NUMERIC_STR,
+ "asn_useful.NumericString",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "numericString"
+ },
+ {/* 23 */
+ BASICTYPE_PRINTABLE_STR,
+ "asn_useful.PrintableString",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "printableString"
+ },
+ {/* 24 */
+ BASICTYPE_UNIVERSAL_STR,
+ "asn_useful.UniversalString",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "universalString"
+ },
+ {/* 25 */
+ BASICTYPE_IA5_STR,
+ "asn_useful.IA5String",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "ia5String"
+ },
+ {/* 26 */
+ BASICTYPE_BMP_STR,
+ "asn_useful.BMPString",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "bmpString"
+ },
+ {/* 27 */
+ BASICTYPE_UTF8_STR,
+ "asn_useful.UTF8String",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "utf8String"
+ },
+ {/* 28 */
+ BASICTYPE_UTCTIME, /* 23 */
+ "asn_useful.UTCTime",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "utcTime"
+ },
+ {/* 29 */
+ BASICTYPE_GENERALIZEDTIME, /* 24 */
+ "asn_useful.GeneralizedTime",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "generalizedTime"
+ },
+ {/* 30 */
+ BASICTYPE_GRAPHIC_STR, /* 25 */
+ "asn_useful.GraphicString",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "graphicString"
+ },
+ {/* 31 */
+ BASICTYPE_VISIBLE_STR, /* 26 */
+ "asn_useful.VisibleString",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "visibleString"
+ },
+ {/* 32 */
+ BASICTYPE_GENERAL_STR, /* 27 */
+ "asn_useful.GeneralString",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "generalString"
+ },
+ {/* 33 */
+ BASICTYPE_OBJECTDESCRIPTOR,
+ "asn_useful.ObjectDescriptor",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "objectDescriptor"
+ } ,
+ {/* 34 */
+ BASICTYPE_VIDEOTEX_STR,
+ "asn_useful.VideotexString",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "videotexString"
+ } ,
+ {/* 35 */
+ BASICTYPE_T61_STR,
+ "asn_useful.T61String",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "t61String"
+ },
+ {/* 36 */
+ BASICTYPE_EXTERNAL,
+ "asn_useful.EXTERNAL",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ TRUE,
+ TRUE,
+ "None",
+ "external"
+ },
+ {/* 37 */
+ BASICTYPE_OCTETCONTAINING,
+ NULL,
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "octetContainer"
+ },
+ {/* 38 */
+ BASICTYPE_BITCONTAINING,
+ NULL,
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "bitContainer"
+ },
+ { /* 39 */
+ BASICTYPE_RELATIVE_OID,
+ "AsnRelativeOid",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "relativeOid"
+ },
+ { /* 40 */
+ BASICTYPE_EXTENSION,
+ "asn_base.AsnExtension",
+ FALSE,
+ TRUE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+ TRUE,
+ "None",
+ "extension"
+ }
+
+ }
+};
diff --git a/compiler/back-ends/py-gen/rules.h b/compiler/back-ends/py-gen/rules.h
new file mode 100644
index 0000000..e5d61bf
--- /dev/null
+++ b/compiler/back-ends/py-gen/rules.h
@@ -0,0 +1,36 @@
+/*
+ * compiler/back-ends/py-gen/rules.h
+ *
+ * Copyright (C) 2016 Aaron Conole
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef PY_RulesInclude
+#define PY_RulesInclude
+/* see asn1module.h for CxxTDI (C++ type def info) */
+
+typedef struct PyRules
+{
+ int maxDigitsToAppend;
+ char *choiceIdFieldName; /* name of choiceId field */
+ char *choiceIdEnumName; /* name (tag) for choiceId enum def name */
+ char *choiceUnionFieldName; /* what the name of the choice's union is */
+ char *choiceUnionName; /* name (tag) for choice union def name */
+ int capitalizeNamedElmts;
+ char *encodeBaseName;
+ char *decodeBaseName;
+ char *encodeContentBaseName;
+ char *decodeContentBaseName;
+ char *encodePduBaseName;
+ char *decodePduBaseName;
+ CxxTDI typeConvTbl[BASICTYPE_EXTENSION + 1];
+} PyRules;
+
+extern PyRules pyRulesG;
+
+#endif
diff --git a/compiler/back-ends/py-gen/types.c b/compiler/back-ends/py-gen/types.c
new file mode 100644
index 0000000..a6a7f3b
--- /dev/null
+++ b/compiler/back-ends/py-gen/types.c
@@ -0,0 +1,529 @@
+/*
+ * compiler/back-ends/py-gen/types.c - fills in python type information
+ *
+ * Copyright (C) 2016 Aaron Conole
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include "asn-incl.h"
+#include "asn1module.h"
+#include "snacc-util.h"
+#include "str-util.h"
+#include "rules.h"
+
+static DefinedObj *definedNamesG;
+
+/* unexported prototypes */
+
+void FillPyTypeDefInfo PROTO ((PyRules *r, Module *m, TypeDef *td));
+static void FillPyFieldNames PROTO ((PyRules *r,
+ NamedTypeList *firstSibling));
+static void FillPyTypeRefInfo PROTO ((PyRules *r, Module *m,
+ TypeDef *head, Type *parent, Type *t));
+static void FillPyStructElmts PROTO ((PyRules *r, Module *m,
+ TypeDef *head, Type *parent,
+ NamedTypeList *t));
+static void FillPyChoiceElmts PROTO ((PyRules *r, Module *m, TypeDef *head,
+ Type *parent, NamedTypeList *first));
+static int IsPyNone PROTO ((PyRules *r, TypeDef *td, Type *parent, Type *t));
+void FillPyTDIDefaults PROTO ((PyRules *r, CxxTDI *ctdi, TypeDef *td));
+
+
+static char *pykwds[] = {
+ "False", "class", "finally", "is", "return",
+ "None", "continue", "for", "lambda", "try",
+ "True", "def", "from", "nonlocal", "while",
+ "and", "del", "global", "not", "with",
+ "as", "elif", "if", "or", "yield",
+ "assert", "else", "import", "pass",
+ "break", "except", "in", "raise", NULL
+};
+
+
+/*
+ * returns non-zero if the given str is a C++ key word
+ */
+int
+IsPyKeyWord PARAMS ((str),
+ char *str)
+{
+ size_t i;
+
+ for (i=0; pykwds[i] != NULL && strcmp(pykwds[i], str); i++);
+
+ return pykwds[i] != NULL;
+}
+
+
+/*
+ * allocates and fills all the cxxTypeInfos
+ * in the type trees for every module in the list
+ */
+void
+FillPyTypeInfo PARAMS ((r, modList),
+ PyRules *r _AND_
+ ModuleList *modList)
+{
+ TypeDef *td;
+ Module *m;
+
+ /*
+ * go through each module's type defs and fill
+ * in the C type and enc/dec routines etc
+ */
+ definedNamesG = NULL;
+
+ FOR_EACH_LIST_ELMT (m, modList) {
+ FOR_EACH_LIST_ELMT (td, m->typeDefs)
+ FillPyTypeDefInfo (r, m, td);
+ }
+
+ /*
+ * now that type def info is filled in
+ * set up set/seq/list/choice elements that ref
+ * those definitions
+ */
+ FOR_EACH_LIST_ELMT (m, modList) {
+ FOR_EACH_LIST_ELMT (td, m->typeDefs)
+ FillPyTypeRefInfo (r, m, td, NULL, td->type);
+ }
+
+ /* done with checking for name conflicts */
+ FreeDefinedObjs (&definedNamesG);
+ definedNamesG = NULL;
+
+}
+
+
+/*
+ * allocates and fills structure holding C type definition information
+ * fo the given ASN.1 type definition. Does not fill CTRI for contained
+ * types etc.
+ */
+void
+FillPyTypeDefInfo PARAMS ((r, m, td),
+ PyRules *r _AND_
+ Module *m _AND_
+ TypeDef *td)
+{
+ char *tmpName;
+ CxxTDI *cxxtdi;
+
+ /*
+ * if CxxTDI is present this type def has already been 'filled'
+ */
+ if (td->cxxTypeDefInfo != NULL)
+ return;
+
+
+ cxxtdi = MT (CxxTDI);
+ td->cxxTypeDefInfo = cxxtdi;
+
+ /* get default type def attributes from table for type on rhs of ::= */
+
+ FillPyTDIDefaults (r, cxxtdi, td);
+
+
+ /*
+ * if defined by a ref to another type definition fill in that type
+ * def's CxxTDI so can inherit (actully completly replace default
+ * attributes) from it
+ */
+ if ((td->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+ (td->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
+ {
+ /*
+ * Fill in CxxTDI for defining type if nec.
+ * this works for importTypeRef as well since both a.localTypeRef
+ * and a.importTypeRef are of type TypeRef
+ */
+ FillPyTypeDefInfo(r, td->type->basicType->a.localTypeRef->module,
+ td->type->basicType->a.localTypeRef->link);
+
+ tmpName = cxxtdi->className; /* save className */
+ /* copy all type def info and restore name related stuff - hack*/
+ *cxxtdi = *td->type->basicType->a.localTypeRef->link->cxxTypeDefInfo;
+ cxxtdi->className = tmpName; /* restore className */
+ }
+} /* FillCxxTypeDefInfo */
+
+
+static void
+FillPyTypeRefInfo PARAMS ((r, m, head, parent, t),
+ PyRules *r _AND_
+ Module *m _AND_
+ TypeDef *head _AND_
+ Type *parent _AND_
+ Type *t)
+{
+ CxxTRI *cxxtri;
+ CxxTDI *tmpCxxtdi;
+ ValueDef *namedElmt;
+ CNamedElmt *cne;
+ CNamedElmt **cneHndl;
+ char *elmtName;
+ int len;
+ enum BasicTypeChoiceId basicTypeId;
+
+ /*
+ * you must check for cycles yourself before calling this
+ */
+ if (t->cxxTypeRefInfo == NULL) {
+ cxxtri = MT (CxxTRI);
+ t->cxxTypeRefInfo = cxxtri;
+ } else
+ cxxtri = t->cxxTypeRefInfo;
+
+ basicTypeId = t->basicType->choiceId;
+
+ tmpCxxtdi = &r->typeConvTbl[basicTypeId];
+
+ /* get base type def info from the conversion table in the rules */
+ cxxtri->isEnc = tmpCxxtdi->isEnc;
+ if ((basicTypeId == BASICTYPE_OCTETCONTAINING) ||
+ (basicTypeId == BASICTYPE_BITCONTAINING)) {
+ cxxtri->className =
+ r->typeConvTbl[t->basicType->a.stringContaining->basicType->
+ choiceId].className;
+ } else
+ cxxtri->className = tmpCxxtdi->className;
+
+ cxxtri->optTestRoutineName = tmpCxxtdi->optTestRoutineName;
+
+
+ /*
+ * convert named elmts to C++ names.
+ * check for name conflict with other defined Types/Names/Values
+ */
+ if (((basicTypeId == BASICTYPE_INTEGER) ||
+ (basicTypeId == BASICTYPE_ENUMERATED) ||
+ (basicTypeId == BASICTYPE_BITSTRING)) &&
+ (!(LIST_EMPTY (t->basicType->a.integer)))) {
+ cxxtri->namedElmts = AsnListNew (sizeof (void*));
+
+ FOR_EACH_LIST_ELMT (namedElmt, t->basicType->a.integer) {
+ cneHndl = (CNamedElmt**)AsnListAppend (cxxtri->namedElmts);
+ cne = *cneHndl = MT(CNamedElmt);
+ elmtName = Asn1ValueName2CValueName(namedElmt->definedName);
+ cne->name = elmtName; /* not very efficient */
+
+ if (namedElmt->value->basicValue->choiceId == BASICVALUE_INTEGER)
+ cne->value = namedElmt->value->basicValue->a.integer;
+ else {
+ fprintf (errFileG, "Warning: unlinked defined value. Using -9999999\n");
+ cne->value = -9999999;
+ }
+
+ if (r->capitalizeNamedElmts)
+ Str2UCase(cne->name, len);
+
+ /*
+ * append digits if enum value name is a keyword
+ */
+ MakePyStrUnique(definedNamesG, cne->name, r->maxDigitsToAppend, 1);
+ }
+ }
+
+ /* fill in rest of type info depending on the type */
+ switch (basicTypeId)
+ {
+ default:
+ case BASICTYPE_UNKNOWN:
+ case BASICTYPE_MACRODEF:
+ case BASICTYPE_MACROTYPE:
+ /* do nothing */
+ case BASICTYPE_BOOLEAN: /* library types */
+ case BASICTYPE_INTEGER:
+ case BASICTYPE_BITSTRING:
+ case BASICTYPE_OCTETSTRING:
+ case BASICTYPE_NULL:
+ case BASICTYPE_OID:
+ case BASICTYPE_RELATIVE_OID:
+ case BASICTYPE_REAL:
+ case BASICTYPE_ENUMERATED:
+ case BASICTYPE_ANY:
+ case BASICTYPE_ANYDEFINEDBY: /* ANY types */
+ /* don't need to do anything else */
+ break;
+
+ case BASICTYPE_SEQUENCEOF: /* list types */
+ case BASICTYPE_SETOF:
+ /* fill in component type */
+ FillPyTypeRefInfo (r, m, head, t, t->basicType->a.setOf);
+ break;
+
+ case BASICTYPE_IMPORTTYPEREF: /* type references */
+ case BASICTYPE_LOCALTYPEREF:
+ /*
+ * grab class name from link (link is the def of the
+ * the ref'd type)
+ */
+ if (t->basicType->a.localTypeRef->link != NULL) {
+ /* inherit attributes from referenced type */
+ tmpCxxtdi= t->basicType->a.localTypeRef->link->cxxTypeDefInfo;
+ cxxtri->className = tmpCxxtdi->className;
+ cxxtri->isEnc = tmpCxxtdi->isEnc;
+ cxxtri->optTestRoutineName = tmpCxxtdi->optTestRoutineName;
+ }
+ break; /* these are handled now */
+
+ case BASICTYPE_CHOICE:
+ /*
+ * must fill field names BEFORE filling choice elmts
+ * (allows better naming for choice ids)
+ */
+ FillPyFieldNames(r, t->basicType->a.choice);
+ FillPyChoiceElmts(r, m, head, t, t->basicType->a.choice);
+ break;
+
+ case BASICTYPE_SET:
+ case BASICTYPE_SEQUENCE:
+ FillPyStructElmts (r, m, head, t, t->basicType->a.set);
+ FillPyFieldNames (r, t->basicType->a.set);
+ break;
+
+ case BASICTYPE_COMPONENTSOF:
+ case BASICTYPE_SELECTION:
+ fprintf(errFileG,
+ "Compiler error - COMPONENTS OF or SELECTION type slipped through normalizing phase.\n");
+ exit(-1);
+ break;
+ }
+
+ /*
+ * figure out whether this is a ptr based on the enclosing
+ * type (if any) and optionality/default
+ */
+ cxxtri->isPtr = (unsigned char)IsPyNone(r, head, parent, t);
+} /* FillCxxTypeRefInfo */
+
+
+
+static void
+FillPyStructElmts PARAMS ((r, m, head, parent, elmts),
+ PyRules *r _AND_
+ Module *m _AND_
+ TypeDef *head _AND_
+ Type *parent _AND_
+ NamedTypeList *elmts)
+{
+ NamedType *et;
+
+ FOR_EACH_LIST_ELMT (et, elmts) {
+ FillPyTypeRefInfo(r, m, head, parent, et->type);
+ }
+}
+
+/*
+ * Figures out non-conflicting enum names for the
+ * choice id's
+ */
+static void
+FillPyChoiceElmts PARAMS ((r, m, head, parent, elmts),
+ PyRules *r _AND_
+ Module *m _AND_
+ TypeDef *head _AND_
+ Type *parent _AND_
+ NamedTypeList *elmts)
+{
+ NamedType *et;
+ int idCount = 0;
+ CxxTRI *cxxtri;
+ int len;
+
+ /*
+ * fill in type info for elmt types first
+ */
+ FOR_EACH_LIST_ELMT (et, elmts)
+ FillPyTypeRefInfo (r, m, head, parent, et->type);
+
+ FOR_EACH_LIST_ELMT (et, elmts) {
+ cxxtri = et->type->cxxTypeRefInfo;
+
+ if (cxxtri == NULL)
+ continue; /* wierd type */
+
+ cxxtri->choiceIdValue = idCount++;
+
+ len = strlen (cxxtri->fieldName);
+ cxxtri->choiceIdSymbol = Malloc (len + 4);
+ strcpy (cxxtri->choiceIdSymbol, cxxtri->fieldName);
+ strcat (cxxtri->choiceIdSymbol, "Cid");
+
+ if (r->capitalizeNamedElmts)
+ Str2UCase (cxxtri->choiceIdSymbol, len);
+ }
+}
+
+/*
+ * takes a list of "sibling" (eg same level in a structure)
+ * ElmtTypes and fills sets up the c field names in
+ * the CxxTRI struct
+ */
+static void
+FillPyFieldNames PARAMS ((r, elmts),
+ PyRules *r _AND_
+ NamedTypeList *elmts)
+{
+ NamedType *et;
+ CxxTRI *cxxtri;
+ DefinedObj *fieldNames;
+ int len;
+ char *tmpName;
+ char *asn1FieldName;
+ char *cFieldName = NULL;
+
+ /*
+ * Initialize fieldname data
+ * allocate (if nec) and fill in CTRI fieldname if poss
+ * from asn1 field name. leave blank otherwise
+ */
+ fieldNames = NewObjList();
+ FOR_EACH_LIST_ELMT (et, elmts) {
+ cxxtri = et->type->cxxTypeRefInfo;
+ if (cxxtri == NULL) {
+ cxxtri = MT(CxxTRI);
+ et->type->cxxTypeRefInfo = cxxtri;
+ }
+
+ if (et->fieldName != NULL) {
+ /*
+ * can assume that the field names are
+ * distinct because they have passed the
+ * error checking step.
+ * However, still call MakeStrUnique
+ * to change any field names that
+ * conflict with C++ keywords
+ */
+ asn1FieldName = et->fieldName;
+ cxxtri->fieldName = Asn1FieldName2CFieldName(asn1FieldName);
+ MakePyStrUnique(fieldNames, cxxtri->fieldName,
+ r->maxDigitsToAppend, 1);
+ DefineObj(&fieldNames, cxxtri->fieldName);
+ }
+
+ /*
+ * generate field names for those without them
+ */
+ cFieldName = cxxtri->fieldName;
+ if (cxxtri->fieldName == NULL) {
+ if ((et->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+ (et->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) {
+ /*
+ * take ref'd type name as field name
+ * convert first let to lower case
+ */
+ tmpName = et->type->basicType->a.localTypeRef->link->
+ cxxTypeDefInfo->className;
+ tmpName = Asn1TypeName2CTypeName(tmpName);
+ } else {
+ /*
+ * get default field name for this type
+ */
+ tmpName = Strdup(r->typeConvTbl[et->type->basicType->choiceId].
+ defaultFieldName);
+ }
+ cFieldName = tmpName;
+ if (isupper(cFieldName[0]))
+ cFieldName[0] = (char)tolower(cFieldName[0]);
+
+ len = strlen(cFieldName);
+
+ /*
+ * try to use just the type name (with lower case first char).
+ * if that is already used in this type or a C++ keyword,
+ * append ascii digits to field name until unique
+ * in this type
+ */
+ MakePyStrUnique(fieldNames, cFieldName, r->maxDigitsToAppend, 1);
+ DefineObj(&fieldNames, cFieldName);
+ cxxtri->fieldName = cFieldName;
+ }
+ }
+ FreeDefinedObjs (&fieldNames);
+}
+
+/*
+ * returns true if this c type for this type should be
+ * be ref'd as a ptr
+ */
+static int
+IsPyNone PARAMS ((r, td, parent, t),
+ PyRules *r _AND_
+ TypeDef *td _AND_
+ Type *parent _AND_
+ Type *t)
+{
+ CxxTDI *cxxtdi;
+ int retVal = FALSE;
+
+ /*
+ * inherit ptr attriubutes from ref'd type if any
+ * otherwise grab lib c type def from the PyRules
+ */
+ if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
+ (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF)) {
+ cxxtdi = t->basicType->a.localTypeRef->link->cxxTypeDefInfo;
+ } else
+ cxxtdi = &r->typeConvTbl[GetBuiltinType (t)];
+
+ /* no parent means t is the root of a typedef */
+ if ((parent == NULL) && (cxxtdi->isPtrForTypeDef))
+ retVal = TRUE;
+ else if ((parent != NULL) &&
+ ((parent->basicType->choiceId == BASICTYPE_SET) ||
+ (parent->basicType->choiceId == BASICTYPE_SEQUENCE)) &&
+ (cxxtdi->isPtrInSetAndSeq))
+ retVal = TRUE;
+ else if ((parent != NULL) &&
+ ((parent->basicType->choiceId == BASICTYPE_SETOF) ||
+ (parent->basicType->choiceId == BASICTYPE_SEQUENCEOF)) &&
+ (cxxtdi->isPtrInList))
+ retVal = TRUE;
+ else if ((parent != NULL) &&
+ (parent->basicType->choiceId == BASICTYPE_CHOICE) &&
+ (cxxtdi->isPtrInChoice))
+ retVal = TRUE;
+ else if (((t->optional) || (t->defaultVal != NULL)) && (cxxtdi->isPtrForOpt))
+ retVal = TRUE;
+
+ return retVal;
+}
+
+/* fill given cxxtdi with defaults from table for given typedef */
+void
+FillPyTDIDefaults PARAMS ((r, cxxtdi, td),
+ PyRules *r _AND_
+ CxxTDI *cxxtdi _AND_
+ TypeDef *td)
+{
+ CxxTDI *tblCxxtdi;
+ int typeIndex;
+ char *tmpName;
+
+ typeIndex = GetBuiltinType (td->type);
+
+ if (typeIndex < 0)
+ return;
+
+ tblCxxtdi = &r->typeConvTbl[typeIndex];
+
+ memcpy (cxxtdi, tblCxxtdi, sizeof (CxxTDI));
+
+ /* make sure class name is unique wrt to previously defined classes */
+ tmpName = Asn1TypeName2CTypeName (td->definedName);
+ cxxtdi->className = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1);
+ strcpy (cxxtdi->className, tmpName);
+ Free (tmpName);
+
+ MakePyStrUnique (definedNamesG, cxxtdi->className, r->maxDigitsToAppend, 1);
+ DefineObj (&definedNamesG, cxxtdi->className);
+
+}
diff --git a/compiler/back-ends/str-util.c b/compiler/back-ends/str-util.c
index 073a4f1..b8c6dfb 100644
--- a/compiler/back-ends/str-util.c
+++ b/compiler/back-ends/str-util.c
@@ -90,6 +90,7 @@
int IsCKeyWord PROTO ((char *str));
int IsCxxKeyWord PROTO ((char *str));
+int IsPyKeyWord PROTO ((char *str));
int keepbaseG = TRUE;
@@ -127,9 +128,8 @@ Asn1FieldName2CFieldName PARAMS ((aName),
if (aName == NULL)
return NULL;
- retVal = Malloc (strlen (aName) + 1);
- strcpy (retVal, aName);
- Dash2Underscore (retVal, strlen (retVal));
+ retVal = Strdup(aName);
+ Dash2Underscore(retVal, strlen(retVal));
return retVal;
} /* Asn1FieldName2CFieldName */
@@ -262,8 +262,7 @@ Dash2Underscore PARAMS ((str, len),
int len)
{
int i;
- for (i=0; i < len; i++)
- {
+ for (i=0; i < len; i++) {
if (str[i] == '-')
str[i] = '_';
}
@@ -377,6 +376,34 @@ MakeCxxStrUnique PARAMS ((nameList, str, maxDigits, startingDigit),
}
} /* MakeCxxStrUnique */
+
+/*
+ * same as MakeCStrUnique except checks against C++ keywords
+ */
+void
+MakePyStrUnique PARAMS ((nameList, str, maxDigits, startingDigit),
+ DefinedObj *nameList _AND_
+ char *str _AND_
+ int maxDigits _AND_
+ int startingDigit)
+{
+ int digit, len, maxDigitVal;
+
+ if (ObjIsDefined(nameList, str, StrObjCmp) || IsPyKeyWord (str)) {
+ for (maxDigitVal = 1; maxDigits > 0; maxDigits--)
+ maxDigitVal *= 10;
+
+ len = strlen(str);
+ digit = startingDigit;
+ do
+ {
+ str[len] = '\0';
+ AppendDigit (str, digit++);
+ } while (ObjIsDefined (nameList, str, StrObjCmp) &&
+ (digit < maxDigitVal));
+ }
+} /* MakeCxxStrUnique */
+
static char *OutputDirectoryName;
void StoreOutputDirectory PARAMS ((directory),
@@ -596,6 +623,17 @@ MakeCxxSrcFileName PARAMS ((refName),
return MakeFileName (refName, ".cpp");
}
+char *
+MakePySrcFileName PARAMS ((refName),
+ const char *refName)
+{
+ char *name = Strdup(refName);
+ Dash2Underscore(name, strlen(refName));
+ char *ret = MakeFileName(name, ".py");
+ Free(name);
+ return ret;
+}
+
#if IDL
char *
MakeIDLFileName PARAMS ((refName),
diff --git a/compiler/back-ends/str-util.h b/compiler/back-ends/str-util.h
index d3a0b54..b758c44 100644
--- a/compiler/back-ends/str-util.h
+++ b/compiler/back-ends/str-util.h
@@ -72,6 +72,7 @@ char *MakeCHdrFileName PROTO ((const char *moduleName));
char *MakeCSrcFileName PROTO ((const char *moduleName));
char *MakeCxxHdrFileName PROTO ((const char *moduleName));
char *MakeCxxSrcFileName PROTO ((const char *moduleName));
+char *MakePySrcFileName PROTO ((const char *moduleName));
#if IDL
char *MakeIDLFileName PROTO ((const char *moduleName));
#endif
diff --git a/compiler/core/define.c b/compiler/core/define.c
index 5d4d92d..3583a19 100644
--- a/compiler/core/define.c
+++ b/compiler/core/define.c
@@ -176,8 +176,7 @@ UndefineObj PARAMS ((objListHndl, obj, cmpRoutine),
int
ObjIsDefined (DefinedObj *objListPtr, void *obj, CmpObjsRoutine cmpRoutine)
{
- for ( ; objListPtr != NULL; objListPtr = objListPtr->next)
- {
+ for ( ; objListPtr != NULL; objListPtr = objListPtr->next) {
if (cmpRoutine (objListPtr->obj, obj))
return TRUE;
}
diff --git a/compiler/core/snacc.c b/compiler/core/snacc.c
index cb0cba8..407394b 100644
--- a/compiler/core/snacc.c
+++ b/compiler/core/snacc.c
@@ -81,6 +81,8 @@ char *bVDAGlobalDLLExport=(char *)0;
#include "c++-gen/rules.h" /* for c++ file generation */
+#include "py-gen/rules.h"
+
#if IDL
#include "idl-gen/rules.h" /* for idl file generation */
#endif
@@ -126,6 +128,12 @@ void PrintCxxCode (FILE *src, FILE *hdr, if_META (MetaNameStyle genMeta COMMA
int printTypes, int printValues, int printEncoders,
int printDecoders, int printPrinters, int printFree,
if_TCL (int printTcl COMMA) int novolatilefuncs);
+void PrintPyCode (FILE *src, FILE *hdr, if_META (MetaNameStyle genMeta COMMA
+ const Meta *meta COMMA MetaPDU *metapdus COMMA)
+ ModuleList *mods, Module *m, CxxRules *r, long longJmpVal,
+ int printTypes, int printValues, int printEncoders,
+ int printDecoders, int printPrinters, int printFree,
+ if_TCL (int printTcl COMMA) int novolatilefuncs);
void PrintIDLCode PROTO ((FILE *idl, ModuleList *mods, Module *m, IDLRules *r,
long int longJmpVal, int printValues));
void ProcessMacros PROTO ((Module *m));
@@ -143,6 +151,11 @@ static void GenCxxCode PROTO ((ModuleList *allMods, long longJmpVal,
int genPrinters, int genValues, int genFree,
if_META (MetaNameStyle genMeta COMMA MetaPDU *meta_pdus COMMA)
if_TCL (int genTcl COMMA) int novolatilefuncs));
+static void GenPyCode PROTO ((ModuleList *allMods, long longJmpVal,
+ int genTypes, int genEncoders, int genDecoders,
+ int genPrinters, int genValues, int genFree,
+ if_META (MetaNameStyle genMeta COMMA MetaPDU *meta_pdus COMMA)
+ if_TCL (int genTcl COMMA) int novolatilefuncs));
static void GenIDLCode PROTO ((ModuleList *allMods, long longJmpVal, int genTypes,
int genPrinters, int genValues, int genFree));
static int ModNamesUnique PROTO ((ModuleList *m));
@@ -317,6 +330,7 @@ int main PARAMS ((argc, argv),
int genCCode = FALSE; /* defaults to C if neither specified */
int genCxxCode = FALSE;
int genIDLCode = FALSE;
+ int genPyCode = FALSE;
long longJmpVal = -100;
int novolatilefuncs = FALSE;
char* dirName; /* REN -- 6/2/03 -- added */
@@ -432,7 +446,11 @@ int main PARAMS ((argc, argv),
break;
case 'p':
- genPrintCode = TRUE;
+ if (argv[currArg][2] == 'y') {
+ genPyCode = TRUE;
+ } else {
+ genPrintCode = TRUE;
+ }
currArg++;
break;
@@ -693,15 +711,15 @@ error:
genFreeCode = TRUE;
genPrintCode = TRUE;
}
- else if (genCCode + genCxxCode + genTypeTbls + genIDLCode > 1)
+ else if (genCCode + genPyCode + genCxxCode + genTypeTbls + genIDLCode > 1)
{
- fprintf (stderr, "%s: ERROR---Choose only one of the -c -C or -T options\n",
+ fprintf (stderr, "%s: ERROR---Choose only one of the -py, -p py, -c, -C or -T options\n",
argv[0]);
Usage (argv[0], stderr);
return 1;
}
- if (!genCCode && !genCxxCode && !genTypeTbls && !genIDLCode)
+ if (!genCCode && !genCxxCode && !genPyCode && !genTypeTbls && !genIDLCode)
genCCode = TRUE; /* default to C if neither specified */
/* Set the encoding rules to BER if not set */
@@ -714,11 +732,9 @@ error:
allMods = (ModuleList *)AsnListNew (sizeof (void*));
tmpLst = srcList;
- while (tmpLst != NULL)
- {
+ while (tmpLst != NULL) {
// Only do if not NULL
- if (tmpLst->fileName)
- {
+ if (tmpLst->fileName) {
currMod = ParseAsn1File (tmpLst->fileName,
tmpLst->ImportFileFlag);
@@ -738,8 +754,7 @@ error:
/*
* Check that the module names/oids are unique
*/
- if (!ModNamesUnique (allMods))
- {
+ if (!ModNamesUnique (allMods)) {
fprintf (errFileG, "\nConflicting module names, cannot proceed.\n");
return 1;
}
@@ -750,8 +765,7 @@ error:
* Now that all files have been parsed,
* link local and locatable import type refs
*/
- if (LinkTypeRefs (allMods) < 0)
- {
+ if (LinkTypeRefs (allMods) < 0) {
fprintf (errFileG, "\nType linking errors---cannot proceed\n");
return 2;
}
@@ -763,8 +777,7 @@ error:
* and have been linked. Need type info to be able to
* parse values easily (elimitate ambiguity).
*/
- FOR_EACH_LIST_ELMT (currMod, allMods)
- {
+ FOR_EACH_LIST_ELMT (currMod, allMods) {
if (ParseValues (allMods, currMod) != 0)
fprintf (errFileG, "WARNING: Value parsing error (s), attempting to continue\n");
}
@@ -775,8 +788,7 @@ error:
* Value parsing may have defined some new values
* so can link local and locatable import value refs now.
*/
- if (LinkValueRefs (allMods) < 0)
- {
+ if (LinkValueRefs (allMods) < 0) {
fprintf (errFileG, "\nValue linking errors---cannot proceed\n");
return 4;
}
@@ -790,8 +802,8 @@ error:
* so they are put in the id to ANY type hash tbl.
*/
semErr = 0;
- FOR_EACH_LIST_ELMT (currMod, allMods)
- { // For Macors, New TypeDefs are added here, if required
+ FOR_EACH_LIST_ELMT (currMod, allMods) {
+ // For Macros, New TypeDefs are added here, if required
ProcessMacros (currMod);
if (currMod->status == MOD_ERROR)
semErr = 1;
@@ -808,8 +820,8 @@ error:
* boil down values into simplest rep. (eg OID -> ENC_OID)
*/
semErr = 0;
- FOR_EACH_LIST_ELMT (currMod, allMods)
- { // New TypeDefs are added here, if required
+ FOR_EACH_LIST_ELMT (currMod, allMods) {
+ // New TypeDefs are added here, if required
NormalizeModule (currMod);
if (currMod->status == MOD_ERROR)
semErr = 1;
@@ -823,8 +835,7 @@ error:
* Mark recusive types. Currently the recursive information is
* not used elsewhere.
*/
- FOR_EACH_LIST_ELMT (currMod, allMods)
- {
+ FOR_EACH_LIST_ELMT (currMod, allMods) {
MarkRecursiveTypes (currMod);
}
@@ -835,8 +846,7 @@ error:
* Check all modules and exit if errors were found
*/
semErr = 0;
- FOR_EACH_LIST_ELMT (currMod, allMods)
- {
+ FOR_EACH_LIST_ELMT (currMod, allMods) {
ErrChkModule (currMod);
if (currMod->status == MOD_ERROR)
semErr = 1;
@@ -851,23 +861,20 @@ error:
* production but should not affect the other processing/error
* checking steps. This allows full display of errors.
*/
- if (smallErrG)
- {
+ if (smallErrG) {
/*
* for debugging show "parsed" version of ASN.1 module if
* the print flag is set.
* Dumps each module to stdout. Printed from Module data struct
* print here before exiting otherwise print after sorting
*/
- if (printModuleFlag)
- {
- FOR_EACH_LIST_ELMT (currMod, allMods)
- {
+ if (printModuleFlag) {
+ FOR_EACH_LIST_ELMT (currMod, allMods) {
printf ("\n\n");
PrintModule (stdout, currMod);
}
}
-
+
return 8;
}
@@ -893,6 +900,8 @@ error:
FillIDLTypeInfo (&idlRulesG, allMods);
#endif
+ else if (genPyCode)
+ FillPyTypeInfo(&pyRulesG, allMods);
/*
* STEP 10
@@ -911,10 +920,8 @@ error:
* dumps each module to stdout. Printed from Module data struct
* Shows the results of normalization and sorting.
*/
- if (printModuleFlag)
- {
- FOR_EACH_LIST_ELMT (currMod, allMods)
- {
+ if (printModuleFlag) {
+ FOR_EACH_LIST_ELMT (currMod, allMods) {
printf ("\n\n");
PrintModule (stdout, currMod);
}
@@ -944,6 +951,12 @@ error:
genPrintCode, genFreeCode);
#endif
+ else if (genPyCode)
+ GenPyCode(allMods, longJmpVal, genTypeCode, genValueCode,
+ genEncodeCode, genDecodeCode, genPrintCode, genFreeCode,
+ if_META (genMetaCode COMMA meta_pdus COMMA)
+ if_TCL (genTclCode COMMA) novolatilefuncs);
+
tmpLst = srcList;
while(tmpLst) {
SRC_FILE *tmp;
@@ -1159,6 +1172,92 @@ GenCCode PARAMS ((allMods, longJmpVal, genTypes, genValues, genEncoders, genDeco
} /* GenCCode */
+void
+GenPyCode PARAMS ((allMods, longJmpVal, genTypes, genValues, genEncoders, genDecoders, genPrinters, genFree, if_META (genMeta COMMA meta_pdus COMMA) if_TCL (genTcl COMMA) novolatilefuncs),
+ ModuleList *allMods _AND_
+ long longJmpVal _AND_
+ int genTypes _AND_
+ int genValues _AND_
+ int genEncoders _AND_
+ int genDecoders _AND_
+ int genPrinters _AND_
+ int genFree _AND_
+ if_META (MetaNameStyle genMeta _AND_)
+ if_META (MetaPDU *meta_pdus _AND_)
+ if_TCL (int genTcl _AND_)
+ int novolatilefuncs)
+{
+ Module *currMod;
+ AsnListNode *saveMods;
+ char *modBaseFileName;
+ FILE *hdrFilePtr;
+ FILE *srcFilePtr;
+ DefinedObj *fNames;
+ int fNameConflict = FALSE;
+
+ /*
+ * Make names for each module's encoder/decoder src and hdr files
+ * so import references can be made via include files
+ * check for truncation --> name conflicts & exit if nec
+ */
+ fNames = NewObjList();
+
+ FOR_EACH_LIST_ELMT (currMod, allMods) {
+ modBaseFileName = MakeBaseFileName (keepbaseG
+ ? currMod->asn1SrcFileName
+ : currMod->modId->name);
+ currMod->cxxHdrFileName = "";
+ currMod->cxxSrcFileName = MakePySrcFileName(modBaseFileName);
+ if (ObjIsDefined (fNames, currMod->cxxHdrFileName, StrObjCmp) ||
+ ObjIsDefined (fNames, currMod->cxxSrcFileName, StrObjCmp)) {
+ fprintf(errFileG,
+ "ERROR: file name conflict for generated source files with names `%s' and `%s'.\n\n",
+ currMod->cxxHdrFileName, currMod->cxxSrcFileName);
+ fprintf(errFileG,
+ "This usually means the max file name length is truncating the file names.\n");
+ fprintf(errFileG,
+ "Try re-naming the modules with shorter names or increasing the argument to -mf option (if you are using it).\n");
+ fprintf(errFileG,
+ "This error can also be caused by 2 modules have the same names but different OBJECT IDENTIFIERs.");
+ fprintf(errFileG,
+ " Try renaming the modules to correct this.\n");
+ fNameConflict = TRUE;
+ } else {
+ DefineObj (&fNames, currMod->cxxHdrFileName);
+ DefineObj (&fNames, currMod->cxxSrcFileName);
+ }
+ Free (modBaseFileName);
+
+ if (fNameConflict)
+ return;
+
+ FreeDefinedObjs (&fNames);
+ }
+
+ FOR_EACH_LIST_ELMT (currMod, allMods) {
+ if (currMod->ImportedFlag == FALSE) {
+ /*
+ * create and fill .h file for module's data structs
+ */
+ srcFilePtr = fopen (currMod->cxxSrcFileName, "wt");
+
+ if (srcFilePtr == NULL) {
+ perror ("fopen");
+ } else {
+ saveMods = allMods->curr;
+ PrintPyCode (srcFilePtr, hdrFilePtr,
+ if_META (genMeta COMMA &meta COMMA meta_pdus COMMA)
+ allMods, currMod, &cxxRulesG, longJmpVal,
+ genTypes, genValues, genEncoders, genDecoders,
+ genPrinters, genFree,
+ if_TCL (genTcl COMMA) novolatilefuncs);
+ allMods->curr = saveMods;
+ fclose (srcFilePtr);
+ }
+ }
+ }
+}
+
/*
* Given the list of parsed, linked, normalized, error-checked and sorted
* modules, and some code generation flags, generates C++ code and
@@ -1345,7 +1444,7 @@ GenCxxCode PARAMS ((allMods, longJmpVal, genTypes, genValues, genEncoders, genDe
fclose (meta.srcfp);
#endif
- }
+ }
}
} /* GenCxxCode */
--
2.7.4
More information about the dev
mailing list