📄 type-info.c
字号:
/* * compiler/back-ends/c-gen/type-info.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/type-info.c,v 1.3 1995/07/25 18:47:45 rj Exp $ * $Log: type-info.c,v $ * Revision 1.3 1995/07/25 18:47:45 rj * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:26:44 rj * snacc_config.h removed. * * Revision 1.1 1994/08/28 09:48:42 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 "asn1module.h"#include "mem.h"#include "snacc-util.h"#include "define.h"#include "str-util.h"#include "rules.h"#include "type-info.h"extern Module *usefulTypeModG;static DefinedObj *definedNamesG;/* * All Typedefs, union,struct & enum Tags, and definedvalues (enum consts) * are assumed to share the same name space - this list is used to * assure uniqueness. (actually 4 name spaces in C - see pg 227 KR 2nd Ed) *//* unexported prototypes */void FillCTypeDefInfo PROTO ((CRules *r, Module *m, TypeDef *td));static void FillCFieldNames PROTO ((CRules *r, NamedTypeList *firstSibling));static void FillCTypeRefInfo PROTO ((CRules *r, Module *m, TypeDef *head, Type *t, CTypeId parentTypeId));static void FillCStructElmts PROTO ((CRules *r, Module *m, TypeDef *head, NamedTypeList *t));static void FillCChoiceElmts PROTO ((CRules *r, Module *m, TypeDef *head, NamedTypeList *first));static int IsCPtr PROTO ((CRules *r, TypeDef *td, Type *t, CTypeId parentTypeId));void ParseTypeDefAttribs PROTO ((CTDI *ctdi, AttributeList *attrList));void ParseTypeRefAttribs PROTO ((CTRI *ctri, AttributeList *attrList));void ParseAttr PROTO ((char *str, int *startLoc, char **attrName, char **attrValue));int ParseBool PROTO ((char *str, int *result));int ParseInt PROTO ((char *str, int *result));int ParseCTypeId PROTO ((char *str, int *result));void FillCTDIDefaults PROTO ((CRules *r, CTDI *ctdi, TypeDef *td));/* * allocates and fills all the "cTypeDefInfo" for each type def * and "cTypeRefInfo" for each type in the given modules. * Also does the useful types module if it is not null. */voidFillCTypeInfo PARAMS ((r, modList), CRules *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 = NewObjList(); /* do useful types first */ if (usefulTypeModG != NULL) { FOR_EACH_LIST_ELMT (td, usefulTypeModG->typeDefs) FillCTypeDefInfo (r, usefulTypeModG, td); } FOR_EACH_LIST_ELMT (m, modList) { FOR_EACH_LIST_ELMT (td, m->typeDefs) FillCTypeDefInfo (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) FillCTypeRefInfo (r, usefulTypeModG, td, td->type, C_TYPEDEF); } FOR_EACH_LIST_ELMT (m, modList) { FOR_EACH_LIST_ELMT (td, m->typeDefs) FillCTypeRefInfo (r, m, td, td->type, C_TYPEDEF); } /* * 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 */ FreeDefinedObjs (&definedNamesG);} /* FillCTypeInfo *//* * allocates and fills structure holding C type definition information * fo the given ASN.1 type definition. Does not fill CTRI for contained * types etc. */voidFillCTypeDefInfo PARAMS ((r, m, td), CRules *r _AND_ Module *m _AND_ TypeDef *td){ int digit; int len; char *tmpName; CTDI *ctdi; /* * if CTDI is present this type def has already been 'filled' */ if (td->cTypeDefInfo != NULL) return; ctdi = td->cTypeDefInfo = MT (CTDI); ctdi->cTypeId = C_TYPEDEF; /* get default type def attributes from table for type on rhs of ::= */ FillCTDIDefaults (r, ctdi, td); /* * if defined by a ref to another type definition fill in that type * def's CTDI 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 CTDI for defining type if nec. * this works for importTypeRef as well since both a.localTypeRef * and a.importTypeRef are of type TypeRef */ FillCTypeDefInfo (r, td->type->basicType->a.localTypeRef->module, td->type->basicType->a.localTypeRef->link); memcpy (ctdi, td->type->basicType->a.localTypeRef->link->cTypeDefInfo, sizeof (CTDI)); } /* * Zap default names for routines/type with NULL so * can determine if the --snacc attributes specified any */ ctdi->cTypeName = NULL; ctdi->printRoutineName = NULL; ctdi->encodeRoutineName = NULL; ctdi->decodeRoutineName = NULL; ctdi->freeRoutineName = NULL; /* * check for any "--snacc" attributes that overide the current * ctdi fields */ ParseTypeDefAttribs (ctdi, td->attrList); /* * generate c typename for this type def if not given by * --snacc attributes */ if (ctdi->cTypeName == NULL) { tmpName = Asn1TypeName2CTypeName (td->definedName); len = strlen (tmpName); ctdi->cTypeName = Malloc (len + r->maxDigitsToAppend + 1); strcpy (ctdi->cTypeName, tmpName); Free (tmpName); /* * make sure c type def name is unique * (no need to check if cTypeName was specified by --snacc attribs) */ MakeCStrUnique (definedNamesG, ctdi->cTypeName,r->maxDigitsToAppend, 1); DefineObj (&definedNamesG, ctdi->cTypeName); } /* * make names for encoder,decoder, print and free routines * (if not already set by --snacc attributes */ if (ctdi->encodeRoutineName == NULL) { ctdi->encodeRoutineName = Malloc (strlen (ctdi->cTypeName) + strlen (r->encodeRoutineBaseName) + 1); strcpy (ctdi->encodeRoutineName, r->encodeRoutineBaseName); strcat (ctdi->encodeRoutineName, ctdi->cTypeName); } if (ctdi->decodeRoutineName == NULL) { ctdi->decodeRoutineName = Malloc (strlen (ctdi->cTypeName) + strlen (r->decodeRoutineBaseName) + 1); strcpy (ctdi->decodeRoutineName, r->decodeRoutineBaseName); strcat (ctdi->decodeRoutineName, ctdi->cTypeName); } if (ctdi->printRoutineName == NULL) { ctdi->printRoutineName = Malloc (strlen (ctdi->cTypeName) + strlen (r->printRoutineBaseName) + 1); strcpy (ctdi->printRoutineName, r->printRoutineBaseName); strcat (ctdi->printRoutineName, ctdi->cTypeName); } if (ctdi->freeRoutineName == NULL) { ctdi->freeRoutineName = Malloc (strlen (ctdi->cTypeName) + strlen (r->freeRoutineBaseName) + 1); strcpy (ctdi->freeRoutineName, r->freeRoutineBaseName); strcat (ctdi->freeRoutineName, ctdi->cTypeName); }} /* FillCTypeDefInfo */static voidFillCTypeRefInfo PARAMS ((r, m, head, t, parentTypeId), CRules *r _AND_ Module *m _AND_ TypeDef *head _AND_ Type *t _AND_ CTypeId parentTypeId){ char *typeStr; CTRI *ctri; CTDI *tmpCtdi; 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->cTypeRefInfo == NULL) { ctri = MT (CTRI); t->cTypeRefInfo = ctri; } else ctri = t->cTypeRefInfo; basicTypeId = t->basicType->choiceId; tmpCtdi = &r->typeConvTbl[basicTypeId]; /* get base type def info from the conversion table in the rules */ /* if the cTypeId is C_LIB, nothing more needs to be done */ ctri->cTypeId = tmpCtdi->cTypeId; ctri->cTypeName = tmpCtdi->cTypeName; ctri->optTestRoutineName = tmpCtdi->optTestRoutineName; ctri->printRoutineName = tmpCtdi->printRoutineName; ctri->encodeRoutineName = tmpCtdi->encodeRoutineName; ctri->decodeRoutineName = tmpCtdi->decodeRoutineName; ctri->freeRoutineName = tmpCtdi->freeRoutineName; ctri->isEncDec = tmpCtdi->isEncDec; if (ctri->cTypeId == C_ANY) { 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"); } /* * convert named elmts to C. * 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))) { ctri->cNamedElmts = AsnListNew (sizeof (void *)); FOR_EACH_LIST_ELMT (namedElmt, t->basicType->a.integer) { cneHndl = (CNamedElmt **)AsnListAppend (ctri->cNamedElmts); 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 until there is not name conflict * if nec */ MakeCStrUnique (definedNamesG, cne->name, r->maxDigitsToAppend, 1); DefineObj (&definedNamesG, cne->name); } } /* * Fill in c type name, routines, ptr attibutes etc */ if (r->typeConvTbl[basicTypeId].cTypeId == C_TYPEREF) { /* * don't do this anymore - it cause problems since FillTypeDef * changes name ie ORName -> ORName1 and other type use new name * * don't define type or print/enc/dec/free routines * if typedef name is the same as the defining type ref name * in P2: ORName ::= P1.ORName if ((parentTypeId == C_TYPEDEF) && (strcmp (head->definedName, t->basicType->a.localTypeRef->typeName) == 0)) { tmpCtdi = head->cTypeDefInfo; tmpCtdi->genPrintRoutine = FALSE; tmpCtdi->genEncodeRoutine = FALSE; tmpCtdi->genDecodeRoutine = FALSE; tmpCtdi->genFreeRoutine = FALSE; tmpCtdi->genTypeDef = FALSE; } */ /* * grab type 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 */ tmpCtdi= t->basicType->a.localTypeRef->link->cTypeDefInfo; ctri->cTypeName = tmpCtdi->cTypeName; ctri->printRoutineName = tmpCtdi->printRoutineName; ctri->encodeRoutineName = tmpCtdi->encodeRoutineName; ctri->decodeRoutineName = tmpCtdi->decodeRoutineName; ctri->freeRoutineName = tmpCtdi->freeRoutineName; ctri->isEncDec = tmpCtdi->isEncDec; ctri->optTestRoutineName = tmpCtdi->optTestRoutineName; } else { /* * guess type and routine names */ fprintf (stderr,"Assuming C Type and Routine names for unresolved type ref \"%s\"\n",t->basicType->a.localTypeRef->typeName); ctri->cTypeName = Asn1TypeName2CTypeName (t->basicType->a.localTypeRef->typeName); ctri->printRoutineName = Malloc (strlen (r->printRoutineBaseName) + strlen (ctri->cTypeName) + 1); strcpy (ctri->printRoutineName, r->printRoutineBaseName); strcat (ctri->printRoutineName, ctri->cTypeName); ctri->encodeRoutineName = Malloc (strlen (r->encodeRoutineBaseName)+ strlen (ctri->cTypeName) + 1); strcpy (ctri->encodeRoutineName, r->encodeRoutineBaseName); strcat (ctri->encodeRoutineName, ctri->cTypeName); ctri->decodeRoutineName = Malloc (strlen (r->decodeRoutineBaseName)+ strlen (ctri->cTypeName) + 1); strcpy (ctri->decodeRoutineName, r->decodeRoutineBaseName); strcat (ctri->decodeRoutineName, ctri->cTypeName); ctri->freeRoutineName = Malloc (strlen (ctri->cTypeName) + strlen (r->freeRoutineBaseName) + 1); strcpy (ctri->freeRoutineName, r->freeRoutineBaseName); strcat (ctri->freeRoutineName, ctri->cTypeName); } } else if (r->typeConvTbl[basicTypeId].cTypeId == C_LIST)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -