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.

1778 lines
51 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. extern int g_fLongNameForImported;
  5. /* get the type by resolving references */
  6. Type_t *
  7. GetType(AssignmentList_t ass, Type_t *type)
  8. {
  9. if (!type)
  10. return NULL;
  11. if (IsReferenceType(type))
  12. return GetType(ass, GetReferencedType(ass, type));
  13. return type;
  14. }
  15. /* get the type's type by resolving references */
  16. Type_e
  17. GetTypeType(AssignmentList_t ass, Type_t *type)
  18. {
  19. type = GetType(ass, type);
  20. return type ? type->Type : eType_Undefined;
  21. }
  22. /* get the type rules */
  23. TypeRules_e
  24. GetTypeRules(AssignmentList_t ass, Type_t *type)
  25. {
  26. if (!IsReferenceType(type))
  27. return type->Rules;
  28. return type->Rules | GetTypeRules(ass, GetReferencedType(ass, type));
  29. }
  30. /* get the value by resolving references */
  31. Value_t *
  32. GetValue(AssignmentList_t ass, Value_t *value)
  33. {
  34. Assignment_t *a;
  35. if (!value)
  36. return NULL;
  37. if (!value->Type) {
  38. a = GetAssignment(ass, FindAssignment(ass, eAssignment_Value,
  39. value->U.Reference.Identifier, value->U.Reference.Module));
  40. if (!a)
  41. return NULL;
  42. return GetValue(ass, a->U.Value.Value);
  43. }
  44. return value;
  45. }
  46. /* get the object class by resolving references */
  47. ObjectClass_t *
  48. GetObjectClass(AssignmentList_t ass, ObjectClass_t *oc)
  49. {
  50. Assignment_t *a;
  51. FieldSpec_t *fs;
  52. ObjectClass_t *oc2;
  53. if (!oc)
  54. return NULL;
  55. switch (oc->Type) {
  56. case eObjectClass_Reference:
  57. a = GetAssignment(ass, FindAssignment(ass, eAssignment_ObjectClass,
  58. oc->U.Reference.Identifier, oc->U.Reference.Module));
  59. if (!a)
  60. return NULL;
  61. return GetObjectClass(ass, a->U.ObjectClass.ObjectClass);
  62. case eObjectClass_FieldReference:
  63. oc2 = GetObjectClass(ass, oc->U.FieldReference.ObjectClass);
  64. if (!oc2)
  65. return NULL;
  66. fs = GetFieldSpec(ass, FindFieldSpec(oc2->U.ObjectClass.FieldSpec,
  67. oc->U.FieldReference.Identifier));
  68. if (!fs)
  69. return NULL;
  70. if (fs->Type == eFieldSpec_Object)
  71. return GetObjectClass(ass, fs->U.Object.ObjectClass);
  72. else if (fs->Type == eFieldSpec_ObjectSet)
  73. return GetObjectClass(ass, fs->U.ObjectSet.ObjectClass);
  74. else
  75. return NULL;
  76. }
  77. return oc;
  78. }
  79. /* get the object by resolving references */
  80. Object_t *
  81. GetObject(AssignmentList_t ass, Object_t *o)
  82. {
  83. Assignment_t *a;
  84. if (!o)
  85. return NULL;
  86. if (o->Type == eObject_Reference) {
  87. a = GetAssignment(ass, FindAssignment(ass, eAssignment_Object,
  88. o->U.Reference.Identifier, o->U.Reference.Module));
  89. if (!a)
  90. return NULL;
  91. return GetObject(ass, a->U.Object.Object);
  92. }
  93. return o;
  94. }
  95. /* get the object set by resolving references */
  96. ObjectSet_t *
  97. GetObjectSet(AssignmentList_t ass, ObjectSet_t *os)
  98. {
  99. Assignment_t *a;
  100. if (!os)
  101. return NULL;
  102. if (os->Type == eObjectSet_Reference) {
  103. a = GetAssignment(ass, FindAssignment(ass, eAssignment_ObjectSet,
  104. os->U.Reference.Identifier, os->U.Reference.Module));
  105. if (!a)
  106. return NULL;
  107. return GetObjectSet(ass, a->U.ObjectSet.ObjectSet);
  108. }
  109. return os;
  110. }
  111. /* get the field spec */
  112. FieldSpec_t *
  113. GetFieldSpec(AssignmentList_t ass, FieldSpec_t *fs)
  114. {
  115. return fs;
  116. }
  117. /* get the field spec type */
  118. FieldSpecs_e
  119. GetFieldSpecType(AssignmentList_t ass, FieldSpec_t *fs)
  120. {
  121. return fs ? fs->Type : eFieldSpec_Undefined;
  122. }
  123. /* convert an identifier into C syntax */
  124. char *
  125. Identifier2C(char *identifier)
  126. {
  127. char buffer[256];
  128. char *p = buffer;
  129. while (*identifier) {
  130. if (isalnum(*identifier))
  131. *p++ = *identifier;
  132. else
  133. *p++ = '_';
  134. identifier++;
  135. }
  136. *p = 0;
  137. return strdup(buffer);
  138. }
  139. /* convert an identifier into C syntax */
  140. char *
  141. PIdentifier2C(char *identifier)
  142. {
  143. char buffer[256];
  144. char *p = buffer;
  145. *p++ = 'P';
  146. while (*identifier) {
  147. if (isalnum(*identifier))
  148. *p++ = *identifier;
  149. else
  150. *p++ = '_';
  151. identifier++;
  152. }
  153. *p = 0;
  154. return strdup(buffer);
  155. }
  156. /* get the integer type and the sign of an integer with the given bounds */
  157. static char *
  158. GetIType(intx_t *lb, intx_t *ub, int32_t *sign)
  159. {
  160. enum {
  161. eint8 = 1,
  162. euint8 = 2,
  163. eint16 = 4,
  164. euint16 = 8,
  165. eint32 = 16,
  166. euint32 = 32,
  167. eint64 = 64,
  168. euint64 = 128,
  169. eintx = 256,
  170. euintx = 512
  171. } type;
  172. type = (eint8 | euint8 | eint16 | euint16 | eint32 | euint32 | eintx | euintx);
  173. if (Has64Bits)
  174. type |= eint64 | euint64;
  175. if (!intxisuint8(lb) || !intxisuint8(ub))
  176. type &= ~euint8;
  177. if (!intxisuint16(lb) || !intxisuint16(ub))
  178. type &= ~euint16;
  179. if (!intxisuint32(lb) || !intxisuint32(ub))
  180. type &= ~euint32;
  181. if (!intxisuint64(lb) || !intxisuint64(ub))
  182. type &= ~euint64;
  183. if (!intxisint8(lb) || !intxisint8(ub))
  184. type &= ~eint8;
  185. if (!intxisint16(lb) || !intxisint16(ub))
  186. type &= ~eint16;
  187. if (!intxisint32(lb) || !intxisint32(ub))
  188. type &= ~eint32;
  189. if (!intxisint64(lb) || !intxisint64(ub))
  190. type &= ~eint64;
  191. if (lb->value[0] >= 0x7f || ub->value[0] >= 0x7f)
  192. type &= ~euintx;
  193. if (type & euint8) {
  194. *sign = 1;
  195. return "ASN1uint16_t"; // lonchanc: for av; original is "ASN1uint8_t";
  196. }
  197. if (type & eint8) {
  198. *sign = -1;
  199. return "ASN1int8_t";
  200. }
  201. if (type & euint16) {
  202. *sign = 1;
  203. return "ASN1uint16_t";
  204. }
  205. if (type & eint16) {
  206. *sign = -1;
  207. return "ASN1int16_t";
  208. }
  209. if (type & euint32) {
  210. *sign = 1;
  211. return "ASN1uint32_t";
  212. }
  213. if (type & eint32) {
  214. *sign = -1;
  215. return "ASN1int32_t";
  216. }
  217. if (type & euint64) {
  218. *sign = 1;
  219. return "ASN1uint64_t";
  220. }
  221. if (type & eint64) {
  222. *sign = -1;
  223. return "ASN1int64_t";
  224. }
  225. if (type & euintx) {
  226. *sign = 1;
  227. return "ASN1intx_t";
  228. }
  229. if (type & eintx) {
  230. *sign = -1;
  231. return "ASN1intx_t";
  232. }
  233. MyAbort();
  234. /*NOTREACHED*/
  235. return NULL;
  236. }
  237. /* adjust the lower and upper bound according to the value constraints in */
  238. /* the constraints list */
  239. void GetMinMax(AssignmentList_t ass, ValueConstraintList_t constraints,
  240. EndPoint_t *lower, EndPoint_t *upper)
  241. {
  242. ValueConstraint_t *vc;
  243. EndPoint_t lo, up;
  244. for (vc = constraints; vc; vc = vc->Next) {
  245. lo = vc->Lower;
  246. up = vc->Upper;
  247. if (CmpLowerEndPoint(ass, lower, &lo) > 0)
  248. *lower = lo;
  249. if (CmpUpperEndPoint(ass, upper, &up) < 0)
  250. *upper = up;
  251. }
  252. }
  253. /* get the integer type and the sign of an integer with the given bounds */
  254. char *GetIntType(AssignmentList_t ass, EndPoint_t *lower, EndPoint_t *upper, int32_t *sign)
  255. {
  256. char *inttype;
  257. if (!(lower->Flags & eEndPoint_Min) &&
  258. !(upper->Flags & eEndPoint_Max)) {
  259. inttype = GetIType(&GetValue(ass, lower->Value)->U.Integer.Value,
  260. &GetValue(ass, upper->Value)->U.Integer.Value, sign);
  261. } else {
  262. if (!(lower->Flags & eEndPoint_Min) &&
  263. intx_cmp(&GetValue(ass, lower->Value)->U.Integer.Value, &intx_0) >= 0) {
  264. inttype = UIntegerRestriction;
  265. *sign = 1;
  266. } else {
  267. inttype = IntegerRestriction;
  268. *sign = -1;
  269. }
  270. if (!strncmp(inttype, "ASN1uint", 8))
  271. *sign = 1;
  272. else if (!strncmp(inttype, "ASN1int", 7))
  273. *sign = -1;
  274. }
  275. return inttype;
  276. }
  277. /* get the integer type and the sign of an integer type */
  278. char *GetIntegerType(AssignmentList_t ass, Type_t *type, int32_t *sign)
  279. {
  280. EndPoint_t lower, upper;
  281. if (type->PrivateDirectives.fIntx)
  282. {
  283. return "ASN1intx_t";
  284. }
  285. lower.Flags = eEndPoint_Max;
  286. upper.Flags = eEndPoint_Min;
  287. GetMinMax(ass, type->PERConstraints.Value.Root, &lower, &upper);
  288. if (type->PERConstraints.Value.Type == eExtension_Extended)
  289. GetMinMax(ass, type->PERConstraints.Value.Additional,
  290. &lower, &upper);
  291. if (lower.Flags & eEndPoint_Max)
  292. lower.Flags = eEndPoint_Min;
  293. if (upper.Flags & eEndPoint_Min)
  294. upper.Flags = eEndPoint_Max;
  295. return GetIntType(ass, &lower, &upper, sign);
  296. }
  297. /* get the real type */
  298. /*ARGSUSED*/
  299. char *GetRealType(Type_t *type)
  300. {
  301. return RealRestriction;
  302. }
  303. /* get the boolean type */
  304. char *GetBooleanType()
  305. {
  306. return "ASN1bool_t";
  307. }
  308. /* get the enumerated type */
  309. char *GetEnumeratedType(AssignmentList_t ass, Type_t *type, int32_t *sign)
  310. {
  311. #if 1 // added by Microsoft
  312. return "ASN1enum_t";
  313. #else
  314. EndPoint_t lower, upper, ep;
  315. NamedNumber_t *namedNumbers;
  316. lower.Flags = eEndPoint_Max;
  317. upper.Flags = eEndPoint_Min;
  318. ep.Flags = 0;
  319. for (namedNumbers = type->U.Enumerated.NamedNumbers; namedNumbers;
  320. namedNumbers = namedNumbers->Next) {
  321. switch (namedNumbers->Type) {
  322. case eNamedNumber_Normal:
  323. ep.Value = namedNumbers->U.Normal.Value;
  324. if (CmpLowerEndPoint(ass, &lower, &ep) > 0)
  325. lower = ep;
  326. if (CmpUpperEndPoint(ass, &upper, &ep) < 0)
  327. upper = ep;
  328. break;
  329. case eNamedNumber_ExtensionMarker:
  330. break;
  331. }
  332. }
  333. if (lower.Flags & eEndPoint_Max)
  334. lower.Flags = eEndPoint_Min;
  335. if (upper.Flags & eEndPoint_Min)
  336. upper.Flags = eEndPoint_Max;
  337. return GetIntType(ass, &lower, &upper, sign);
  338. #endif
  339. }
  340. /* get the type of an choice selector */
  341. char *GetChoiceType(Type_t *type)
  342. {
  343. #if 1 // added by Microsoft
  344. return "ASN1choice_t";
  345. #else
  346. uint32_t nchoice;
  347. Component_t *components;
  348. nchoice = 0;
  349. for (components = type->U.Choice.Components; components;
  350. components = components->Next) {
  351. switch (components->Type) {
  352. case eComponent_Normal:
  353. nchoice++;
  354. break;
  355. case eComponent_ExtensionMarker:
  356. nchoice++; /* one reserved value for unknown extensions */
  357. break;
  358. default:
  359. MyAbort();
  360. }
  361. }
  362. if (nchoice < 0x100)
  363. return "ASN1uint8_t";
  364. if (nchoice < 0x10000)
  365. return "ASN1uint16_t";
  366. return "ASN1uint32_t";
  367. #endif
  368. }
  369. /* get the type of a string */
  370. char *GetStringType(AssignmentList_t ass, Type_t *type, int32_t *noctets, uint32_t *zero)
  371. {
  372. EndPoint_t lower, upper;
  373. uint32_t up;
  374. type = GetType(ass, type);
  375. *zero = type->PrivateDirectives.fLenPtr ? 0 : 1; // null terminator
  376. /* get the upper bound and zero flag of the type */
  377. switch (type->Type) {
  378. case eType_NumericString:
  379. up = 0x39;
  380. break;
  381. case eType_PrintableString:
  382. up = 0x7a;
  383. break;
  384. case eType_ISO646String:
  385. case eType_VisibleString:
  386. up = 0x7e;
  387. break;
  388. case eType_IA5String:
  389. up = 0x7f;
  390. // *zero = 0;
  391. break;
  392. case eType_UTF8String:
  393. up = 0xffff;
  394. break;
  395. case eType_BMPString:
  396. up = 0xffff;
  397. *zero = 0; // must be unbounded
  398. break;
  399. case eType_UniversalString:
  400. up = 0xffffffff;
  401. *zero = 0; // must be unbounded
  402. break;
  403. case eType_GeneralString:
  404. case eType_GraphicString:
  405. up = 0xff;
  406. break;
  407. case eType_TeletexString:
  408. up = 0xff;
  409. break;
  410. case eType_T61String:
  411. up = 0xff;
  412. break;
  413. case eType_VideotexString:
  414. up = 0xff;
  415. break;
  416. default:
  417. MyAbort();
  418. /*NOTREACHED*/
  419. }
  420. lower.Flags = eEndPoint_Max;
  421. upper.Flags = 0;
  422. upper.Value = NewValue(NULL, NewType(eType_RestrictedString));
  423. upper.Value->U.RestrictedString.Value.length = 1;
  424. upper.Value->U.RestrictedString.Value.value = &up;
  425. /* apply permitted alphabet constraints */
  426. if (type->PERConstraints.PermittedAlphabet.Type !=
  427. eExtension_Unconstrained) {
  428. GetMinMax(ass, type->PERConstraints.PermittedAlphabet.Root,
  429. &lower, &upper);
  430. if (type->PERConstraints.PermittedAlphabet.Type == eExtension_Extended)
  431. GetMinMax(ass, type->PERConstraints.PermittedAlphabet.Additional,
  432. &lower, &upper);
  433. }
  434. /* set zero flag if the resulting type rejects the 0-character */
  435. if (!(lower.Flags & eEndPoint_Max) &&
  436. *GetValue(ass, lower.Value)->U.RestrictedString.Value.value > 0)
  437. *zero = 1;
  438. /* get the number of octets needed for a character */
  439. *noctets = uint32_uoctets(
  440. *GetValue(ass, upper.Value)->U.RestrictedString.Value.value);
  441. /* if the type is marked as zero-terminated or length/value, use the */
  442. /* appropriate type */
  443. if (GetTypeRules(ass, type) & eTypeRules_ZeroTerminated)
  444. *zero = 1;
  445. else if (GetTypeRules(ass, type) & (eTypeRules_LengthPointer|eTypeRules_FixedArray))
  446. *zero = 0;
  447. /* return the correct type */
  448. if (*zero) {
  449. if (*noctets == 1)
  450. {
  451. #ifdef ENABLE_CHAR_STR_SIZE
  452. if (g_eEncodingRule == eEncoding_Packed &&
  453. type->PERTypeInfo.Root.LConstraint == ePERSTIConstraint_Constrained)
  454. {
  455. return "ASN1char_t";
  456. }
  457. else
  458. {
  459. return "ASN1ztcharstring_t";
  460. }
  461. #else
  462. return "ASN1ztcharstring_t";
  463. #endif
  464. }
  465. if (*noctets == 2)
  466. return "ASN1ztchar16string_t";
  467. *noctets = 4;
  468. return "ASN1ztchar32string_t";
  469. } else {
  470. if (*noctets == 1)
  471. return "ASN1charstring_t";
  472. if (*noctets == 2)
  473. return "ASN1char16string_t";
  474. *noctets = 4;
  475. return "ASN1char32string_t";
  476. }
  477. }
  478. /* check if a type is a restricted string type */
  479. int IsRestrictedString(Type_e type)
  480. {
  481. return
  482. type == eType_NumericString ||
  483. type == eType_PrintableString ||
  484. type == eType_TeletexString ||
  485. type == eType_T61String ||
  486. type == eType_VideotexString ||
  487. type == eType_IA5String ||
  488. type == eType_GraphicString ||
  489. type == eType_VisibleString ||
  490. type == eType_ISO646String ||
  491. type == eType_GeneralString ||
  492. type == eType_UniversalString ||
  493. type == eType_BMPString ||
  494. type == eType_RestrictedString;
  495. }
  496. /* create a reference to a value */
  497. char *Reference(char *p)
  498. {
  499. char *q;
  500. if (*p == '*')
  501. return p + 1;
  502. q = (char *)malloc(strlen(p) + 2);
  503. *q = '&';
  504. strcpy(q + 1, p);
  505. return q;
  506. }
  507. /* create a dereference to a value */
  508. char *Dereference(char *p)
  509. {
  510. char *q;
  511. if (*p == '&')
  512. return p + 1;
  513. q = (char *)malloc(strlen(p) + 2);
  514. *q = '*';
  515. strcpy(q + 1, p);
  516. return q;
  517. }
  518. /* get the name of a type */
  519. char *GetTypeName(AssignmentList_t ass, Type_t *t)
  520. {
  521. Assignment_t *a;
  522. int32_t noctets;
  523. uint32_t zero;
  524. int32_t sign;
  525. char buf[256];
  526. char *p;
  527. switch (t->Type) {
  528. case eType_Boolean:
  529. return GetBooleanType();
  530. case eType_Integer:
  531. return GetIntegerType(ass, t, &sign);
  532. case eType_BitString:
  533. return "ASN1bitstring_t";
  534. case eType_OctetString:
  535. return "ASN1octetstring_t";
  536. case eType_UTF8String:
  537. return "ASN1wstring_t";
  538. case eType_Null:
  539. MyAbort();
  540. /*NOTREACHED*/
  541. case eType_ObjectIdentifier:
  542. if (t->PrivateDirectives.fOidPacked)
  543. {
  544. return "ASN1encodedOID_t";
  545. }
  546. return t->PrivateDirectives.fOidArray ? "ASN1objectidentifier2_t" : "ASN1objectidentifier_t";
  547. case eType_Real:
  548. return GetRealType(t);
  549. case eType_Enumerated:
  550. return GetEnumeratedType(ass, t, &sign);
  551. case eType_EmbeddedPdv:
  552. return "ASN1embeddedpdv_t";
  553. case eType_Sequence:
  554. case eType_SequenceOf:
  555. case eType_Set:
  556. case eType_SetOf:
  557. case eType_Choice:
  558. case eType_InstanceOf:
  559. MyAbort();
  560. /*NOTREACHED*/
  561. case eType_NumericString:
  562. case eType_PrintableString:
  563. case eType_VisibleString:
  564. case eType_ISO646String:
  565. case eType_GraphicString:
  566. case eType_GeneralString:
  567. case eType_IA5String:
  568. case eType_UniversalString:
  569. case eType_BMPString:
  570. case eType_TeletexString:
  571. case eType_T61String:
  572. case eType_VideotexString:
  573. return GetStringType(ass, t, &noctets, &zero);
  574. case eType_UTCTime:
  575. return "ASN1utctime_t";
  576. case eType_GeneralizedTime:
  577. return "ASN1generalizedtime_t";
  578. case eType_ObjectDescriptor:
  579. return "ASN1objectdescriptor_t";
  580. case eType_External:
  581. return "ASN1external_t";
  582. case eType_CharacterString:
  583. return "ASN1characterstring_t";
  584. /*NOTREACHED*/
  585. case eType_Selection:
  586. MyAbort();
  587. /*NOTREACHED*/
  588. case eType_Reference:
  589. a = FindAssignment(ass, eAssignment_Type,
  590. t->U.Reference.Identifier, t->U.Reference.Module);
  591. return GetName(a);
  592. case eType_FieldReference:
  593. p = GetObjectClassName(ass, t->U.FieldReference.ObjectClass);
  594. sprintf(buf, "%s_%s", p, t->U.FieldReference.Identifier);
  595. return Identifier2C(buf);
  596. case eType_RestrictedString:
  597. MyAbort();
  598. /*NOTREACHED*/
  599. case eType_Open:
  600. return "ASN1open_t";
  601. case eType_Undefined:
  602. MyAbort();
  603. /*NOTREACHED*/
  604. }
  605. /*NOTREACHED*/
  606. return NULL;
  607. }
  608. /* get the name of a type */
  609. char *PGetTypeName(AssignmentList_t ass, Type_t *t)
  610. {
  611. Assignment_t *a;
  612. if (t->Type == eType_Reference)
  613. {
  614. a = FindAssignment(ass, eAssignment_Type,
  615. t->U.Reference.Identifier, t->U.Reference.Module);
  616. return IsPSetOfType(ass, a) ? PGetName(ass, a) : GetName(a);
  617. }
  618. return GetTypeName(ass, t);
  619. }
  620. /* get the name of a value */
  621. char *GetValueName(AssignmentList_t ass, Value_t *value)
  622. {
  623. Assignment_t *a;
  624. if (value->Type)
  625. MyAbort();
  626. a = FindAssignment(ass, eAssignment_Value,
  627. value->U.Reference.Identifier, value->U.Reference.Module);
  628. return GetName(a);
  629. }
  630. /* get the name of an object class */
  631. char *GetObjectClassName(AssignmentList_t ass, ObjectClass_t *oc)
  632. {
  633. Assignment_t *a;
  634. switch (oc->Type) {
  635. case eObjectClass_Reference:
  636. a = FindAssignment(ass, eAssignment_ObjectClass,
  637. oc->U.Reference.Identifier, oc->U.Reference.Module);
  638. return GetName(a);
  639. default:
  640. MyAbort();
  641. /*NOTREACHED*/
  642. }
  643. return NULL;
  644. }
  645. /* check if a type is of structured type */
  646. int IsStructuredType(Type_t *type)
  647. {
  648. switch (type->Type) {
  649. case eType_Sequence:
  650. case eType_SequenceOf:
  651. case eType_Set:
  652. case eType_SetOf:
  653. case eType_Choice:
  654. case eType_InstanceOf:
  655. return 1;
  656. default:
  657. return 0;
  658. }
  659. }
  660. /* check if a type is of sequence type */
  661. int IsSequenceType(Type_t *type)
  662. {
  663. switch (type->Type) {
  664. case eType_Sequence:
  665. case eType_Set:
  666. case eType_Choice:
  667. case eType_Real:
  668. case eType_External:
  669. case eType_EmbeddedPdv:
  670. case eType_CharacterString:
  671. case eType_InstanceOf:
  672. return 1;
  673. default:
  674. return 0;
  675. }
  676. }
  677. /* check if a type is a reference type */
  678. int IsReferenceType(Type_t *type)
  679. {
  680. switch (type->Type) {
  681. case eType_Reference:
  682. case eType_FieldReference:
  683. return 1;
  684. default:
  685. return 0;
  686. }
  687. }
  688. /* get the tag of a type */
  689. Tag_t *GetTag(AssignmentList_t ass, Type_t *type)
  690. {
  691. Type_t *type2;
  692. for (;;) {
  693. if (type->Tags || !IsReferenceType(type))
  694. return type->Tags;
  695. type2 = GetReferencedType(ass, type);
  696. /*XXX self-referencing types will idle forever */
  697. if (type == type2)
  698. {
  699. ASSERT(0);
  700. return NULL;
  701. }
  702. type = type2;
  703. }
  704. /*NOTREACHED*/
  705. }
  706. /* get the number of octets of a C type */
  707. int32_t GetOctets(char *inttype)
  708. {
  709. if (!strcmp(inttype, "ASN1uint8_t"))
  710. return sizeof(ASN1uint8_t);
  711. if (!strcmp(inttype, "ASN1uint16_t"))
  712. return sizeof(ASN1uint16_t);
  713. if (!strcmp(inttype, "ASN1uint32_t"))
  714. return sizeof(ASN1uint32_t);
  715. if (!strcmp(inttype, "ASN1uint64_t"))
  716. return 8;
  717. if (!strcmp(inttype, "ASN1int8_t"))
  718. return sizeof(ASN1int8_t);
  719. if (!strcmp(inttype, "ASN1int16_t"))
  720. return sizeof(ASN1int16_t);
  721. if (!strcmp(inttype, "ASN1int32_t"))
  722. return sizeof(ASN1int32_t);
  723. if (!strcmp(inttype, "ASN1int64_t"))
  724. return 8;
  725. if (!strcmp(inttype, "ASN1intx_t"))
  726. return 0;
  727. if (!strcmp(inttype, "ASN1bool_t"))
  728. return sizeof(ASN1bool_t);
  729. if (!strcmp(inttype, "ASN1char_t"))
  730. return sizeof(ASN1char_t);
  731. if (!strcmp(inttype, "ASN1char16_t"))
  732. return sizeof(ASN1char16_t);
  733. if (!strcmp(inttype, "ASN1char32_t"))
  734. return sizeof(ASN1char32_t);
  735. if (!strcmp(inttype, "double"))
  736. return 8;
  737. if (!strcmp(inttype, "ASN1real_t"))
  738. return 0;
  739. // added by Microsoft
  740. if (!strcmp(inttype, "ASN1enum_t"))
  741. return sizeof(ASN1enum_t);
  742. if (!strcmp(inttype, "ASN1choice_t"))
  743. return sizeof(ASN1choice_t);
  744. MyAbort();
  745. /*NOTREACHED*/
  746. return 0;
  747. }
  748. /* compare two values; return 0 if equal */
  749. int CmpValue(AssignmentList_t ass, Value_t *v1, Value_t *v2)
  750. {
  751. uint32_t i;
  752. int32_t d;
  753. Type_e t1, t2;
  754. v1 = GetValue(ass, v1);
  755. v2 = GetValue(ass, v2);
  756. t1 = GetTypeType(ass, v1->Type);
  757. t2 = GetTypeType(ass, v2->Type);
  758. if (t1 == eType_Integer && t2 == eType_Integer) {
  759. return intx_cmp(&v1->U.Integer.Value, &v2->U.Integer.Value);
  760. }
  761. if (t1 == eType_ObjectIdentifier && t2 == eType_ObjectIdentifier) {
  762. d = v1->U.ObjectIdentifier.Value.length -
  763. v2->U.ObjectIdentifier.Value.length;
  764. if (d)
  765. return d;
  766. for (i = 0; i < v1->U.ObjectIdentifier.Value.length; i++) {
  767. d = v1->U.ObjectIdentifier.Value.value[i] -
  768. v2->U.ObjectIdentifier.Value.value[i];
  769. if (d)
  770. return d;
  771. }
  772. return 0;
  773. }
  774. if (IsRestrictedString(t1) && IsRestrictedString(t2)) {
  775. if (v1->U.RestrictedString.Value.length != 1 ||
  776. v2->U.RestrictedString.Value.length != 1)
  777. MyAbort();
  778. if (*v1->U.RestrictedString.Value.value <
  779. *v2->U.RestrictedString.Value.value)
  780. return -1;
  781. if (*v1->U.RestrictedString.Value.value >
  782. *v2->U.RestrictedString.Value.value)
  783. return 1;
  784. return 0;
  785. }
  786. MyAbort();
  787. /*NOTREACHED*/
  788. return 1; // not equal
  789. }
  790. /* substract two values (integer/character) */
  791. int SubstractValues(AssignmentList_t ass, intx_t *diff, Value_t *v1, Value_t *v2)
  792. {
  793. v1 = GetValue(ass, v1);
  794. v2 = GetValue(ass, v2);
  795. switch (GetTypeType(ass, v1->Type)) {
  796. case eType_Integer:
  797. intx_sub(diff, &v1->U.Integer.Value, &v2->U.Integer.Value);
  798. return 1;
  799. default:
  800. if (IsRestrictedString(GetTypeType(ass, v1->Type))) {
  801. if (v1->U.RestrictedString.Value.length != 1 ||
  802. v2->U.RestrictedString.Value.length != 1)
  803. return 0;
  804. intx_setuint32(diff, v2->U.RestrictedString.Value.value[0] -
  805. v1->U.RestrictedString.Value.value[0]);
  806. return 1;
  807. }
  808. break;
  809. }
  810. MyAbort();
  811. /*NOTREACHED*/
  812. return 0;
  813. }
  814. /* get the lower endpoint; adjust endpoint if the endpoint is "open" */
  815. /* (means "not including the value") */
  816. EndPoint_t *GetLowerEndPoint(AssignmentList_t ass, EndPoint_t *e)
  817. {
  818. EndPoint_t *newe;
  819. Type_t *type;
  820. if ((e->Flags & eEndPoint_Min) || !(e->Flags & eEndPoint_Open))
  821. return e;
  822. type = GetType(ass, GetValue(ass, e->Value)->Type);
  823. switch (type->Type) {
  824. case eType_Integer:
  825. newe = NewEndPoint();
  826. newe->Value = NewValue(ass, type);
  827. intx_add(&newe->Value->U.Integer.Value, &e->Value->U.Integer.Value,
  828. &intx_1);
  829. return newe;
  830. case eType_NumericString:
  831. case eType_PrintableString:
  832. case eType_TeletexString:
  833. case eType_T61String:
  834. case eType_VideotexString:
  835. case eType_IA5String:
  836. case eType_GraphicString:
  837. case eType_VisibleString:
  838. case eType_ISO646String:
  839. case eType_GeneralString:
  840. case eType_UniversalString:
  841. case eType_BMPString:
  842. case eType_RestrictedString:
  843. newe = NewEndPoint();
  844. newe->Value = NewValue(ass, type);
  845. newe->Value->U.RestrictedString.Value.length = 1;
  846. newe->Value->U.RestrictedString.Value.value =
  847. (char32_t *)malloc(sizeof(char32_t));
  848. *newe->Value->U.RestrictedString.Value.value =
  849. *e->Value->U.RestrictedString.Value.value + 1;
  850. return newe;
  851. default:
  852. return e;
  853. }
  854. }
  855. /* get the upper endpoint; adjust endpoint if the endpoint is "open" */
  856. /* (means "not including the value") */
  857. EndPoint_t *GetUpperEndPoint(AssignmentList_t ass, EndPoint_t *e)
  858. {
  859. EndPoint_t *newe;
  860. Type_t *type;
  861. if ((e->Flags & eEndPoint_Max) || !(e->Flags & eEndPoint_Open))
  862. return e;
  863. type = GetType(ass, GetValue(ass, e->Value)->Type);
  864. switch (type->Type) {
  865. case eType_Integer:
  866. newe = NewEndPoint();
  867. newe->Value = NewValue(ass, type);
  868. intx_sub(&newe->Value->U.Integer.Value, &e->Value->U.Integer.Value,
  869. &intx_1);
  870. return newe;
  871. case eType_NumericString:
  872. case eType_PrintableString:
  873. case eType_TeletexString:
  874. case eType_T61String:
  875. case eType_VideotexString:
  876. case eType_IA5String:
  877. case eType_GraphicString:
  878. case eType_VisibleString:
  879. case eType_ISO646String:
  880. case eType_GeneralString:
  881. case eType_UniversalString:
  882. case eType_BMPString:
  883. case eType_RestrictedString:
  884. newe = NewEndPoint();
  885. newe->Value = NewValue(ass, type);
  886. newe->Value->U.RestrictedString.Value.length = 1;
  887. newe->Value->U.RestrictedString.Value.value =
  888. (char32_t *)malloc(sizeof(char32_t));
  889. *newe->Value->U.RestrictedString.Value.value =
  890. *e->Value->U.RestrictedString.Value.value - 1;
  891. return newe;
  892. default:
  893. return e;
  894. }
  895. }
  896. /* compare two lower endpoints */
  897. int CmpLowerEndPoint(AssignmentList_t ass, EndPoint_t *e1, EndPoint_t *e2)
  898. {
  899. int ret;
  900. e1 = GetLowerEndPoint(ass, e1);
  901. e2 = GetLowerEndPoint(ass, e2);
  902. if (e1->Flags & eEndPoint_Min) {
  903. if (e2->Flags & eEndPoint_Min)
  904. return 0;
  905. return -1;
  906. } else if (e2->Flags & eEndPoint_Min) {
  907. return 1;
  908. } else if (e1->Flags & eEndPoint_Max) {
  909. if (e2->Flags & eEndPoint_Max)
  910. return 0;
  911. return 1;
  912. } else if (e2->Flags & eEndPoint_Max) {
  913. return -1;
  914. } else {
  915. ret = CmpValue(ass, e1->Value, e2->Value);
  916. if (ret != 0)
  917. return ret;
  918. if (e1->Flags & eEndPoint_Open) {
  919. if (e2->Flags & eEndPoint_Open)
  920. return 0;
  921. else
  922. return 1;
  923. } else {
  924. if (e2->Flags & eEndPoint_Open)
  925. return -1;
  926. else
  927. return 0;
  928. }
  929. }
  930. }
  931. /* compare two upper endpoints */
  932. int CmpUpperEndPoint(AssignmentList_t ass, EndPoint_t *e1, EndPoint_t *e2)
  933. {
  934. int ret;
  935. e1 = GetUpperEndPoint(ass, e1);
  936. e2 = GetUpperEndPoint(ass, e2);
  937. if (e1->Flags & eEndPoint_Min) {
  938. if (e2->Flags & eEndPoint_Min)
  939. return 0;
  940. return -1;
  941. } else if (e2->Flags & eEndPoint_Min) {
  942. return 1;
  943. } else if (e1->Flags & eEndPoint_Max) {
  944. if (e2->Flags & eEndPoint_Max)
  945. return 0;
  946. return 1;
  947. } else if (e2->Flags & eEndPoint_Max) {
  948. return -1;
  949. } else {
  950. ret = CmpValue(ass, e1->Value, e2->Value);
  951. if (ret != 0)
  952. return ret;
  953. if (e1->Flags & eEndPoint_Open) {
  954. if (e2->Flags & eEndPoint_Open)
  955. return 0;
  956. else
  957. return -1;
  958. } else {
  959. if (e2->Flags & eEndPoint_Open)
  960. return 1;
  961. else
  962. return 0;
  963. }
  964. }
  965. }
  966. /* compare a lower and an upper endpoints */
  967. int CmpLowerUpperEndPoint(AssignmentList_t ass, EndPoint_t *e1, EndPoint_t *e2)
  968. {
  969. int ret;
  970. e1 = GetLowerEndPoint(ass, e1);
  971. e2 = GetUpperEndPoint(ass, e2);
  972. if (e1->Flags & eEndPoint_Min) {
  973. if (e2->Flags & eEndPoint_Min)
  974. return 0;
  975. return -1;
  976. } else if (e2->Flags & eEndPoint_Min) {
  977. return 1;
  978. } else if (e1->Flags & eEndPoint_Max) {
  979. if (e2->Flags & eEndPoint_Max)
  980. return 0;
  981. return 1;
  982. } else if (e2->Flags & eEndPoint_Max) {
  983. return -1;
  984. } else {
  985. ret = CmpValue(ass, e1->Value, e2->Value);
  986. if (ret != 0)
  987. return ret;
  988. if ((e1->Flags & eEndPoint_Open) || (e2->Flags & eEndPoint_Open))
  989. return 1;
  990. else
  991. return 0;
  992. }
  993. }
  994. /* check whether two EndPoint_t's join together */
  995. int CheckEndPointsJoin(AssignmentList_t ass, EndPoint_t *e1, EndPoint_t *e2)
  996. {
  997. intx_t ix;
  998. Value_t *v1, *v2;
  999. /* check if endpoints overlap */
  1000. if (CmpLowerUpperEndPoint(ass, e2, e1) <= 0)
  1001. return 1;
  1002. e1 = GetUpperEndPoint(ass, e1);
  1003. e2 = GetLowerEndPoint(ass, e2);
  1004. v1 = GetValue(ass, e1->Value);
  1005. v2 = GetValue(ass, e2->Value);
  1006. switch (GetTypeType(ass, v1->Type)) {
  1007. case eType_Integer:
  1008. /* check for subsequent integers */
  1009. intx_dup(&ix, &v1->U.Integer.Value);
  1010. intx_inc(&ix);
  1011. return intx_cmp(&ix, &v2->U.Integer.Value) >= 0;
  1012. case eType_NumericString:
  1013. case eType_PrintableString:
  1014. case eType_TeletexString:
  1015. case eType_T61String:
  1016. case eType_VideotexString:
  1017. case eType_IA5String:
  1018. case eType_GraphicString:
  1019. case eType_VisibleString:
  1020. case eType_ISO646String:
  1021. case eType_GeneralString:
  1022. case eType_UniversalString:
  1023. case eType_BMPString:
  1024. case eType_RestrictedString:
  1025. /* reject multiple characters */
  1026. if (v1->U.RestrictedString.Value.length != 1 ||
  1027. v2->U.RestrictedString.Value.length != 1)
  1028. MyAbort();
  1029. /* beware of wrap around */
  1030. if (v1->U.RestrictedString.Value.value[0] == 0xffffffff &&
  1031. v2->U.RestrictedString.Value.value[0] == 0)
  1032. return 0;
  1033. /* check for subsequent characters */
  1034. return v2->U.RestrictedString.Value.value[0] -
  1035. v1->U.RestrictedString.Value.value[0] == 1;
  1036. }
  1037. MyAbort();
  1038. /*NOTREACHED*/
  1039. return 0;
  1040. }
  1041. /* compare two module identifiers; return 0 if equal */
  1042. int CmpModuleIdentifier(AssignmentList_t ass, ModuleIdentifier_t *mod1, ModuleIdentifier_t *mod2)
  1043. {
  1044. if (mod1->ObjectIdentifier && mod2->ObjectIdentifier)
  1045. return CmpValue(ass, mod1->ObjectIdentifier, mod2->ObjectIdentifier);
  1046. if (mod1->Identifier && mod2->Identifier)
  1047. return strcmp(mod1->Identifier, mod2->Identifier);
  1048. return 0;
  1049. }
  1050. /* get the name of an assignment */
  1051. char *GetNameEx(AssignmentList_t ass, AssignmentList_t a, int fPSetOf)
  1052. {
  1053. char *p;
  1054. char *ide;
  1055. char *mod;
  1056. if (a->Type == eAssignment_Type &&
  1057. a->U.Type.Type && a->U.Type.Type->PrivateDirectives.pszTypeName)
  1058. {
  1059. if (fPSetOf && IsPSetOfType(ass, a))
  1060. {
  1061. ide = PIdentifier2C(a->U.Type.Type->PrivateDirectives.pszTypeName);
  1062. }
  1063. else
  1064. {
  1065. ide = Identifier2C(a->U.Type.Type->PrivateDirectives.pszTypeName);
  1066. }
  1067. }
  1068. else
  1069. {
  1070. if (fPSetOf && IsPSetOfType(ass, a))
  1071. {
  1072. ide = PIdentifier2C(a->Identifier);
  1073. }
  1074. else
  1075. {
  1076. ide = Identifier2C(a->Identifier);
  1077. }
  1078. }
  1079. // LONCHANC: disable the following code per MikeV.
  1080. if (g_fLongNameForImported)
  1081. {
  1082. if (!(a->Flags & eAssignmentFlags_LongName))
  1083. return ide;
  1084. mod = Identifier2C(a->Module->Identifier);
  1085. p = (char *)malloc(strlen(mod) + strlen(ide) + 2);
  1086. sprintf(p, "%s_%s", mod, ide);
  1087. return p;
  1088. }
  1089. else
  1090. {
  1091. return ide;
  1092. }
  1093. }
  1094. /* get the name of an assignment */
  1095. char *GetName(AssignmentList_t a)
  1096. {
  1097. return GetNameEx(NULL, a, 0);
  1098. }
  1099. char *PGetName(AssignmentList_t ass, AssignmentList_t a)
  1100. {
  1101. return GetNameEx(ass, a, 1);
  1102. }
  1103. /* convert a 32 bit string into a generalized time */
  1104. int String2GeneralizedTime(generalizedtime_t *time, char32string_t *string)
  1105. {
  1106. char str[64];
  1107. unsigned i;
  1108. if (string->length > 63 || string->length < 10)
  1109. return 0;
  1110. for (i = 0; i < string->length; i++)
  1111. str[i] = (char)string->value[i];
  1112. str[i] = 0;
  1113. return string2generalizedtime(time, str);
  1114. }
  1115. /* convert a 32 bit string into an utc time */
  1116. int String2UTCTime(utctime_t *time, char32string_t *string)
  1117. {
  1118. char str[64];
  1119. unsigned i;
  1120. if (string->length > 63 || string->length < 10)
  1121. return 0;
  1122. for (i = 0; i < string->length; i++)
  1123. str[i] = (char)string->value[i];
  1124. str[i] = 0;
  1125. return string2utctime(time, str);
  1126. }
  1127. /* build an intersection of two constraints */
  1128. void IntersectConstraints(Constraint_t **ret, Constraint_t *c1, Constraint_t *c2)
  1129. {
  1130. ElementSetSpec_t *e;
  1131. if (!c2) {
  1132. *ret = c1;
  1133. return;
  1134. }
  1135. if (!c1) {
  1136. *ret = c2;
  1137. return;
  1138. }
  1139. *ret = NewConstraint();
  1140. if (!c1->Root) {
  1141. (*ret)->Root = c2->Root;
  1142. } else if (!c2->Root) {
  1143. (*ret)->Root = c1->Root;
  1144. } else {
  1145. (*ret)->Root = e = NewElementSetSpec(eElementSetSpec_Intersection);
  1146. e->U.Intersection.Elements1 = c1->Root;
  1147. e->U.Intersection.Elements2 = c2->Root;
  1148. }
  1149. if (c1->Type > c2->Type)
  1150. (*ret)->Type = c1->Type;
  1151. else
  1152. (*ret)->Type = c2->Type;
  1153. if ((*ret)->Type == eExtension_Extended) {
  1154. if (c1->Type != eExtension_Extended || !c1->Additional) {
  1155. (*ret)->Additional = c2->Additional;
  1156. } else if (c2->Type != eExtension_Extended || !c2->Additional) {
  1157. (*ret)->Additional = c1->Additional;
  1158. } else {
  1159. (*ret)->Additional = e =
  1160. NewElementSetSpec(eElementSetSpec_Intersection);
  1161. e->U.Intersection.Elements1 = c1->Additional;
  1162. e->U.Intersection.Elements2 = c2->Additional;
  1163. }
  1164. }
  1165. }
  1166. /* find a field spec by name of an object class */
  1167. FieldSpec_t *GetObjectClassField(AssignmentList_t ass, ObjectClass_t *oc, char *field)
  1168. {
  1169. oc = GetObjectClass(ass, oc);
  1170. if (!oc)
  1171. return NULL;
  1172. return GetFieldSpec(ass, FindFieldSpec(oc->U.ObjectClass.FieldSpec, field));
  1173. }
  1174. /* find a field spec by name list of an object class */
  1175. FieldSpec_t *GetFieldSpecFromObjectClass(AssignmentList_t ass, ObjectClass_t *oc, StringList_t sl)
  1176. {
  1177. FieldSpec_t *fs;
  1178. for (; sl; sl = sl->Next) {
  1179. fs = GetObjectClassField(ass, oc, sl->String);
  1180. if (!fs)
  1181. return NULL;
  1182. if (!sl->Next)
  1183. return fs;
  1184. if (fs->Type == eFieldSpec_Object)
  1185. oc = fs->U.Object.ObjectClass;
  1186. else if (fs->Type == eFieldSpec_ObjectSet)
  1187. oc = fs->U.ObjectSet.ObjectClass;
  1188. else
  1189. return NULL;
  1190. }
  1191. return NULL;
  1192. }
  1193. /* get the default setting of a field spec */
  1194. static Setting_t *GetDefaultSetting(FieldSpec_t *fs)
  1195. {
  1196. Setting_t *ret = NULL;
  1197. Optionality_t *op;
  1198. switch (fs->Type) {
  1199. case eFieldSpec_Type:
  1200. op = fs->U.Type.Optionality;
  1201. if (op && op->Type == eOptionality_Default_Type) {
  1202. ret = NewSetting(eSetting_Type);
  1203. ret->Identifier = fs->Identifier;
  1204. ret->U.Type.Type = op->U.Type;
  1205. }
  1206. break;
  1207. case eFieldSpec_FixedTypeValue:
  1208. op = fs->U.FixedTypeValue.Optionality;
  1209. if (op && op->Type == eOptionality_Default_Value) {
  1210. ret = NewSetting(eSetting_Value);
  1211. ret->Identifier = fs->Identifier;
  1212. ret->U.Value.Value = op->U.Value;
  1213. }
  1214. break;
  1215. case eFieldSpec_VariableTypeValue:
  1216. op = fs->U.VariableTypeValue.Optionality;
  1217. if (op && op->Type == eOptionality_Default_Value) {
  1218. ret = NewSetting(eSetting_Value);
  1219. ret->Identifier = fs->Identifier;
  1220. ret->U.Value.Value = op->U.Value;
  1221. }
  1222. break;
  1223. case eFieldSpec_FixedTypeValueSet:
  1224. op = fs->U.FixedTypeValueSet.Optionality;
  1225. if (op && op->Type == eOptionality_Default_ValueSet) {
  1226. ret = NewSetting(eSetting_ValueSet);
  1227. ret->Identifier = fs->Identifier;
  1228. ret->U.ValueSet.ValueSet = op->U.ValueSet;
  1229. }
  1230. break;
  1231. case eFieldSpec_VariableTypeValueSet:
  1232. op = fs->U.VariableTypeValueSet.Optionality;
  1233. if (op && op->Type == eOptionality_Default_ValueSet) {
  1234. ret = NewSetting(eSetting_ValueSet);
  1235. ret->Identifier = fs->Identifier;
  1236. ret->U.ValueSet.ValueSet = op->U.ValueSet;
  1237. }
  1238. break;
  1239. case eFieldSpec_Object:
  1240. op = fs->U.Object.Optionality;
  1241. if (op && op->Type == eOptionality_Default_Object) {
  1242. ret = NewSetting(eSetting_Object);
  1243. ret->Identifier = fs->Identifier;
  1244. ret->U.Object.Object = op->U.Object;
  1245. }
  1246. break;
  1247. case eFieldSpec_ObjectSet:
  1248. op = fs->U.Object.Optionality;
  1249. if (op && op->Type == eOptionality_Default_ObjectSet) {
  1250. ret = NewSetting(eSetting_ObjectSet);
  1251. ret->Identifier = fs->Identifier;
  1252. ret->U.ObjectSet.ObjectSet = op->U.ObjectSet;
  1253. }
  1254. break;
  1255. default:
  1256. return NULL;
  1257. }
  1258. return ret;
  1259. }
  1260. Setting_t *GetSettingFromSettings(AssignmentList_t ass, SettingList_t se, StringList_t sl)
  1261. {
  1262. Object_t *o;
  1263. for (; sl; sl = sl->Next) {
  1264. for (; se; se = se->Next) {
  1265. if (!strcmp(se->Identifier, sl->String))
  1266. break;
  1267. }
  1268. if (!se)
  1269. return NULL;
  1270. if (!sl->Next)
  1271. return se;
  1272. if (se->Type != eSetting_Object)
  1273. return NULL;
  1274. o = GetObject(ass, se->U.Object.Object);
  1275. if (!o)
  1276. return NULL;
  1277. se = o->U.Object.Settings;
  1278. }
  1279. return NULL;
  1280. }
  1281. Setting_t *GetSettingFromObject(AssignmentList_t ass, Object_t *o, StringList_t sl)
  1282. {
  1283. FieldSpec_t *fs;
  1284. Setting_t *se;
  1285. ObjectClass_t *oc;
  1286. for (; sl; sl = sl->Next) {
  1287. o = GetObject(ass, o);
  1288. if (!o)
  1289. return NULL;
  1290. oc = GetObjectClass(ass, o->U.Object.ObjectClass);
  1291. if (!oc)
  1292. return NULL;
  1293. fs = GetFieldSpec(ass,
  1294. FindFieldSpec(oc->U.ObjectClass.FieldSpec, sl->String));
  1295. if (!fs)
  1296. return NULL;
  1297. se = FindSetting(o->U.Object.Settings, sl->String);
  1298. if (!se) {
  1299. se = GetDefaultSetting(fs);
  1300. if (!se)
  1301. return NULL;
  1302. }
  1303. if (!sl->Next)
  1304. return se;
  1305. if (fs->Type == eFieldSpec_Object && se->Type == eSetting_Object) {
  1306. o = se->U.Object.Object;
  1307. } else {
  1308. return NULL;
  1309. }
  1310. }
  1311. return NULL;
  1312. }
  1313. ObjectClass_t *GetObjectClassFromElementSetSpec(AssignmentList_t ass, ElementSetSpec_t *elems)
  1314. {
  1315. ObjectSetElement_t *ose;
  1316. Object_t *o;
  1317. ObjectSet_t *os;
  1318. switch (elems->Type) {
  1319. case eElementSetSpec_AllExcept:
  1320. return GetObjectClassFromElementSetSpec(ass,
  1321. elems->U.AllExcept.Elements);
  1322. case eElementSetSpec_Union:
  1323. case eElementSetSpec_Intersection:
  1324. case eElementSetSpec_Exclusion:
  1325. return GetObjectClassFromElementSetSpec(ass,
  1326. elems->U.UIE.Elements1);
  1327. case eElementSetSpec_SubtypeElement:
  1328. MyAbort();
  1329. /*NOTREACHED*/
  1330. case eElementSetSpec_ObjectSetElement:
  1331. ose = elems->U.ObjectSetElement.ObjectSetElement;
  1332. switch (ose->Type) {
  1333. case eObjectSetElement_Object:
  1334. o = ose->U.Object.Object;
  1335. o = GetObject(ass, o);
  1336. if (!o)
  1337. return NULL;
  1338. return o->U.Object.ObjectClass;
  1339. case eObjectSetElement_ObjectSet:
  1340. os = ose->U.ObjectSet.ObjectSet;
  1341. os = GetObjectSet(ass, os);
  1342. if (!os)
  1343. return NULL;
  1344. return os->U.ObjectSet.ObjectClass;
  1345. case eObjectSetElement_ElementSetSpec:
  1346. return GetObjectClassFromElementSetSpec(ass,
  1347. ose->U.ElementSetSpec.ElementSetSpec);
  1348. }
  1349. /*NOTREACHED*/
  1350. }
  1351. /*NOTREACHED*/
  1352. return NULL;
  1353. }
  1354. #if 0
  1355. Type_t *GetTypeFromElementSetSpec(AssignmentList_t ass, ElementSetSpec_t *elems)
  1356. {
  1357. Type_t *ret;
  1358. SubtypeElement_t *sub;
  1359. Value_t *value;
  1360. switch (elems->Type) {
  1361. case eElementSetSpec_AllExcept:
  1362. return GetTypeFromElementSetSpec(ass,
  1363. elems->U.AllExcept.Elements);
  1364. case eElementSetSpec_Union:
  1365. case eElementSetSpec_Intersection:
  1366. case eElementSetSpec_Exclusion:
  1367. ret = GetTypeFromElementSetSpec(ass, elems->U.UIE.Elements1);
  1368. if (ret)
  1369. return ret;
  1370. return GetTypeFromElementSetSpec(ass, elems->U.UIE.Elements2);
  1371. case eElementSetSpec_SubtypeElement:
  1372. sub = elems->U.SubtypeElement.SubtypeElement;
  1373. switch (sub->Type) {
  1374. case eSubtypeElement_Size:
  1375. case eSubtypeElement_PermittedAlphabet:
  1376. case eSubtypeElement_SingleType:
  1377. case eSubtypeElement_FullSpecification:
  1378. case eSubtypeElement_PartialSpecification:
  1379. return NULL;
  1380. case eSubtypeElement_Type:
  1381. return Builtin_Type_Open;
  1382. case eSubtypeElement_ContainedSubtype:
  1383. return sub->U.ContainedSubtype.Type;
  1384. case eSubtypeElement_SingleValue:
  1385. value = GetValue(ass, sub->U.SingleValue.Value);
  1386. return value->Type;
  1387. case eSubtypeElement_ValueRange:
  1388. if (!(sub->U.ValueRange.Lower.Flags & eEndPoint_Min)) {
  1389. value = GetValue(ass, sub->U.ValueRange.Lower.Value);
  1390. return value->Type;
  1391. }
  1392. if (!(sub->U.ValueRange.Upper.Flags & eEndPoint_Max)) {
  1393. value = GetValue(ass, sub->U.ValueRange.Upper.Value);
  1394. return value->Type;
  1395. }
  1396. return NULL;
  1397. case eSubtypeElement_ElementSetSpec:
  1398. return GetTypeFromElementSetSpec(ass,
  1399. sub->U.ElementSetSpec.ElementSetSpec);
  1400. }
  1401. /*NOTREACHED*/
  1402. case eElementSetSpec_ObjectSetElement:
  1403. MyAbort();
  1404. /*NOTREACHED*/
  1405. }
  1406. /*NOTREACHED*/
  1407. }
  1408. #endif
  1409. Type_t *GetTypeOfValueSet(AssignmentList_t ass, ValueSet_t *vs)
  1410. {
  1411. Type_t *ret;
  1412. Constraint_t *c;
  1413. if (!vs)
  1414. return NULL;
  1415. ret = DupType(vs->Type);
  1416. c = NewConstraint();
  1417. c->Type = eExtension_Unextended;
  1418. c->Root = vs->Elements;
  1419. IntersectConstraints(&ret->Constraints, vs->Type->Constraints, c);
  1420. return ret;
  1421. }
  1422. Value_t *GetValueFromObject(AssignmentList_t ass, Object_t *o, StringList_t sl)
  1423. {
  1424. Setting_t *se;
  1425. se = GetSettingFromObject(ass, o, sl);
  1426. if (!se)
  1427. return NULL;
  1428. if (se->Type != eSetting_Value)
  1429. return NULL; /* error */
  1430. return se->U.Value.Value;
  1431. }
  1432. ValueSet_t *GetValueSetFromObject(AssignmentList_t ass, Object_t *o, StringList_t sl)
  1433. {
  1434. Setting_t *se;
  1435. se = GetSettingFromObject(ass, o, sl);
  1436. if (!se)
  1437. return NULL;
  1438. if (se->Type != eSetting_ValueSet)
  1439. return NULL; /* error */
  1440. return se->U.ValueSet.ValueSet;
  1441. }
  1442. Type_t *GetTypeFromObject(AssignmentList_t ass, Object_t *o, StringList_t sl)
  1443. {
  1444. Setting_t *se;
  1445. se = GetSettingFromObject(ass, o, sl);
  1446. if (!se)
  1447. return NULL;
  1448. if (se->Type != eSetting_Type)
  1449. return NULL; /* error */
  1450. return se->U.Type.Type;
  1451. }
  1452. Object_t *GetObjectFromObject(AssignmentList_t ass, Object_t *o, StringList_t sl)
  1453. {
  1454. Setting_t *se;
  1455. se = GetSettingFromObject(ass, o, sl);
  1456. if (!se)
  1457. return NULL;
  1458. if (se->Type != eSetting_Object)
  1459. return NULL; /* error */
  1460. return se->U.Object.Object;
  1461. }
  1462. ObjectSet_t *GetObjectSetFromObject(AssignmentList_t ass, Object_t *o, StringList_t sl)
  1463. {
  1464. Setting_t *se;
  1465. se = GetSettingFromObject(ass, o, sl);
  1466. if (!se)
  1467. return NULL;
  1468. if (se->Type != eSetting_ObjectSet)
  1469. return NULL; /* error */
  1470. return se->U.ObjectSet.ObjectSet;
  1471. }
  1472. ElementSetSpec_t *ConvertElementSetSpecToElementSetSpec(AssignmentList_t ass, ElementSetSpec_t *elems, StringList_t sl, ElementSetSpec_t *(*fn)(AssignmentList_t ass, Object_t *o, StringList_t sl))
  1473. {
  1474. ElementSetSpec_t *ret, *e1, *e2;
  1475. ObjectSetElement_t *ose;
  1476. ret = NULL;
  1477. switch (elems->Type) {
  1478. case eElementSetSpec_AllExcept:
  1479. e1 = ConvertElementSetSpecToElementSetSpec(
  1480. ass, elems->U.AllExcept.Elements, sl, fn);
  1481. if (e1) {
  1482. ret = NewElementSetSpec(elems->Type);
  1483. ret->U.AllExcept.Elements = e1;
  1484. }
  1485. break;
  1486. case eElementSetSpec_Union:
  1487. case eElementSetSpec_Intersection:
  1488. case eElementSetSpec_Exclusion:
  1489. e1 = ConvertElementSetSpecToElementSetSpec(
  1490. ass, elems->U.UIE.Elements1, sl, fn);
  1491. e2 = ConvertElementSetSpecToElementSetSpec(
  1492. ass, elems->U.UIE.Elements2, sl, fn);
  1493. if (e1 && e2) {
  1494. ret = NewElementSetSpec(elems->Type);
  1495. ret->U.UIE.Elements1 = ConvertElementSetSpecToElementSetSpec(
  1496. ass, elems->U.UIE.Elements1, sl, fn);
  1497. ret->U.UIE.Elements2 = ConvertElementSetSpecToElementSetSpec(
  1498. ass, elems->U.UIE.Elements2, sl, fn);
  1499. } else if (e1) {
  1500. ret = e1;
  1501. } else if (e2) {
  1502. if (elems->Type == eElementSetSpec_Exclusion) {
  1503. ret = NewElementSetSpec(eElementSetSpec_AllExcept);
  1504. ret->U.AllExcept.Elements = e2;
  1505. } else {
  1506. ret = e2;
  1507. }
  1508. }
  1509. break;
  1510. case eElementSetSpec_ObjectSetElement:
  1511. ose = elems->U.ObjectSetElement.ObjectSetElement;
  1512. switch (ose->Type) {
  1513. case eObjectSetElement_Object:
  1514. ret = fn(ass, ose->U.Object.Object, sl);
  1515. break;
  1516. case eObjectSetElement_ObjectSet:
  1517. ret = ConvertObjectSetToElementSetSpec(ass,
  1518. ose->U.ObjectSet.ObjectSet, sl, fn);
  1519. break;
  1520. case eObjectSetElement_ElementSetSpec:
  1521. ret = ConvertElementSetSpecToElementSetSpec(ass,
  1522. ose->U.ElementSetSpec.ElementSetSpec, sl, fn);
  1523. break;
  1524. }
  1525. break;
  1526. case eElementSetSpec_SubtypeElement:
  1527. MyAbort();
  1528. /*NOTREACHED*/
  1529. }
  1530. return ret;
  1531. }
  1532. ElementSetSpec_t *ConvertObjectSetToElementSetSpec(AssignmentList_t ass, ObjectSet_t *os, StringList_t sl, ElementSetSpec_t *(*fn)(AssignmentList_t ass, Object_t *o, StringList_t sl))
  1533. {
  1534. os = GetObjectSet(ass, os);
  1535. if (!os)
  1536. return NULL;
  1537. return ConvertElementSetSpecToElementSetSpec(ass,
  1538. os->U.ObjectSet.Elements, sl, fn);
  1539. }
  1540. static ElementSetSpec_t *CbGetValueSetFromObjectSet(AssignmentList_t ass, Object_t *o, StringList_t sl)
  1541. {
  1542. ElementSetSpec_t *ret;
  1543. Setting_t *se;
  1544. SubtypeElement_t *sub;
  1545. se = GetSettingFromObject(ass, o, sl);
  1546. if (!se)
  1547. return NULL;
  1548. if (se->Type == eSetting_Value) {
  1549. sub = NewSubtypeElement(eSubtypeElement_SingleValue);
  1550. sub->U.SingleValue.Value = se->U.Value.Value;
  1551. ret = NewElementSetSpec(eElementSetSpec_SubtypeElement);
  1552. ret->U.SubtypeElement.SubtypeElement = sub;
  1553. return ret;
  1554. } else if (se->Type == eSetting_ValueSet) {
  1555. return se->U.ValueSet.ValueSet->Elements;
  1556. } else {
  1557. return NULL; /* error */
  1558. }
  1559. }
  1560. ValueSet_t *GetValueSetFromObjectSet(AssignmentList_t ass, ObjectSet_t *os, StringList_t sl)
  1561. {
  1562. ElementSetSpec_t *elems;
  1563. ValueSet_t *ret;
  1564. ObjectClass_t *oc;
  1565. FieldSpec_t *fs;
  1566. Type_t *type;
  1567. os = GetObjectSet(ass, os);
  1568. if (!os)
  1569. return NULL;
  1570. oc = os->U.ObjectSet.ObjectClass;
  1571. fs = GetFieldSpecFromObjectClass(ass, oc, sl);
  1572. if (!fs)
  1573. return NULL;
  1574. if (fs->Type == eFieldSpec_FixedTypeValue)
  1575. type = fs->U.FixedTypeValue.Type;
  1576. else if (fs->Type == eFieldSpec_FixedTypeValueSet)
  1577. type = fs->U.FixedTypeValueSet.Type;
  1578. else
  1579. return NULL;
  1580. elems = ConvertObjectSetToElementSetSpec(ass, os, sl,
  1581. CbGetValueSetFromObjectSet);
  1582. if (!elems)
  1583. return NULL;
  1584. ret = NewValueSet();
  1585. ret->Elements = elems;
  1586. ret->Type = type;
  1587. return ret;
  1588. }
  1589. static ElementSetSpec_t *CbGetObjectSetFromObjectSet(AssignmentList_t ass, Object_t *o, StringList_t sl)
  1590. {
  1591. ElementSetSpec_t *ret;
  1592. Setting_t *se;
  1593. ObjectSetElement_t *sub;
  1594. se = GetSettingFromObject(ass, o, sl);
  1595. if (!se)
  1596. return NULL;
  1597. if (se->Type == eSetting_Object) {
  1598. sub = NewObjectSetElement(eObjectSetElement_Object);
  1599. sub->U.Object.Object = se->U.Object.Object;
  1600. ret = NewElementSetSpec(eElementSetSpec_ObjectSetElement);
  1601. ret->U.ObjectSetElement.ObjectSetElement = sub;
  1602. return ret;
  1603. } else if (se->Type == eSetting_ObjectSet) {
  1604. return se->U.ObjectSet.ObjectSet->U.ObjectSet.Elements;
  1605. } else {
  1606. return NULL; /* error */
  1607. }
  1608. }
  1609. ObjectSet_t *GetObjectSetFromObjectSet(AssignmentList_t ass, ObjectSet_t *os, StringList_t sl)
  1610. {
  1611. ElementSetSpec_t *elems;
  1612. ObjectSet_t *ret;
  1613. elems = ConvertObjectSetToElementSetSpec(ass, os, sl,
  1614. CbGetObjectSetFromObjectSet);
  1615. if (!elems)
  1616. return NULL;
  1617. ret = NewObjectSet(eObjectSet_ObjectSet);
  1618. ret->U.ObjectSet.Elements = elems;
  1619. ret->U.ObjectSet.ObjectClass = GetObjectClassFromElementSetSpec(ass, elems);
  1620. return ret;
  1621. }
  1622. // The following is added by Microsoft
  1623. int IsPSetOfType(AssignmentList_t ass, Assignment_t *a)
  1624. {
  1625. Type_t *t2 = a->U.Type.Type;
  1626. #if 0
  1627. if (t2->Type == eType_Reference)
  1628. {
  1629. t2 = GetType(ass, t2);
  1630. }
  1631. #endif
  1632. return ((eType_SequenceOf == t2->Type || eType_SetOf == t2->Type)
  1633. &&
  1634. (t2->Rules & (eTypeRules_LinkedListMask | eTypeRules_PointerToElement))
  1635. // (t2->PrivateDirectives.fSLinked)
  1636. );
  1637. }
  1638. void MyAbort(void)
  1639. {
  1640. ASSERT(0);
  1641. abort();
  1642. }
  1643. void MyExit(int val)
  1644. {
  1645. ASSERT(0);
  1646. exit(val);
  1647. }