]> git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/compiler/core/snacc-util.c
Security-54.1.7.tar.gz
[apple/security.git] / SecuritySNACCRuntime / compiler / core / snacc-util.c
1 /*
2 * compiler/core/snacc_util.c
3 *
4 * utilities for dealing with the Module data structure
5 *
6 * AUTHOR: Mike Sample
7 * DATE: 91/09/02
8 *
9 * Copyright (C) 1991, 1992 Michael Sample
10 * and the University of British Columbia
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * $Header: /cvs/root/Security/SecuritySNACCRuntime/compiler/core/Attic/snacc-util.c,v 1.1 2001/06/20 21:27:59 dmitch Exp $
18 * $Log: snacc-util.c,v $
19 * Revision 1.1 2001/06/20 21:27:59 dmitch
20 * Adding missing snacc compiler files.
21 *
22 * Revision 1.1.1.1 1999/03/16 18:06:52 aram
23 * Originals from SMIME Free Library.
24 *
25 * Revision 1.3 1995/07/25 19:41:44 rj
26 * changed `_' to `-' in file names.
27 *
28 * Revision 1.2 1994/09/01 00:45:09 rj
29 * snacc_config.h removed.
30 *
31 * Revision 1.1 1994/08/28 09:49:39 rj
32 * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
33 *
34 */
35
36 #include <stdio.h>
37
38 #include "asn-incl.h"
39 #include "mem.h"
40 #include "asn1module.h"
41 #include "lib-types.h"
42 #include "define.h"
43 #include "snacc-util.h"
44
45
46
47 /*
48 * Allocates and initializes a type and it's basicType info
49 * used extensively by asn1.yacc
50 * (was a macro)
51 */
52 void
53 SetupType PARAMS ((t, typeId, lineNum),
54 Type **t _AND_
55 enum BasicTypeChoiceId typeId _AND_
56 unsigned long lineNum)
57 {
58 Tag **tmpPtr;
59
60 (*t) = (Type*)Malloc (sizeof (Type));
61 (*t)->lineNo = lineNum;
62 (*t)->basicType = (BasicType*)Malloc (sizeof (BasicType));
63 (*t)->basicType->choiceId = typeId;
64 (*t)->tags = (TagList*)AsnListNew (sizeof (void*));
65 if (LIBTYPE_GET_UNIV_TAG_CODE ((typeId)) != NO_TAG_CODE)
66 {
67 tmpPtr = (Tag**)AsnListAppend ((AsnList*)(*t)->tags);
68 *tmpPtr = (Tag*)Malloc (sizeof (Tag));
69 (*tmpPtr)->tclass = UNIV;
70 (*tmpPtr)->code = LIBTYPE_GET_UNIV_TAG_CODE ((typeId));
71 }
72 } /* SetupType */
73
74
75 /*
76 * Allocates and initializes a type and it's basicType to MACROTYPE
77 * and sets the MACROTYPE type to the given macrotype
78 */
79 void
80 SetupMacroType PARAMS ((t, macroTypeId, lineNum),
81 Type **t _AND_
82 enum MacroTypeChoiceId macroTypeId _AND_
83 unsigned long lineNum)
84 {
85 Tag **tmpPtr;
86
87 (*t) = MT (Type);
88 (*t)->lineNo = lineNum;
89 (*t)->basicType = MT (BasicType);
90 (*t)->basicType->choiceId = BASICTYPE_MACROTYPE;
91 (*t)->tags = (TagList*)AsnListNew (sizeof (void*));
92 (*t)->basicType->a.macroType = MT (MacroType);
93 (*t)->basicType->a.macroType->choiceId = macroTypeId;
94 } /* SetupMacroType */
95
96
97 /*
98 * similar to SetupType but for values instead
99 */
100 void
101 SetupValue PARAMS ((v, valId, lineNum),
102 Value **v _AND_
103 enum BasicValueChoiceId valId _AND_
104 unsigned long lineNum)
105 {
106 *v = (Value*)Malloc (sizeof (Value));
107 (*v)->basicValue = (BasicValue*)Malloc (sizeof (BasicValue));
108 (*v)->basicValue->choiceId = valId;
109 (*v)->lineNo = lineNum;
110 } /* SetupValue */
111
112
113 /*
114 * adds elmt with given name to module m's import list from
115 * the module with name refdModuleName. If module m does not
116 * have an import list from that module one is created.
117 * The import element is given the private scope implied
118 * by the ASN.1 modname.typ-or-val-name reference format
119 * The passed in strings (name, refdModuleName) are copied.
120 */
121 void
122 AddPrivateImportElmt PARAMS ((m, name, refdModuleName, lineNo),
123 Module *m _AND_
124 char *name _AND_
125 char *refdModuleName _AND_
126 long int lineNo)
127 {
128 ImportElmt *newElmt;
129 ImportElmt *ie;
130 ImportModule *impMod;
131
132
133 /* see if module m already imports something from "refdModule" */
134 if ((impMod = LookupImportModule (m, refdModuleName)) == NULL)
135 {
136 impMod = MT (ImportModule);
137 impMod->modId = MT (ModuleId);
138 impMod->modId->name = Malloc (strlen (refdModuleName)+1);
139 strcpy (impMod->modId->name, refdModuleName);
140
141 newElmt = MT (ImportElmt);
142 newElmt->name = Malloc (strlen (name)+1);
143 strcpy (newElmt->name, name);
144 newElmt->privateScope = TRUE;
145
146 APPEND (newElmt, impMod->importElmts);
147 APPEND (impMod, m->imports);
148 }
149 else /* module "refdModule is already imported from */
150 {
151 ie = LookupImportElmtInImportElmtList (impMod->importElmts, name);
152
153 if (ie == NULL)
154 {
155 newElmt = MT (ImportElmt);
156 newElmt->name = Malloc (strlen (name)+1);
157 strcpy (newElmt->name, name);
158 APPEND (newElmt, impMod->importElmts);
159 }
160 else if (!ie->privateScope)
161 {
162 PrintErrLoc (m->asn1SrcFileName, lineNo);
163 fprintf (stderr, "WARNING - \"%s.%s\" type/value reference refers to a type/value already in the import list that does not have private scope.\n", refdModuleName, name);
164 }
165 }
166 } /* AddPrivateImportElmt */
167
168 /*
169 * looks for the named import type/value in all of the IMPORT lists of the
170 * given module.
171 * RETURNS a ptr to the import elmt if found, NULL if it was not found.
172 * If the item was found (ptr returned) the foundImportModule addr
173 * parameter will be set to the module's importModule that holds
174 * the found elmt.
175 *
176 * returns NULL if the named import name was not found
177 *
178 */
179 ImportElmt*
180 LookupImportElmtInModule PARAMS ((m, name, foundImportModule),
181 Module *m _AND_
182 char *name _AND_
183 ImportModule **foundImportModule)
184 {
185 ImportModule *importMod;
186 ImportElmt *importElmt;
187 ImportElmt *retVal;
188 void *tmp;
189
190 if (m->imports == NULL)
191 return NULL;
192
193 tmp = (void*)CURR_LIST_NODE (m->imports);
194 retVal = NULL;
195 FOR_EACH_LIST_ELMT (importMod, m->imports)
196 {
197 importElmt = LookupImportElmtInImportElmtList (importMod->importElmts, name);
198 if (importElmt != NULL)
199 {
200 *foundImportModule = importMod;
201 retVal = importElmt;
202 break;
203 }
204 }
205
206 SET_CURR_LIST_NODE (m->imports, tmp); /* restore orig loc */
207 return retVal;
208
209 } /* LookupImportElmtInModule */
210
211
212 /*
213 * given a list of import elmts, returns ptr to the elmt with
214 * the matching name. NULL if not found
215 */
216 ImportElmt*
217 LookupImportElmtInImportElmtList PARAMS ((impElmtList, name),
218 ImportElmtList *impElmtList _AND_
219 char *name)
220
221 {
222 ImportElmt *impElmt;
223 ImportElmt *retVal;
224 void *tmp;
225
226 if (impElmtList == NULL)
227 return NULL;
228
229 tmp = (void*) CURR_LIST_NODE (impElmtList);
230 retVal = NULL;
231 FOR_EACH_LIST_ELMT (impElmt, impElmtList)
232 {
233 if (strcmp (impElmt->name, name) == 0)
234 {
235 retVal = impElmt;
236 break;
237 }
238 }
239
240 SET_CURR_LIST_NODE (impElmtList, tmp);
241 return retVal;
242
243 } /* LookupImportElmtInImportElmtList */
244
245
246
247
248 /*
249 * looks for an import list that imports from "importModuleName"
250 * module in the given module.
251 *
252 * returns a ptr to the ImportList if found
253 * returns NULL if not found
254 */
255 ImportModule*
256 LookupImportModule PARAMS ((m, importModuleName),
257 Module *m _AND_
258 char *importModuleName)
259 {
260 ImportModule *importModule;
261 ImportModule *retVal;
262 void *tmp;
263
264 if (m->imports == NULL)
265 return NULL;
266
267 tmp = (void*)CURR_LIST_NODE (m->imports);
268 retVal = NULL;
269 FOR_EACH_LIST_ELMT (importModule, m->imports)
270 {
271 if (strcmp (importModule->modId->name, importModuleName) == 0)
272 {
273 retVal= importModule;
274 break;
275 }
276 }
277
278 SET_CURR_LIST_NODE (m->imports, tmp);
279 return retVal;
280
281 } /* LookupImportModule */
282
283
284
285
286 /*
287 * Looks for the type with name matching typeName (null terminated char*)
288 * in the given the TypeDef list
289 *
290 * RETURNS: ptr to the TypeDef with the matching typeName (if any)
291 * NULL if no match was made
292 */
293 TypeDef*
294 LookupType PARAMS ((typeDefList, typeName),
295 TypeDefList *typeDefList _AND_
296 char *typeName)
297 {
298 TypeDef *td;
299 TypeDef *retVal;
300 void *tmp;
301
302 if (typeDefList == NULL)
303 return NULL;
304
305 if (typeName == NULL)
306 {
307 #ifdef DEBUG
308 fprintf (stderr,"LookupType: warning - failure due to NULL key\n");
309 #endif
310 return NULL;
311 }
312
313 tmp = (void*)CURR_LIST_NODE (typeDefList); /* remember curr list spot */
314 retVal = NULL;
315 FOR_EACH_LIST_ELMT (td, typeDefList)
316 {
317 if (strcmp (typeName, td->definedName) == 0)
318 {
319 retVal = td;
320 break;
321 }
322 }
323
324 SET_CURR_LIST_NODE (typeDefList,tmp); /* restore curr location */
325
326 return retVal;
327
328 } /* LookupType */
329
330
331 /*
332 * Returns ptr to module that has matching name or OID
333 * if oid is not null, lookup done only by oid
334 *
335 * returns NULL if no match was found
336 */
337 Module*
338 LookupModule PARAMS ((moduleList, modName, oid),
339 ModuleList *moduleList _AND_
340 char *modName _AND_
341 OID *oid)
342 {
343 Module *currMod;
344 Module *retVal;
345 int strMatch = FALSE;
346 int oidMatch = FALSE;
347 OID *oid1;
348 OID *oid2;
349 void *tmp;
350
351 if ((moduleList == NULL) || ((modName == NULL) && (oid == NULL)))
352 return NULL;
353
354 tmp = (void*)CURR_LIST_NODE (moduleList); /* remember orig loc */
355 retVal = NULL;
356 FOR_EACH_LIST_ELMT (currMod, moduleList)
357 {
358
359 /*
360 * may fail due to unresolved int or oid value ref
361 * so try name match anyway.
362 * This is not standard (CCITT) if the oids were resolved
363 * but different, in which case the match should
364 * fail regardless of the name match. oh well, ts.
365 */
366 if (CompareOids (oid, currMod->modId->oid))
367 {
368 retVal = currMod;
369 break; /* exit for loop */
370 }
371
372 else if ((modName != NULL) &&
373 (strcmp (modName, currMod->modId->name) == 0))
374 {
375 retVal = currMod;
376 break; /* exit for loop */
377 }
378 }
379
380 SET_CURR_LIST_NODE (moduleList, tmp);
381 return retVal;
382
383 } /* LookupModule */
384
385
386
387
388 /*
389 * Given a constructed type, it returns the component of that
390 * type with the matching field name. Returns NULL if teh
391 * given type does not have the named field or is not
392 * a type that has fields.
393 */
394 NamedType*
395 LookupFieldInType PARAMS ((tRef, fieldName),
396 Type *tRef _AND_
397 char *fieldName)
398 {
399 NamedType *e;
400 NamedType *retVal;
401 Type *t;
402 void *tmp;
403
404 t = ParanoidGetType (tRef); /* skip any references etc */
405
406 if ((t->basicType->choiceId != BASICTYPE_SET) &&
407 (t->basicType->choiceId != BASICTYPE_SEQUENCE) &&
408 (t->basicType->choiceId != BASICTYPE_CHOICE))
409 {
410 #ifdef DEBUG
411 fprintf (stderr,"LookupFieldInType: ERROR - attempt to look for field in a non SET/SEQ/CHOICE type\n");
412 #endif
413 return NULL;
414 }
415
416 /* return if null list */
417 if (t->basicType->a.set == NULL)
418 return NULL;
419
420 /* remember set's original curr elmt */
421 tmp = (void*)CURR_LIST_NODE (t->basicType->a.set);
422 retVal = NULL;
423 FOR_EACH_LIST_ELMT (e, t->basicType->a.set)
424 {
425 /* remember fieldname is optional so it can be null */
426 if ((e->fieldName != NULL) && (strcmp (e->fieldName, fieldName) == 0))
427 {
428 retVal = e;
429 break; /* exit for loop */
430 }
431 }
432 SET_CURR_LIST_NODE (t->basicType->a.set, tmp);
433 return retVal;
434
435 } /* LookupFieldInType */
436
437
438
439 /*
440 * Goes through typerefs (if any) to get to actual
441 * ASN1 type. Returns the found "defining" type.
442 * May return the given type t, if it's not a typeref
443 * or if it is an unlinked type ref
444 */
445 Type*
446 GetType PARAMS ((type),
447 Type *type)
448 {
449 TypeDef *td;
450 Type *t;
451
452 t = type;
453 if (t == NULL)
454 return NULL;
455
456 while (1)
457 {
458 switch (t->basicType->choiceId)
459 {
460 case BASICTYPE_LOCALTYPEREF:
461 case BASICTYPE_IMPORTTYPEREF:
462 td = t->basicType->a.localTypeRef->link;
463 if (td == NULL)
464 return type;
465 else
466 t = td->type;
467 break;
468
469 default:
470 return t;
471 }
472 }
473 } /* GetType */
474
475
476 /*
477 * like GetType ie, skips type references to return the defining type.
478 * This is a paranoid version - it checks for circular type errors.
479 * eg: A ::= B
480 * B ::= A
481 * would make the normal GetType recurse forever (until no stk mem)
482 */
483 Type*
484 ParanoidGetType PARAMS ((type),
485 Type *type)
486 {
487 TypeDef *td;
488 Type *t;
489 DefinedObj *l;
490
491 t = type;
492 if (t == NULL)
493 return NULL;
494
495 l = NewObjList();
496 while (1)
497 {
498 switch (t->basicType->choiceId)
499 {
500 case BASICTYPE_LOCALTYPEREF:
501 case BASICTYPE_IMPORTTYPEREF:
502 td = t->basicType->a.localTypeRef->link;
503 if ((td == NULL) || (ObjIsDefined (l, td->type, ObjPtrCmp)))
504 {
505 return type;
506 }
507 else
508 {
509 t = td->type;
510 DefineObj (&l, t);
511 }
512 break;
513
514 default:
515 FreeDefinedObjs (&l);
516 return t;
517 }
518 }
519
520 } /* ParnoidGetType */
521
522
523 /*
524 * Goes through typerefs (if any) to get to actual
525 * ASN1 basic type (eg int, bool, seq, seq of, set,
526 * set of, choice, any, etc.
527 * Returns the typeId of that type, otherwise -1.
528 */
529 enum BasicTypeChoiceId
530 GetBuiltinType PARAMS ((t),
531 Type *t)
532 {
533 Type *definingType;
534
535 definingType = GetType (t);
536 if (definingType != NULL)
537 return definingType->basicType->choiceId;
538 else
539 return -1;
540
541 } /* GetBuiltinType */
542
543
544 /* Paranoid version of GetBuiltinType
545 * goes through typerefs (if any) to get to actual
546 * ASN1 basic type (eg int, bool, seq, seq of, set,
547 * set of, choice, any, etc.
548 * Returns the typeId of that type, otherwise -1.
549 */
550 enum BasicTypeChoiceId
551 ParanoidGetBuiltinType PARAMS ((t),
552 Type *t)
553 {
554 Type *definingType;
555
556 definingType = ParanoidGetType (t);
557 if (definingType != NULL)
558 return definingType->basicType->choiceId;
559 else
560 return -1;
561
562 } /* GetBuiltinType */
563
564
565
566 /*
567 * Goes through typerefs (if any) to get to
568 * the namedElmts (if any) associated with the
569 * given type (INTEGER, ENUMERATED, BITSTRING or
570 * LOCAL/IMPORT REFS to these types).
571 * Returns NULL if there are no associated Named Elmts
572 */
573 NamedNumberList*
574 GetNamedElmts PARAMS ((t),
575 Type *t)
576 {
577 Type *definingType;
578
579 if (t == NULL)
580 return NULL;
581
582 definingType = ParanoidGetType (t);
583
584 if (definingType == NULL)
585 return NULL;
586
587 switch (definingType->basicType->choiceId)
588 {
589 case BASICTYPE_INTEGER:
590 case BASICTYPE_ENUMERATED:
591 case BASICTYPE_BITSTRING:
592 return definingType->basicType->a.integer;
593
594 /*
595 * for non-named elmt types
596 * just return NULL
597 */
598 default:
599 return NULL;
600 }
601
602 /* not reached */
603 } /* GetNamedElmts */
604
605
606 /*
607 * [Same as GetNamedElmts except goes through CHOICEs as well &
608 * REQUIRES you to deallocate the list (but not its members).]
609 * This is nec. for CHOICEs that contain INTs etc. with named #'s]
610 * This is used for value linking.
611 *
612 * Goes through typerefs (if any) to get to
613 * the namedElmts (if any) associated with the
614 * given type (INTEGER, ENUMERATED, BITSTRING or
615 * LOCAL/IMPORT REFS to these types). Also returns
616 * a named element list for CHOICE types that contain
617 * named elemnts
618 * Returns an empty list if there are no associated Named Elmts.
619 * you are responsible for freeing this list. Do not free the list
620 * elmts - they are part of the types.
621 */
622 NamedNumberList*
623 GetAllNamedElmts PARAMS ((t),
624 Type *t)
625 {
626 Type *definingType;
627 NamedType *nt;
628 NamedNumberList *retVal;
629 NamedNumberList *ntElmtList;
630 ValueDef *nn; /* named number is a valuedef */
631 ValueDef **nnHndl;
632
633 retVal = AsnListNew (sizeof (void*));
634
635 if (t == NULL)
636 return retVal;
637
638 definingType = ParanoidGetType (t);
639
640 if (definingType == NULL)
641 return retVal;
642
643
644 switch (definingType->basicType->choiceId)
645 {
646 case BASICTYPE_INTEGER:
647 case BASICTYPE_ENUMERATED:
648 case BASICTYPE_BITSTRING:
649 /*
650 * add the named elmts (if any) to the new list
651 */
652 FOR_EACH_LIST_ELMT (nn, definingType->basicType->a.integer)
653 {
654 nnHndl = (ValueDef**)AsnListAppend (retVal);
655 *nnHndl = nn;
656 }
657 break;
658
659 /*
660 * for choices must group all named elmts from choice components
661 * and return in a list.
662 */
663 case BASICTYPE_CHOICE:
664 FOR_EACH_LIST_ELMT (nt, definingType->basicType->a.choice)
665 {
666 ntElmtList = GetAllNamedElmts (nt->type);
667 retVal = AsnListConcat (retVal, ntElmtList);
668 Free (ntElmtList); /* zap now unused list head */
669 }
670 break;
671 }
672 return retVal;
673 } /* GetAllNamedElmts */
674
675
676 /*
677 * Recursively does pseudo breadth first search from the given ancestor
678 * looking for the given child node. Returns the direct parent Type
679 * of the child if found, NULL otherwise. This routine does not follow
680 * type references.
681 */
682 Type*
683 GetParent PARAMS ((ancestor, child),
684 Type *ancestor _AND_
685 Type *child)
686 {
687 NamedType *e;
688 Type *parent;
689 void *tmp;
690
691 if ((ancestor->basicType->choiceId != BASICTYPE_SET) &&
692 (ancestor->basicType->choiceId != BASICTYPE_SEQUENCE) &&
693 (ancestor->basicType->choiceId != BASICTYPE_CHOICE) &&
694 (ancestor->basicType->choiceId != BASICTYPE_SETOF) &&
695 (ancestor->basicType->choiceId != BASICTYPE_SEQUENCEOF))
696 {
697 return NULL;
698 }
699
700 if (ancestor->basicType->a.set == NULL)
701 return NULL;
702
703 if ((ancestor->basicType->choiceId == BASICTYPE_SETOF) ||
704 (ancestor->basicType->choiceId == BASICTYPE_SEQUENCEOF))
705 {
706 if (child == ancestor->basicType->a.setOf)
707 return ancestor;
708 else
709 return GetParent (ancestor->basicType->a.setOf, child);
710 }
711
712 tmp = (void*)CURR_LIST_NODE (ancestor->basicType->a.set);
713 /*
714 * look through direct children of ancestor first
715 */
716 FOR_EACH_LIST_ELMT (e, ancestor->basicType->a.set)
717 {
718 if (child == e->type)
719 {
720 SET_CURR_LIST_NODE (ancestor->basicType->a.set, tmp);
721 return ancestor;
722 }
723 }
724
725
726 /*
727 * look through grandchildren if not in children
728 */
729 FOR_EACH_LIST_ELMT (e, ancestor->basicType->a.set)
730 {
731 if ((parent = GetParent (e->type, child)) != NULL)
732 {
733 SET_CURR_LIST_NODE (ancestor->basicType->a.set, tmp);
734 return parent;
735 }
736 }
737
738 SET_CURR_LIST_NODE (ancestor->basicType->a.set, tmp);
739 return NULL;
740 } /* GetParent */
741
742
743
744 /*
745 * Looks for the value with the given valueName (null term char*) in the
746 * given list of ValueDefs
747 * RETURNS: ptr to ValueDef with matching key (if any)
748 * NULL if no match was made
749 */
750
751 ValueDef*
752 LookupValue PARAMS ((valueList, valueName),
753 ValueDefList *valueList _AND_
754 char *valueName)
755 {
756 ValueDef *v;
757 ValueDef *retVal;
758 void *tmp;
759
760 if (valueName == NULL)
761 {
762 #ifdef DEBUG
763 fprintf (stderr,"LookupType: warning - failure due to NULL key\n");
764 #endif
765 return NULL;
766 }
767
768 if (valueList == NULL)
769 return NULL;
770
771 tmp = (void*)CURR_LIST_NODE (valueList);
772 retVal = NULL;
773 FOR_EACH_LIST_ELMT (v, valueList)
774 {
775 if (strcmp (valueName, v->definedName) == 0)
776 {
777 retVal = v;
778 break; /* exit for loop */
779 }
780 }
781
782 SET_CURR_LIST_NODE (valueList, tmp);
783 return retVal;
784
785 } /* LookupValue */
786
787
788
789 /*
790 * Goes through valuerefs (if any) to get to actual
791 * ASN1 value. Analogous to GetType.
792 */
793 Value*
794 GetValue PARAMS ((v),
795 Value *v)
796 {
797 ValueDef *vd;
798
799 while (v != NULL)
800 {
801 switch (v->basicValue->choiceId)
802 {
803 case BASICVALUE_LOCALVALUEREF:
804 case BASICVALUE_IMPORTVALUEREF:
805 vd = v->basicValue->a.localValueRef->link;
806 if (vd == NULL)
807 v = NULL;
808 else
809 v = vd->value;
810 break;
811
812 default:
813 return v;
814 }
815 }
816 fprintf (stderr, "GetValue: ERROR - cannot get value for unlinked local/import value refs\n");
817 return NULL;
818
819 } /* GetValue */
820
821
822 /*
823 * Returns TRUE if oid1 and oid2 are identical otherwise FALSE
824 */
825 int
826 CompareOids PARAMS ((oid1, oid2),
827 OID *oid1 _AND_
828 OID *oid2)
829 {
830 if ((oid1 == NULL) && (oid2 == NULL))
831 return FALSE;
832
833 for (; (oid1 != NULL) && (oid2 != NULL); oid1 = oid1->next, oid2 = oid2->next)
834 {
835 /*
836 * fail if value refs have not been resolved or
837 * no match between arcnums
838 */
839 if ((oid1->arcNum == NULL_OID_ARCNUM) ||
840 (oid2->arcNum == NULL_OID_ARCNUM) ||
841 (oid1->arcNum != oid2->arcNum))
842 return FALSE;
843
844 /*
845 * could check ref'd values for same name
846 * incase value ref has not been resolved
847 * and put in arcNum
848 */
849 }
850
851 if ((oid1 == NULL) && (oid2 == NULL))
852 return TRUE;
853 else
854 return FALSE;
855
856 } /* CompareOids */
857
858
859 /*
860 * Returns TRUE if the given type is INTEGER, ENUMERATED or
861 * BIT STRING and it has named elements
862 * ie Foo ::= INTEGER { one (1), two (2) } would return TRUE
863 */
864 int
865 HasNamedElmts PARAMS ((t),
866 Type *t)
867 {
868 return ((t->basicType->choiceId == BASICTYPE_INTEGER) ||
869 (t->basicType->choiceId == BASICTYPE_ENUMERATED) ||
870 (t->basicType->choiceId == BASICTYPE_BITSTRING)) &&
871 (t->basicType->a.integer != NULL) &&
872 !LIST_EMPTY (t->basicType->a.integer);
873 } /* HasNamedElmts */
874
875
876 /*
877 * Returns true if the given tag lists are the same
878 * (assumes value refs have be resolved)
879 */
880 int
881 TagsAreIdentical PARAMS ((t1, t2),
882 TagList *t1 _AND_
883 TagList *t2)
884 {
885 Tag *tag1;
886 Tag *tag2;
887
888 /* both lists are empty */
889 if (((t1 == NULL) || LIST_EMPTY (t1)) &&
890 ((t2 == NULL) || LIST_EMPTY (t2)))
891 return TRUE;
892
893 else if ((t1 == NULL) || (t2 == NULL))
894 return FALSE;
895
896 else if (LIST_COUNT (t1) == LIST_COUNT (t2))
897 {
898 SET_CURR_LIST_NODE (t2, FIRST_LIST_NODE (t2));
899 FOR_EACH_LIST_ELMT (tag1, t1)
900 {
901 tag2 = (Tag*) CURR_LIST_ELMT (t2);
902 if ((tag1->tclass != tag2->tclass) || (tag1->code == tag2->code))
903 return FALSE;
904 SET_CURR_LIST_NODE (t2, NEXT_LIST_NODE (t2));
905 }
906 return TRUE;
907 }
908 else
909 return FALSE;
910
911 } /* TagsAreIdentical */
912
913
914
915 /*
916 * Returns TRUE if the tag currently on the given type has the default
917 * tag specified in the type tbl. otherwise returns FALSE.
918 */
919 int
920 HasDefaultTag PARAMS ((t),
921 Type *t)
922 {
923 Tag *firstTag = NULL;
924 int dfltCode;
925 int dfltClass;
926
927 dfltClass = UNIV;
928 dfltCode = LIBTYPE_GET_UNIV_TAG_CODE (t->basicType->choiceId);
929 if ((t->tags != NULL) && !LIST_EMPTY (t->tags))
930 firstTag = (Tag*)FIRST_LIST_ELMT (t->tags);
931
932 return ((firstTag != NULL) && (LIST_COUNT (t->tags) == 1) &&
933 (firstTag->tclass == dfltClass) && (firstTag->code == dfltCode)) ||
934 ((firstTag == NULL) && (dfltCode == NO_TAG_CODE));
935
936 } /* HasDefaultTag */
937
938
939 /*
940 * Returns TRUE if t is a primitive type or if it is
941 * defined by a reference to a primitive type
942 */
943 int
944 IsPrimitiveByDefOrRef PARAMS ((t),
945 Type *t)
946 {
947 Type *definingType;
948
949 definingType = GetType (t);
950
951 if (definingType == NULL)
952 return FALSE; /* bad error handling */
953
954 return IsPrimitiveByDef (definingType);
955 } /* IsPrimitiveByDefOrRef */
956
957
958 /*
959 * Returns TRUE if the given type is a primitive type. Does NOT
960 * follow type references - type refs are not considered primitive.
961 * The following types are considered primitive:
962 * BOOLEAN
963 * INTEGER
964 * BITSTRING
965 * OCTETSTRING
966 * NULL
967 * OID
968 * REAL
969 * ENUMERATED
970 */
971 int
972 IsPrimitiveByDef PARAMS ((t),
973 Type *t)
974 {
975 switch (t->basicType->choiceId)
976 {
977 case BASICTYPE_LOCALTYPEREF:
978 case BASICTYPE_IMPORTTYPEREF:
979 case BASICTYPE_SEQUENCE:
980 case BASICTYPE_SET:
981 case BASICTYPE_CHOICE:
982 case BASICTYPE_SEQUENCEOF:
983 case BASICTYPE_SETOF:
984 case BASICTYPE_COMPONENTSOF:
985 case BASICTYPE_ANYDEFINEDBY:
986 case BASICTYPE_ANY:
987 return FALSE;
988 break;
989
990
991 case BASICTYPE_SELECTION:
992 if (t->basicType->a.selection->link != NULL)
993 return IsPrimitiveByDef (t->basicType->a.selection->link->type);
994 break;
995
996 case BASICTYPE_BOOLEAN:
997 case BASICTYPE_INTEGER:
998 case BASICTYPE_BITSTRING:
999 case BASICTYPE_OCTETSTRING:
1000 case BASICTYPE_NULL:
1001 case BASICTYPE_OID:
1002 case BASICTYPE_REAL:
1003 case BASICTYPE_ENUMERATED:
1004 return TRUE;
1005 break;
1006
1007 case BASICTYPE_UNKNOWN:
1008 case BASICTYPE_MACROTYPE:
1009 case BASICTYPE_MACRODEF:
1010 return FALSE;
1011 break;
1012
1013 default:
1014 fprintf (stderr, "IsPrimitiveByDef: ERROR - unknown type id ?!");
1015 }
1016 return FALSE;
1017 } /* IsPrimitiveByDef */
1018
1019
1020 /*
1021 * Returns TRUE if the given type is a local type reference or an
1022 * import type ref.
1023 * e.g.
1024 *
1025 * Gumby ::= P1.ORName --> isTypeRef returns TRUE P1.ORName
1026 * Bar ::= INTEGER --> isTypeRef returns FALSE for INTEGER
1027 * Foo ::= Bar --> isTypeRef returns TRUE for Bar
1028 */
1029 int
1030 IsTypeRef PARAMS ((t),
1031 Type *t)
1032 {
1033 if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
1034 (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
1035 return TRUE;
1036 else
1037 return FALSE;
1038 } /* IsTypeRef */
1039
1040
1041
1042 /*
1043 * Returns TRUE if the given type is defined
1044 * by a library type such as OCTET STRING.
1045 * Does NOT follow type refs - type refs return FALSE.
1046 *
1047 * NOTE - some possibly non-primitive types are defined by
1048 * library types (ANY, ANY DEFINED BY)
1049 *
1050 * types defined by type refs or structured defs
1051 * cause FALSE to be returned. i.e.
1052 * Foo ::= Bar -> FALSE for Bar
1053 * Bell ::= SEQUENCE { .. } -> False for SEQ...
1054 *
1055 * useful types are considered as type references and hence
1056 * return FALSE.
1057 */
1058 int
1059 IsDefinedByLibraryType PARAMS ((t),
1060 Type *t)
1061 {
1062 int retVal;
1063
1064 if (t == NULL)
1065 retVal = FALSE;
1066
1067 else if (IsPrimitiveByDef (t))
1068 retVal = TRUE;
1069
1070 /*
1071 * check for non-primitive types that
1072 * are defined by a library type
1073 */
1074 else
1075 switch (t->basicType->choiceId)
1076 {
1077 case BASICTYPE_ANYDEFINEDBY:
1078 case BASICTYPE_ANY:
1079 retVal = TRUE;
1080 break;
1081
1082 default:
1083 retVal = FALSE;
1084 }
1085 return retVal;
1086
1087 } /* IsDefinedByLibraryType*/
1088
1089
1090 /*
1091 * Returns FALSE if type t is
1092 * a. a library type with default universal tags and no named elements
1093 * OR
1094 * b. a reference to a type with no extra tagging
1095 *
1096 * otherwise returns true, indicating that is is a new type derived
1097 * by tagging or adding named elmts to another type.
1098 *
1099 * eg INTEGER --> FALSE (same as lib type)
1100 * [APPLICATION 2] INTEGER --> TRUE (re-tagged lib type)
1101 * INTEGER { one (1), two (2) } --> TRUE (lib type with named elmts)
1102 * Bar2 --> FALSE (simple type ref)
1103 */
1104 int
1105 IsNewType PARAMS ((t),
1106 Type *t)
1107 {
1108 /*
1109 * Type = [re-tagging] DefiningType [namedelmts]
1110 * identical: no retagging and no named elements
1111 */
1112 if (IsDefinedByLibraryType (t) && HasDefaultTag (t) && ! HasNamedElmts (t))
1113 return FALSE;
1114
1115 else if (IsTypeRef (t) && ((t->tags == NULL) || (LIST_EMPTY (t->tags))))
1116 return FALSE;
1117
1118 else
1119 return TRUE;
1120
1121 } /* IsNewType */
1122
1123
1124 /*
1125 * Returns TRUE if elmts including curr list elmt
1126 * onward are all optional otherwise returns FALSE.
1127 * (note: this relies on the 'curr' ptr in the list)
1128 * if the list is null or the curr elmt is null
1129 * then returns TRUE
1130 */
1131 int
1132 IsTailOptional PARAMS ((e),
1133 NamedTypeList *e)
1134 {
1135 NamedType *elmt;
1136 void *tmp;
1137 int retVal;
1138
1139 if (e == NULL)
1140 return TRUE;
1141
1142 tmp = (void*)CURR_LIST_NODE (e);
1143 if (tmp == NULL)
1144 return TRUE;
1145
1146 retVal = TRUE;
1147 FOR_REST_LIST_ELMT (elmt, e)
1148 {
1149 if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL))
1150 {
1151 retVal = FALSE;
1152 break;
1153 }
1154 }
1155 SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */
1156 return retVal;
1157 } /* IsTailOptional */
1158
1159
1160
1161 /*
1162 * Returns TRUE if all elmts after but not including the curr list elmt
1163 * are optional otherwise returns FALSE.
1164 * (note: this relies on the 'curr' ptr in the list)
1165 * if the list is null or the curr elmt is null
1166 * then returns TRUE. if there are no elmts after the curr elmt
1167 * returns TRUE.
1168 */
1169 int
1170 NextIsTailOptional PARAMS ((e),
1171 NamedTypeList *e)
1172 {
1173 NamedType *elmt;
1174 void *tmp;
1175 void *tmp2;
1176 int retVal;
1177
1178 if ((e == NULL) || (LIST_EMPTY (e)))
1179 return TRUE;
1180
1181 tmp = (void*)CURR_LIST_NODE (e);
1182 if (tmp == NULL)
1183 return TRUE;
1184
1185 tmp2 = (void*)NEXT_LIST_NODE (e);
1186 if (tmp2 == NULL)
1187 return TRUE;
1188
1189 SET_CURR_LIST_NODE (e, tmp2);
1190
1191 retVal = TRUE;
1192 FOR_REST_LIST_ELMT (elmt, e)
1193 {
1194 if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL))
1195 {
1196 retVal = FALSE;
1197 break;
1198 }
1199 }
1200 SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */
1201 return retVal;
1202 } /* NextIsTailOptional */
1203
1204
1205 /*
1206 * Returns TRUE if all elmts of the curr list are optional
1207 * or have default values. Useful with SET and SEQ elements.
1208 */
1209 int
1210 AllElmtsOptional PARAMS ((e),
1211 NamedTypeList *e)
1212 {
1213 NamedType *elmt;
1214 void *tmp;
1215 int retVal;
1216
1217 if ((e == NULL) || LIST_EMPTY (e))
1218 return TRUE;
1219
1220 tmp = (void*)CURR_LIST_NODE (e);
1221 SET_CURR_LIST_NODE (e, FIRST_LIST_NODE (e));
1222
1223 retVal = TRUE;
1224 FOR_REST_LIST_ELMT (elmt, e)
1225 {
1226 if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL))
1227 {
1228 retVal = FALSE;
1229 break;
1230 }
1231 }
1232 SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */
1233 return retVal;
1234 } /* AllElmtsOptional */
1235
1236
1237
1238
1239
1240 /*
1241 * Follows single levely of type ref or library type and returns a
1242 * handle to its AnyRefList. Typically used in do_macros.c to
1243 * add a hash key for the type that t is or refs. Need to get
1244 * to the type def of type t to give the AnyRefListHndl.
1245 */
1246 AnyRefList**
1247 GetAnyRefListHndl PARAMS ((t),
1248 Type *t)
1249 {
1250 TypeDef *td;
1251
1252 if (IsDefinedByLibraryType (t))
1253 return LIBTYPE_GET_ANY_REFS_HNDL (t->basicType->choiceId);
1254 else
1255 {
1256 if (!IsTypeRef (t))
1257 return NULL;
1258 else
1259 {
1260 td = t->basicType->a.localTypeRef->link;
1261 return &td->anyRefs;
1262 }
1263 }
1264 } /* GetAnyRefListHndl */
1265
1266
1267 /*
1268 * Given a subtype list s (possibly empty *s == NULL) it tacks on
1269 * the newSubtype in a appropriate fashion, possible chaning *s.
1270 * Op can be SUBTYPE_AND or SUBTYPE_OR.
1271 *
1272 * e.g. Foo ::= INTEGER ((1..100) | 200)
1273 *
1274 * Add the subtypes by
1275 * AppendSubtype (&t->subtypes, (1..100), SUBTYPE_AND)
1276 * AppendSubtype (&t->subtypes, 200, SUBTYPE_OR)
1277 *
1278 * op is meaningless if s is empty
1279 */
1280 void
1281 AppendSubtype PARAMS ((s, newSubtype, op),
1282 Subtype **s _AND_
1283 Subtype *newSubtype _AND_
1284 enum SubtypeChoiceId op)
1285 {
1286 void **tmpPtr;
1287 Subtype *sPtr;
1288
1289 if (*s == NULL)
1290 *s = newSubtype;
1291
1292 else if (op == SUBTYPE_AND)
1293 {
1294 if ((*s)->choiceId == SUBTYPE_AND)
1295 {
1296 tmpPtr = (void**)AsnListAppend ((*s)->a.and);
1297 *tmpPtr = (void*)newSubtype;
1298 }
1299 else
1300 {
1301 sPtr = (Subtype*)Malloc (sizeof (Subtype));
1302 sPtr->choiceId = SUBTYPE_AND;
1303 sPtr->a.and = NEWLIST();
1304 tmpPtr = (void**)AsnListAppend (sPtr->a.and);
1305 *tmpPtr = (void*)*s;
1306 tmpPtr = (void**)AsnListAppend (sPtr->a.and);
1307 *tmpPtr = (void*)newSubtype;
1308 *s = sPtr;
1309 }
1310 }
1311 else if (op == SUBTYPE_OR)
1312 {
1313 if ((*s)->choiceId == SUBTYPE_OR)
1314 {
1315 tmpPtr = (void**)AsnListAppend ((*s)->a.or);
1316 *tmpPtr = (void*)newSubtype;
1317 }
1318 else
1319 {
1320 sPtr = (Subtype*)Malloc (sizeof (Subtype));
1321 sPtr->choiceId = SUBTYPE_OR;
1322 sPtr->a.or = NEWLIST();
1323 tmpPtr = (void**)AsnListAppend (sPtr->a.or);
1324 *tmpPtr = (void*)*s;
1325 tmpPtr = (void**)AsnListAppend (sPtr->a.or);
1326 *tmpPtr = (void*)newSubtype;
1327 *s = sPtr;
1328 }
1329 }
1330 else
1331 /* NOT not supported here */
1332 fprintf (stderr,"AppendSubtype - unknown operation\n");
1333
1334 } /* AppendSubtype */