📄 gen-enc.c
字号:
/* * compiler/back-ends/c-gen/gen-enc.c - routines for printing c encoders from type trees * * Mike Sample * 91/09/26 * 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-enc.c,v 1.3 1995/07/25 18:42:24 rj Exp $ * $Log: gen-enc.c,v $ * Revision 1.3 1995/07/25 18:42:24 rj * file name has been shortened for redundant part: c-gen/gen-c-enc -> c-gen/gen-enc. * * changed `_' to `-' in file names. * * Revision 1.2 1994/09/01 00:23:10 rj * snacc_config.h and other superfluous .h files removed. * * Revision 1.1 1994/08/28 09:48:24 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 "rules.h"#include "type-info.h"#include "str-util.h"#include "util.h"#include "tag-util.h"#include "snacc-util.h"#include "gen-enc.h"static int moduleImplicitTagsG;static CRules *genEncCRulesG;extern char *valueArgNameG;char *encodedLenVarNameG = "totalLen";char *itemLenNameG = "itemLen";char *listComponentNameG = "component";char *listLenNameG = "listLen";char *returnTypeG = "AsnLen";extern char *bufTypeNameG;extern char *lenTypeNameG;extern char *tagTypeNameG;extern char *envTypeNameG;/* non-exported prototypes */static void PrintCBerEncoderPrototype PROTO ((FILE *hdr, TypeDef *td));static void PrintCBerEncoderDeclaration PROTO ((FILE *src, TypeDef *td));static void PrintCBerEncoderDefine PROTO ((FILE *src, TypeDef *td));static void PrintCBerEncoderLocals PROTO ((FILE *src, TypeDef *td));static void PrintCBerElmtsEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int level, char *varName));static void PrintCBerElmtEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedType *e, int level, char *varName));static void PrintCBerListEncoderCode PROTO ((FILE *src, TypeDef *td, Type *t, int level, char *varName));static void PrintCBerChoiceEncodeCode PROTO ((FILE *src, TypeDef *td, Type *t, int level, char *varName));static void PrintCTagAndLenEncodingCode PROTO ((FILE *src, TypeDef *td, Type *t));static void PrintEocEncoders PROTO ((FILE *src, TypeDef *td, Type *t));static void PrintCLenEncodingCode PROTO ((FILE *f, int isCons, int isShort));static void PrintCTagAndLenList PROTO ((FILE *src, Type *t,TagList *tg));voidPrintCBerEncoder PARAMS ((src, hdr, r, m, td), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td){ enum BasicTypeChoiceId typeId; int elmtLevel; CTDI *ctdi; TagList *tags; Tag *tag; char *formStr; char *classStr; int tagLen; int stoleChoiceTags; ctdi = td->cTypeDefInfo; if (!ctdi->genEncodeRoutine) 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->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);/* fprintf(hdr,"#define B%s(b, v, bytesDecoded, env) B%s(b, v, bytesDecoded, env)\n", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName); */ return; } typeId = GetBuiltinType (td->type); /* print proto to hdr file */ fprintf (hdr,"%s B%s PROTO ((%s b, %s *v));\n\n", lenTypeNameG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName); /* print routine to src file */ fprintf (src,"%s B%s PARAMS ((b, v),\n", lenTypeNameG, ctdi->encodeRoutineName); fprintf (src,"%s b _AND_\n",bufTypeNameG); fprintf (src,"%s *v)\n",ctdi->cTypeName); fprintf (src,"{\n"); fprintf (src," %s l;\n", lenTypeNameG); PrintEocEncoders (src, td, td->type); fprintf (src," l = B%sContent (b, v);\n", ctdi->encodeRoutineName); /* encode each tag/len pair if any */ tags = GetTags (td->type, &stoleChoiceTags); if (! stoleChoiceTags) { FOR_EACH_LIST_ELMT_RVS (tag, tags) { classStr = Class2ClassStr (tag->tclass); if (tag->form == ANY_FORM) tag->form = PRIM; formStr = Form2FormStr (tag->form); tagLen = TagByteLen (tag->code); if (tag->form == CONS) fprintf (src," l += BEncConsLen (b, l);\n"); else fprintf (src," l += BEncDefLen (b, l);\n"); if (tag->tclass == UNIV) fprintf (src," l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code)); else fprintf (src," l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code); } } fprintf (src," return l;\n"); fprintf (src,"} /* B%s */\n\n", ctdi->encodeRoutineName); FreeTags (tags);} /* PrintCBerEncoder */voidPrintCBerContentEncoder PARAMS ((src, hdr, r, m, td), FILE *src _AND_ FILE *hdr _AND_ CRules *r _AND_ Module *m _AND_ TypeDef *td){ NamedType *e; CTDI *ctdi; CTypeId rhsTypeId; /* cTypeId of the type that defined this typedef */ genEncCRulesG = r; ctdi = td->cTypeDefInfo; if (!ctdi->genEncodeRoutine) return; rhsTypeId = td->type->cTypeRefInfo->cTypeId; switch (rhsTypeId) { case C_ANY: fprintf (hdr, "/* ANY - Fix Me! */\n"); /* * Note - ANY's don't have the 'Content' suffix cause they * encode their tags and lengths */ fprintf(hdr, "#define B%s B%s\n", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);/* fprintf(hdr, "#define B%s( b, v) ",td->cTypeDefInfo->encodeRoutineName); fprintf (hdr, "B%s (b, v)", td->type->cTypeRefInfo->encodeRoutineName);*/ break; case C_LIB: case C_TYPEREF: PrintCBerEncoderDefine (hdr, td); fprintf (hdr,"\n\n"); break; case C_CHOICE: PrintCBerEncoderPrototype (hdr, td); PrintCBerEncoderDeclaration (src, td); fprintf (src,"{\n"); PrintCBerEncoderLocals (src, td); fprintf (src,"\n\n"); PrintCBerChoiceEncodeCode (src, td, td->type, FIRST_LEVEL, valueArgNameG); fprintf (src," return %s;\n\n", encodedLenVarNameG); fprintf (src,"} /* B%sContent */",td->cTypeDefInfo->encodeRoutineName); fprintf (hdr,"\n\n"); fprintf (src,"\n\n"); break; case C_STRUCT: PrintCBerEncoderPrototype (hdr, td); PrintCBerEncoderDeclaration (src, td); fprintf (src,"{\n"); PrintCBerEncoderLocals (src, td); fprintf (src,"\n\n"); PrintCBerElmtsEncodeCode (src, td, td->type, td->type->basicType->a.set, FIRST_LEVEL, valueArgNameG); fprintf (src," return %s;\n\n", encodedLenVarNameG); fprintf (src,"} /* B%sContent */",td->cTypeDefInfo->encodeRoutineName); fprintf (hdr,"\n\n"); fprintf (src,"\n\n"); break; case C_LIST: PrintCBerEncoderPrototype (hdr, td); fprintf (hdr,"\n\n"); PrintCBerEncoderDeclaration (src, td); fprintf (src,"{\n"); PrintCBerEncoderLocals (src, td); fprintf (src,"\n\n"); PrintCBerListEncoderCode (src, td, td->type, FIRST_LEVEL, valueArgNameG); fprintf (src," return %s;\n\n", listLenNameG); fprintf (src,"} /* B%sContent */", td->cTypeDefInfo->encodeRoutineName); fprintf (src,"\n\n"); break; case C_NO_TYPE:/* fprintf (src," sorry, unsupported type \n\n"); */ break; default: fprintf (stderr,"PrintCBerEncoder: ERROR - unknown c type id\n"); break; }} /* PrintCBerContentEncoder *//* * Prints prototype for encode routine in hdr file */static voidPrintCBerEncoderPrototype PARAMS ((hdr, td), FILE *hdr _AND_ TypeDef *td){ CTDI *ctdi; ctdi = td->cTypeDefInfo; fprintf (hdr,"%s B%sContent PROTO ((%s b, %s *v));", returnTypeG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);} /* PrintCBerEncoderPrototype *//* * Prints declarations of encode routine for the given type def */static voidPrintCBerEncoderDeclaration PARAMS ((src, td), FILE *src _AND_ TypeDef *td){ CTDI *ctdi; ctdi = td->cTypeDefInfo; fprintf (src,"%s\nB%sContent PARAMS ((b, v),\n%s b _AND_\n%s *v)\n", returnTypeG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);} /* PrintCBerEncoderDeclaration *//* * makes a define for type refs or primitive type renaming * EG: * TypeX ::= INTEGER --> #define BerEncodeTypeX(b,v) BerEncodeInteger(b,v) * TypeX ::= TypeY --> #define BerEncodeTypeX(b,v) BerEncodeTypeY(b,v) */static voidPrintCBerEncoderDefine PARAMS ((hdr, td), FILE *hdr _AND_ TypeDef *td){ fprintf(hdr, "#define B%sContent B%sContent", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);/* fprintf(hdr, "#define B%sContent( b, v) ",td->cTypeDefInfo->encodeRoutineName); fprintf (hdr, "B%sContent (b, v)", td->type->cTypeRefInfo->encodeRoutineName);*/} /* PrintCBerEncoderDefine */static voidPrintCBerEncoderLocals PARAMS ((src, td), FILE *src _AND_ TypeDef *td){ fprintf (src, " AsnLen %s = 0;\n", encodedLenVarNameG); fprintf (src, " AsnLen %s;\n", itemLenNameG); fprintf (src, " AsnLen %s;\n", listLenNameG); fprintf (src, " void *%s;", listComponentNameG);} /* PrintCBerEncoderLocals *//* * runs through elmts backwards and prints * encoding code for each one */static voidPrintCBerElmtsEncodeCode PARAMS ((src, td, parent, elmts, level, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedTypeList *elmts _AND_ int level _AND_ char *varName){ NamedType *e; if (elmts == NULL) { fprintf (src,"/* ERROR? - expected elmts for this type*/\n"); return; } /* * remember! encoding "backwards" so recursively traverse * list backwards */ FOR_EACH_LIST_ELMT_RVS (e, elmts) { PrintCBerElmtEncodeCode (src, td, parent, e, level, varName); }} /* PrintCBerElmtsEncodeCode *//* * Prints code for encoding the elmts of a SEQ or SET */static voidPrintCBerElmtEncodeCode PARAMS ((src, td, parent, e, level, varName), FILE *src _AND_ TypeDef *td _AND_ Type *parent _AND_ NamedType *e _AND_ int level _AND_ char *varName){ CTRI *ctri; char elmtVarRef[MAX_VAR_REF]; char idVarRef[MAX_VAR_REF]; enum BasicTypeChoiceId tmpTypeId; Type *tmpType; NamedType *idNamedType; if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL)) return; ctri = e->type->cTypeRefInfo; /* check if meant to be encoded */ if (!ctri->isEncDec) return; MakeVarPtrRef (genEncCRulesG, td, parent, e->type, varName, elmtVarRef); if (e->type->optional || (e->type->defaultVal != NULL)) fprintf (src, " if (%s (%s))\n {\n", ctri->optTestRoutineName, elmtVarRef); PrintEocEncoders (src, td, e->type);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -