#include <ctype.h>
#include <stdio.h>
#include "asn-incl.h"
#include "define.h"
#include "asn1module.h"
#include "mem.h"
#include "snacc-util.h"
#include "str-util.h"
#include "rules.h"
#include "kwd.h"
#include "types.h"
extern Module *usefulTypeModG;
static DefinedObj *definedNamesG;
void FillCxxTypeDefInfo PROTO ((CxxRules *r, Module *m, TypeDef *td));
static void FillCxxFieldNames PROTO ((CxxRules *r, NamedTypeList *firstSibling));
static void FillCxxTypeRefInfo PROTO ((CxxRules *r, Module *m, TypeDef *head, Type *parent, Type *t));
static void FillCxxStructElmts PROTO ((CxxRules *r, Module *m, TypeDef *head, Type *parent, NamedTypeList *t));
static void FillCxxChoiceElmts PROTO ((CxxRules *r, Module *m, TypeDef *head, Type *parent, NamedTypeList *first));
static int IsCxxPtr PROTO ((CxxRules *r, TypeDef *td, Type *parent, Type *t));
void FillCxxTDIDefaults PROTO ((CxxRules *r, CxxTDI *ctdi, TypeDef *td));
void
FillCxxTypeInfo PARAMS ((r, modList),
CxxRules *r _AND_
ModuleList *modList)
{
TypeDef *td;
Module *m;
definedNamesG = NULL;
if (usefulTypeModG != NULL)
{
FOR_EACH_LIST_ELMT (td, usefulTypeModG->typeDefs)
FillCxxTypeDefInfo (r, usefulTypeModG, td);
}
FOR_EACH_LIST_ELMT (m, modList)
{
FOR_EACH_LIST_ELMT (td, m->typeDefs)
FillCxxTypeDefInfo (r, m, td);
}
if (usefulTypeModG != NULL)
{
FOR_EACH_LIST_ELMT (td, usefulTypeModG->typeDefs)
FillCxxTypeRefInfo (r, usefulTypeModG, td, NULL, td->type);
}
FOR_EACH_LIST_ELMT (m, modList)
{
FOR_EACH_LIST_ELMT (td, m->typeDefs)
FillCxxTypeRefInfo (r, m, td, NULL, td->type);
}
FreeDefinedObjs (&definedNamesG);
}
void
FillCxxTypeDefInfo PARAMS ((r, m, td),
CxxRules *r _AND_
Module *m _AND_
TypeDef *td)
{
int digit;
int len;
char *tmpName;
CxxTDI *cxxtdi;
if (td->cxxTypeDefInfo != NULL)
return;
cxxtdi = MT (CxxTDI);
td->cxxTypeDefInfo = cxxtdi;
FillCxxTDIDefaults (r, cxxtdi, td);
if ((td->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
(td->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
{
FillCxxTypeDefInfo (r, td->type->basicType->a.localTypeRef->module, td->type->basicType->a.localTypeRef->link);
tmpName = cxxtdi->className;
*cxxtdi = *td->type->basicType->a.localTypeRef->link->cxxTypeDefInfo;
cxxtdi->className = tmpName;
}
}
static void
FillCxxTypeRefInfo PARAMS ((r, m, head, parent, t),
CxxRules *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;
char *listName;
char *choiceName;
char *unionName;
Type *tmpT;
int len, digit;
enum BasicTypeChoiceId basicTypeId;
if (t->cxxTypeRefInfo == NULL)
{
cxxtri = MT (CxxTRI);
t->cxxTypeRefInfo = cxxtri;
}
else
cxxtri = t->cxxTypeRefInfo;
basicTypeId = t->basicType->choiceId;
tmpCxxtdi = &r->typeConvTbl[basicTypeId];
cxxtri->isEnc = tmpCxxtdi->isEnc;
cxxtri->className = tmpCxxtdi->className;
cxxtri->optTestRoutineName = tmpCxxtdi->optTestRoutineName;
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);
len = strlen (elmtName);
cne->name = Malloc (len + 1 + r->maxDigitsToAppend);
strcpy (cne->name, elmtName);
Free (elmtName);
if (namedElmt->value->basicValue->choiceId == BASICVALUE_INTEGER)
cne->value = namedElmt->value->basicValue->a.integer;
else
{
fprintf (stderr,"Warning: unlinked defined value. Using -9999999\n");
cne->value = -9999999;
}
if (r->capitalizeNamedElmts)
Str2UCase (cne->name, len);
MakeCxxStrUnique (definedNamesG, cne->name, r->maxDigitsToAppend, 1);
}
}
switch (basicTypeId)
{
case BASICTYPE_BOOLEAN:
case BASICTYPE_INTEGER:
case BASICTYPE_BITSTRING:
case BASICTYPE_OCTETSTRING:
case BASICTYPE_NULL:
case BASICTYPE_OID:
case BASICTYPE_REAL:
case BASICTYPE_ENUMERATED:
break;
case BASICTYPE_SEQUENCEOF:
case BASICTYPE_SETOF:
FillCxxTypeRefInfo (r, m, head, t, t->basicType->a.setOf);
break;
case BASICTYPE_IMPORTTYPEREF:
case BASICTYPE_LOCALTYPEREF:
if (t->basicType->a.localTypeRef->link != NULL)
{
tmpCxxtdi= t->basicType->a.localTypeRef->link->cxxTypeDefInfo;
cxxtri->className = tmpCxxtdi->className;
cxxtri->isEnc = tmpCxxtdi->isEnc;
cxxtri->optTestRoutineName = tmpCxxtdi->optTestRoutineName;
}
break;
case BASICTYPE_ANYDEFINEDBY:
break;
case BASICTYPE_ANY:
PrintErrLoc (m->asn1SrcFileName, t->lineNo);
#ifndef VDADER_RULES
fprintf (stderr,"Warning - generated code for the \"ANY\" type in type \"%s\" will need modification by YOU.", head->definedName);
fprintf (stderr," The source files will have a \"/* ANY - Fix Me! */\" comment before related code.\n\n");
#else
if (gVDADER_RULES)
{
fprintf (stderr,"Warning - VDA Enchanced ANY processing being used.\n");
}
#endif
break;
case BASICTYPE_CHOICE:
FillCxxFieldNames (r, t->basicType->a.choice);
FillCxxChoiceElmts (r, m, head, t, t->basicType->a.choice);
break;
case BASICTYPE_SET:
case BASICTYPE_SEQUENCE:
FillCxxStructElmts (r, m, head, t, t->basicType->a.set);
FillCxxFieldNames (r, t->basicType->a.set);
break;
case BASICTYPE_COMPONENTSOF:
case BASICTYPE_SELECTION:
fprintf (stderr,"Compiler error - COMPONENTS OF or SELECTION type slipped through normalizing phase.\n");
break;
case BASICTYPE_UNKNOWN:
case BASICTYPE_MACRODEF:
case BASICTYPE_MACROTYPE:
break;
}
cxxtri->isPtr = IsCxxPtr (r, head, parent, t);
}
static void
FillCxxStructElmts PARAMS ((r, m, head, parent, elmts),
CxxRules *r _AND_
Module *m _AND_
TypeDef *head _AND_
Type *parent _AND_
NamedTypeList *elmts)
{
NamedType *et;
FOR_EACH_LIST_ELMT (et, elmts)
{
FillCxxTypeRefInfo (r, m, head, parent, et->type);
}
}
static void
FillCxxChoiceElmts PARAMS ((r, m, head, parent, elmts),
CxxRules *r _AND_
Module *m _AND_
TypeDef *head _AND_
Type *parent _AND_
NamedTypeList *elmts)
{
NamedType *et;
int idCount = 0;
CxxTRI *cxxtri;
int len;
FOR_EACH_LIST_ELMT (et, elmts)
FillCxxTypeRefInfo (r, m, head, parent, et->type);
FOR_EACH_LIST_ELMT (et, elmts)
{
cxxtri = et->type->cxxTypeRefInfo;
if (cxxtri == NULL)
continue;
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);
}
}
static void
FillCxxFieldNames PARAMS ((r, elmts),
CxxRules *r _AND_
NamedTypeList *elmts)
{
NamedType *et;
CxxTRI *cxxtri;
DefinedObj *fieldNames;
int len, num, digit, i, tmpLen;
char *tmpName;
char *asn1FieldName;
char *cFieldName;
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)
{
asn1FieldName = et->fieldName;
tmpName = Asn1FieldName2CFieldName (asn1FieldName);
cxxtri->fieldName = Malloc (strlen (tmpName) + 1 +
r->maxDigitsToAppend);
strcpy (cxxtri->fieldName, tmpName);
Free (tmpName);
MakeCxxStrUnique (fieldNames, cxxtri->fieldName, r->maxDigitsToAppend, 1);
DefineObj (&fieldNames, cxxtri->fieldName);
}
}
FOR_EACH_LIST_ELMT (et, elmts)
{
cxxtri = et->type->cxxTypeRefInfo;
if (cxxtri->fieldName == NULL)
{
if ((et->type->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
(et->type->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
{
tmpName = et->type->basicType->a.localTypeRef->link->cxxTypeDefInfo->className;
tmpName = Asn1TypeName2CTypeName (tmpName);
cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1);
strcpy (cFieldName, tmpName);
Free (tmpName);
if (isupper (cFieldName[0]))
cFieldName[0] = tolower (cFieldName[0]);
}
else
{
tmpName = r->typeConvTbl[et->type->basicType->choiceId].defaultFieldName;
cFieldName = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1);
strcpy (cFieldName, tmpName);
if (isupper (cFieldName[0]))
cFieldName[0] = tolower (cFieldName[0]);
}
len = strlen (cFieldName);
MakeCxxStrUnique (fieldNames, cFieldName, r->maxDigitsToAppend, 1);
DefineObj (&fieldNames, cFieldName);
cxxtri->fieldName = cFieldName;
}
}
FreeDefinedObjs (&fieldNames);
}
static int
IsCxxPtr PARAMS ((r, td, parent, t),
CxxRules *r _AND_
TypeDef *td _AND_
Type *parent _AND_
Type *t)
{
CxxTDI *cxxtdi;
int retVal = FALSE;
if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
(t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
{
cxxtdi = t->basicType->a.localTypeRef->link->cxxTypeDefInfo;
}
else
cxxtdi = &r->typeConvTbl[GetBuiltinType (t)];
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;
}
void
FillCxxTDIDefaults PARAMS ((r, cxxtdi, td),
CxxRules *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));
tmpName = Asn1TypeName2CTypeName (td->definedName);
cxxtdi->className = Malloc (strlen (tmpName) + r->maxDigitsToAppend +1);
strcpy (cxxtdi->className, tmpName);
Free (tmpName);
MakeCxxStrUnique (definedNamesG, cxxtdi->className, r->maxDigitsToAppend, 1);
DefineObj (&definedNamesG, cxxtdi->className);
}