|
|
/* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */ /* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */
#include "precomp.h"
#ifndef HAS_GETOPT
extern int getopt(int argc, char **argv, const char *opts); extern char *optarg; extern int optind; #endif
int pass;
/* if ForceAllTypes is set, asn1c will generate encoding functions for */ /* all types (default: only for sequence/set/choice/sequence of/set of) */ int ForceAllTypes = 0;
/* type to use for unconstrained integers/semiconstrained signed integers */ char *IntegerRestriction = "ASN1int32_t";
/* type to use for semiconstrained unsigned integers */ char *UIntegerRestriction = "ASN1uint32_t";
/* type to use for real */ char *RealRestriction = "double";
/* output language */ Language_e g_eProgramLanguage = eLanguage_C;
/* alignment of encoding */ Alignment_e Alignment = eAlignment_Aligned;
/* encoding to generate code for */ Encoding_e g_eEncodingRule = eEncoding_Packed;
/* subencoding to generate code for */ SubEncoding_e g_eSubEncodingRule = eSubEncoding_Basic;
/* target compiler supports 64 bit integers */ int Has64Bits = 0;
/* zero out allocated buffers for decoded data */ int g_fDecZeroMemory = 1;
/* debug module name */ int g_nDbgModuleName = 0;
/* source file and header file pointers */ FILE *g_finc, *g_fout;
// default tag type in this module
TagType_e g_eDefTagType = eTagType_Unknown;
/* original main module name without postfixed _Module */ char *g_pszOrigModuleName = NULL; char *g_pszOrigModuleNameLowerCase = NULL;
/* enable long name (prefixed with module name for imported) */ int g_fLongNameForImported = 0;
// extra struct type name postfixed with _s, and its original name is its pointer type.
int g_fExtraStructPtrTypeSS = 0;
// the default structure type for Sequence Of and Set Of
TypeRules_e g_eDefTypeRuleSS_NonSized = eTypeRules_SinglyLinkedList; TypeRules_e g_eDefTypeRuleSS_Sized = eTypeRules_FixedArray;
// ignore the assertion
int g_fNoAssert = 0;
// object identifier is 16-node array
int g_fOidArray = 0;
// case based optimizer switch
int g_fCaseBasedOptimizer = 1;
// enable in-file directive
int g_fMicrosoftExtensions = 1;
// all platforms: little endian (default) and big endian
int g_fAllEndians = 0;
// directive begin, end, AND
int g_chDirectiveBegin = '#'; int g_chDirectiveEnd = '#'; int g_chDirectiveAND = '&';
// postfix
char *g_pszApiPostfix = "ID"; char *g_pszChoicePostfix = "choice"; char *g_pszOptionPostfix = "option";
// option value
char *g_pszOptionValue = "option_bits";
// invisble file array
int g_cGhostFiles = 0; GhostFile_t g_aGhostFiles[16];
int _cdecl main(int argc, char **argv) { FILE *finc, *fout; char *p; int c, chInvalidDir; LLSTATE in, out; UndefinedSymbol_t *lastundef; Assignment_t *a, **aa; LLTERM *tokens; unsigned ntokens; int fSupported; char *psz; char incfilename[256], outfilename[256], module[256];
/* parse options */ // if an option is followed by ':', then it has a parameter.
while ((c = getopt(argc, argv, "ab:c:d:e:fg:hil:mn:o:p:q:s:t:uv:wy")) != EOF) { chInvalidDir = 0; switch (c) { case 'a':
/* enable for all platforms: little endian and big endian */ g_fAllEndians = 1; break;
case 'b':
/* maximum number of bits of target machine */ if (atoi(optarg) == 32) { Has64Bits = 0; break; } if (atoi(optarg) == 64) { Has64Bits = 1; break; } fprintf(stderr, "Bad number of bits specified.\n"); MyExit(1); /*NOTREACHED*/
case 'c':
// Choice postfix
psz = strdup(optarg); if (psz && isalpha(*psz)) { g_pszChoicePostfix = psz; } break;
case 'd':
// sequence of and set of data structure types
if (! stricmp(optarg, "linked") || ! stricmp(optarg, "slinked")) { g_eDefTypeRuleSS_NonSized = eTypeRules_SinglyLinkedList; } else if (! stricmp(optarg, "lenptr")) { g_eDefTypeRuleSS_NonSized = eTypeRules_LengthPointer; } else if (! stricmp(optarg, "dlinked")) { g_eDefTypeRuleSS_NonSized = eTypeRules_DoublyLinkedList; } else { goto usage; } break;
case 'e':
/* encoding to generate code for */ if (!stricmp(optarg, "packed")) { g_eEncodingRule = eEncoding_Packed; } else if (!stricmp(optarg, "basic")) { g_eEncodingRule = eEncoding_Basic; } else if (!stricmp(optarg, "per")) { g_eEncodingRule = eEncoding_Packed; Alignment = eAlignment_Aligned; } else if (!stricmp(optarg, "cer")) { g_eEncodingRule = eEncoding_Basic; g_eSubEncodingRule = eSubEncoding_Canonical; } else if (!stricmp(optarg, "der")) { g_eEncodingRule = eEncoding_Basic; g_eSubEncodingRule = eSubEncoding_Distinguished; } else if (!stricmp(optarg, "ber")) { g_eEncodingRule = eEncoding_Basic; g_eSubEncodingRule = eSubEncoding_Basic; } else { fprintf(stderr, "Bad encoding specified.\n"); fprintf(stderr, "Allowed encodings are:\n"); fprintf(stderr, "- packed (default)\n"); fprintf(stderr, "- basic\n"); MyExit(1); /*NOTREACHED*/ } break;
case 'f':
/* force generation of encoding/decoding functions for all types */ ForceAllTypes = 1; break;
case 'g':
/* ghost asn1 files */ g_aGhostFiles[g_cGhostFiles].pszFileName = strdup(optarg); g_aGhostFiles[g_cGhostFiles++].pszModuleName = NULL; break;
case 'h':
goto usage;
case 'i':
/* ignore assertion */ g_fNoAssert = 1; break;
case 'l':
/* set output language */ if (!stricmp(optarg, "c")) { g_eProgramLanguage = eLanguage_C; break; } if (!stricmp(optarg, "c++") || !stricmp(optarg, "cpp")) { g_eProgramLanguage = eLanguage_Cpp; break; } goto usage;
case 'm':
/* enable Microsoft extension */ g_fMicrosoftExtensions = 1; break;
case 'n':
/* debug module name */ g_nDbgModuleName = 0; { int len = strlen(optarg); if (len > 4) len = 4; memcpy(&g_nDbgModuleName, optarg, len); } break;
case 'o':
// Option postfix
psz = strdup(optarg); if (psz && isalpha(*psz)) { g_pszOptionPostfix = psz; } break;
case 'p':
// API postfix
psz = strdup(optarg); if (psz && isalpha(*psz)) { g_pszApiPostfix = psz; } break;
case 'q':
// sequence of and set of data structure types
if (! stricmp(optarg, "linked") || ! stricmp(optarg, "slinked")) { g_eDefTypeRuleSS_Sized = eTypeRules_SinglyLinkedList; } else if (! stricmp(optarg, "lenptr")) { g_eDefTypeRuleSS_Sized = eTypeRules_LengthPointer; } else if (! stricmp(optarg, "array")) { g_eDefTypeRuleSS_Sized = eTypeRules_FixedArray; } else if (! stricmp(optarg, "pointer")) { g_eDefTypeRuleSS_Sized = eTypeRules_PointerToElement | eTypeRules_FixedArray; } else if (! stricmp(optarg, "dlinked")) { g_eDefTypeRuleSS_Sized = eTypeRules_DoublyLinkedList; } else { goto usage; } break;
case 's':
/* set subencoding */ if (!stricmp(optarg, "aligned")) { Alignment = eAlignment_Aligned; } else if (!stricmp(optarg, "unaligned")) { Alignment = eAlignment_Unaligned; } else if (!stricmp(optarg, "cer")) { g_eSubEncodingRule = eSubEncoding_Canonical; } else if (!stricmp(optarg, "der")) { g_eSubEncodingRule = eSubEncoding_Distinguished; } else if (!stricmp(optarg, "basic")) { g_eSubEncodingRule = eSubEncoding_Basic; } else { fprintf(stderr, "Bad sub-encoding specified.\n"); fprintf(stderr, "Allowed sub-encodings are:\n"); fprintf(stderr, "- aligned (default) or unaligned\n"); fprintf(stderr, "- basic (default), cer or der\n"); MyExit(1); /*NOTREACHED*/ } break;
case 't':
/* specify type to use for unconstrained/semiconstrained types */ p = strchr(optarg, '='); if (!p) goto usage; *p++ = 0; if (!stricmp(optarg, "integer")) { if (!stricmp(p, "ASN1int32_t")) { IntegerRestriction = "ASN1int32_t"; break; } if (!stricmp(p, "ASN1uint32_t")) { IntegerRestriction = "ASN1uint32_t"; break; } if (!stricmp(p, "ASN1int64_t")) { IntegerRestriction = "ASN1int64_t"; break; } if (!stricmp(p, "ASN1uint64_t")) { IntegerRestriction = "ASN1uint64_t"; break; } if (!stricmp(p, "ASN1intx_t")) { IntegerRestriction = "ASN1intx_t"; break; } } if (!stricmp(optarg, "unsigned")) { if (!stricmp(p, "ASN1int32_t")) { UIntegerRestriction = "ASN1int32_t"; break; } if (!stricmp(p, "ASN1uint32_t")) { UIntegerRestriction = "ASN1uint32_t"; break; } if (!stricmp(p, "ASN1int64_t")) { UIntegerRestriction = "ASN1int64_t"; break; } if (!stricmp(p, "ASN1uint64_t")) { UIntegerRestriction = "ASN1uint64_t"; break; } if (!stricmp(p, "ASN1intx_t")) { UIntegerRestriction = "ASN1intx_t"; break; } } if (!stricmp(optarg, "real")) { if (!stricmp(p, "double")) { RealRestriction = "double"; break; } if (!stricmp(p, "ASN1real_t")) { RealRestriction = "ASN1real_t"; break; } } goto usage;
case 'u':
// no case-based optimizer
g_fCaseBasedOptimizer = 0; break;
case 'v':
// Option value
psz = strdup(optarg); if (psz && isalpha(*psz)) { g_pszOptionValue = psz; } break;
case 'w':
// --#OID ARRAY#--
g_fOidArray = 1; break;
case 'y':
/* enable long name (prefixed with module name for imported) */ g_fLongNameForImported = 1; break;
default:
chInvalidDir = c;
usage: fprintf(stderr,"ASN.1 Compiler V1.0\n"); fprintf(stderr, "Copyright (C) Microsoft Corporation, U.S.A., 1997-1998. All rights reserved.\n"); fprintf(stderr, "Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved.\n"); if (chInvalidDir) { fprintf(stderr, "Invalid option -%c\n", chInvalidDir); } else { fprintf(stderr, "Usage: %s [options] [imported.asn1 ...] main.asn1\n", argv[0]); fprintf(stderr, "Options:\n"); fprintf(stderr, "-h\t\tthis help\n"); fprintf(stderr, "-z\t\tzero out allocated buffers for decoded data\n"); fprintf(stderr, "-x\t\tbridge APIs\n"); fprintf(stderr, "-a\t\textra type definition for structure\n"); fprintf(stderr, "-n name\t\tmodule name for debugging purpose\n"); // fprintf(stderr, "-l language\tgenerate code for <language> (c (default), c++)\n");
// fprintf(stderr, "-b 64\t\tenable 64 bit support\n");
fprintf(stderr, "-e encoding\tuse <encoding> as encoding rule\n"); fprintf(stderr, "\t\t(possible values: packed (default), basic)\n"); fprintf(stderr, "-s subencoding\tuse <subencoding> as subencoding rules\n"); fprintf(stderr, "\t\t(possible values: aligned (default) or unaligned,\n"); fprintf(stderr, "\t\tbasic (default), canonical or distinguished)\n"); fprintf(stderr, "-t type=rest.\trestrict/unrestrict a unconstrained/semiconstrained type:\n"); fprintf(stderr, "\t\tinteger=type\tuse <type> (ASN1[u]int32_t, ASN1[u]int64_t or\n\t\t\t\tASN1intx_t) for unconstrained integers\n\t\t\t\t(default: ASN1int32_t)\n"); fprintf(stderr, "\t\tunsigned=type\tuse <type> (ASN1[u]int32_t, ASN1[u]int64_t or\n\t\t\t\tASN1intx_t) for positive semiconstrained\n\t\t\t\tintegers (default: ASN1uint32_t)\n"); fprintf(stderr, "\t\treal=type\tuse <type> (double or ASN1real_t) for\n\t\t\t\tunconstrained floating point numbers\n\t\t\t\t(default: double)\n"); } MyExit(1); } }
/* check if any modules are given */ if (argc < optind + 1) goto usage;
/* check for unsupported encoding */ fSupported = TRUE; if (g_eEncodingRule == eEncoding_Packed) { if (Alignment != eAlignment_Aligned || g_eSubEncodingRule != eSubEncoding_Basic) { fSupported = FALSE; } } else if (g_eEncodingRule == eEncoding_Basic) { // if (Alignment != eAlignment_Aligned || g_eSubEncodingRule == eSubEncoding_Distinguished)
if (Alignment != eAlignment_Aligned) { fSupported = FALSE; } } if (! fSupported) { fprintf(stderr, "Encoding not implemented (yet)\n"); MyExit(1); }
/* initialize */ InitBuiltin();
/* scan file(s) */ #if defined(LLDEBUG) && LLDEBUG > 0
pass = 1; fprintf(stderr, "Pass 1: Scanning input file\n"); #endif
readfiles(argv + optind); llscanner(&tokens, &ntokens);
/* setup initial state */ in.Assignments = Builtin_Assignments; in.AssignedObjIds = Builtin_ObjIds; in.Undefined = NULL; in.BadlyDefined = NULL; in.Module = NULL; in.MainModule = NULL; in.Imported = NULL; in.TagDefault = eTagType_Unknown; in.ExtensionDefault = eExtensionType_None; lastundef = NULL;
/* parse the modules */ do { #if defined(LLDEBUG) && LLDEBUG > 0
fprintf(stderr, "Pass %d: Parsing \n", ++pass); #endif
/* parse modules */ if (!llparser(tokens, ntokens, &in, &out)) { llprinterror(stderr); MyExit(1); }
/* if undefined symbols remain the same as in previous pass */ /* than print these undefined symbols and MyExit */ if (!CmpUndefinedSymbolList(out.Assignments, out.Undefined, lastundef)) UndefinedError(out.Assignments, out.Undefined, out.BadlyDefined);
/* setup data for next pass */ in = out; aa = &in.Assignments; for (a = Builtin_Assignments; a; a = a->Next) { *aa = DupAssignment(a); aa = &(*aa)->Next; } *aa = NewAssignment(eAssignment_NextPass); aa = &(*aa)->Next; *aa = out.Assignments; lastundef = out.Undefined; in.Undefined = NULL; in.BadlyDefined = NULL;
/* continue parsing until no undefined symbols left */ } while (lastundef);
/* build internal information */ #if defined(LLDEBUG) && LLDEBUG > 0
fprintf(stderr, "Pass %d: Building internal information \n", ++pass); #endif
Examination(&out.Assignments, out.MainModule); ExaminePER(out.Assignments); ExamineBER(out.Assignments);
// remember who is the local duplicate of imported types
for (a = out.Assignments; a; a = a->Next) { a->fImportedLocalDuplicate = IsImportedLocalDuplicate(out.Assignments, out.MainModule, a) ? 1 : 0; }
/* create file names and open files */ #if defined(LLDEBUG) && LLDEBUG > 0
fprintf(stderr, "Pass %d: Code generation \n", ++pass); #endif
// create module name
StripModuleName(module, argv[argc - 1]);
// create inc file and out file names
strcpy(incfilename, module); strcat(incfilename, ".h"); strcpy(outfilename, module); strcat(outfilename, ".c"); for (p = module; *p; p++) *p = (char)toupper(*p); finc = fopen(incfilename, "w"); if (!finc) { perror(incfilename); MyExit(1); } fout = fopen(outfilename, "w"); if (!fout) { perror(outfilename); MyExit(1); }
// lonchanc: change the full path name to file name only
{ char *psz = strrchr(module, '\\'); if (psz) { strcpy(module, psz+1); } }
// save the original module names
g_pszOrigModuleName = strdup(module); g_pszOrigModuleNameLowerCase = strdup(module); { char *psz; for (psz = g_pszOrigModuleNameLowerCase; *psz; psz++) { *psz = (char)tolower(*psz); } }
// lonchanc: append "_Module" to module name
strcat(module, "_Module");
/* code generation */ g_finc = finc; g_fout = fout; GenInc(out.Assignments, finc, module); GenPrg(out.Assignments, fout, module, incfilename);
setoutfile(finc); output("\n#ifdef __cplusplus\n"); outputni("} /* extern \"C\" */\n"); output("#endif\n\n"); output("#endif /* _%s_H_ */\n", module); setoutfile(fout);
/* finitialize */ fclose(finc); fclose(fout); #if defined(LLDEBUG) && LLDEBUG > 0
fprintf(stderr, "Finished. \n"); #endif
return 0; }
/* why is this function not in MS libc? */ #ifndef HAS_GETOPT
char *optarg; int optind = 1; static int optpos = 1;
/* get the next option from the command line arguments */ int getopt(int argc, char **argv, const char *options) { char *p, *q;
optarg = NULL;
/* find start of next option */ do { if (optind >= argc) return EOF; if (*argv[optind] != '-' && *argv[optind] != '/') return EOF; p = argv[optind] + optpos++; if (!*p) { optind++; optpos = 1; } } while (!*p);
/* find option in option string */ q = strchr(options, *p); if (!q) return '?';
/* set optarg for parameterized option and adjust optind and optpos for next call */ if (q[1] == ':') { if (p[1]) { optarg = p + 1; optind++; optpos = 1; } else if (++optind < argc) { optarg = argv[optind]; optind++; optpos = 1; } else { return '?'; } }
/* return found option */ return *p; } #endif
void StripModuleName(char *pszDst, char *pszSrc) { strcpy(pszDst, pszSrc); if (!strcmp(pszDst + strlen(pszDst) - 5, ".asn1")) pszDst[strlen(pszDst) - 5] = 0; else if (!strcmp(pszDst + strlen(pszDst) - 4, ".asn")) pszDst[strlen(pszDst) - 4] = 0; }
|