📄 gen-dec.c
字号:
/* * compiler/back-ends/c-gen/gen-dec.c - routines for printing C decoders from type trees * * The type tree has already been run through the c type generator * (type-info.c). Types that the type generator didn't know how * to handle (or didn't want/need to handle eg macros) get the * C_NO_TYPE label and are ignored for code generation. * * NOTE: this is a real rats nest - it sort of evolved. It was * written assuming SETs/SEQ/CHOICE etc could be nested * hence all the crap about 'levels'. * * Mike Sample * 91/10/23 * 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/gen-dec.c,v 1.4 1997/02/28 13:39:54 wan Exp $ * $Log: gen-dec.c,v $ * Revision 1.4 1997/02/28 13:39:54 wan * Modifications collected for new version 1.3: Bug fixes, tk4.2. * * Revision 1.3 1995/07/25 18:41:01 rj * file name has been shortened for redundant part: c-gen/gen-c-dec -> c-gen/gen-dec. * * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:22:06 rj * snacc_config.h and other superfluous .h files removed. * * Revision 1.1 1994/08/28 09:48:20 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */#include <stdio.h>#include "asn-incl.h"#include "asn1module.h"#include "mem.h"#include "define.h"#include "lib-types.h"#include "rules.h"#include "type-info.h"#include "str-util.h"#include "snacc-util.h"#include "util.h"#include "tag-util.h"#include "gen-dec.h"static CRules *genDecCRulesG;char *valueArgNameG = "v";static long int *longJmpValG;static char *decodedLenVarNameG = "totalElmtsLen";static char *itemLenVarNameG = "elmtLen";static char *mecVarNameG = "mandatoryElmtCount";static char *tagIdVarNameG = "tagId";char *bufTypeNameG = "BUF_TYPE";char *lenTypeNameG = "AsnLen";char *tagTypeNameG = "AsnTag";char *envTypeNameG = "ENV_TYPE";/* non-exported prototypes */static void PrintCBerDecoderPrototype PROTO ((FILE *hdr, TypeDef *td));static void PrintCBerDecoderDeclaration PROTO ((FILE *src, TypeDef *td));static void PrintCBerDecoderDefine PROTO ((FILE *src, TypeDef *td));static int RecCountVariableLevels PROTO ((Type *t));static int CountVariableLevels PROTO ((Type *t));static void PrintCBerDecoderLocals PROTO ((FILE *src, TypeDef *td));static void PrintCBerListDecoderLocals PROTO ((FILE *src));static void PrintCBerSetDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int elmtLevel, int totalLevel, int tagLevel, char *varName));static void PrintCBerSeqDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int elmtLevel, int totalLevel, int tagLevel, char *varName));static void PrintCBerListDecoderCode PROTO ((FILE *src, TypeDef *td, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *varName));static void PrintCBerChoiceDecodeCode PROTO ((FILE *src, TypeDef *td, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *varName));static void PrintCLenDecodingCode PROTO ((FILE *f));static void PrintCBerDecoderIncludes PROTO ((FILE *src, Module *m, ModuleList *mods));static void PrintCBerElmtDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *parnetVarName, char *elmtVarName, int stoleChoiceTags));voidPrintCBerDecoder PARAMS ((src, hdr, r, m, td, longJmpVal), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ long int *longJmpVal){ int i; enum BasicTypeChoiceId typeId; int elmtLevel; CTDI *ctdi; Tag *tag; char *classStr; char *formStr; int stoleChoiceTags; TagList *tags; ctdi = td->cTypeDefInfo; if (!ctdi->genDecodeRoutine) return; /* * if is type that refs another pdu type or lib type * without generating a new type via tagging or named elmts * print define to the hdr file * (a type is a pdu by default if it is ref'd by an ANY) */ if (!IsNewType (td->type) && (!IsTypeRef (td->type) || (IsTypeRef (td->type) && (td->type->basicType->a.localTypeRef->link->cTypeDefInfo->isPdu || ((td->type->basicType->a.localTypeRef->link->anyRefs != NULL) && !LIST_EMPTY (td->type->basicType->a.localTypeRef->link->anyRefs)))))) { fprintf(hdr,"#define B%s B%s\n", td->cTypeDefInfo->decodeRoutineName, td->type->cTypeRefInfo->decodeRoutineName);/* fprintf(hdr,"#define B%s(b, v, bytesDecoded, env) B%s(b, v, bytesDecoded, env)\n", td->cTypeDefInfo->decodeRoutineName, td->type->cTypeRefInfo->decodeRoutineName);*/ return; } typeId = GetBuiltinType (td->type); /* print proto type to hdr file */ fprintf (hdr, "void B%s PROTO ((%s b, %s *result, %s *bytesDecoded, %s env));\n", ctdi->decodeRoutineName, bufTypeNameG, ctdi->cTypeName, lenTypeNameG, envTypeNameG); /* print routine in src */ fprintf (src,"void B%s PARAMS ((b, result, bytesDecoded, env),\n", ctdi->decodeRoutineName); fprintf (src,"%s b _AND_\n", bufTypeNameG); fprintf (src,"%s *result _AND_\n", ctdi->cTypeName); fprintf (src,"%s *bytesDecoded _AND_\n", lenTypeNameG); fprintf (src,"%s env)\n", envTypeNameG); fprintf (src,"{\n"); fprintf (src," %s tag;\n", tagTypeNameG); /* print extra locals for redundant lengths */ tags = GetTags (td->type, &stoleChoiceTags); for (i = 1; !stoleChoiceTags && (i <= LIST_COUNT (tags)); i++) fprintf (src," %s elmtLen%d;\n", lenTypeNameG, i); /* add extra len for choice */ if (typeId == BASICTYPE_CHOICE) fprintf (src," %s elmtLen%d;\n", lenTypeNameG, i); fprintf (src,"\n"); /* decode tag/length pairs */ elmtLevel = 0; if (!stoleChoiceTags) { FOR_EACH_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); if (tag->form == ANY_FORM) formStr = Form2FormStr (PRIM); else formStr = Form2FormStr (tag->form); fprintf (src," if (((tag = BDecTag (b, bytesDecoded, env)) != \n"); if (tag->tclass == UNIV) { fprintf (src,"MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, Code2UnivCodeStr (tag->code)); if (tag->form == ANY_FORM) fprintf (src,"&&\n (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), Code2UnivCodeStr (tag->code)); else fprintf (src,")\n"); } else { fprintf (src,"MAKE_TAG_ID (%s, %s, %d))", classStr, formStr, tag->code); if (tag->form == ANY_FORM) fprintf (src,"&&\n (tag != MAKE_TAG_ID (%s, %s, %d)))\n", classStr, Form2FormStr (CONS), tag->code); else fprintf (src,")\n"); } fprintf (src," {\n"); fprintf (src," Asn1Error (\"B%s: ERROR - wrong tag\\n\");\n", ctdi->decodeRoutineName); fprintf (src," longjmp (env, %d);\n", (*longJmpVal)--); fprintf (src," }\n"); fprintf (src," elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel); } } /* for choices always decode first tag of the choice's content */ if (typeId == BASICTYPE_CHOICE) { fprintf (src," tag = BDecTag (b, bytesDecoded, env);\n"); fprintf (src," elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel); } if ((typeId != BASICTYPE_ANY) && (typeId != BASICTYPE_ANYDEFINEDBY)) fprintf (src," B%sContent (b, tag, elmtLen%d, result, bytesDecoded, env);\n", ctdi->decodeRoutineName, elmtLevel); else fprintf (src," B%s (b, result, bytesDecoded, env);\n", ctdi->decodeRoutineName, elmtLevel); /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel-1; i > 0; i--) { fprintf (src," if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src," BDecEoc (b, bytesDecoded, env);\n"); } fprintf (src,"} /* B%s */\n\n", ctdi->decodeRoutineName); FreeTags (tags);} /* PrintCBerDecoder */voidPrintCBerContentDecoder PARAMS ((src, hdr, r, m, td, longJmpVal), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ long int *longJmpVal){ NamedType *e; CTDI *ctdi; CTypeId rhsTypeId; /* cTypeId of the type that defined this typedef */ Type *t; BER_FORM form; longJmpValG = longJmpVal; genDecCRulesG = r; ctdi = td->cTypeDefInfo; if ((ctdi == NULL) || (td->type->cTypeRefInfo == NULL)) { fprintf (stderr,"PrintCBerDecoder: ERROR - no type info\n"); return; } if (!ctdi->genDecodeRoutine) return; rhsTypeId = td->type->cTypeRefInfo->cTypeId; switch (rhsTypeId) { /* * type refs or primitive types are * defined as calls to the referenced type */ case C_ANY: fprintf (hdr, "/* ANY - Fix Me! */\n"); case C_ANYDEFINEDBY: fprintf(hdr, "#define B%s B%s\n", td->cTypeDefInfo->decodeRoutineName, td->type->cTypeRefInfo->decodeRoutineName);/* fprintf(hdr, "#define B%s( b, tagId, elmtLen, v, bytesDecoded, env) ", td->cTypeDefInfo->decodeRoutineName); fprintf (hdr, "B%s (b, tagId, elmtLen, v, bytesDecoded, env)", td->type->cTypeRefInfo->decodeRoutineName);*/ fprintf (hdr,"\n\n"); break; case C_LIB: case C_TYPEREF: PrintCBerDecoderDefine (hdr, td); fprintf (hdr,"\n\n"); break; case C_CHOICE: PrintCBerDecoderPrototype (hdr, td); fprintf (hdr,"\n\n"); PrintCBerDecoderDeclaration (src, td); fprintf (src,"{\n"); PrintCBerDecoderLocals (src, td); fprintf (src,"\n\n"); PrintCBerChoiceDecodeCode (src, td, td->type, FIRST_LEVEL-1, FIRST_LEVEL,FIRST_LEVEL-1, valueArgNameG); fprintf (src, " (*bytesDecoded) += totalElmtsLen1;\n"); fprintf (src,"} /* B%sContent */",td->cTypeDefInfo->decodeRoutineName); fprintf (src,"\n\n"); break; case C_STRUCT: PrintCBerDecoderPrototype (hdr, td); fprintf (hdr,"\n\n"); PrintCBerDecoderDeclaration (src, td); fprintf (src,"{\n"); PrintCBerDecoderLocals (src, td); fprintf (src,"\n\n"); if (td->type->basicType->choiceId == BASICTYPE_SET) PrintCBerSetDecodeCode (src, td, td->type, td->type->basicType->a.set, FIRST_LEVEL-1, FIRST_LEVEL, FIRST_LEVEL-1, valueArgNameG); else PrintCBerSeqDecodeCode (src, td, td->type, td->type->basicType->a.sequence, FIRST_LEVEL-1, FIRST_LEVEL, FIRST_LEVEL-1, valueArgNameG); fprintf (src, " (*bytesDecoded) += totalElmtsLen1;\n"); fprintf (src,"} /* B%sContent */",td->cTypeDefInfo->decodeRoutineName); fprintf (src,"\n\n"); break; case C_LIST: PrintCBerDecoderPrototype (hdr, td); fprintf (hdr,"\n\n"); PrintCBerDecoderDeclaration (src, td); fprintf (src,"{\n"); PrintCBerDecoderLocals (src, td); fprintf (src,"\n\n"); PrintCBerListDecoderCode (src, td, td->type, FIRST_LEVEL-1, FIRST_LEVEL, FIRST_LEVEL-1, valueArgNameG); fprintf (src, " (*bytesDecoded) += totalElmtsLen1;\n"); fprintf (src,"} /* B%sContent */",td->cTypeDefInfo->decodeRoutineName); fprintf (src,"\n\n"); break; case C_NO_TYPE:/* fprintf (src,"< sorry, unsupported type >\n\n"); */ return; /* dont' print newlines */ break; default: fprintf (stderr,"PrintCBerContentDecoder: ERROR - unknown c type id\n"); return; break; }} /* PrintCBerContentDecoder *//* * Prints prototype for decode routine in hdr file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -