Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

725 lines
21 KiB

  1. /* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */
  2. /* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */
  3. #include "precomp.h"
  4. #ifndef HAS_GETOPT
  5. extern int getopt(int argc, char **argv, const char *opts);
  6. extern char *optarg;
  7. extern int optind;
  8. #endif
  9. int pass;
  10. /* if ForceAllTypes is set, asn1c will generate encoding functions for */
  11. /* all types (default: only for sequence/set/choice/sequence of/set of) */
  12. int ForceAllTypes = 0;
  13. /* type to use for unconstrained integers/semiconstrained signed integers */
  14. char *IntegerRestriction = "ASN1int32_t";
  15. /* type to use for semiconstrained unsigned integers */
  16. char *UIntegerRestriction = "ASN1uint32_t";
  17. /* type to use for real */
  18. char *RealRestriction = "double";
  19. /* output language */
  20. Language_e g_eProgramLanguage = eLanguage_C;
  21. /* alignment of encoding */
  22. Alignment_e Alignment = eAlignment_Aligned;
  23. /* encoding to generate code for */
  24. Encoding_e g_eEncodingRule = eEncoding_Packed;
  25. /* subencoding to generate code for */
  26. SubEncoding_e g_eSubEncodingRule = eSubEncoding_Basic;
  27. /* target compiler supports 64 bit integers */
  28. int Has64Bits = 0;
  29. /* zero out allocated buffers for decoded data */
  30. int g_fDecZeroMemory = 1;
  31. /* debug module name */
  32. int g_nDbgModuleName = 0;
  33. /* source file and header file pointers */
  34. FILE *g_finc, *g_fout;
  35. // default tag type in this module
  36. TagType_e g_eDefTagType = eTagType_Unknown;
  37. /* original main module name without postfixed _Module */
  38. char *g_pszOrigModuleName = NULL;
  39. char *g_pszOrigModuleNameLowerCase = NULL;
  40. /* enable long name (prefixed with module name for imported) */
  41. int g_fLongNameForImported = 0;
  42. // extra struct type name postfixed with _s, and its original name is its pointer type.
  43. int g_fExtraStructPtrTypeSS = 0;
  44. // the default structure type for Sequence Of and Set Of
  45. TypeRules_e g_eDefTypeRuleSS_NonSized = eTypeRules_SinglyLinkedList;
  46. TypeRules_e g_eDefTypeRuleSS_Sized = eTypeRules_FixedArray;
  47. // ignore the assertion
  48. int g_fNoAssert = 0;
  49. // object identifier is 16-node array
  50. int g_fOidArray = 0;
  51. // case based optimizer switch
  52. int g_fCaseBasedOptimizer = 1;
  53. // enable in-file directive
  54. int g_fMicrosoftExtensions = 1;
  55. // all platforms: little endian (default) and big endian
  56. int g_fAllEndians = 0;
  57. // directive begin, end, AND
  58. int g_chDirectiveBegin = '#';
  59. int g_chDirectiveEnd = '#';
  60. int g_chDirectiveAND = '&';
  61. // postfix
  62. char *g_pszApiPostfix = "ID";
  63. char *g_pszChoicePostfix = "choice";
  64. char *g_pszOptionPostfix = "option";
  65. // option value
  66. char *g_pszOptionValue = "option_bits";
  67. // invisble file array
  68. int g_cGhostFiles = 0;
  69. GhostFile_t g_aGhostFiles[16];
  70. int _cdecl main(int argc, char **argv)
  71. {
  72. FILE *finc, *fout;
  73. char *p;
  74. int c, chInvalidDir;
  75. LLSTATE in, out;
  76. UndefinedSymbol_t *lastundef;
  77. Assignment_t *a, **aa;
  78. LLTERM *tokens;
  79. unsigned ntokens;
  80. int fSupported;
  81. char *psz;
  82. char incfilename[256], outfilename[256], module[256];
  83. /* parse options */
  84. // if an option is followed by ':', then it has a parameter.
  85. while ((c = getopt(argc, argv, "ab:c:d:e:fg:hil:mn:o:p:q:s:t:uv:wy")) != EOF)
  86. {
  87. chInvalidDir = 0;
  88. switch (c)
  89. {
  90. case 'a':
  91. /* enable for all platforms: little endian and big endian */
  92. g_fAllEndians = 1;
  93. break;
  94. case 'b':
  95. /* maximum number of bits of target machine */
  96. if (atoi(optarg) == 32) {
  97. Has64Bits = 0;
  98. break;
  99. }
  100. if (atoi(optarg) == 64) {
  101. Has64Bits = 1;
  102. break;
  103. }
  104. fprintf(stderr, "Bad number of bits specified.\n");
  105. MyExit(1);
  106. /*NOTREACHED*/
  107. case 'c':
  108. // Choice postfix
  109. psz = strdup(optarg);
  110. if (psz && isalpha(*psz))
  111. {
  112. g_pszChoicePostfix = psz;
  113. }
  114. break;
  115. case 'd':
  116. // sequence of and set of data structure types
  117. if (! stricmp(optarg, "linked") || ! stricmp(optarg, "slinked"))
  118. {
  119. g_eDefTypeRuleSS_NonSized = eTypeRules_SinglyLinkedList;
  120. }
  121. else
  122. if (! stricmp(optarg, "lenptr"))
  123. {
  124. g_eDefTypeRuleSS_NonSized = eTypeRules_LengthPointer;
  125. }
  126. else
  127. if (! stricmp(optarg, "dlinked"))
  128. {
  129. g_eDefTypeRuleSS_NonSized = eTypeRules_DoublyLinkedList;
  130. }
  131. else
  132. {
  133. goto usage;
  134. }
  135. break;
  136. case 'e':
  137. /* encoding to generate code for */
  138. if (!stricmp(optarg, "packed"))
  139. {
  140. g_eEncodingRule = eEncoding_Packed;
  141. }
  142. else
  143. if (!stricmp(optarg, "basic"))
  144. {
  145. g_eEncodingRule = eEncoding_Basic;
  146. }
  147. else
  148. if (!stricmp(optarg, "per"))
  149. {
  150. g_eEncodingRule = eEncoding_Packed;
  151. Alignment = eAlignment_Aligned;
  152. }
  153. else
  154. if (!stricmp(optarg, "cer"))
  155. {
  156. g_eEncodingRule = eEncoding_Basic;
  157. g_eSubEncodingRule = eSubEncoding_Canonical;
  158. }
  159. else
  160. if (!stricmp(optarg, "der"))
  161. {
  162. g_eEncodingRule = eEncoding_Basic;
  163. g_eSubEncodingRule = eSubEncoding_Distinguished;
  164. }
  165. else
  166. if (!stricmp(optarg, "ber"))
  167. {
  168. g_eEncodingRule = eEncoding_Basic;
  169. g_eSubEncodingRule = eSubEncoding_Basic;
  170. }
  171. else
  172. {
  173. fprintf(stderr, "Bad encoding specified.\n");
  174. fprintf(stderr, "Allowed encodings are:\n");
  175. fprintf(stderr, "- packed (default)\n");
  176. fprintf(stderr, "- basic\n");
  177. MyExit(1);
  178. /*NOTREACHED*/
  179. }
  180. break;
  181. case 'f':
  182. /* force generation of encoding/decoding functions for all types */
  183. ForceAllTypes = 1;
  184. break;
  185. case 'g':
  186. /* ghost asn1 files */
  187. g_aGhostFiles[g_cGhostFiles].pszFileName = strdup(optarg);
  188. g_aGhostFiles[g_cGhostFiles++].pszModuleName = NULL;
  189. break;
  190. case 'h':
  191. goto usage;
  192. case 'i':
  193. /* ignore assertion */
  194. g_fNoAssert = 1;
  195. break;
  196. case 'l':
  197. /* set output language */
  198. if (!stricmp(optarg, "c")) {
  199. g_eProgramLanguage = eLanguage_C;
  200. break;
  201. }
  202. if (!stricmp(optarg, "c++") || !stricmp(optarg, "cpp")) {
  203. g_eProgramLanguage = eLanguage_Cpp;
  204. break;
  205. }
  206. goto usage;
  207. case 'm':
  208. /* enable Microsoft extension */
  209. g_fMicrosoftExtensions = 1;
  210. break;
  211. case 'n':
  212. /* debug module name */
  213. g_nDbgModuleName = 0;
  214. {
  215. int len = strlen(optarg);
  216. if (len > 4)
  217. len = 4;
  218. memcpy(&g_nDbgModuleName, optarg, len);
  219. }
  220. break;
  221. case 'o':
  222. // Option postfix
  223. psz = strdup(optarg);
  224. if (psz && isalpha(*psz))
  225. {
  226. g_pszOptionPostfix = psz;
  227. }
  228. break;
  229. case 'p':
  230. // API postfix
  231. psz = strdup(optarg);
  232. if (psz && isalpha(*psz))
  233. {
  234. g_pszApiPostfix = psz;
  235. }
  236. break;
  237. case 'q':
  238. // sequence of and set of data structure types
  239. if (! stricmp(optarg, "linked") || ! stricmp(optarg, "slinked"))
  240. {
  241. g_eDefTypeRuleSS_Sized = eTypeRules_SinglyLinkedList;
  242. }
  243. else
  244. if (! stricmp(optarg, "lenptr"))
  245. {
  246. g_eDefTypeRuleSS_Sized = eTypeRules_LengthPointer;
  247. }
  248. else
  249. if (! stricmp(optarg, "array"))
  250. {
  251. g_eDefTypeRuleSS_Sized = eTypeRules_FixedArray;
  252. }
  253. else
  254. if (! stricmp(optarg, "pointer"))
  255. {
  256. g_eDefTypeRuleSS_Sized = eTypeRules_PointerToElement | eTypeRules_FixedArray;
  257. }
  258. else
  259. if (! stricmp(optarg, "dlinked"))
  260. {
  261. g_eDefTypeRuleSS_Sized = eTypeRules_DoublyLinkedList;
  262. }
  263. else
  264. {
  265. goto usage;
  266. }
  267. break;
  268. case 's':
  269. /* set subencoding */
  270. if (!stricmp(optarg, "aligned"))
  271. {
  272. Alignment = eAlignment_Aligned;
  273. }
  274. else
  275. if (!stricmp(optarg, "unaligned"))
  276. {
  277. Alignment = eAlignment_Unaligned;
  278. }
  279. else
  280. if (!stricmp(optarg, "cer"))
  281. {
  282. g_eSubEncodingRule = eSubEncoding_Canonical;
  283. }
  284. else
  285. if (!stricmp(optarg, "der"))
  286. {
  287. g_eSubEncodingRule = eSubEncoding_Distinguished;
  288. }
  289. else
  290. if (!stricmp(optarg, "basic"))
  291. {
  292. g_eSubEncodingRule = eSubEncoding_Basic;
  293. }
  294. else
  295. {
  296. fprintf(stderr, "Bad sub-encoding specified.\n");
  297. fprintf(stderr, "Allowed sub-encodings are:\n");
  298. fprintf(stderr, "- aligned (default) or unaligned\n");
  299. fprintf(stderr, "- basic (default), cer or der\n");
  300. MyExit(1);
  301. /*NOTREACHED*/
  302. }
  303. break;
  304. case 't':
  305. /* specify type to use for unconstrained/semiconstrained types */
  306. p = strchr(optarg, '=');
  307. if (!p)
  308. goto usage;
  309. *p++ = 0;
  310. if (!stricmp(optarg, "integer")) {
  311. if (!stricmp(p, "ASN1int32_t")) {
  312. IntegerRestriction = "ASN1int32_t";
  313. break;
  314. }
  315. if (!stricmp(p, "ASN1uint32_t")) {
  316. IntegerRestriction = "ASN1uint32_t";
  317. break;
  318. }
  319. if (!stricmp(p, "ASN1int64_t")) {
  320. IntegerRestriction = "ASN1int64_t";
  321. break;
  322. }
  323. if (!stricmp(p, "ASN1uint64_t")) {
  324. IntegerRestriction = "ASN1uint64_t";
  325. break;
  326. }
  327. if (!stricmp(p, "ASN1intx_t")) {
  328. IntegerRestriction = "ASN1intx_t";
  329. break;
  330. }
  331. }
  332. if (!stricmp(optarg, "unsigned")) {
  333. if (!stricmp(p, "ASN1int32_t")) {
  334. UIntegerRestriction = "ASN1int32_t";
  335. break;
  336. }
  337. if (!stricmp(p, "ASN1uint32_t")) {
  338. UIntegerRestriction = "ASN1uint32_t";
  339. break;
  340. }
  341. if (!stricmp(p, "ASN1int64_t")) {
  342. UIntegerRestriction = "ASN1int64_t";
  343. break;
  344. }
  345. if (!stricmp(p, "ASN1uint64_t")) {
  346. UIntegerRestriction = "ASN1uint64_t";
  347. break;
  348. }
  349. if (!stricmp(p, "ASN1intx_t")) {
  350. UIntegerRestriction = "ASN1intx_t";
  351. break;
  352. }
  353. }
  354. if (!stricmp(optarg, "real")) {
  355. if (!stricmp(p, "double")) {
  356. RealRestriction = "double";
  357. break;
  358. }
  359. if (!stricmp(p, "ASN1real_t")) {
  360. RealRestriction = "ASN1real_t";
  361. break;
  362. }
  363. }
  364. goto usage;
  365. case 'u':
  366. // no case-based optimizer
  367. g_fCaseBasedOptimizer = 0;
  368. break;
  369. case 'v':
  370. // Option value
  371. psz = strdup(optarg);
  372. if (psz && isalpha(*psz))
  373. {
  374. g_pszOptionValue = psz;
  375. }
  376. break;
  377. case 'w':
  378. // --#OID ARRAY#--
  379. g_fOidArray = 1;
  380. break;
  381. case 'y':
  382. /* enable long name (prefixed with module name for imported) */
  383. g_fLongNameForImported = 1;
  384. break;
  385. default:
  386. chInvalidDir = c;
  387. usage:
  388. fprintf(stderr,"ASN.1 Compiler V1.0\n");
  389. fprintf(stderr, "Copyright (C) Microsoft Corporation, U.S.A., 1997-1998. All rights reserved.\n");
  390. fprintf(stderr, "Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved.\n");
  391. if (chInvalidDir)
  392. {
  393. fprintf(stderr, "Invalid option -%c\n", chInvalidDir);
  394. }
  395. else
  396. {
  397. fprintf(stderr, "Usage: %s [options] [imported.asn1 ...] main.asn1\n", argv[0]);
  398. fprintf(stderr, "Options:\n");
  399. fprintf(stderr, "-h\t\tthis help\n");
  400. fprintf(stderr, "-z\t\tzero out allocated buffers for decoded data\n");
  401. fprintf(stderr, "-x\t\tbridge APIs\n");
  402. fprintf(stderr, "-a\t\textra type definition for structure\n");
  403. fprintf(stderr, "-n name\t\tmodule name for debugging purpose\n");
  404. // fprintf(stderr, "-l language\tgenerate code for <language> (c (default), c++)\n");
  405. // fprintf(stderr, "-b 64\t\tenable 64 bit support\n");
  406. fprintf(stderr, "-e encoding\tuse <encoding> as encoding rule\n");
  407. fprintf(stderr, "\t\t(possible values: packed (default), basic)\n");
  408. fprintf(stderr, "-s subencoding\tuse <subencoding> as subencoding rules\n");
  409. fprintf(stderr, "\t\t(possible values: aligned (default) or unaligned,\n");
  410. fprintf(stderr, "\t\tbasic (default), canonical or distinguished)\n");
  411. fprintf(stderr, "-t type=rest.\trestrict/unrestrict a unconstrained/semiconstrained type:\n");
  412. 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");
  413. 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");
  414. 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");
  415. }
  416. MyExit(1);
  417. }
  418. }
  419. /* check if any modules are given */
  420. if (argc < optind + 1)
  421. goto usage;
  422. /* check for unsupported encoding */
  423. fSupported = TRUE;
  424. if (g_eEncodingRule == eEncoding_Packed)
  425. {
  426. if (Alignment != eAlignment_Aligned || g_eSubEncodingRule != eSubEncoding_Basic)
  427. {
  428. fSupported = FALSE;
  429. }
  430. }
  431. else
  432. if (g_eEncodingRule == eEncoding_Basic)
  433. {
  434. // if (Alignment != eAlignment_Aligned || g_eSubEncodingRule == eSubEncoding_Distinguished)
  435. if (Alignment != eAlignment_Aligned)
  436. {
  437. fSupported = FALSE;
  438. }
  439. }
  440. if (! fSupported)
  441. {
  442. fprintf(stderr, "Encoding not implemented (yet)\n");
  443. MyExit(1);
  444. }
  445. /* initialize */
  446. InitBuiltin();
  447. /* scan file(s) */
  448. #if defined(LLDEBUG) && LLDEBUG > 0
  449. pass = 1;
  450. fprintf(stderr, "Pass 1: Scanning input file\n");
  451. #endif
  452. readfiles(argv + optind);
  453. llscanner(&tokens, &ntokens);
  454. /* setup initial state */
  455. in.Assignments = Builtin_Assignments;
  456. in.AssignedObjIds = Builtin_ObjIds;
  457. in.Undefined = NULL;
  458. in.BadlyDefined = NULL;
  459. in.Module = NULL;
  460. in.MainModule = NULL;
  461. in.Imported = NULL;
  462. in.TagDefault = eTagType_Unknown;
  463. in.ExtensionDefault = eExtensionType_None;
  464. lastundef = NULL;
  465. /* parse the modules */
  466. do {
  467. #if defined(LLDEBUG) && LLDEBUG > 0
  468. fprintf(stderr, "Pass %d: Parsing \n", ++pass);
  469. #endif
  470. /* parse modules */
  471. if (!llparser(tokens, ntokens, &in, &out)) {
  472. llprinterror(stderr);
  473. MyExit(1);
  474. }
  475. /* if undefined symbols remain the same as in previous pass */
  476. /* than print these undefined symbols and MyExit */
  477. if (!CmpUndefinedSymbolList(out.Assignments, out.Undefined, lastundef))
  478. UndefinedError(out.Assignments, out.Undefined, out.BadlyDefined);
  479. /* setup data for next pass */
  480. in = out;
  481. aa = &in.Assignments;
  482. for (a = Builtin_Assignments; a; a = a->Next) {
  483. *aa = DupAssignment(a);
  484. aa = &(*aa)->Next;
  485. }
  486. *aa = NewAssignment(eAssignment_NextPass);
  487. aa = &(*aa)->Next;
  488. *aa = out.Assignments;
  489. lastundef = out.Undefined;
  490. in.Undefined = NULL;
  491. in.BadlyDefined = NULL;
  492. /* continue parsing until no undefined symbols left */
  493. } while (lastundef);
  494. /* build internal information */
  495. #if defined(LLDEBUG) && LLDEBUG > 0
  496. fprintf(stderr, "Pass %d: Building internal information \n", ++pass);
  497. #endif
  498. Examination(&out.Assignments, out.MainModule);
  499. ExaminePER(out.Assignments);
  500. ExamineBER(out.Assignments);
  501. // remember who is the local duplicate of imported types
  502. for (a = out.Assignments; a; a = a->Next)
  503. {
  504. a->fImportedLocalDuplicate = IsImportedLocalDuplicate(out.Assignments, out.MainModule, a) ? 1 : 0;
  505. }
  506. /* create file names and open files */
  507. #if defined(LLDEBUG) && LLDEBUG > 0
  508. fprintf(stderr, "Pass %d: Code generation \n", ++pass);
  509. #endif
  510. // create module name
  511. StripModuleName(module, argv[argc - 1]);
  512. // create inc file and out file names
  513. strcpy(incfilename, module);
  514. strcat(incfilename, ".h");
  515. strcpy(outfilename, module);
  516. strcat(outfilename, ".c");
  517. for (p = module; *p; p++)
  518. *p = (char)toupper(*p);
  519. finc = fopen(incfilename, "w");
  520. if (!finc) {
  521. perror(incfilename);
  522. MyExit(1);
  523. }
  524. fout = fopen(outfilename, "w");
  525. if (!fout) {
  526. perror(outfilename);
  527. MyExit(1);
  528. }
  529. // lonchanc: change the full path name to file name only
  530. {
  531. char *psz = strrchr(module, '\\');
  532. if (psz)
  533. {
  534. strcpy(module, psz+1);
  535. }
  536. }
  537. // save the original module names
  538. g_pszOrigModuleName = strdup(module);
  539. g_pszOrigModuleNameLowerCase = strdup(module);
  540. {
  541. char *psz;
  542. for (psz = g_pszOrigModuleNameLowerCase; *psz; psz++)
  543. {
  544. *psz = (char)tolower(*psz);
  545. }
  546. }
  547. // lonchanc: append "_Module" to module name
  548. strcat(module, "_Module");
  549. /* code generation */
  550. g_finc = finc;
  551. g_fout = fout;
  552. GenInc(out.Assignments, finc, module);
  553. GenPrg(out.Assignments, fout, module, incfilename);
  554. setoutfile(finc);
  555. output("\n#ifdef __cplusplus\n");
  556. outputni("} /* extern \"C\" */\n");
  557. output("#endif\n\n");
  558. output("#endif /* _%s_H_ */\n", module);
  559. setoutfile(fout);
  560. /* finitialize */
  561. fclose(finc);
  562. fclose(fout);
  563. #if defined(LLDEBUG) && LLDEBUG > 0
  564. fprintf(stderr, "Finished. \n");
  565. #endif
  566. return 0;
  567. }
  568. /* why is this function not in MS libc? */
  569. #ifndef HAS_GETOPT
  570. char *optarg;
  571. int optind = 1;
  572. static int optpos = 1;
  573. /* get the next option from the command line arguments */
  574. int getopt(int argc, char **argv, const char *options) {
  575. char *p, *q;
  576. optarg = NULL;
  577. /* find start of next option */
  578. do {
  579. if (optind >= argc)
  580. return EOF;
  581. if (*argv[optind] != '-' && *argv[optind] != '/')
  582. return EOF;
  583. p = argv[optind] + optpos++;
  584. if (!*p) {
  585. optind++;
  586. optpos = 1;
  587. }
  588. } while (!*p);
  589. /* find option in option string */
  590. q = strchr(options, *p);
  591. if (!q)
  592. return '?';
  593. /* set optarg for parameterized option and adjust optind and optpos for next call */
  594. if (q[1] == ':') {
  595. if (p[1]) {
  596. optarg = p + 1;
  597. optind++;
  598. optpos = 1;
  599. } else if (++optind < argc) {
  600. optarg = argv[optind];
  601. optind++;
  602. optpos = 1;
  603. } else {
  604. return '?';
  605. }
  606. }
  607. /* return found option */
  608. return *p;
  609. }
  610. #endif
  611. void StripModuleName(char *pszDst, char *pszSrc)
  612. {
  613. strcpy(pszDst, pszSrc);
  614. if (!strcmp(pszDst + strlen(pszDst) - 5, ".asn1"))
  615. pszDst[strlen(pszDst) - 5] = 0;
  616. else if (!strcmp(pszDst + strlen(pszDst) - 4, ".asn"))
  617. pszDst[strlen(pszDst) - 4] = 0;
  618. }