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.

1912 lines
69 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. #include "optcase.h"
  5. void GenFuncType(AssignmentList_t ass, char *module, Assignment_t *at, TypeFunc_e et);
  6. void GenFuncComponents(AssignmentList_t ass, char *module, Type_t *type, char *ideref, uint32_t optindex, ComponentList_t components, char *valref1, char *valref2, TypeFunc_e et, int inextension, int inchoice);
  7. void GenFuncSequenceSetType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref1, char *valref2, TypeFunc_e et);
  8. void GenFuncChoiceType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref1, char *valref2, TypeFunc_e et);
  9. void GenFuncSimpleType(AssignmentList_t ass, Type_t *type, char *ideref, char *valref1, char *valref2, TypeFunc_e et);
  10. void GenFreeSimpleType(AssignmentList_t ass, Type_t *type, char *ideref, char *valref);
  11. void GenCompareSimpleType(AssignmentList_t ass, Type_t *type, char *ideref, char *valref1, char *valref2);
  12. void GenCompareExpression(AssignmentList_t ass, Type_t *type, char *ideref, char *valref1, char *valref2);
  13. void GenFuncValue(AssignmentList_t ass, Assignment_t *at, ValueFunc_e cod);
  14. void GenDeclGeneric(AssignmentList_t ass, char *ideref, char *typeref, Value_t *value, Type_t *t);
  15. void GenDefhGeneric(AssignmentList_t ass, char *ideref, char *typeref, Value_t *value, Type_t *t);
  16. void GenDefnGeneric(AssignmentList_t ass, char *ideref, char *typeref, Value_t *value, Type_t *t);
  17. void GenInitGeneric(AssignmentList_t ass, char *ideref, char *typeref, Value_t *value, Type_t *t);
  18. extern unsigned g_cPDUs;
  19. extern char *g_pszOrigModuleNameLowerCase;
  20. extern int g_fLongNameForImported;
  21. extern int g_fNoAssert;
  22. extern int g_fCaseBasedOptimizer;
  23. extern uint32_t Tag2uint32(AssignmentList_t ass, Tag_t *tag);
  24. int NotInFunTbl(Assignment_t *a)
  25. {
  26. if (a->Type != eAssignment_Type)
  27. {
  28. return 1;
  29. }
  30. if (a->U.Type.Type->PrivateDirectives.fPublic)
  31. {
  32. return 0;
  33. }
  34. return ((a->U.Type.Type->Flags & eTypeFlags_Null) ||
  35. !(a->U.Type.Type->Flags & eTypeFlags_GenType) ||
  36. !(a->U.Type.Type->Flags & eTypeFlags_GenPdu) ||
  37. (a->U.Type.Type->Flags & eTypeFlags_MiddlePDU));
  38. }
  39. /* generate c file */
  40. void
  41. GenPrg(AssignmentList_t ass, FILE *fout, char *module, char *incfilename)
  42. {
  43. Assignment_t *a;
  44. TypeFunc_e et;
  45. ValueFunc_e ev;
  46. Arguments_t args;
  47. unsigned i;
  48. char *pszFunParam;
  49. char *identifier;
  50. char funcbuf[256];
  51. setoutfile(fout);
  52. // print verbatim
  53. PrintVerbatim();
  54. /* file header */
  55. output("#include <windows.h>\n");
  56. output("#include \"%s\"\n", incfilename);
  57. switch (g_eEncodingRule) {
  58. case eEncoding_Packed:
  59. GenPERHeader();
  60. GetPERPrototype(&args);
  61. pszFunParam = "x,y";
  62. break;
  63. case eEncoding_Basic:
  64. GenBERHeader();
  65. GetBERPrototype(&args);
  66. pszFunParam = "x,y,z";
  67. break;
  68. default:
  69. MyAbort();
  70. }
  71. output("\n");
  72. output("ASN1module_t %s = NULL;\n", module);
  73. output("\n");
  74. /* write function prototypes */
  75. for (et = eStringTable; et <= eCopy; et++)
  76. {
  77. for (a = ass; a; a = a->Next)
  78. {
  79. if (a->Type != eAssignment_Type)
  80. continue;
  81. if ((! g_fLongNameForImported) && a->fImportedLocalDuplicate)
  82. continue;
  83. if (a->U.Type.Type->PrivateDirectives.fPublic)
  84. {
  85. a->U.Type.Type->Flags |= eTypeFlags_GenEncode;
  86. a->U.Type.Type->Flags |= eTypeFlags_GenDecode;
  87. a->U.Type.Type->Flags |= eTypeFlags_GenFree;
  88. a->U.Type.Type->Flags |= eTypeFlags_GenCompare;
  89. }
  90. else
  91. {
  92. if ((GetType(ass, a->U.Type.Type)->Flags & eTypeFlags_Null) ||
  93. !(a->U.Type.Type->Flags & eTypeFlags_GenType) ||
  94. !(a->U.Type.Type->Flags & eTypeFlags_GenPdu))
  95. continue;
  96. }
  97. switch (et)
  98. {
  99. case eStringTable:
  100. continue;
  101. case eEncode:
  102. if (!(a->U.Type.Type->Flags & eTypeFlags_GenEncode))
  103. continue;
  104. identifier = GetName(a);
  105. sprintf(funcbuf, IsPSetOfType(ass, a) ? args.Pencfunc : args.encfunc, identifier);
  106. if (a->U.Type.Type->PrivateDirectives.fNoCode)
  107. {
  108. output("#define ASN1Enc_%s(%s) 0\n", identifier, pszFunParam);
  109. }
  110. else
  111. {
  112. output("static int ASN1CALL ASN1Enc_%s(%s);\n", identifier, funcbuf);
  113. }
  114. break;
  115. case eDecode:
  116. if (!(a->U.Type.Type->Flags & eTypeFlags_GenDecode))
  117. continue;
  118. identifier = GetName(a);
  119. sprintf(funcbuf, IsPSetOfType(ass, a) ? args.Pdecfunc : args.decfunc, identifier);
  120. if (a->U.Type.Type->PrivateDirectives.fNoCode)
  121. {
  122. output("#define ASN1Dec_%s(%s) 0\n", identifier, pszFunParam);
  123. }
  124. else
  125. {
  126. output("static int ASN1CALL ASN1Dec_%s(%s);\n", identifier, funcbuf);
  127. }
  128. break;
  129. case eCheck:
  130. continue;
  131. case ePrint:
  132. continue;
  133. case eFree:
  134. if (!(a->U.Type.Type->Flags & eTypeFlags_GenFree) ||
  135. (a->U.Type.Type->Flags & eTypeFlags_Simple))
  136. continue;
  137. identifier = GetName(a);
  138. sprintf(funcbuf, IsPSetOfType(ass, a) ? args.Pfreefunc : args.freefunc, identifier);
  139. if (a->U.Type.Type->PrivateDirectives.fNoCode)
  140. {
  141. output("#define ASN1Free_%s(x) \n", identifier);
  142. }
  143. else
  144. {
  145. output("static void ASN1CALL ASN1Free_%s(%s);\n", identifier, funcbuf);
  146. }
  147. break;
  148. #ifdef ENABLE_COMPARE
  149. case eCompare:
  150. if (!(a->U.Type.Type->Flags & eTypeFlags_GenCompare))
  151. continue;
  152. identifier = GetName(a);
  153. sprintf(funcbuf, IsPSetOfType(ass, a) ? args.Pcmpfun : args.cmpfunc, identifier, identifier);
  154. if (a->U.Type.Type->PrivateDirectives.fNoCode)
  155. {
  156. output("#define ASN1Compare_%s(x,y) 0\n", identifier);
  157. }
  158. else
  159. {
  160. output("static int ASN1CALL ASN1Compare_%s(%s);\n", identifier, funcbuf);
  161. }
  162. break;
  163. #endif // ENABLE_COMPARE
  164. case eCopy:
  165. continue;
  166. }
  167. }
  168. }
  169. output("\n");
  170. /* write a table containing the encode function addresses */
  171. switch (g_eEncodingRule)
  172. {
  173. case eEncoding_Packed:
  174. output("typedef ASN1PerEncFun_t ASN1EncFun_t;\n");
  175. break;
  176. case eEncoding_Basic:
  177. output("typedef ASN1BerEncFun_t ASN1EncFun_t;\n");
  178. break;
  179. default:
  180. output("typedef int (ASN1CALL *ASN1EncFun_t)(%s);\n", args.enccast);
  181. break;
  182. }
  183. output("static const ASN1EncFun_t encfntab[%u] = {\n", g_cPDUs);
  184. for (a = ass; a; a = a->Next) {
  185. if ((! g_fLongNameForImported) && a->fImportedLocalDuplicate)
  186. continue;
  187. if (NotInFunTbl(a))
  188. continue;
  189. if (!(a->U.Type.Type->Flags & eTypeFlags_GenEncode)) {
  190. ASSERT(0);
  191. output("(ASN1EncFun_t) NULL,\n");
  192. continue;
  193. }
  194. output("(ASN1EncFun_t) ASN1Enc_%s,\n", GetName(a));
  195. }
  196. output("};\n");
  197. /* write a table containing the decode function addresses */
  198. switch (g_eEncodingRule)
  199. {
  200. case eEncoding_Packed:
  201. output("typedef ASN1PerDecFun_t ASN1DecFun_t;\n");
  202. break;
  203. case eEncoding_Basic:
  204. output("typedef ASN1BerDecFun_t ASN1DecFun_t;\n");
  205. break;
  206. default:
  207. output("typedef int (ASN1CALL *ASN1DecFun_t)(%s);\n", args.deccast);
  208. break;
  209. }
  210. output("static const ASN1DecFun_t decfntab[%u] = {\n", g_cPDUs);
  211. for (a = ass; a; a = a->Next)
  212. {
  213. if ((! g_fLongNameForImported) && a->fImportedLocalDuplicate)
  214. continue;
  215. if (NotInFunTbl(a))
  216. continue;
  217. if (!(a->U.Type.Type->Flags & eTypeFlags_GenDecode))
  218. {
  219. ASSERT(0);
  220. output("(ASN1DecFun_t) NULL,\n");
  221. continue;
  222. }
  223. output("(ASN1DecFun_t) ASN1Dec_%s,\n", GetName(a));
  224. }
  225. output("};\n");
  226. /* write a table containing the free function addresses */
  227. output("static const ASN1FreeFun_t freefntab[%u] = {\n", g_cPDUs);
  228. for (a = ass; a; a = a->Next)
  229. {
  230. if ((! g_fLongNameForImported) && a->fImportedLocalDuplicate)
  231. continue;
  232. if (NotInFunTbl(a))
  233. continue;
  234. if (!(a->U.Type.Type->Flags & eTypeFlags_GenFree) ||
  235. (a->U.Type.Type->Flags & eTypeFlags_Simple))
  236. {
  237. output("(ASN1FreeFun_t) NULL,\n");
  238. continue;
  239. }
  240. output("(ASN1FreeFun_t) ASN1Free_%s,\n", GetName(a));
  241. }
  242. output("};\n");
  243. #ifdef ENABLE_COMPARE
  244. /* write a table containing the compare function addresses */
  245. output("typedef int (ASN1CALL *ASN1CmpFun_t)(%s);\n", args.cmpcast);
  246. output("static const ASN1CmpFun_t cmpfntab[%u] = {\n", g_cPDUs);
  247. for (a = ass; a; a = a->Next)
  248. {
  249. if ((! g_fLongNameForImported) && a->fImportedLocalDuplicate)
  250. continue;
  251. if (NotInFunTbl(a))
  252. continue;
  253. if (!(a->U.Type.Type->Flags & eTypeFlags_GenCompare))
  254. {
  255. ASSERT(0);
  256. output("(ASN1CmpFun_t) NULL,\n");
  257. continue;
  258. }
  259. output("(ASN1CmpFun_t) ASN1Compare_%s,\n", GetName(a));
  260. }
  261. output("};\n");
  262. output("\n");
  263. #endif // ENABLE_COMPARE
  264. /* write a table containing the sizeof pdu structures */
  265. output("static const ULONG sizetab[%u] = {\n", g_cPDUs);
  266. for (i = 0; i < g_cPDUs; i++)
  267. {
  268. output("SIZE_%s_%s_%u,\n", module, g_pszApiPostfix, i);
  269. }
  270. output("};\n");
  271. output("\n");
  272. /* handle values in 4 steps: */
  273. /* 1. write forward declarations, */
  274. /* 2. write definitions of value components, */
  275. /* 3. write definitions of values, */
  276. /* 4. write assignments into the initialization function */
  277. for (ev = eDecl; ev <= eFinit; ev++)
  278. {
  279. switch (ev)
  280. {
  281. case eDecl:
  282. output("/* forward declarations of values: */\n");
  283. break;
  284. case eDefh:
  285. output("/* definitions of value components: */\n");
  286. break;
  287. case eDefn:
  288. output("/* definitions of values: */\n");
  289. break;
  290. case eInit:
  291. output("\nvoid ASN1CALL %s_Startup(void)\n", module);
  292. output("{\n");
  293. switch (g_eEncodingRule)
  294. {
  295. case eEncoding_Packed:
  296. GenPERInit(ass, module);
  297. break;
  298. case eEncoding_Basic:
  299. GenBERInit(ass, module);
  300. break;
  301. }
  302. break;
  303. case eFinit:
  304. output("\nvoid ASN1CALL %s_Cleanup(void)\n", module);
  305. output("{\n");
  306. output("ASN1_CloseModule(%s);\n", module);
  307. output("%s = NULL;\n", module);
  308. break;
  309. }
  310. for (a = ass; a; a = a->Next)
  311. {
  312. if (a->Type != eAssignment_Value)
  313. continue;
  314. if (GetValue(ass, a->U.Value.Value)->Type->Flags & eTypeFlags_Null)
  315. continue;
  316. switch (ev)
  317. {
  318. case eDecl:
  319. case eDefh:
  320. case eDefn:
  321. case eInit:
  322. case eFinit:
  323. if (!(a->U.Value.Value->Flags & eValueFlags_GenValue))
  324. continue;
  325. break;
  326. }
  327. GenFuncValue(ass, a, ev);
  328. }
  329. if (ev == eInit || ev == eFinit) {
  330. output("}\n");
  331. }
  332. }
  333. output("\n");
  334. /* generate the type functions for all assignments as wanted */
  335. for (a = ass; a; a = a->Next)
  336. {
  337. if (a->Type != eAssignment_Type)
  338. continue;
  339. /* skip null types */
  340. if (a->U.Type.Type->Flags & eTypeFlags_Null)
  341. continue;
  342. if ((! g_fLongNameForImported) && a->fImportedLocalDuplicate)
  343. continue;
  344. if (a->U.Type.Type->PrivateDirectives.fNoCode)
  345. continue;
  346. /* generate the functions */
  347. identifier = GetName(a);
  348. for (et = eStringTable; et <= eCopy; et++)
  349. {
  350. switch (et)
  351. {
  352. case eStringTable:
  353. if (!(a->U.Type.Type->Flags &
  354. (eTypeFlags_GenEncode | eTypeFlags_GenDecode)))
  355. continue;
  356. switch (g_eEncodingRule)
  357. {
  358. case eEncoding_Packed:
  359. GenPERFuncType(ass, module, a, et);
  360. break;
  361. case eEncoding_Basic:
  362. GenBERFuncType(ass, module, a, et);
  363. break;
  364. }
  365. break;
  366. case eEncode:
  367. if (!(a->U.Type.Type->Flags & eTypeFlags_GenEncode))
  368. continue;
  369. sprintf(funcbuf, IsPSetOfType(ass, a) ? args.Pencfunc : args.encfunc, identifier);
  370. output("static int ASN1CALL ASN1Enc_%s(%s)\n",
  371. identifier, funcbuf);
  372. output("{\n");
  373. switch (g_eEncodingRule)
  374. {
  375. case eEncoding_Packed:
  376. GenPERFuncType(ass, module, a, et);
  377. break;
  378. case eEncoding_Basic:
  379. GenBERFuncType(ass, module, a, et);
  380. break;
  381. }
  382. output("return 1;\n");
  383. output("}\n\n");
  384. break;
  385. case eDecode:
  386. if (!(a->U.Type.Type->Flags & eTypeFlags_GenDecode))
  387. continue;
  388. sprintf(funcbuf, IsPSetOfType(ass, a) ? args.Pdecfunc : args.decfunc, identifier);
  389. output("static int ASN1CALL ASN1Dec_%s(%s)\n",
  390. identifier, funcbuf);
  391. output("{\n");
  392. switch (g_eEncodingRule)
  393. {
  394. case eEncoding_Packed:
  395. GenPERFuncType(ass, module, a, et);
  396. break;
  397. case eEncoding_Basic:
  398. GenBERFuncType(ass, module, a, et);
  399. break;
  400. }
  401. output("return 1;\n");
  402. output("}\n\n");
  403. break;
  404. case eCheck:
  405. if (!(a->U.Type.Type->Flags & eTypeFlags_GenCheck))
  406. continue;
  407. GenFuncType(ass, module, a, et);
  408. break;
  409. case ePrint:
  410. if (!(a->U.Type.Type->Flags & eTypeFlags_GenPrint))
  411. continue;
  412. GenFuncType(ass, module, a, et);
  413. break;
  414. case eFree:
  415. if (!(a->U.Type.Type->Flags & eTypeFlags_GenFree) ||
  416. (a->U.Type.Type->Flags & eTypeFlags_Simple))
  417. continue;
  418. sprintf(funcbuf, IsPSetOfType(ass, a) ? args.Pfreefunc : args.freefunc, identifier);
  419. output("static void ASN1CALL ASN1Free_%s(%s)\n",
  420. identifier, funcbuf);
  421. output("{\n");
  422. output("if (val) {\n"); // opening the null pointer check
  423. GenFuncType(ass, module, a, et);
  424. output("}\n"); // closing the null pointer check
  425. output("}\n\n");
  426. break;
  427. #ifdef ENABLE_COMPARE
  428. case eCompare:
  429. if (!(a->U.Type.Type->Flags & eTypeFlags_GenCompare))
  430. continue;
  431. sprintf(funcbuf, IsPSetOfType(ass, a) ? args.Pcmpfunc : args.cmpfunc, identifier);
  432. output("static int ASN1CALL ASN1Compare_%s(%s)\n",
  433. identifier, funcbuf);
  434. output("{\n");
  435. outputvar("int ret;\n");
  436. GenFuncType(ass, module, a, et);
  437. output("return 0;\n");
  438. output("}\n\n");
  439. break;
  440. #endif // ENABLE_COMPARE
  441. case eCopy:
  442. if (!(a->U.Type.Type->Flags & eTypeFlags_GenCopy))
  443. continue;
  444. GenFuncType(ass, module, a, et);
  445. break;
  446. }
  447. }
  448. }
  449. }
  450. /* generate function encoding-independent type-specific functions */
  451. void
  452. GenFuncType(AssignmentList_t ass, char *module, Assignment_t *at, TypeFunc_e et)
  453. {
  454. Type_t *type;
  455. char *ideref;
  456. char *valref1, *valref2;
  457. /* get some informations */
  458. type = at->U.Type.Type;
  459. ideref = GetName(at);
  460. switch (et) {
  461. case eCompare:
  462. valref1 = "val1";
  463. valref2 = "val2";
  464. break;
  465. default:
  466. valref1 = "val";
  467. valref2 = "";
  468. break;
  469. }
  470. /* function body */
  471. switch (type->Type) {
  472. case eType_Boolean:
  473. case eType_Integer:
  474. case eType_Enumerated:
  475. case eType_Real:
  476. case eType_BitString:
  477. case eType_OctetString:
  478. case eType_UTF8String:
  479. case eType_Null:
  480. case eType_EmbeddedPdv:
  481. case eType_External:
  482. case eType_ObjectIdentifier:
  483. case eType_BMPString:
  484. case eType_GeneralString:
  485. case eType_GraphicString:
  486. case eType_IA5String:
  487. case eType_ISO646String:
  488. case eType_NumericString:
  489. case eType_PrintableString:
  490. case eType_TeletexString:
  491. case eType_T61String:
  492. case eType_UniversalString:
  493. case eType_VideotexString:
  494. case eType_VisibleString:
  495. case eType_CharacterString:
  496. case eType_GeneralizedTime:
  497. case eType_UTCTime:
  498. case eType_ObjectDescriptor:
  499. case eType_RestrictedString:
  500. case eType_Open:
  501. case eType_Reference:
  502. /* generate function for a simple type */
  503. GenFuncSimpleType(ass, type, ideref, Dereference(valref1), Dereference(valref2), et);
  504. break;
  505. case eType_SequenceOf:
  506. case eType_SetOf:
  507. /* generate function for seq-of and set-of */
  508. GenFuncSimpleType(ass, type, ideref, Dereference(valref1), Dereference(valref2), et);
  509. break;
  510. case eType_Sequence:
  511. case eType_Set:
  512. case eType_InstanceOf:
  513. /* generate function for a sequence/set/instanceof type */
  514. GenFuncSequenceSetType(ass, module, at, valref1, valref2, et);
  515. break;
  516. case eType_Choice:
  517. /* generate function for a choice type */
  518. GenFuncChoiceType(ass, module, at, valref1, valref2, et);
  519. break;
  520. case eType_Selection:
  521. MyAbort();
  522. /*NOTREACHED*/
  523. case eType_Undefined:
  524. MyAbort();
  525. /*NOTREACHED*/
  526. }
  527. }
  528. /* generate encoding-independent statements for components of a */
  529. /* sequence/set/choice type */
  530. void
  531. GenFuncComponents(AssignmentList_t ass, char *module, Type_t *type, char *ideref, uint32_t optindex, ComponentList_t components, char *valref1, char *valref2, TypeFunc_e et, int inextension, int inchoice)
  532. {
  533. Component_t *com;
  534. NamedType_t *namedType;
  535. char *ide, idebuf[256];
  536. char valbuf1[256], valbuf2[256], valbuf3[256];
  537. int skip;
  538. /* emit components of extension root */
  539. for (com = components; com; com = com->Next) {
  540. if (com->Type == eComponent_ExtensionMarker)
  541. break;
  542. /* get some information */
  543. namedType = com->U.NOD.NamedType;
  544. ide = Identifier2C(namedType->Identifier);
  545. sprintf(idebuf, "%s_%s", ideref, ide);
  546. /* skip unnecessary elements */
  547. switch (et) {
  548. case eFree:
  549. skip = (namedType->Type->Flags & eTypeFlags_Simple);
  550. break;
  551. default:
  552. skip = 0;
  553. break;
  554. }
  555. /* dereference pointer if pointer directive used */
  556. if (inchoice) {
  557. if (GetTypeRules(ass, namedType->Type) & eTypeRules_Pointer) {
  558. sprintf(valbuf1, "*(%s)->u.%s", valref1, ide);
  559. sprintf(valbuf2, "*(%s)->u.%s", valref2, ide);
  560. } else {
  561. sprintf(valbuf1, "(%s)->u.%s", valref1, ide);
  562. sprintf(valbuf2, "(%s)->u.%s", valref2, ide);
  563. }
  564. } else {
  565. if (GetTypeRules(ass, namedType->Type) & eTypeRules_Pointer) {
  566. sprintf(valbuf1, "*(%s)->%s", valref1, ide);
  567. sprintf(valbuf2, "*(%s)->%s", valref2, ide);
  568. } else {
  569. sprintf(valbuf1, "(%s)->%s", valref1, ide);
  570. sprintf(valbuf2, "(%s)->%s", valref2, ide);
  571. }
  572. }
  573. /* check if optional/default component is present */
  574. if (!skip) {
  575. if (inchoice) {
  576. switch (et) {
  577. case eFree:
  578. output("case %d:\n", optindex);
  579. GenFuncSimpleType(ass, namedType->Type, idebuf,
  580. valbuf1, valbuf2, et);
  581. if ((GetTypeRules(ass, namedType->Type) &
  582. eTypeRules_Pointer) &&
  583. !(GetType(ass, namedType->Type)->Flags &
  584. eTypeFlags_Null))
  585. output("ASN1Free(%s);\n", Reference(valbuf1));
  586. output("break;\n");
  587. break;
  588. default:
  589. output("case %d:\n", optindex);
  590. GenFuncSimpleType(ass, namedType->Type, idebuf,
  591. valbuf1, valbuf2, et);
  592. output("break;\n");
  593. break;
  594. }
  595. } else {
  596. if (com->Type == eComponent_Optional ||
  597. com->Type == eComponent_Default ||
  598. inextension) {
  599. switch (et) {
  600. case eFree:
  601. output("if ((%s)->o[%u] & 0x%x) {\n", valref1,
  602. optindex / 8, 0x80 >> (optindex & 7));
  603. GenFuncSimpleType(ass, namedType->Type, idebuf,
  604. valbuf1, valbuf2, et);
  605. if ((GetTypeRules(ass, namedType->Type) &
  606. eTypeRules_Pointer) &&
  607. !(GetType(ass, namedType->Type)->Flags &
  608. eTypeFlags_Null))
  609. output("ASN1Free(%s);\n", Reference(valbuf1));
  610. output("}\n");
  611. break;
  612. case eCompare:
  613. sprintf(valbuf3, "%s_default", idebuf);
  614. output("if (((%s)->o[%u] & 0x%x)) {\n", valref1,
  615. optindex / 8, 0x80 >> (optindex & 7));
  616. output("if (((%s)->o[%u] & 0x%x)) {\n", valref2,
  617. optindex / 8, 0x80 >> (optindex & 7));
  618. GenFuncSimpleType(ass, namedType->Type, idebuf,
  619. valbuf1, valbuf2, et);
  620. output("} else {\n");
  621. if (com->Type == eComponent_Default) {
  622. GenFuncSimpleType(ass, namedType->Type, idebuf,
  623. valbuf1, valbuf3, et);
  624. } else {
  625. output("return 1;\n");
  626. }
  627. output("}\n");
  628. output("} else {\n");
  629. output("if (((%s)->o[%u] & 0x%x)) {\n", valref2,
  630. optindex / 8, 0x80 >> (optindex & 7));
  631. if (com->Type == eComponent_Default) {
  632. GenFuncSimpleType(ass, namedType->Type, idebuf,
  633. valbuf3, valbuf2, et);
  634. } else {
  635. output("return 1;\n");
  636. }
  637. output("}\n");
  638. output("}\n");
  639. break;
  640. default:
  641. GenFuncSimpleType(ass, namedType->Type, idebuf,
  642. valbuf1, valbuf2, et);
  643. break;
  644. }
  645. } else {
  646. GenFuncSimpleType(ass, namedType->Type, idebuf,
  647. valbuf1, valbuf2, et);
  648. }
  649. }
  650. }
  651. if (inchoice ||
  652. com->Type == eComponent_Optional ||
  653. com->Type == eComponent_Default ||
  654. inextension)
  655. optindex++;
  656. }
  657. }
  658. /* generate encoding-independent statements for sequence/set type */
  659. void
  660. GenFuncSequenceSetType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref1, char *valref2, TypeFunc_e et)
  661. {
  662. uint32_t optionals, extensions;
  663. Component_t *components, *com;
  664. Type_t *type;
  665. char *ideref;
  666. type = at->U.Type.Type;
  667. ideref = GetName(at);
  668. optionals = type->U.SSC.Optionals;
  669. extensions = type->U.SSC.Extensions;
  670. components = type->U.SSC.Components;
  671. /* emit components of extension root */
  672. GenFuncComponents(ass, module, type, ideref, 0,
  673. components, valref1, valref2, et, 0, 0);
  674. /* handle extensions */
  675. if (type->Flags & eTypeFlags_ExtensionMarker) {
  676. if (extensions) {
  677. /* get start of extensions */
  678. for (com = components; com; com = com->Next) {
  679. if (com->Type == eComponent_ExtensionMarker) {
  680. com = com->Next;
  681. break;
  682. }
  683. }
  684. /* emit components of extension */
  685. GenFuncComponents(ass, module, type, ideref, (optionals + 7) & ~7,
  686. com, valref1, valref2, et, 1, 0);
  687. }
  688. }
  689. }
  690. /* generate encoding-independent statements for choice type */
  691. void
  692. GenFuncChoiceType(AssignmentList_t ass, char *module, Assignment_t *at, char *valref1, char *valref2, TypeFunc_e et)
  693. {
  694. Type_t *type;
  695. char *ideref;
  696. char valbuf1[256], valbuf2[256];
  697. uint32_t alternatives;
  698. Component_t *components, *com;
  699. /* get some informations */
  700. type = at->U.Type.Type;
  701. ideref = GetName(at);
  702. alternatives = type->U.SSC.Alternatives;
  703. components = type->U.SSC.Components;
  704. /* encode choice selector */
  705. sprintf(valbuf1, "(%s)->choice", valref1);
  706. sprintf(valbuf2, "(%s)->choice", valref2);
  707. GenFuncSimpleType(ass, type, ideref, valbuf1, valbuf2, et);
  708. /* finished if choice only contains NULL alternatives or if choice */
  709. /* contains no data to free */
  710. if ((type->Flags & eTypeFlags_NullChoice) ||
  711. (et == eFree && (type->Flags & eTypeFlags_Simple)))
  712. return;
  713. /* create switch statement */
  714. output("switch ((%s)->choice) {\n", valref1);
  715. /* generate components of extension root */
  716. GenFuncComponents(ass, module, type, ideref, ASN1_CHOICE_BASE,
  717. type->U.SSC.Components, valref1, valref2, et, 0, 1);
  718. /* get start of extensions */
  719. for (com = components; com; com = com->Next) {
  720. if (com->Type == eComponent_ExtensionMarker) {
  721. com = com->Next;
  722. break;
  723. }
  724. }
  725. /* generate components of extension */
  726. GenFuncComponents(ass, module, type, ideref, ASN1_CHOICE_BASE + alternatives,
  727. com, valref1, valref2, et, 1, 1);
  728. /* end of switch statement */
  729. output("}\n");
  730. }
  731. /* generate encoding-independent statements for a simple type */
  732. void
  733. GenFuncSimpleType(AssignmentList_t ass, Type_t *type, char *ideref, char *valref1, char *valref2, TypeFunc_e et)
  734. {
  735. switch (et) {
  736. case eFree:
  737. GenFreeSimpleType(ass, type, ideref, valref1);
  738. break;
  739. #ifdef ENABLE_COMPARE
  740. case eCompare:
  741. GenCompareSimpleType(ass, type, ideref, valref1, valref2);
  742. break;
  743. #endif // ENABLE_COMPARE
  744. }
  745. }
  746. /* generate free statements for a simple type */
  747. void
  748. GenFreeSimpleType(AssignmentList_t ass, Type_t *type, char *ideref, char *valref)
  749. {
  750. char idebuf[256];
  751. char valbuf[256];
  752. char valbuf2[256];
  753. char *itype;
  754. int32_t noctets;
  755. uint32_t zero;
  756. if (type->Flags & eTypeFlags_Simple)
  757. return;
  758. if (type->Type == eType_Reference && !IsStructuredType(GetType(ass, type)))
  759. type = GetType(ass, type);
  760. switch (type->Type) {
  761. case eType_Boolean:
  762. case eType_Integer:
  763. case eType_Enumerated:
  764. /* check if we have to free an intx_t value */
  765. itype = GetTypeName(ass, type);
  766. if (!strcmp(itype, "ASN1intx_t"))
  767. output("ASN1intx_free(%s);\n", Reference(valref));
  768. break;
  769. case eType_BitString:
  770. /* free bit string value */
  771. if (g_eEncodingRule == eEncoding_Packed)
  772. {
  773. if (type->PERTypeInfo.Root.cbFixedSizeBitString == 0)
  774. {
  775. output("ASN1bitstring_free(%s);\n", Reference(valref));
  776. }
  777. }
  778. else
  779. {
  780. // only support unbounded in BER
  781. if (! type->PrivateDirectives.fNoMemCopy)
  782. {
  783. output("ASN1bitstring_free(%s);\n", Reference(valref));
  784. }
  785. }
  786. break;
  787. case eType_OctetString:
  788. /* free octet string value */
  789. if (g_eEncodingRule == eEncoding_Packed)
  790. {
  791. if (type->PERTypeInfo.Root.LConstraint != ePERSTIConstraint_Constrained ||
  792. type->PrivateDirectives.fLenPtr)
  793. {
  794. output("ASN1octetstring_free(%s);\n", Reference(valref));
  795. }
  796. }
  797. else
  798. {
  799. // only support unbounded in BER
  800. if (! type->PrivateDirectives.fNoMemCopy)
  801. {
  802. output("ASN1octetstring_free(%s);\n", Reference(valref));
  803. }
  804. }
  805. break;
  806. case eType_UTF8String:
  807. /* free octet string value */
  808. output("ASN1utf8string_free(%s);\n", Reference(valref));
  809. break;
  810. case eType_ObjectIdentifier:
  811. /* free object identifier value */
  812. if (type->PrivateDirectives.fOidPacked)
  813. {
  814. output("ASN1BEREoid_free(%s);\n", Reference(valref));
  815. }
  816. else
  817. if (! (type->PrivateDirectives.fOidArray || g_fOidArray))
  818. {
  819. output("ASN1objectidentifier_free(%s);\n", Reference(valref));
  820. }
  821. break;
  822. case eType_External:
  823. /* free external value */
  824. output("ASN1external_free(%s);\n", Reference(valref));
  825. break;
  826. case eType_Real:
  827. /* free real value */
  828. output("ASN1real_free(%s);\n", Reference(valref));
  829. break;
  830. case eType_EmbeddedPdv:
  831. /* free embedded pdv value */
  832. output("ASN1embeddedpdv_free(%s);\n", Reference(valref));
  833. break;
  834. case eType_SetOf:
  835. /* create name of identifier */
  836. sprintf(idebuf, "%s_Set", ideref);
  837. goto FreeSequenceSetOf;
  838. case eType_SequenceOf:
  839. /* create name of identifier */
  840. sprintf(idebuf, "%s_Sequence", ideref);
  841. FreeSequenceSetOf:
  842. if (type->Rules & eTypeRules_FixedArray)
  843. {
  844. char *pszPrivateValueName = GetPrivateValueName(&type->PrivateDirectives, "value");
  845. /* free components of sequence of/set of */
  846. if (! (type->Rules & eTypeRules_PointerToElement))
  847. valref = Reference(valref);
  848. if (!(type->U.SS.Type->Flags & eTypeFlags_Simple)) {
  849. outputvar("ASN1uint32_t i;\n");
  850. output("for (i = 0; i < (%s)->count; i++) {\n", valref);
  851. sprintf(valbuf, "(%s)->%s[i]", valref, pszPrivateValueName);
  852. GenFuncSimpleType(ass, type->U.SS.Type, idebuf, valbuf, "", eFree);
  853. output("}\n");
  854. }
  855. }
  856. else
  857. if (type->Rules & eTypeRules_LengthPointer)
  858. {
  859. char *pszPrivateValueName = GetPrivateValueName(&type->PrivateDirectives, "value");
  860. /* free components of sequence of/set of */
  861. if (! (type->Rules & eTypeRules_PointerToElement))
  862. valref = Reference(valref);
  863. if (!(type->U.SS.Type->Flags & eTypeFlags_Simple)) {
  864. sprintf(valbuf2, "(%s)->%s[0]", valref, pszPrivateValueName);
  865. GenFuncSimpleType(ass, type->U.SS.Type, idebuf, valbuf2, "", eFree);
  866. outputvar("ASN1uint32_t i;\n");
  867. output("for (i = 1; i < (%s)->count; i++) {\n", valref);
  868. sprintf(valbuf2, "(%s)->%s[i]", valref, pszPrivateValueName);
  869. GenFuncSimpleType(ass, type->U.SS.Type, idebuf, valbuf2, "", eFree);
  870. output("}\n");
  871. }
  872. // lonchanc: no need to check length because we zero out decoded buffers.
  873. // output("if ((%s)->count)\n", valref);
  874. output("ASN1Free((%s)->%s);\n", valref, pszPrivateValueName);
  875. }
  876. else
  877. if (type->Rules & eTypeRules_LinkedListMask)
  878. {
  879. char szPrivateValueName[68];
  880. if (g_fCaseBasedOptimizer)
  881. {
  882. if (g_eEncodingRule == eEncoding_Packed &&
  883. PerOptCase_IsTargetSeqOf(&type->PERTypeInfo))
  884. {
  885. // generate the iterator
  886. PERTypeInfo_t *info = &type->PERTypeInfo;
  887. char szElmFn[128];
  888. char szElmFnDecl[256];
  889. sprintf(szElmFn, "ASN1Free_%s_ElmFn", info->Identifier);
  890. sprintf(szElmFnDecl, "void ASN1CALL %s(P%s val)",
  891. szElmFn, info->Identifier);
  892. setoutfile(g_finc);
  893. output("extern %s;\n", szElmFnDecl);
  894. setoutfile(g_fout);
  895. output("ASN1PERFreeSeqOf((ASN1iterator_t **) %s, (ASN1iterator_freefn) %s);\n",
  896. Reference(valref), szElmFn);
  897. output("}\n"); // closing the null pointer check
  898. output("}\n\n"); // end of iterator body
  899. // generate the element function
  900. output("static %s\n", szElmFnDecl);
  901. output("{\n");
  902. output("if (val) {\n"); // opening the null pointer check
  903. sprintf(&szPrivateValueName[0], "val->%s", GetPrivateValueName(info->pPrivateDirectives, "value"));
  904. GenFuncSimpleType(ass, type->U.SS.Type, idebuf,
  905. &szPrivateValueName[0], "", eFree);
  906. // output("}\n"); // closing the null pointer check. lonchanc: closed by caller
  907. // end of element body
  908. return;
  909. }
  910. }
  911. /* free components of sequence of/set of */
  912. outputvar("P%s f, ff;\n", ideref);
  913. output("for (f = %s; f; f = ff) {\n", valref);
  914. sprintf(&szPrivateValueName[0], "f->%s", type->PrivateDirectives.pszValueName ? type->PrivateDirectives.pszValueName : "value");
  915. GenFuncSimpleType(ass, type->U.SS.Type, idebuf,
  916. &szPrivateValueName[0], "", eFree);
  917. output("ff = f->next;\n");
  918. /* free list entry of sequence of/set of */
  919. output("ASN1Free(f);\n");
  920. output("}\n");
  921. }
  922. break;
  923. case eType_ObjectDescriptor:
  924. /* free object descriptor value */
  925. output("ASN1ztcharstring_free(%s);\n", valref);
  926. break;
  927. case eType_NumericString:
  928. case eType_PrintableString:
  929. case eType_TeletexString:
  930. case eType_T61String:
  931. case eType_VideotexString:
  932. case eType_IA5String:
  933. case eType_GraphicString:
  934. case eType_VisibleString:
  935. case eType_ISO646String:
  936. case eType_GeneralString:
  937. case eType_UniversalString:
  938. #ifdef ENABLE_CHAR_STR_SIZE
  939. if (g_eEncodingRule == eEncoding_Packed &&
  940. type->PERTypeInfo.NOctets == 1 &&
  941. type->PERTypeInfo.Root.LConstraint == ePERSTIConstraint_Constrained)
  942. {
  943. // it is an array, no need to free it.
  944. break;
  945. }
  946. #endif
  947. case eType_BMPString:
  948. case eType_RestrictedString:
  949. /* free string value */
  950. GetStringType(ass, type, &noctets, &zero);
  951. if (zero) {
  952. switch (noctets) {
  953. case 1:
  954. output("ASN1ztcharstring_free(%s);\n", valref);
  955. break;
  956. case 2:
  957. output("ASN1ztchar16string_free(%s);\n", valref);
  958. break;
  959. case 4:
  960. output("ASN1ztchar32string_free(%s);\n", valref);
  961. break;
  962. }
  963. } else {
  964. switch (noctets) {
  965. case 1:
  966. output("ASN1charstring_free(%s);\n", Reference(valref));
  967. break;
  968. case 2:
  969. output("ASN1char16string_free(%s);\n", Reference(valref));
  970. break;
  971. case 4:
  972. output("ASN1char32string_free(%s);\n", Reference(valref));
  973. break;
  974. }
  975. }
  976. break;
  977. case eType_CharacterString:
  978. /* free character string value */
  979. output("ASN1characterstring_free(%s);\n", Reference(valref));
  980. break;
  981. case eType_Reference:
  982. /* call free function of referenced type */
  983. output("ASN1Free_%s(%s);\n",
  984. GetTypeName(ass, type), Reference(valref));
  985. break;
  986. case eType_Open:
  987. /* free open type value */
  988. if (g_eEncodingRule == eEncoding_Packed || (! type->PrivateDirectives.fNoMemCopy))
  989. {
  990. output("ASN1open_free(%s);\n", Reference(valref));
  991. }
  992. break;
  993. }
  994. }
  995. /* generate compare statements for a simple type */
  996. /*ARGSUSED*/
  997. #ifdef ENABLE_COMPARE
  998. void
  999. GenCompareSimpleType(AssignmentList_t ass, Type_t *type, char *ideref, char *valref1, char *valref2)
  1000. {
  1001. /* skip null type */
  1002. if (type->Flags & eTypeFlags_Null)
  1003. return;
  1004. /* compare the values and return difference if different */
  1005. output("if ((ret = (");
  1006. GenCompareExpression(ass, type, ideref, valref1, valref2);
  1007. output(")))\n");
  1008. output("return ret;\n");
  1009. }
  1010. #endif // ENABLE_COMPARE
  1011. /* generate compare expression for two values of simple type */
  1012. /*ARGSUSED*/
  1013. #ifdef ENABLE_COMPARE
  1014. void
  1015. GenCompareExpression(AssignmentList_t ass, Type_t *type, char *ideref, char *valref1, char *valref2)
  1016. {
  1017. PERSTIData_e dat;
  1018. uint32_t noctets;
  1019. char *itype;
  1020. char *subide;
  1021. char *pszPrivateValueName;
  1022. /*XXX switch to PER-independent field */
  1023. dat = type->PERTypeInfo.Root.Data;
  1024. noctets = type->PERTypeInfo.NOctets;
  1025. switch (dat) {
  1026. case ePERSTIData_Null:
  1027. /* null values equal */
  1028. output("0");
  1029. break;
  1030. case ePERSTIData_Boolean:
  1031. /* boolean values have to be converted to 0/1 values before */
  1032. /* comparison */
  1033. output("!!%s - !!%s", valref1, valref2);
  1034. break;
  1035. case ePERSTIData_Integer:
  1036. case ePERSTIData_Unsigned:
  1037. /* substract integer values */
  1038. if (noctets) {
  1039. if (noctets <= 4)
  1040. output("%s - %s", valref1, valref2);
  1041. else
  1042. output("%s < %s ? -1 : %s > %s ? 1 : 0",
  1043. valref1, valref2, valref1, valref2);
  1044. } else {
  1045. output("ASN1intx_cmp(%s, %s)",
  1046. Reference(valref1), Reference(valref2));
  1047. }
  1048. break;
  1049. case ePERSTIData_Real:
  1050. /* compare real values */
  1051. itype = GetTypeName(ass, type);
  1052. if (!strcmp(itype, "ASN1real_t"))
  1053. output("ASN1real_cmp(%s, %s)",
  1054. Reference(valref1), Reference(valref2));
  1055. else
  1056. output("ASN1double_cmp(%s, %s)",
  1057. valref1, valref2);
  1058. break;
  1059. case ePERSTIData_BitString:
  1060. /* compare bit string values */
  1061. output("ASN1bitstring_cmp(%s, %s, 0)",
  1062. Reference(valref1), Reference(valref2));
  1063. break;
  1064. case ePERSTIData_RZBBitString:
  1065. /* compare remove-zero-bit bit string values */
  1066. output("ASN1bitstring_cmp(%s, %s, 1)",
  1067. Reference(valref1), Reference(valref2));
  1068. break;
  1069. case ePERSTIData_OctetString:
  1070. /* compare octet string values */
  1071. output("ASN1octetstring_cmp(%s, %s)",
  1072. Reference(valref1), Reference(valref2));
  1073. break;
  1074. case ePERSTIData_UTF8String:
  1075. /* compare octet string values */
  1076. output("ASN1utf8string_cmp(%s, %s)",
  1077. Reference(valref1), Reference(valref2));
  1078. break;
  1079. case ePERSTIData_ObjectIdentifier:
  1080. /* compare object identifier values */
  1081. output("ASN1objectidentifier_cmp(%s, %s)",
  1082. Reference(valref1), Reference(valref2));
  1083. break;
  1084. case ePERSTIData_String:
  1085. case ePERSTIData_TableString:
  1086. /* compare string values */
  1087. switch (noctets) {
  1088. case 1:
  1089. output("ASN1charstring_cmp(%s, %s)",
  1090. Reference(valref1), Reference(valref2));
  1091. break;
  1092. case 2:
  1093. output("ASN1char16string_cmp(%s, %s)",
  1094. Reference(valref1), Reference(valref2));
  1095. break;
  1096. case 4:
  1097. output("ASN1char32string_cmp(%s, %s)",
  1098. Reference(valref1), Reference(valref2));
  1099. break;
  1100. }
  1101. break;
  1102. case ePERSTIData_ZeroString:
  1103. case ePERSTIData_ZeroTableString:
  1104. /* compare zero-terminated string values */
  1105. switch (noctets) {
  1106. case 1:
  1107. output("ASN1ztcharstring_cmp(%s, %s)",
  1108. valref1, valref2);
  1109. break;
  1110. case 2:
  1111. output("ASN1ztchar16string_cmp(%s, %s)",
  1112. valref1, valref2);
  1113. break;
  1114. case 4:
  1115. output("ASN1ztchar32string_cmp(%s, %s)",
  1116. valref1, valref2);
  1117. break;
  1118. }
  1119. break;
  1120. case ePERSTIData_SequenceOf:
  1121. /* compare sequence of values by use of a comparison function */
  1122. /* use element comparison function as argument */
  1123. subide = GetTypeName(ass, type->U.SS.Type);
  1124. pszPrivateValueName = GetPrivateValueName(&type->PrivateDirectives, "value");
  1125. if (type->Rules & eTypeRules_PointerArrayMask)
  1126. {
  1127. output("ASN1sequenceoflengthpointer_cmp((%s)->count, (%s)->%s, (%s)->count, (%s)->%s, sizeof(%s), (int (*)(void *, void *))ASN1Compare_%s)",
  1128. Reference(valref1), Reference(valref1), pszPrivateValueName,
  1129. Reference(valref2), Reference(valref2), pszPrivateValueName, subide, subide);
  1130. }
  1131. else
  1132. if (type->Rules & eTypeRules_SinglyLinkedList)
  1133. {
  1134. output("ASN1sequenceofsinglylinkedlist_cmp(%s, %s, offsetof(%s_Element, %s), (ASN1int32_t (*)(void *, void *))ASN1Compare_%s)",
  1135. valref1, valref2, ideref, pszPrivateValueName, subide);
  1136. }
  1137. else
  1138. if (type->Rules & eTypeRules_DoublyLinkedList)
  1139. {
  1140. output("ASN1sequenceofdoublylinkedlist_cmp(%s, %s, offsetof(%s_Element, %s), (ASN1int32_t (*)(void *, void *))ASN1Compare_%s)",
  1141. valref1, valref2, ideref, pszPrivateValueName, subide);
  1142. }
  1143. else
  1144. {
  1145. MyAbort();
  1146. }
  1147. break;
  1148. case ePERSTIData_SetOf:
  1149. /* compare set of values by use of a comparison function */
  1150. /* use element comparison function as argument */
  1151. subide = GetTypeName(ass, type->U.SS.Type);
  1152. pszPrivateValueName = GetPrivateValueName(&type->PrivateDirectives, "value");
  1153. if (type->Rules & eTypeRules_PointerArrayMask)
  1154. {
  1155. output("ASN1setoflengthpointer_cmp((%s)->count, (%s)->%s, (%s)->count, (%s)->%s, sizeof(%s), (int (*)(void *, void *))ASN1Compare_%s)",
  1156. Reference(valref1), Reference(valref1), pszPrivateValueName,
  1157. Reference(valref2), Reference(valref2), pszPrivateValueName, subide, subide);
  1158. }
  1159. else
  1160. if (type->Rules & eTypeRules_SinglyLinkedList)
  1161. {
  1162. output("ASN1setofsinglylinkedlist_cmp(%s, %s, offsetof(%s_Element, %s), (ASN1int32_t (*)(void *, void *))ASN1Compare_%s)",
  1163. valref1, valref2, ideref, pszPrivateValueName, subide);
  1164. }
  1165. else
  1166. if (type->Rules & eTypeRules_DoublyLinkedList)
  1167. {
  1168. output("ASN1setofdoublylinkedlist_cmp(%s, %s, offsetof(%s_Element, %s), (ASN1int32_t (*)(void *, void *))ASN1Compare_%s)",
  1169. valref1, valref2, ideref, pszPrivateValueName, subide);
  1170. }
  1171. else
  1172. {
  1173. MyAbort();
  1174. }
  1175. break;
  1176. case ePERSTIData_Reference:
  1177. /* call compare function of referenced value */
  1178. output("ASN1Compare_%s(%s, %s)",
  1179. GetTypeName(ass, type), Reference(valref1), Reference(valref2));
  1180. break;
  1181. case ePERSTIData_External:
  1182. /* compare external values */
  1183. output("ASN1external_cmp(%s, %s)",
  1184. Reference(valref1), Reference(valref2));
  1185. break;
  1186. case ePERSTIData_EmbeddedPdv:
  1187. /* compare embedded pdv values */
  1188. output("ASN1embeddedpdv_cmp(%s, %s)",
  1189. Reference(valref1), Reference(valref2));
  1190. break;
  1191. case ePERSTIData_MultibyteString:
  1192. /* compare multibyte string values */
  1193. output("ASN1ztcharstring_cmp(%s, %s)",
  1194. valref1, valref2);
  1195. break;
  1196. case ePERSTIData_UnrestrictedString:
  1197. /* compare character string values */
  1198. output("ASN1characterstring_cmp(%s, %s)",
  1199. Reference(valref1), Reference(valref2));
  1200. break;
  1201. case ePERSTIData_GeneralizedTime:
  1202. /* compare generalized time values */
  1203. output("ASN1generalizedtime_cmp(%s, %s)",
  1204. Reference(valref1), Reference(valref2));
  1205. break;
  1206. case ePERSTIData_UTCTime:
  1207. /* compare utc time values */
  1208. output("ASN1utctime_cmp(%s, %s)",
  1209. Reference(valref1), Reference(valref2));
  1210. break;
  1211. case ePERSTIData_Open:
  1212. /* compare open type values */
  1213. output("ASN1open_cmp(%s, %s)",
  1214. Reference(valref1), Reference(valref2));
  1215. break;
  1216. }
  1217. }
  1218. #endif // ENABLE_COMPARE
  1219. /* generate encoding-independent statements for better optional flags of */
  1220. /* a sequence/set value */
  1221. void
  1222. GenFuncSequenceSetOptionals(AssignmentList_t ass, char *valref, ComponentList_t components, uint32_t optionals, uint32_t extensions, char *obuf, TypeFunc_e et)
  1223. {
  1224. uint32_t optindex, inextension, oflg;
  1225. Component_t *com;
  1226. char *ide;
  1227. char *itype;
  1228. int flg;
  1229. int32_t sign, noctets;
  1230. uint32_t zero;
  1231. sprintf(obuf, "(%s)->o", valref);
  1232. oflg = 0;
  1233. if (et == eEncode) {
  1234. optindex = 0;
  1235. inextension = 0;
  1236. for (com = components; com; com = com->Next) {
  1237. switch (com->Type) {
  1238. case eComponent_Normal:
  1239. /* non-optional fields in an extension will be mandatory, */
  1240. /* so we can set the optional flag always. */
  1241. if (inextension) {
  1242. if (!oflg) {
  1243. outputvar("ASN1octet_t o[%u];\n",
  1244. (optionals + 7) / 8 + (extensions + 7) / 8);
  1245. output("CopyMemory(o, (%s)->o, %u);\n", valref,
  1246. (optionals + 7) / 8 + (extensions + 7) / 8);
  1247. strcpy(obuf, "o");
  1248. oflg = 1;
  1249. }
  1250. output("%s[%u] |= 0x%x;\n", obuf, optindex / 8,
  1251. 0x80 >> (optindex & 7));
  1252. optindex++;
  1253. }
  1254. break;
  1255. case eComponent_Optional:
  1256. /* optional pointers with value null are absent, so we */
  1257. /* will clear the optional flag */
  1258. ide = Identifier2C(com->U.Optional.NamedType->Identifier);
  1259. switch (com->U.Optional.NamedType->Type->Type) {
  1260. case eType_Reference:
  1261. if (GetTypeRules(ass, com->U.Optional.NamedType->Type) &
  1262. eTypeRules_Pointer) {
  1263. if (!oflg) {
  1264. outputvar("ASN1octet_t o[%u];\n",
  1265. (optionals + 7) / 8 + (extensions + 7) / 8);
  1266. output("CopyMemory(o, (%s)->o, %u);\n", valref,
  1267. (optionals + 7) / 8 + (extensions + 7) / 8);
  1268. strcpy(obuf, "o");
  1269. oflg = 1;
  1270. }
  1271. output("if (!(%s)->%s)\n", valref, ide);
  1272. output("o[%u] &= ~0x%x;\n", valref, optindex / 8,
  1273. 0x80 >> (optindex & 7));
  1274. }
  1275. break;
  1276. }
  1277. optindex++;
  1278. break;
  1279. case eComponent_Default:
  1280. /* default pointers with value null are absent, so we */
  1281. /* will clear the optional flag */
  1282. ide = Identifier2C(com->U.Default.NamedType->Identifier);
  1283. switch (com->U.Default.NamedType->Type->Type) {
  1284. case eType_Reference:
  1285. if (GetTypeRules(ass, com->U.Default.NamedType->Type) &
  1286. eTypeRules_Pointer) {
  1287. if (!oflg) {
  1288. outputvar("ASN1octet_t o[%u];\n",
  1289. (optionals + 7) / 8 + (extensions + 7) / 8);
  1290. output("CopyMemory(o, (%s)->o, %u);\n", valref,
  1291. (optionals + 7) / 8 + (extensions + 7) / 8);
  1292. strcpy(obuf, "o");
  1293. oflg = 1;
  1294. }
  1295. output("if (!(%s)->%s)\n", valref, ide);
  1296. output("o[%u] &= ~0x%x;\n", valref, optindex / 8,
  1297. 0x80 >> (optindex & 7));
  1298. }
  1299. break;
  1300. }
  1301. /* if the given value is the default value, we can (BER) */
  1302. /* or have to (CER) clear the corresponding optional flag */
  1303. flg = 1;
  1304. if (!oflg) {
  1305. switch (GetTypeType(ass, com->U.Default.NamedType->Type)) {
  1306. case eType_Choice:
  1307. if (!(GetType(ass, com->U.Default.NamedType->Type)->
  1308. Flags & eTypeFlags_NullChoice)) {
  1309. if (g_eSubEncodingRule == eSubEncoding_Canonical)
  1310. MyAbort(); /*XXX*/
  1311. flg = 0;
  1312. }
  1313. break;
  1314. case eType_Sequence:
  1315. case eType_Set:
  1316. case eType_InstanceOf:
  1317. if (g_eSubEncodingRule == eSubEncoding_Canonical)
  1318. MyAbort(); /*XXX*/
  1319. flg = 0;
  1320. break;
  1321. case eType_SequenceOf:
  1322. case eType_SetOf:
  1323. if (GetValue(ass, com->U.Default.Value)->U.SS.Values) {
  1324. if (g_eSubEncodingRule == eSubEncoding_Canonical)
  1325. MyAbort();
  1326. flg = 0;
  1327. }
  1328. break;
  1329. }
  1330. if (flg) {
  1331. outputvar("ASN1octet_t o[%u];\n",
  1332. (optionals + 7) / 8 + (extensions + 7) / 8);
  1333. output("CopyMemory(o, (%s)->o, %u);\n", valref,
  1334. (optionals + 7) / 8 + (extensions + 7) / 8);
  1335. strcpy(obuf, "o");
  1336. oflg = 1;
  1337. }
  1338. }
  1339. switch (GetTypeType(ass, com->U.Default.NamedType->Type)) {
  1340. case eType_Boolean:
  1341. output("if (%s(%s)->%s)\n",
  1342. GetValue(ass,
  1343. com->U.Default.Value)->U.Boolean.Value ? "" : "!",
  1344. valref, ide);
  1345. break;
  1346. case eType_Integer:
  1347. itype = GetIntegerType(ass,
  1348. GetType(ass, com->U.Default.NamedType->Type),
  1349. &sign);
  1350. if (!strcmp(itype, "ASN1intx_t")) {
  1351. output("if (!ASN1intx_cmp(&(%s)->%s, &%s))\n",
  1352. valref, ide,
  1353. GetValueName(ass, com->U.Default.Value));
  1354. } else if (sign > 0) {
  1355. output("if ((%s)->%s == %u)\n", valref, ide,
  1356. intx2uint32(&GetValue(ass, com->U.Default.Value)
  1357. ->U.Integer.Value));
  1358. } else {
  1359. output("if ((%s)->%s == %d)\n", valref, ide,
  1360. intx2int32(&GetValue(ass, com->U.Default.Value)
  1361. ->U.Integer.Value));
  1362. }
  1363. break;
  1364. case eType_BitString:
  1365. if (GetValue(ass, com->U.Default.Value)->
  1366. U.BitString.Value.length) {
  1367. output("if (!ASN1bitstring_cmp(&%s->%s, &%s, %d))\n",
  1368. valref, ide,
  1369. GetValueName(ass, com->U.Default.Value),
  1370. !!GetType(ass, com->U.Default.NamedType->Type)->
  1371. U.BitString.NamedNumbers);
  1372. } else {
  1373. output("if (!(%s)->%s.length)\n", valref, ide);
  1374. }
  1375. break;
  1376. case eType_OctetString:
  1377. if (GetValue(ass, com->U.Default.Value)->U.OctetString.
  1378. Value.length) {
  1379. output("if (!ASN1octetstring_cmp(&%s->%s, &%s))\n",
  1380. valref, ide,
  1381. GetValueName(ass, com->U.Default.Value));
  1382. } else {
  1383. output("if (!(%s)->%s.length)\n", valref, ide);
  1384. }
  1385. break;
  1386. case eType_UTF8String:
  1387. if (GetValue(ass, com->U.Default.Value)->U.UTF8String.
  1388. Value.length) {
  1389. output("if (!ASN1utf8string_cmp(&%s->%s, &%s))\n",
  1390. valref, ide,
  1391. GetValueName(ass, com->U.Default.Value));
  1392. } else {
  1393. output("if (!(%s)->%s.length)\n", valref, ide);
  1394. }
  1395. break;
  1396. case eType_Null:
  1397. break;
  1398. case eType_ObjectIdentifier:
  1399. if (GetValue(ass, com->U.Default.Value)->U.
  1400. ObjectIdentifier.Value.length) {
  1401. output("if (!ASN1objectidentifier%s_cmp(&%s->%s, &%s))\n",
  1402. com->U.Default.NamedType->Type->PrivateDirectives.fOidArray ? "2" : "",
  1403. valref, ide,
  1404. GetValueName(ass, com->U.Default.Value));
  1405. } else {
  1406. output("if (!(%s)->%s.length)\n", valref, ide);
  1407. }
  1408. break;
  1409. case eType_ObjectDescriptor:
  1410. output("if (!strcmp((%s)->%s, %s))\n",
  1411. valref, ide,
  1412. GetValueName(ass, com->U.Default.Value));
  1413. break;
  1414. case eType_External:
  1415. output("if (!ASN1external_cmp(&(%s)->%s, &%s))\n",
  1416. valref, ide,
  1417. GetValueName(ass, com->U.Default.Value));
  1418. break;
  1419. case eType_Real:
  1420. itype = GetTypeName(ass, com->U.Default.NamedType->Type);
  1421. if (!strcmp(itype, "ASN1real_t")) {
  1422. output("if (!ASN1real_cmp(&(%s)->%s, &%s))\n",
  1423. valref, ide,
  1424. GetValueName(ass, com->U.Default.Value));
  1425. }
  1426. else
  1427. {
  1428. output("if ((%s)->%s == %g)\n",
  1429. valref, ide,
  1430. real2double(&GetValue(ass,
  1431. com->U.Default.Value)->U.Real.Value));
  1432. }
  1433. break;
  1434. case eType_Enumerated:
  1435. output("if ((%s)->%s == %u)\n", valref, ide,
  1436. GetValue(ass, com->U.Default.Value)->
  1437. U.Enumerated.Value);
  1438. break;
  1439. case eType_EmbeddedPdv:
  1440. output("if (!ASN1embeddedpdv_cmp(&(%s)->%s, &%s))\n",
  1441. valref, ide,
  1442. GetValueName(ass, com->U.Default.Value));
  1443. break;
  1444. case eType_NumericString:
  1445. case eType_PrintableString:
  1446. case eType_TeletexString:
  1447. case eType_T61String:
  1448. case eType_VideotexString:
  1449. case eType_IA5String:
  1450. case eType_GraphicString:
  1451. case eType_VisibleString:
  1452. case eType_ISO646String:
  1453. case eType_GeneralString:
  1454. case eType_UniversalString:
  1455. case eType_BMPString:
  1456. case eType_RestrictedString:
  1457. GetStringType(ass, com->U.Default.NamedType->Type,
  1458. &noctets, &zero);
  1459. if (zero) {
  1460. switch (noctets) {
  1461. case 1:
  1462. output("if (!strcmp((%s)->%s, %s))\n",
  1463. valref, ide,
  1464. GetValueName(ass, com->U.Default.Value));
  1465. break;
  1466. case 2:
  1467. output("if (!ASN1str16cmp((%s)->%s, %s))\n",
  1468. valref, ide,
  1469. GetValueName(ass, com->U.Default.Value));
  1470. break;
  1471. case 4:
  1472. output("if (!ASN1str32cmp((%s)->%s, %s))\n",
  1473. valref, ide,
  1474. GetValueName(ass, com->U.Default.Value));
  1475. break;
  1476. default:
  1477. MyAbort();
  1478. }
  1479. } else {
  1480. switch (noctets) {
  1481. case 1:
  1482. output("if (!ASN1charstring_cmp(&(%s)->%s, &%s))\n",
  1483. valref, ide,
  1484. GetValueName(ass, com->U.Default.Value));
  1485. break;
  1486. case 2:
  1487. output("if (!ASN1char16string_cmp(&(%s)->%s, &%s))\n",
  1488. valref, ide,
  1489. GetValueName(ass, com->U.Default.Value));
  1490. break;
  1491. case 4:
  1492. output("if (!ASN1char32string_cmp(&(%s)->%s, &%s))\n",
  1493. valref, ide,
  1494. GetValueName(ass, com->U.Default.Value));
  1495. break;
  1496. default:
  1497. MyAbort();
  1498. }
  1499. }
  1500. break;
  1501. case eType_CharacterString:
  1502. output("if (!ASN1characterstring_cmp(&(%s)->%s, &%s))\n",
  1503. valref, ide,
  1504. GetValueName(ass, com->U.Default.Value));
  1505. break;
  1506. case eType_UTCTime:
  1507. output("if (!ASN1utctime_cmp(&(%s)->%s, &%s))\n",
  1508. valref, ide,
  1509. GetValueName(ass, com->U.Default.Value));
  1510. break;
  1511. case eType_GeneralizedTime:
  1512. output("if (!ASN1generalizedtime_cmp(&(%s)->%s, &%s))\n",
  1513. valref, ide,
  1514. GetValueName(ass, com->U.Default.Value));
  1515. break;
  1516. case eType_Choice:
  1517. if (GetType(ass, com->U.Default.NamedType->Type)->Flags
  1518. & eTypeFlags_NullChoice) {
  1519. output("if ((%s)->%s.o == %s.o)\n",
  1520. valref, ide,
  1521. GetValueName(ass, com->U.Default.Value));
  1522. } else {
  1523. if (g_eSubEncodingRule == eSubEncoding_Canonical)
  1524. MyAbort(); /*XXX*/
  1525. flg = 0;
  1526. }
  1527. break;
  1528. case eType_Sequence:
  1529. case eType_Set:
  1530. case eType_InstanceOf:
  1531. if (g_eSubEncodingRule == eSubEncoding_Canonical)
  1532. MyAbort(); /*XXX*/
  1533. flg = 0;
  1534. break;
  1535. case eType_SequenceOf:
  1536. case eType_SetOf:
  1537. if (!GetValue(ass, com->U.Default.Value)->U.SS.Values) {
  1538. output("if (!(%s)->%s.count)\n", valref, ide);
  1539. } else {
  1540. if (g_eSubEncodingRule == eSubEncoding_Canonical)
  1541. MyAbort();
  1542. flg = 0;
  1543. }
  1544. break;
  1545. default:
  1546. MyAbort();
  1547. }
  1548. if (flg)
  1549. output("%s[%u] &= ~0x%x;\n", obuf, optindex / 8,
  1550. 0x80 >> (optindex & 7));
  1551. optindex++;
  1552. break;
  1553. case eComponent_ExtensionMarker:
  1554. /* update the optional index for extensions */
  1555. optindex = (optindex + 7) & ~7;
  1556. inextension = 1;
  1557. break;
  1558. }
  1559. }
  1560. }
  1561. }
  1562. /* generate encoding-independent statements for better optional values of */
  1563. /* a sequence/set value */
  1564. void
  1565. GenFuncSequenceSetDefaults(AssignmentList_t ass, char *valref, ComponentList_t components, char *obuf, TypeFunc_e et)
  1566. {
  1567. uint32_t optindex, inextension;
  1568. Component_t *com;
  1569. char *ide;
  1570. char *itype;
  1571. int32_t sign;
  1572. if (et == eDecode) {
  1573. optindex = 0;
  1574. inextension = 0;
  1575. for (com = components; com; com = com->Next) {
  1576. switch (com->Type) {
  1577. case eComponent_Normal:
  1578. /* all values in an extension are optional */
  1579. if (!inextension)
  1580. break;
  1581. /*FALLTHROUGH*/
  1582. case eComponent_Optional:
  1583. /* clear the pointer if the component is not present */
  1584. ide = Identifier2C(com->U.Optional.NamedType->Identifier);
  1585. switch (com->U.Optional.NamedType->Type->Type) {
  1586. case eType_Reference:
  1587. if (GetTypeRules(ass, com->U.Optional.NamedType->Type) &
  1588. eTypeRules_Pointer) {
  1589. output("if (!(%s[%u] & 0x%x))\n", obuf,
  1590. optindex / 8, 0x80 >> (optindex & 7));
  1591. output("(%s)->%s = NULL;\n", valref, ide);
  1592. }
  1593. break;
  1594. }
  1595. optindex++;
  1596. break;
  1597. case eComponent_Default:
  1598. /* clear the pointer if the component is not present */
  1599. ide = Identifier2C(com->U.Default.NamedType->Identifier);
  1600. switch (com->U.Optional.NamedType->Type->Type) {
  1601. case eType_Reference:
  1602. if (GetTypeRules(ass, com->U.Optional.NamedType->Type) &
  1603. eTypeRules_Pointer) {
  1604. output("if (!(%s[%u] & 0x%x))\n", obuf,
  1605. optindex / 8, 0x80 >> (optindex & 7));
  1606. output("(%s)->%s = NULL;\n", valref, ide);
  1607. }
  1608. break;
  1609. }
  1610. /* set the element to the default value if it is simple */
  1611. /* and not present */
  1612. switch (GetTypeType(ass, com->U.Default.NamedType->Type)) {
  1613. case eType_Boolean:
  1614. output("if (!(%s[%u] & 0x%x))\n", obuf, optindex / 8,
  1615. 0x80 >> (optindex & 7));
  1616. output("(%s)->%s = %u;\n",
  1617. valref, ide, GetValue(ass, com->U.Default.Value)->
  1618. U.Boolean.Value);
  1619. break;
  1620. case eType_Integer:
  1621. output("if (!(%s[%u] & 0x%x))\n", obuf, optindex / 8,
  1622. 0x80 >> (optindex & 7));
  1623. itype = GetIntegerType(ass,
  1624. GetType(ass, com->U.Default.NamedType->Type),
  1625. &sign);
  1626. if (!strcmp(itype, "ASN1intx_t")) {
  1627. /*EMPTY*/
  1628. } else if (sign > 0) {
  1629. output("(%s)->%s = %u;\n", valref, ide,
  1630. intx2uint32(&GetValue(ass, com->U.Default.Value)
  1631. ->U.Integer.Value));
  1632. } else {
  1633. output("(%s)->%s = %d;\n", valref, ide,
  1634. intx2int32(&GetValue(ass, com->U.Default.Value)
  1635. ->U.Integer.Value));
  1636. }
  1637. break;
  1638. case eType_Enumerated:
  1639. output("if (!(%s[%u] & 0x%x))\n", obuf, optindex / 8,
  1640. 0x80 >> (optindex & 7));
  1641. output("(%s)->%s = %u;\n", valref, ide,
  1642. GetValue(ass, com->U.Default.Value)->
  1643. U.Enumerated.Value);
  1644. break;
  1645. }
  1646. optindex++;
  1647. break;
  1648. case eComponent_ExtensionMarker:
  1649. /* update the optional index for extensions */
  1650. optindex = (optindex + 7) & ~7;
  1651. inextension = 1;
  1652. break;
  1653. }
  1654. }
  1655. }
  1656. }
  1657. /* generate values */
  1658. void
  1659. GenFuncValue(AssignmentList_t ass, Assignment_t *av, ValueFunc_e ev)
  1660. {
  1661. char *ideref;
  1662. char *typeref;
  1663. Type_t *t;
  1664. ideref = GetName(av);
  1665. t = GetValue(ass, av->U.Value.Value)->Type;
  1666. typeref = GetTypeName(ass, t);
  1667. switch (ev) {
  1668. case eDecl:
  1669. GenDeclGeneric(ass, ideref, typeref, av->U.Value.Value, t);
  1670. break;
  1671. case eDefh:
  1672. GenDefhGeneric(ass, ideref, typeref, av->U.Value.Value, t);
  1673. break;
  1674. case eDefn:
  1675. GenDefnGeneric(ass, ideref, typeref, av->U.Value.Value, t);
  1676. break;
  1677. case eInit:
  1678. GenInitGeneric(ass, ideref, typeref, av->U.Value.Value, t);
  1679. break;
  1680. case eFinit:
  1681. break;
  1682. }
  1683. }
  1684. /* generate forward declarations */
  1685. void
  1686. GenDeclGeneric(AssignmentList_t ass, char *ideref, char *typeref, Value_t *value, Type_t *t)
  1687. {
  1688. value = GetValue(ass, value);
  1689. #if 0 // duplicate in the generated header file
  1690. switch (t->Type)
  1691. {
  1692. case eType_ObjectIdentifier:
  1693. if (t->PrivateDirectives.fOidArray || g_fOidArray)
  1694. {
  1695. output("extern ASN1objectidentifier2_t *%s;\n", ideref);
  1696. break;
  1697. }
  1698. // intentionally fall through
  1699. default:
  1700. output("extern %s %s;\n", typeref, ideref);
  1701. break;
  1702. }
  1703. #endif // 0
  1704. outputvalue0(ass, ideref, typeref, value);
  1705. }
  1706. /* generate definitions of value components */
  1707. void
  1708. GenDefhGeneric(AssignmentList_t ass, char *ideref, char *typeref, Value_t *value, Type_t *t)
  1709. {
  1710. value = GetValue(ass, value);
  1711. outputvalue1(ass, ideref, typeref, value);
  1712. }
  1713. /* generate definitions of values */
  1714. void
  1715. GenDefnGeneric(AssignmentList_t ass, char *ideref, char *typeref, Value_t *value, Type_t *t)
  1716. {
  1717. value = GetValue(ass, value);
  1718. switch (t->Type)
  1719. {
  1720. case eType_ObjectIdentifier:
  1721. if (t->PrivateDirectives.fOidPacked ||
  1722. t->PrivateDirectives.fOidArray || g_fOidArray)
  1723. {
  1724. // lonchanc: intentionally comment out the lines below
  1725. // output("ASN1objectidentifier2_t *%s = ", ideref);
  1726. // break;
  1727. return;
  1728. }
  1729. // intentionally fall through
  1730. default:
  1731. output("%s %s = ", typeref, ideref);
  1732. break;
  1733. }
  1734. outputvalue2(ass, ideref, value);
  1735. output(";\n");
  1736. }
  1737. /* generate assignments into the initialization function */
  1738. /*ARGSUSED*/
  1739. void
  1740. GenInitGeneric(AssignmentList_t ass, char *ideref, char *typeref, Value_t *value, Type_t *t)
  1741. {
  1742. outputvalue3(ass, ideref, ideref, value);
  1743. }