2 * compiler/core/snacc_util.c
4 * utilities for dealing with the Module data structure
9 * Copyright (C) 1991, 1992 Michael Sample
10 * and the University of British Columbia
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.
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.
22 * Revision 1.1.1.1 1999/03/16 18:06:52 aram
23 * Originals from SMIME Free Library.
25 * Revision 1.3 1995/07/25 19:41:44 rj
26 * changed `_' to `-' in file names.
28 * Revision 1.2 1994/09/01 00:45:09 rj
29 * snacc_config.h removed.
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.
40 #include "asn1module.h"
41 #include "lib-types.h"
43 #include "snacc-util.h"
48 * Allocates and initializes a type and it's basicType info
49 * used extensively by asn1.yacc
53 SetupType
PARAMS ((t
, typeId
, lineNum
),
55 enum BasicTypeChoiceId typeId _AND_
56 unsigned long lineNum
)
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
)
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
));
76 * Allocates and initializes a type and it's basicType to MACROTYPE
77 * and sets the MACROTYPE type to the given macrotype
80 SetupMacroType
PARAMS ((t
, macroTypeId
, lineNum
),
82 enum MacroTypeChoiceId macroTypeId _AND_
83 unsigned long lineNum
)
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 */
98 * similar to SetupType but for values instead
101 SetupValue
PARAMS ((v
, valId
, lineNum
),
103 enum BasicValueChoiceId valId _AND_
104 unsigned long lineNum
)
106 *v
= (Value
*)Malloc (sizeof (Value
));
107 (*v
)->basicValue
= (BasicValue
*)Malloc (sizeof (BasicValue
));
108 (*v
)->basicValue
->choiceId
= valId
;
109 (*v
)->lineNo
= lineNum
;
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.
122 AddPrivateImportElmt
PARAMS ((m
, name
, refdModuleName
, lineNo
),
125 char *refdModuleName _AND_
130 ImportModule
*impMod
;
133 /* see if module m already imports something from "refdModule" */
134 if ((impMod
= LookupImportModule (m
, refdModuleName
)) == NULL
)
136 impMod
= MT (ImportModule
);
137 impMod
->modId
= MT (ModuleId
);
138 impMod
->modId
->name
= Malloc (strlen (refdModuleName
)+1);
139 strcpy (impMod
->modId
->name
, refdModuleName
);
141 newElmt
= MT (ImportElmt
);
142 newElmt
->name
= Malloc (strlen (name
)+1);
143 strcpy (newElmt
->name
, name
);
144 newElmt
->privateScope
= TRUE
;
146 APPEND (newElmt
, impMod
->importElmts
);
147 APPEND (impMod
, m
->imports
);
149 else /* module "refdModule is already imported from */
151 ie
= LookupImportElmtInImportElmtList (impMod
->importElmts
, name
);
155 newElmt
= MT (ImportElmt
);
156 newElmt
->name
= Malloc (strlen (name
)+1);
157 strcpy (newElmt
->name
, name
);
158 APPEND (newElmt
, impMod
->importElmts
);
160 else if (!ie
->privateScope
)
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
);
166 } /* AddPrivateImportElmt */
169 * looks for the named import type/value in all of the IMPORT lists of the
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
176 * returns NULL if the named import name was not found
180 LookupImportElmtInModule
PARAMS ((m
, name
, foundImportModule
),
183 ImportModule
**foundImportModule
)
185 ImportModule
*importMod
;
186 ImportElmt
*importElmt
;
190 if (m
->imports
== NULL
)
193 tmp
= (void*)CURR_LIST_NODE (m
->imports
);
195 FOR_EACH_LIST_ELMT (importMod
, m
->imports
)
197 importElmt
= LookupImportElmtInImportElmtList (importMod
->importElmts
, name
);
198 if (importElmt
!= NULL
)
200 *foundImportModule
= importMod
;
206 SET_CURR_LIST_NODE (m
->imports
, tmp
); /* restore orig loc */
209 } /* LookupImportElmtInModule */
213 * given a list of import elmts, returns ptr to the elmt with
214 * the matching name. NULL if not found
217 LookupImportElmtInImportElmtList
PARAMS ((impElmtList
, name
),
218 ImportElmtList
*impElmtList _AND_
226 if (impElmtList
== NULL
)
229 tmp
= (void*) CURR_LIST_NODE (impElmtList
);
231 FOR_EACH_LIST_ELMT (impElmt
, impElmtList
)
233 if (strcmp (impElmt
->name
, name
) == 0)
240 SET_CURR_LIST_NODE (impElmtList
, tmp
);
243 } /* LookupImportElmtInImportElmtList */
249 * looks for an import list that imports from "importModuleName"
250 * module in the given module.
252 * returns a ptr to the ImportList if found
253 * returns NULL if not found
256 LookupImportModule
PARAMS ((m
, importModuleName
),
258 char *importModuleName
)
260 ImportModule
*importModule
;
261 ImportModule
*retVal
;
264 if (m
->imports
== NULL
)
267 tmp
= (void*)CURR_LIST_NODE (m
->imports
);
269 FOR_EACH_LIST_ELMT (importModule
, m
->imports
)
271 if (strcmp (importModule
->modId
->name
, importModuleName
) == 0)
273 retVal
= importModule
;
278 SET_CURR_LIST_NODE (m
->imports
, tmp
);
281 } /* LookupImportModule */
287 * Looks for the type with name matching typeName (null terminated char*)
288 * in the given the TypeDef list
290 * RETURNS: ptr to the TypeDef with the matching typeName (if any)
291 * NULL if no match was made
294 LookupType
PARAMS ((typeDefList
, typeName
),
295 TypeDefList
*typeDefList _AND_
302 if (typeDefList
== NULL
)
305 if (typeName
== NULL
)
308 fprintf (stderr
,"LookupType: warning - failure due to NULL key\n");
313 tmp
= (void*)CURR_LIST_NODE (typeDefList
); /* remember curr list spot */
315 FOR_EACH_LIST_ELMT (td
, typeDefList
)
317 if (strcmp (typeName
, td
->definedName
) == 0)
324 SET_CURR_LIST_NODE (typeDefList
,tmp
); /* restore curr location */
332 * Returns ptr to module that has matching name or OID
333 * if oid is not null, lookup done only by oid
335 * returns NULL if no match was found
338 LookupModule
PARAMS ((moduleList
, modName
, oid
),
339 ModuleList
*moduleList _AND_
345 int strMatch
= FALSE
;
346 int oidMatch
= FALSE
;
351 if ((moduleList
== NULL
) || ((modName
== NULL
) && (oid
== NULL
)))
354 tmp
= (void*)CURR_LIST_NODE (moduleList
); /* remember orig loc */
356 FOR_EACH_LIST_ELMT (currMod
, moduleList
)
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.
366 if (CompareOids (oid
, currMod
->modId
->oid
))
369 break; /* exit for loop */
372 else if ((modName
!= NULL
) &&
373 (strcmp (modName
, currMod
->modId
->name
) == 0))
376 break; /* exit for loop */
380 SET_CURR_LIST_NODE (moduleList
, tmp
);
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.
395 LookupFieldInType
PARAMS ((tRef
, fieldName
),
404 t
= ParanoidGetType (tRef
); /* skip any references etc */
406 if ((t
->basicType
->choiceId
!= BASICTYPE_SET
) &&
407 (t
->basicType
->choiceId
!= BASICTYPE_SEQUENCE
) &&
408 (t
->basicType
->choiceId
!= BASICTYPE_CHOICE
))
411 fprintf (stderr
,"LookupFieldInType: ERROR - attempt to look for field in a non SET/SEQ/CHOICE type\n");
416 /* return if null list */
417 if (t
->basicType
->a
.set
== NULL
)
420 /* remember set's original curr elmt */
421 tmp
= (void*)CURR_LIST_NODE (t
->basicType
->a
.set
);
423 FOR_EACH_LIST_ELMT (e
, t
->basicType
->a
.set
)
425 /* remember fieldname is optional so it can be null */
426 if ((e
->fieldName
!= NULL
) && (strcmp (e
->fieldName
, fieldName
) == 0))
429 break; /* exit for loop */
432 SET_CURR_LIST_NODE (t
->basicType
->a
.set
, tmp
);
435 } /* LookupFieldInType */
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
446 GetType
PARAMS ((type
),
458 switch (t
->basicType
->choiceId
)
460 case BASICTYPE_LOCALTYPEREF
:
461 case BASICTYPE_IMPORTTYPEREF
:
462 td
= t
->basicType
->a
.localTypeRef
->link
;
477 * like GetType ie, skips type references to return the defining type.
478 * This is a paranoid version - it checks for circular type errors.
481 * would make the normal GetType recurse forever (until no stk mem)
484 ParanoidGetType
PARAMS ((type
),
498 switch (t
->basicType
->choiceId
)
500 case BASICTYPE_LOCALTYPEREF
:
501 case BASICTYPE_IMPORTTYPEREF
:
502 td
= t
->basicType
->a
.localTypeRef
->link
;
503 if ((td
== NULL
) || (ObjIsDefined (l
, td
->type
, ObjPtrCmp
)))
515 FreeDefinedObjs (&l
);
520 } /* ParnoidGetType */
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.
529 enum BasicTypeChoiceId
530 GetBuiltinType
PARAMS ((t
),
535 definingType
= GetType (t
);
536 if (definingType
!= NULL
)
537 return definingType
->basicType
->choiceId
;
541 } /* GetBuiltinType */
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.
550 enum BasicTypeChoiceId
551 ParanoidGetBuiltinType
PARAMS ((t
),
556 definingType
= ParanoidGetType (t
);
557 if (definingType
!= NULL
)
558 return definingType
->basicType
->choiceId
;
562 } /* GetBuiltinType */
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
574 GetNamedElmts
PARAMS ((t
),
582 definingType
= ParanoidGetType (t
);
584 if (definingType
== NULL
)
587 switch (definingType
->basicType
->choiceId
)
589 case BASICTYPE_INTEGER
:
590 case BASICTYPE_ENUMERATED
:
591 case BASICTYPE_BITSTRING
:
592 return definingType
->basicType
->a
.integer
;
595 * for non-named elmt types
603 } /* GetNamedElmts */
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.
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
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.
623 GetAllNamedElmts
PARAMS ((t
),
628 NamedNumberList
*retVal
;
629 NamedNumberList
*ntElmtList
;
630 ValueDef
*nn
; /* named number is a valuedef */
633 retVal
= AsnListNew (sizeof (void*));
638 definingType
= ParanoidGetType (t
);
640 if (definingType
== NULL
)
644 switch (definingType
->basicType
->choiceId
)
646 case BASICTYPE_INTEGER
:
647 case BASICTYPE_ENUMERATED
:
648 case BASICTYPE_BITSTRING
:
650 * add the named elmts (if any) to the new list
652 FOR_EACH_LIST_ELMT (nn
, definingType
->basicType
->a
.integer
)
654 nnHndl
= (ValueDef
**)AsnListAppend (retVal
);
660 * for choices must group all named elmts from choice components
661 * and return in a list.
663 case BASICTYPE_CHOICE
:
664 FOR_EACH_LIST_ELMT (nt
, definingType
->basicType
->a
.choice
)
666 ntElmtList
= GetAllNamedElmts (nt
->type
);
667 retVal
= AsnListConcat (retVal
, ntElmtList
);
668 Free (ntElmtList
); /* zap now unused list head */
673 } /* GetAllNamedElmts */
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
683 GetParent
PARAMS ((ancestor
, child
),
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
))
700 if (ancestor
->basicType
->a
.set
== NULL
)
703 if ((ancestor
->basicType
->choiceId
== BASICTYPE_SETOF
) ||
704 (ancestor
->basicType
->choiceId
== BASICTYPE_SEQUENCEOF
))
706 if (child
== ancestor
->basicType
->a
.setOf
)
709 return GetParent (ancestor
->basicType
->a
.setOf
, child
);
712 tmp
= (void*)CURR_LIST_NODE (ancestor
->basicType
->a
.set
);
714 * look through direct children of ancestor first
716 FOR_EACH_LIST_ELMT (e
, ancestor
->basicType
->a
.set
)
718 if (child
== e
->type
)
720 SET_CURR_LIST_NODE (ancestor
->basicType
->a
.set
, tmp
);
727 * look through grandchildren if not in children
729 FOR_EACH_LIST_ELMT (e
, ancestor
->basicType
->a
.set
)
731 if ((parent
= GetParent (e
->type
, child
)) != NULL
)
733 SET_CURR_LIST_NODE (ancestor
->basicType
->a
.set
, tmp
);
738 SET_CURR_LIST_NODE (ancestor
->basicType
->a
.set
, tmp
);
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
752 LookupValue
PARAMS ((valueList
, valueName
),
753 ValueDefList
*valueList _AND_
760 if (valueName
== NULL
)
763 fprintf (stderr
,"LookupType: warning - failure due to NULL key\n");
768 if (valueList
== NULL
)
771 tmp
= (void*)CURR_LIST_NODE (valueList
);
773 FOR_EACH_LIST_ELMT (v
, valueList
)
775 if (strcmp (valueName
, v
->definedName
) == 0)
778 break; /* exit for loop */
782 SET_CURR_LIST_NODE (valueList
, tmp
);
790 * Goes through valuerefs (if any) to get to actual
791 * ASN1 value. Analogous to GetType.
794 GetValue
PARAMS ((v
),
801 switch (v
->basicValue
->choiceId
)
803 case BASICVALUE_LOCALVALUEREF
:
804 case BASICVALUE_IMPORTVALUEREF
:
805 vd
= v
->basicValue
->a
.localValueRef
->link
;
816 fprintf (stderr
, "GetValue: ERROR - cannot get value for unlinked local/import value refs\n");
823 * Returns TRUE if oid1 and oid2 are identical otherwise FALSE
826 CompareOids
PARAMS ((oid1
, oid2
),
830 if ((oid1
== NULL
) && (oid2
== NULL
))
833 for (; (oid1
!= NULL
) && (oid2
!= NULL
); oid1
= oid1
->next
, oid2
= oid2
->next
)
836 * fail if value refs have not been resolved or
837 * no match between arcnums
839 if ((oid1
->arcNum
== NULL_OID_ARCNUM
) ||
840 (oid2
->arcNum
== NULL_OID_ARCNUM
) ||
841 (oid1
->arcNum
!= oid2
->arcNum
))
845 * could check ref'd values for same name
846 * incase value ref has not been resolved
851 if ((oid1
== NULL
) && (oid2
== NULL
))
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
865 HasNamedElmts
PARAMS ((t
),
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 */
877 * Returns true if the given tag lists are the same
878 * (assumes value refs have be resolved)
881 TagsAreIdentical
PARAMS ((t1
, t2
),
888 /* both lists are empty */
889 if (((t1
== NULL
) || LIST_EMPTY (t1
)) &&
890 ((t2
== NULL
) || LIST_EMPTY (t2
)))
893 else if ((t1
== NULL
) || (t2
== NULL
))
896 else if (LIST_COUNT (t1
) == LIST_COUNT (t2
))
898 SET_CURR_LIST_NODE (t2
, FIRST_LIST_NODE (t2
));
899 FOR_EACH_LIST_ELMT (tag1
, t1
)
901 tag2
= (Tag
*) CURR_LIST_ELMT (t2
);
902 if ((tag1
->tclass
!= tag2
->tclass
) || (tag1
->code
== tag2
->code
))
904 SET_CURR_LIST_NODE (t2
, NEXT_LIST_NODE (t2
));
911 } /* TagsAreIdentical */
916 * Returns TRUE if the tag currently on the given type has the default
917 * tag specified in the type tbl. otherwise returns FALSE.
920 HasDefaultTag
PARAMS ((t
),
923 Tag
*firstTag
= NULL
;
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
);
932 return ((firstTag
!= NULL
) && (LIST_COUNT (t
->tags
) == 1) &&
933 (firstTag
->tclass
== dfltClass
) && (firstTag
->code
== dfltCode
)) ||
934 ((firstTag
== NULL
) && (dfltCode
== NO_TAG_CODE
));
936 } /* HasDefaultTag */
940 * Returns TRUE if t is a primitive type or if it is
941 * defined by a reference to a primitive type
944 IsPrimitiveByDefOrRef
PARAMS ((t
),
949 definingType
= GetType (t
);
951 if (definingType
== NULL
)
952 return FALSE
; /* bad error handling */
954 return IsPrimitiveByDef (definingType
);
955 } /* IsPrimitiveByDefOrRef */
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:
972 IsPrimitiveByDef
PARAMS ((t
),
975 switch (t
->basicType
->choiceId
)
977 case BASICTYPE_LOCALTYPEREF
:
978 case BASICTYPE_IMPORTTYPEREF
:
979 case BASICTYPE_SEQUENCE
:
981 case BASICTYPE_CHOICE
:
982 case BASICTYPE_SEQUENCEOF
:
983 case BASICTYPE_SETOF
:
984 case BASICTYPE_COMPONENTSOF
:
985 case BASICTYPE_ANYDEFINEDBY
:
991 case BASICTYPE_SELECTION
:
992 if (t
->basicType
->a
.selection
->link
!= NULL
)
993 return IsPrimitiveByDef (t
->basicType
->a
.selection
->link
->type
);
996 case BASICTYPE_BOOLEAN
:
997 case BASICTYPE_INTEGER
:
998 case BASICTYPE_BITSTRING
:
999 case BASICTYPE_OCTETSTRING
:
1000 case BASICTYPE_NULL
:
1002 case BASICTYPE_REAL
:
1003 case BASICTYPE_ENUMERATED
:
1007 case BASICTYPE_UNKNOWN
:
1008 case BASICTYPE_MACROTYPE
:
1009 case BASICTYPE_MACRODEF
:
1014 fprintf (stderr
, "IsPrimitiveByDef: ERROR - unknown type id ?!");
1017 } /* IsPrimitiveByDef */
1021 * Returns TRUE if the given type is a local type reference or an
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
1030 IsTypeRef
PARAMS ((t
),
1033 if ((t
->basicType
->choiceId
== BASICTYPE_LOCALTYPEREF
) ||
1034 (t
->basicType
->choiceId
== BASICTYPE_IMPORTTYPEREF
))
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.
1047 * NOTE - some possibly non-primitive types are defined by
1048 * library types (ANY, ANY DEFINED BY)
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...
1055 * useful types are considered as type references and hence
1059 IsDefinedByLibraryType
PARAMS ((t
),
1067 else if (IsPrimitiveByDef (t
))
1071 * check for non-primitive types that
1072 * are defined by a library type
1075 switch (t
->basicType
->choiceId
)
1077 case BASICTYPE_ANYDEFINEDBY
:
1087 } /* IsDefinedByLibraryType*/
1091 * Returns FALSE if type t is
1092 * a. a library type with default universal tags and no named elements
1094 * b. a reference to a type with no extra tagging
1096 * otherwise returns true, indicating that is is a new type derived
1097 * by tagging or adding named elmts to another type.
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)
1105 IsNewType
PARAMS ((t
),
1109 * Type = [re-tagging] DefiningType [namedelmts]
1110 * identical: no retagging and no named elements
1112 if (IsDefinedByLibraryType (t
) && HasDefaultTag (t
) && ! HasNamedElmts (t
))
1115 else if (IsTypeRef (t
) && ((t
->tags
== NULL
) || (LIST_EMPTY (t
->tags
))))
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
1132 IsTailOptional
PARAMS ((e
),
1142 tmp
= (void*)CURR_LIST_NODE (e
);
1147 FOR_REST_LIST_ELMT (elmt
, e
)
1149 if ((!elmt
->type
->optional
) && (elmt
->type
->defaultVal
== NULL
))
1155 SET_CURR_LIST_NODE (e
, tmp
); /* reset list to orig loc */
1157 } /* IsTailOptional */
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
1170 NextIsTailOptional
PARAMS ((e
),
1178 if ((e
== NULL
) || (LIST_EMPTY (e
)))
1181 tmp
= (void*)CURR_LIST_NODE (e
);
1185 tmp2
= (void*)NEXT_LIST_NODE (e
);
1189 SET_CURR_LIST_NODE (e
, tmp2
);
1192 FOR_REST_LIST_ELMT (elmt
, e
)
1194 if ((!elmt
->type
->optional
) && (elmt
->type
->defaultVal
== NULL
))
1200 SET_CURR_LIST_NODE (e
, tmp
); /* reset list to orig loc */
1202 } /* NextIsTailOptional */
1206 * Returns TRUE if all elmts of the curr list are optional
1207 * or have default values. Useful with SET and SEQ elements.
1210 AllElmtsOptional
PARAMS ((e
),
1217 if ((e
== NULL
) || LIST_EMPTY (e
))
1220 tmp
= (void*)CURR_LIST_NODE (e
);
1221 SET_CURR_LIST_NODE (e
, FIRST_LIST_NODE (e
));
1224 FOR_REST_LIST_ELMT (elmt
, e
)
1226 if ((!elmt
->type
->optional
) && (elmt
->type
->defaultVal
== NULL
))
1232 SET_CURR_LIST_NODE (e
, tmp
); /* reset list to orig loc */
1234 } /* AllElmtsOptional */
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.
1247 GetAnyRefListHndl
PARAMS ((t
),
1252 if (IsDefinedByLibraryType (t
))
1253 return LIBTYPE_GET_ANY_REFS_HNDL (t
->basicType
->choiceId
);
1260 td
= t
->basicType
->a
.localTypeRef
->link
;
1261 return &td
->anyRefs
;
1264 } /* GetAnyRefListHndl */
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.
1272 * e.g. Foo ::= INTEGER ((1..100) | 200)
1274 * Add the subtypes by
1275 * AppendSubtype (&t->subtypes, (1..100), SUBTYPE_AND)
1276 * AppendSubtype (&t->subtypes, 200, SUBTYPE_OR)
1278 * op is meaningless if s is empty
1281 AppendSubtype
PARAMS ((s
, newSubtype
, op
),
1283 Subtype
*newSubtype _AND_
1284 enum SubtypeChoiceId op
)
1292 else if (op
== SUBTYPE_AND
)
1294 if ((*s
)->choiceId
== SUBTYPE_AND
)
1296 tmpPtr
= (void**)AsnListAppend ((*s
)->a
.and);
1297 *tmpPtr
= (void*)newSubtype
;
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
;
1311 else if (op
== SUBTYPE_OR
)
1313 if ((*s
)->choiceId
== SUBTYPE_OR
)
1315 tmpPtr
= (void**)AsnListAppend ((*s
)->a
.or);
1316 *tmpPtr
= (void*)newSubtype
;
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
;
1331 /* NOT not supported here */
1332 fprintf (stderr
,"AppendSubtype - unknown operation\n");
1334 } /* AppendSubtype */