📄 types.c
字号:
/* * compiler/back-ends/c++-gen/types.c - fills in c++ type information * * MS 91/92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * 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. * * $Header: /usr/app/odstb/CVS/snacc/compiler/back-ends/c++-gen/types.c,v 1.4 1995/07/25 18:25:11 rj Exp $ * $Log: types.c,v $ * Revision 1.4 1995/07/25 18:25:11 rj * file name has been shortened for redundant part: c++-gen/c++-types -> c++-gen/types. * * changed `_' to `-' in file names. * * Revision 1.3 1994/10/08 03:47:51 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * Revision 1.2 1994/09/01 01:06:02 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:47:56 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */#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;/* unexported prototypes */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));/* * allocates and fills all the cxxTypeInfos * in the type trees for every module in the list */voidFillCxxTypeInfo PARAMS ((r, modList), CxxRules *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; /* do useful types first */ 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); } /* * now that type def info is filled in * set up set/seq/list/choice elements that ref * those definitions */ /* do useful types first */ 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); } /* * modules compiled together (ie one call to snacc with * multiple args) likely to be C compiled together so * need a unique routines/types/defines/enum values * since assuming they share same name space. * All Typedefs, union, struct & enum Tags, and defined values * (enum consts), #define names * are assumed to share the same name space */ /* done with checking for name conflicts */ FreeDefinedObjs (&definedNamesG);} /* FillCxxTypeInfo *//* * allocates and fills structure holding C type definition information * fo the given ASN.1 type definition. Does not fill CTRI for contained * types etc. */voidFillCxxTypeDefInfo PARAMS ((r, m, td), CxxRules *r _AND_ Module *m _AND_ TypeDef *td){ int digit; int len; 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 ::= */ FillCxxTDIDefaults (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 */ FillCxxTypeDefInfo (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 */ } /* * check for any "--snacc" attributes that overide the current * cxxtdi fields * UNDEFINED FOR C++ ParseTypeDefAttribs (cxxtdi, td->attrList); */} /* FillCxxTypeDefInfo */static voidFillCxxTypeRefInfo 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; /* * 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; 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); len = strlen (elmtName); cne->name = Malloc (len + 1 + r->maxDigitsToAppend); strcpy (cne->name, elmtName); Free (elmtName); /* not very efficient */ 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); /* * append digits if enum value name is a keyword */ MakeCxxStrUnique (definedNamesG, cne->name, r->maxDigitsToAppend, 1); /* not nec since each class hides the enum scope DefineObj (&definedNamesG, cne->name); */ } } /* fill in rest of type info depending on the type */ switch (basicTypeId) { case BASICTYPE_BOOLEAN: /* library types */ case BASICTYPE_INTEGER: case BASICTYPE_BITSTRING: case BASICTYPE_OCTETSTRING: case BASICTYPE_NULL: case BASICTYPE_OID: case BASICTYPE_REAL: case BASICTYPE_ENUMERATED: /* don't need to do anything else */ break; case BASICTYPE_SEQUENCEOF: /* list types */ case BASICTYPE_SETOF: /* fill in component type */ FillCxxTypeRefInfo (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; case BASICTYPE_ANYDEFINEDBY: /* ANY types */ break; /* these are handled now */ case BASICTYPE_ANY: PrintErrLoc (m->asn1SrcFileName, t->lineNo); 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"); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -