📄 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: /baseline/SNACC/compiler/back-ends/c-gen/gen-dec.c,v 1.15 2004/03/12 18:51:20 gronej Exp $ * */#include <string.h>#include "asn-incl.h"#include "asn1module.h"#include "rules.h"#include "snacc-util.h"#include "util.h"#include "tag-util.h"#include "enc-rules.h"static CRules *genDecCRulesG;char *valueArgNameG = "v";static long *longJmpValG;static char *decodedLenVarNameG = "totalElmtsLen";static char *itemLenVarNameG = "elmtLen";/*static char *mecVarNameG = "mandatoryElmtCount";*/static char *tagIdVarNameG = "tagId";char *bufTypeNameG = "GenBuf *";char *lenTypeNameG = "AsnLen";char *tagTypeNameG = "AsnTag";char *envTypeNameG = "ENV_TYPE";/* non-exported prototypes */static void PrintCDecoderPrototype PROTO ((FILE *hdr, TypeDef *td));static void PrintCDecoderDeclaration PROTO ((FILE *src, TypeDef *td));static void PrintCDecoderDefine PROTO ((FILE *src, TypeDef *td));static int RecCountVariableLevels PROTO ((Type *t));static int CountVariableLevels PROTO ((Type *t));static void PrintCDecoderLocals PROTO ((FILE *src, TypeDef *td));/*static void PrintCListDecoderLocals PROTO ((FILE *src));*/static void PrintCSetDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int elmtLevel, int totalLevel, int tagLevel, char *varName));static void PrintCSeqDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int elmtLevel, int totalLevel, int tagLevel, char *varName));static void PrintCListDecoderCode PROTO ((FILE *src, TypeDef *td, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *varName));static void PrintCChoiceDecodeCode PROTO ((FILE *src, TypeDef *td, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *varName));/*static void PrintCLenDecodingCode PROTO ((FILE *f));static void PrintCDecoderIncludes PROTO ((FILE *src, Module *m, ModuleList *mods));*/static void PrintCElmtDecodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, Type *t, int elmtLevel, int totalLevel, int tagLevel, char *parnetVarName, char *elmtVarName, int stoleChoiceTags));voidPrintCDecoder PARAMS ((src, hdr, r, m, td, longJmpVal), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ long *longJmpVal){ int i; enum BasicTypeChoiceId typeId; int elmtLevel; CTDI *ctdi; Tag *tag; char *classStr; char *formStr; int stoleChoiceTags; TagList *tags; EncRulesType *encoding; ctdi = td->cTypeDefInfo; if (!ctdi->genDecodeRoutine) return; encoding = GetEncRules(); while (SetEncRules(*encoding)) { encoding++; /* * 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 %s%s %s%s\n", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName, GetEncRulePrefix(), td->type->cTypeRefInfo->decodeRoutineName); /* fprintf(hdr,"#define %s%s(b, v, bytesDecoded, env) %s%s(b, v, bytesDecoded, env)\n", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName, GetEncRulePrefix() td->type->cTypeRefInfo->decodeRoutineName); */ return; } typeId = GetBuiltinType (td->type); /* print proto type to hdr file */ fprintf (hdr, "void %s%s PROTO ((%s b, %s *result, %s *bytesDecoded, %s env));\n", GetEncRulePrefix(), ctdi->decodeRoutineName, bufTypeNameG, ctdi->cTypeName, lenTypeNameG, envTypeNameG); /* print routine in src */ fprintf (src,"void %s%s PARAMS ((b, result, bytesDecoded, env),\n", GetEncRulePrefix(), 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 = %sDecTag (b, bytesDecoded, env)) != \n", GetEncRulePrefix()); if (tag->tclass == UNIV) { fprintf (src,"MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, DetermineCode(tag, NULL, 0));//RWC;Code2UnivCodeStr (tag->code)); if (tag->form == ANY_FORM) fprintf (src,"&&\n (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 0));//RWC;Code2UnivCodeStr (tag->code)); else fprintf (src,")\n"); } else { fprintf (src,"MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, DetermineCode(tag, NULL, 1));//RWC;tag->code); if (tag->form == ANY_FORM) fprintf (src,"&&\n (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), DetermineCode(tag, NULL, 1));//RWC;tag->code); else fprintf (src,")\n"); } fprintf (src," {\n"); fprintf (src," Asn1Error (\"%s%s: ERROR - wrong tag\\n\");\n", GetEncRulePrefix(), ctdi->decodeRoutineName); fprintf (src," longjmp (env, %d);\n", (int)(*longJmpVal)--); fprintf (src," }\n"); fprintf (src," elmtLen%d = %sDecLen (b, bytesDecoded, env);\n", ++elmtLevel, GetEncRulePrefix()); } } /* for choices always decode first tag of the choice's content */ if (typeId == BASICTYPE_CHOICE) { fprintf (src," tag = %sDecTag (b, bytesDecoded, env);\n", GetEncRulePrefix()); fprintf (src," elmtLen%d = %sDecLen (b, bytesDecoded, env);\n", ++elmtLevel, GetEncRulePrefix()); } if ((typeId != BASICTYPE_ANY) && (typeId != BASICTYPE_ANYDEFINEDBY)) fprintf (src," %s%sContent (b, tag, elmtLen%d, result, bytesDecoded, env);\n", GetEncRulePrefix(), ctdi->decodeRoutineName, elmtLevel); else fprintf (src," %s%s (b, result, bytesDecoded, env);\n", GetEncRulePrefix(), ctdi->decodeRoutineName); /* 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," %sDecEoc (b, bytesDecoded, env);\n", GetEncRulePrefix()); } fprintf (src,"} /* %s%s */\n\n", GetEncRulePrefix(), ctdi->decodeRoutineName); FreeTags (tags); } m = m; r = r; /* AVOIDS warning. */} /* PrintCDecoder */voidPrintCContentDecoder PARAMS ((src, hdr, r, m, td, longJmpVal), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td _AND_ long *longJmpVal){ CTDI *ctdi; CTypeId rhsTypeId; /* cTypeId of the type that defined this typedef */ EncRulesType* encoding; longJmpValG = longJmpVal; genDecCRulesG = r; ctdi = td->cTypeDefInfo; if ((ctdi == NULL) || (td->type->cTypeRefInfo == NULL)) { fprintf (stderr,"PrintCDecoder: ERROR - no type info\n"); return; } if (!ctdi->genDecodeRoutine) return; rhsTypeId = td->type->cTypeRefInfo->cTypeId; encoding = GetEncRules(); while(SetEncRules(*encoding)) { encoding++; switch (rhsTypeId) { /* * type refs or primitive types are * defined as calls to the referenced type */ case C_ANY: //RWC;fprintf (hdr, "/* ANY - Fix Me! */\n"); case C_ANYDEFINEDBY: fprintf(hdr, "#define %s%s %s%s\n", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName, GetEncRulePrefix(), td->type->cTypeRefInfo->decodeRoutineName); /* fprintf(hdr, "#define %s%s( b, tagId, elmtLen, v, bytesDecoded, env) ", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName); fprintf (hdr, "%s%s (b, tagId, elmtLen, v, bytesDecoded, env)", GetEncRulePrefix(), td->type->cTypeRefInfo->decodeRoutineName); */ fprintf (hdr,"\n\n"); break; case C_LIB: case C_TYPEREF: PrintCDecoderDefine (hdr, td); fprintf (hdr,"\n\n"); break; case C_CHOICE: PrintCDecoderPrototype (hdr, td); fprintf (hdr,"\n\n"); PrintCDecoderDeclaration (src, td); fprintf (src,"{\n"); PrintCDecoderLocals (src, td); fprintf (src,"\n\n"); PrintCChoiceDecodeCode (src, td, td->type, FIRST_LEVEL-1, FIRST_LEVEL,FIRST_LEVEL-1, valueArgNameG); fprintf (src, " (*bytesDecoded) += totalElmtsLen1;\n"); fprintf (src,"} /* %s%sContent */", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName); fprintf (src,"\n\n"); break; case C_STRUCT: PrintCDecoderPrototype (hdr, td); fprintf (hdr,"\n\n"); PrintCDecoderDeclaration (src, td); fprintf (src,"{\n"); PrintCDecoderLocals (src, td); fprintf (src,"\n\n"); if (td->type->basicType->choiceId == BASICTYPE_SET) PrintCSetDecodeCode (src, td, td->type, td->type->basicType->a.set, FIRST_LEVEL-1, FIRST_LEVEL, FIRST_LEVEL-1, valueArgNameG); else PrintCSeqDecodeCode (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,"} /* %s%sContent */", GetEncRulePrefix(), td->cTypeDefInfo->decodeRoutineName); fprintf (src,"\n\n"); break; case C_LIST: PrintCDecoderPrototype (hdr, td); fprintf (hdr,"\n\n"); PrintCDecoderDeclaration (src, td); fprintf (src,"{\n"); PrintCDecoderLocals (src, td); fprintf (src,"\n\n"); PrintCListDecoderCode (src, td, td->type, FIRST_LEVEL-1, FIRST_LEVEL, FIRST_LEVEL-1, valueArgNameG); fprintf (src, " (*bytesDecoded) += totalElmtsLen1;\n"); fprintf (src,"} /* %s%sContent */", GetEncRulePrefix(), 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,"PrintCContentDecoder: ERROR - unknown c type id\n"); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -