]>
git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/compiler/core/normalize.c
2 * compiler/core/normalize.c
4 * 1. swap COMPONENTS OF for actual types
5 * - do this since save lots of special case handling in
8 * 2. change SEQUENCE OF/SET OF (type def (not ref))
9 * to SEQUENCE OF/SEQ OF (type ref)
10 * and add type def for orig.
11 * - do this since OF type are AsnList
13 * 3. change CHOICE defs within other constructed types
15 * - makes code production easier. can be changed
18 * 4. change SEQUENCE/SET defs within other constructed types
19 * into SEQUENCE/SET refs
20 * - makes code production easier. can be changed
21 * with some work (allocation in decode is wrong
22 * - isPtr set incorrectly)
24 * 5. change SELECTION types to the actual field from the choice
26 * 6. convert Linked oid's with value refs into a ENC_OID's
27 * so values can be easily defined in C/C++. MS 92/03/01
29 * 7. if IMPLICIT-TAGS is specified, mark type references
30 * as implicit, if the ref'd type is not CHOICE or ANY.
31 * (Extra tags on primitives (ie not references) are already
32 * removed in the parsing step (asn1.yacc)).
34 * 8. SET OF/SEQ OF defs nested in other SETs/SEQ/CHOICEs/SET OF/SEQ OF
35 * types are moved to separate type defs - added 08/92 to support
36 * C++ lists more easily.
38 * 9. INTEGERs with named elmts and ENUM defs nested in other
39 * SETs/SEQ/CHOICEs/SET OF/SEQ OF types are moved to separate type
40 * defs - added 08/92 to support C++ class hierarchy better.
42 * ******** 10 is no longer done - in fact it was stupid for ******
43 * ******** ANY DEFINED BY types MS 09/92 ******
44 * 10. Move ANY and ANY DEFINED BY type defs nested in SET/SEQ/CHOICE/SET OF
45 * /SEQ OF to a separate definition - this should make fixing the
46 * produced code simpler.
51 * Copyright (C) 1991, 1992 Michael Sample
52 * and the University of British Columbia
54 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
56 * the Free Software Foundation; either version 2 of the License, or
57 * (at your option) any later version.
59 * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/normalize.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
60 * $Log: normalize.c,v $
61 * Revision 1.1 2001/06/20 21:27:58 dmitch
62 * Adding missing snacc compiler files.
64 * Revision 1.1.1.1 1999/03/16 18:06:50 aram
65 * Originals from SMIME Free Library.
67 * Revision 1.3 1995/07/25 19:41:40 rj
68 * changed `_' to `-' in file names.
70 * Revision 1.2 1994/09/01 00:40:56 rj
71 * snacc_config.h removed.
73 * Revision 1.1 1994/08/28 09:49:23 rj
74 * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
82 #include "asn1module.h"
84 #include "lib-types.h"
85 #include "snacc-util.h"
86 #include "normalize.h"
88 #define LIST_ELMT_SUFFIX "ListElmt"
89 #define CHOICE_SUFFIX "Choice"
90 #define SET_SUFFIX "Set"
91 #define SEQ_SUFFIX "Seq"
92 #define SETOF_SUFFIX "SetOf"
93 #define SEQOF_SUFFIX "SeqOf"
94 #define INT_SUFFIX "Int"
95 #define ENUM_SUFFIX "Enum"
96 #define BITS_SUFFIX "Bits"
97 #define ANY_SUFFIX "Any"
99 long int oidRecursionCountG
= 0 ;
101 void NormalizeTypeDef
PROTO (( Module
* m
, TypeDef
* td
));
103 void NormalizeType
PROTO (( Module
* m
, TypeDef
* td
, Type
* parent
, NamedTypeList
* e
, Type
* t
));
105 void NormalizeElmtTypes
PROTO (( Module
* m
, TypeDef
* td
, Type
* parent
, NamedTypeList
* e
));
107 void NormalizeBasicType
PROTO (( Module
* m
, TypeDef
* td
, Type
* parent
, NamedTypeList
* e
, Type
* type
, BasicType
* bt
));
109 TypeDef
* AddListElmtTypeDef
PROTO (( Module
* m
, TypeDef
* td
, Type
* t
, BasicType
* bt
));
111 TypeDef
* AddConsTypeDef
PROTO (( Module
* m
, TypeDef
* td
, Type
* t
, BasicType
* bt
, char * suffix
));
113 void NormalizeValueDef
PROTO (( Module
* m
, ValueDef
* vd
));
115 int FlattenLinkedOid
PROTO (( OID
* o
, char * asn1FileName
, AsnInt lineNo
, int quiet
));
118 * looks through the given module and performs the operations
122 NormalizeModule
PARAMS (( m
),
129 * go through each type in typeList
131 FOR_EACH_LIST_ELMT ( td
, m
-> typeDefs
)
133 NormalizeTypeDef ( m
, td
);
137 * go through each value for types?
139 FOR_EACH_LIST_ELMT ( vd
, m
-> valueDefs
)
141 NormalizeValueDef ( m
, vd
);
144 } /* NormalizeModule */
148 NormalizeTypeDef
PARAMS (( m
, td
),
155 NormalizeType ( m
, td
, NULL
, NULL
, td
-> type
);
157 } /* NormalizeTypeDef */
161 NormalizeType
PARAMS (( m
, td
, parent
, e
, t
),
165 NamedTypeList
* e _AND_
168 enum BasicTypeChoiceId typeId
;
175 NormalizeBasicType ( m
, td
, parent
, e
, t
, t
-> basicType
);
178 * make type refs implicit if IMPLICIT-TAGS specified and
179 * ref'd type is OK for implicit tagging.
180 * Tag removal work is done in parsing (yacc).
182 if (( m
-> tagDefault
== IMPLICIT_TAGS
))
184 tmpType
= ParanoidGetType ( t
);
185 typeId
= tmpType
-> basicType
-> choiceId
;
187 if (( t
-> tags
!= NULL
) && (! LIST_EMPTY ( t
-> tags
)))
188 lastTag
= ( Tag
*) LAST_LIST_ELMT ( t
-> tags
);
193 * only mark as implicit if
194 * 1. This type has a tag in it's taglist
195 * 2. This type is a reference to another type
196 * 3. the referenced type is not an untagged CHOICE, ANY or
197 * ANY DEFINED BY (just need to check that it has
198 * tags since all other types have tags)
200 if ((( lastTag
!= NULL
) && !( lastTag
-> explicit )) &&
201 (( t
-> basicType
-> choiceId
== BASICTYPE_LOCALTYPEREF
) ||
202 ( t
-> basicType
-> choiceId
== BASICTYPE_IMPORTTYPEREF
)) &&
203 ( CountTags ( t
-> basicType
-> a
. localTypeRef
-> link
-> type
) != 0 ))
209 } /* NormalizeType */
214 NormalizeElmtTypes
PARAMS (( m
, td
, parent
, e
),
222 FOR_EACH_LIST_ELMT ( nt
, e
)
224 NormalizeType ( m
, td
, parent
, e
, nt
-> type
);
226 } /* NormalizeElmtTypes */
230 * this is where most of the action happens
231 * assumes that "e"'s curr ptr is namedtype that holds "type"
234 NormalizeBasicType
PARAMS (( m
, td
, parent
, e
, type
, bt
),
238 NamedTypeList
* e _AND_
242 int i
, numElmtsAdded
;
244 NamedType
** newElmtHndl
;
246 NamedTypeList
* elmts
;
251 BasicType
* tmpBasicType
;
259 switch ( bt
-> choiceId
)
262 case BASICTYPE_COMPONENTSOF
:
264 * copy elmts of COMPONENTS OF type into this type
268 PrintErrLoc ( m
-> asn1SrcFileName
, type
-> lineNo
);
269 fprintf ( stderr
, "ERROR - COMPONENTS OF must be a SET or SEQUENCE element \n " );
270 m
-> status
= MOD_ERROR
;
274 compType
= ParanoidGetType ( bt
-> a
. componentsOf
);
275 parentType
= ParanoidGetType ( parent
);
277 /* COMPONENTS OF must be nested in a SET or SEQUENCE type */
278 if (( parentType
-> basicType
-> choiceId
!= BASICTYPE_SET
) &&
279 ( parentType
-> basicType
-> choiceId
!= BASICTYPE_SEQUENCE
))
281 PrintErrLoc ( m
-> asn1SrcFileName
, type
-> lineNo
);
282 fprintf ( stderr
, "ERROR - COMPONENTS OF must be a SET or SEQUENCE element \n " );
283 m
-> status
= MOD_ERROR
;
287 /* COMPONENTS OF in a SET must ref a SET and vice versa for SEQ */
288 if ((( parentType
-> basicType
-> choiceId
== BASICTYPE_SET
) &&
289 ( compType
-> basicType
-> choiceId
!= BASICTYPE_SET
)) ||
290 (( parentType
-> basicType
-> choiceId
== BASICTYPE_SEQUENCE
) &&
291 ( compType
-> basicType
-> choiceId
!= BASICTYPE_SEQUENCE
)))
293 PrintErrLoc ( m
-> asn1SrcFileName
, type
-> lineNo
);
294 fprintf ( stderr
, "ERROR - COMPONENTS OF in a SET must reference a SET type and COMPONENTS OF in SEQUENCE must reference a SEQUENCE type \n " );
295 type
-> basicType
= compType
-> basicType
;
296 m
-> status
= MOD_ERROR
;
301 * replace "COMPONENTS OF" with elmts from ref'd set
303 elmts
= compType
-> basicType
-> a
. set
;
309 * add new list elmts that point to elmts
310 * of type ref'd by COMPONENTS OF
312 FOR_EACH_LIST_ELMT ( nt
, elmts
)
314 newElmtHndl
= ( NamedType
**) AsnListAdd ( e
);
319 * Set e list's curr ptr to first of of the
320 * newly added components.
321 * Do this so NormalizeElmtTypes will do the
322 * newly added ones as well
324 numElmtsAdded
= AsnListCount ( elmts
);
325 for ( i
= 0 ; i
< numElmtsAdded
; i
++)
328 /* remove the componets of ref since elmts copied in */
334 case BASICTYPE_SELECTION
:
336 * first normalize the CHOICE that is selected from
337 * - this will be done twice to the CHOICE but nothing
338 * bad should happen. The main reason for 'normalizing'
339 * the CHOICE first is to strip tags from the choice elmts
340 * if IMPLICIT-TAGS is set.
341 * NOTE: this call assumes that import/local type refs
342 * both use the 'TypeRef' struct and that a selection references
343 * a CHOICE by name (not definition)
345 NormalizeType ( m
, type
-> basicType
-> a
. selection
-> typeRef
-> basicType
-> a
. localTypeRef
-> link
, NULL
, NULL
, type
-> basicType
-> a
. selection
-> typeRef
-> basicType
-> a
. localTypeRef
-> link
-> type
);
348 * use SELECTION field name if this is an elmt type with no
352 ((( NamedType
*) e
-> curr
-> data
)-> fieldName
== NULL
))
353 (( NamedType
*) e
-> curr
-> data
)-> fieldName
=
354 type
-> basicType
-> a
. selection
-> link
-> fieldName
;
357 * replace SELECTION type with refd type.
358 * must append the named CHOICE field's tags to
359 * any existing tags on this SELECTION type.
361 tmpBasicType
= type
-> basicType
-> a
. selection
-> link
-> type
-> basicType
;
362 tags
= type
-> basicType
-> a
. selection
-> link
-> type
-> tags
;
365 FOR_EACH_LIST_ELMT ( tag
, tags
)
367 if (!((( m
-> tagDefault
== IMPLICIT_TAGS
) || ( type
-> implicit
)) &&
368 ( tag
== ( Tag
*) FIRST_LIST_ELMT ( tags
))))
370 tagHndl
= ( Tag
**) AsnListAppend ( type
-> tags
);
373 type
-> implicit
= FALSE
;
376 if ( type
-> basicType
-> a
. selection
-> link
-> type
-> implicit
)
377 type
-> implicit
= TRUE
;
379 Free ( type
-> basicType
-> a
. selection
-> fieldName
);
380 Free ( type
-> basicType
-> a
. selection
-> typeRef
-> basicType
);
381 Free ( type
-> basicType
-> a
. selection
-> typeRef
);
382 type
-> basicType
= tmpBasicType
;
388 case BASICTYPE_SEQUENCEOF
:
389 case BASICTYPE_SETOF
:
390 /* convert def inside other type into a ref */
391 if ( td
-> type
!= type
)
393 if ( bt
-> choiceId
== BASICTYPE_SETOF
)
394 newDef
= AddConsTypeDef ( m
, td
, type
, bt
, SETOF_SUFFIX
);
396 newDef
= AddConsTypeDef ( m
, td
, type
, bt
, SEQOF_SUFFIX
);
398 NormalizeType ( m
, newDef
, NULL
, NULL
, newDef
-> type
);
401 NormalizeType ( m
, td
, type
, NULL
, type
-> basicType
-> a
. setOf
);
404 /* NOT NEEDED ANY MORE
405 * convert typdef after SET OF/SEQ OF to type REFS
406 switch (bt->a.setOf->basicType->choiceId)
408 case BASICTYPE_SEQUENCE:
410 case BASICTYPE_CHOICE:
411 case BASICTYPE_SEQUENCEOF:
412 case BASICTYPE_SETOF:
413 case BASICTYPE_COMPONENTSOF:
414 newDef = AddListElmtTypeDef (m, td, type, bt);
415 NormalizeType (m, newDef, NULL, NULL, newDef->type);
419 NormalizeType (m, td, NULL, NULL, bt->a.setOf);
426 case BASICTYPE_CHOICE
:
428 * change CHOICE defs embedded in other types
431 if ( td
-> type
!= type
)
433 newDef
= AddConsTypeDef ( m
, td
, type
, bt
, CHOICE_SUFFIX
);
434 NormalizeType ( m
, newDef
, NULL
, NULL
, newDef
-> type
);
437 NormalizeElmtTypes ( m
, td
, type
, bt
-> a
. set
);
442 case BASICTYPE_SEQUENCE
:
444 * change SEQ defs embedded in other types
447 if ( td
-> type
!= type
)
449 newDef
= AddConsTypeDef ( m
, td
, type
, bt
, SEQ_SUFFIX
);
450 NormalizeType ( m
, newDef
, NULL
, NULL
, newDef
-> type
);
453 NormalizeElmtTypes ( m
, td
, type
, bt
-> a
. sequence
);
459 * change SET defs embedded in other types
462 if ( td
-> type
!= type
)
464 newDef
= AddConsTypeDef ( m
, td
, type
, bt
, SET_SUFFIX
);
465 NormalizeType ( m
, newDef
, NULL
, NULL
, newDef
-> type
);
468 NormalizeElmtTypes ( m
, td
, type
, bt
-> a
. set
);
472 case BASICTYPE_INTEGER
:
473 /* if they have named elements convert this def into a ref */
474 if (( td
-> type
!= type
) && ( bt
-> a
. integer
!= NULL
) &&
475 (! LIST_EMPTY ( bt
-> a
. integer
)))
477 newDef
= AddConsTypeDef ( m
, td
, type
, bt
, INT_SUFFIX
);
481 case BASICTYPE_ENUMERATED
:
482 /* if they have named elements convert this def into a ref */
483 if (( td
-> type
!= type
) && ( bt
-> a
. enumerated
!= NULL
) &&
484 (! LIST_EMPTY ( bt
-> a
. enumerated
)))
486 newDef
= AddConsTypeDef ( m
, td
, type
, bt
, ENUM_SUFFIX
);
490 case BASICTYPE_BITSTRING
:
491 /* if they have named elements convert this def into a ref */
492 if (( td
-> type
!= type
) && ( bt
-> a
. bitString
!= NULL
) &&
493 (! LIST_EMPTY ( bt
-> a
. bitString
)))
495 newDef
= AddConsTypeDef ( m
, td
, type
, bt
, BITS_SUFFIX
);
500 case BASICTYPE_ANYDEFINEDBY
:
503 * change ANY defs embedded in other types
506 if (td->type != type)
507 newDef = AddConsTypeDef (m, td, type, bt, ANY_SUFFIX);
512 /* the rest are not processed */
515 } /* NormalizeBasicType */
521 * given a set of/seq of type t within typedef td, change the
522 * set of /seq of elmt type def into a type ref and
523 * add a type def for the elmt at the top level.
526 AddListElmtTypeDef
PARAMS (( m
, td
, t
, bt
),
533 TypeDef
** typeDefHndl
;
540 newDef
= ( TypeDef
*) Malloc ( sizeof ( TypeDef
));
541 newDef
-> exported
= FALSE
;
542 newDef
-> type
= bt
-> a
. setOf
;
544 * make name for new type
545 * Foo ::= SET OF SEQUENCE {...}
547 * FooListElmt ::= SEQUENCE {...}
548 * Foo ::= SET OF FooListElmt
550 newDef
-> definedName
=
551 Malloc ( strlen ( td
-> definedName
) +
552 strlen ( LIST_ELMT_SUFFIX
) + 4 );
554 strcpy ( newDef
-> definedName
, td
-> definedName
);
555 strcat ( newDef
-> definedName
, LIST_ELMT_SUFFIX
);
556 end
= strlen ( newDef
-> definedName
);
558 while ( LookupType ( m
-> typeDefs
, newDef
-> definedName
) != NULL
)
560 newDef
-> definedName
[ end
] = '\0' ;
561 AppendDigit ( newDef
-> definedName
, digit
++);
565 * now put new type at head of list
567 typeDefHndl
= ( TypeDef
**) AsnListPrepend ( m
-> typeDefs
);
568 * typeDefHndl
= newDef
;
573 * replace SET OF/SEQ OF body with type ref
575 bt
-> a
. setOf
= ( Type
*) Malloc ( sizeof ( Type
));
576 bt
-> a
. setOf
-> optional
= FALSE
;
577 bt
-> a
. setOf
-> implicit
= FALSE
;
578 bt
-> a
. setOf
-> lineNo
= t
-> lineNo
;
579 bt
-> a
. setOf
-> basicType
= ( BasicType
*) Malloc ( sizeof ( BasicType
));
580 bt
-> a
. setOf
-> basicType
-> choiceId
= BASICTYPE_LOCALTYPEREF
;
581 bt
-> a
. setOf
-> basicType
-> a
. localTypeRef
= ( TypeRef
*) Malloc ( sizeof ( TypeRef
));
582 bt
-> a
. setOf
-> basicType
-> a
. localTypeRef
-> link
= newDef
;
583 bt
-> a
. setOf
-> basicType
-> a
. localTypeRef
-> typeName
=
585 bt
-> a
. setOf
-> basicType
-> a
. localTypeRef
-> moduleName
= NULL
;
590 } /* AddListElmtTypeDefs */
595 * given a CHOICE/SET/SEQ/etc type t within typedef td, make t into a ref
596 * to a new top level typdef of the CHOICE/SET/SEQ
599 AddConsTypeDef
PARAMS (( m
, td
, t
, bt
, suffix
),
607 TypeDef
** typeDefHndl
;
616 newDef
= ( TypeDef
*) Malloc ( sizeof ( TypeDef
));
617 newDef
-> exported
= FALSE
;
618 newDef
-> recursive
= FALSE
;
619 newDef
-> localRefCount
= 1 ;
620 newDef
-> type
= ( Type
*) Malloc ( sizeof ( Type
));
621 newDef
-> type
-> optional
= FALSE
;
622 newDef
-> type
-> lineNo
= t
-> lineNo
;
623 newDef
-> type
-> basicType
= bt
;
626 * make name for new choice/SET/SEQ
627 * Foo ::= SEQUENCE { .., bar CHOICE { ...}, ..}
629 * FooChoice ::= CHOICE { ...}
630 * Foo ::= SEQUENCE { .., bar FooChoice, .. }
632 newDef
-> definedName
=
633 Malloc ( strlen ( td
-> definedName
) +
634 strlen ( suffix
) + 4 );
636 strcpy ( newDef
-> definedName
, td
-> definedName
);
637 strcat ( newDef
-> definedName
, suffix
);
638 end
= strlen ( newDef
-> definedName
);
641 /* keep name unique */
642 while ( LookupType ( m
-> typeDefs
, newDef
-> definedName
) != NULL
)
644 newDef
-> definedName
[ end
] = '\0' ;
645 AppendDigit ( newDef
-> definedName
, digit
++);
649 * now put new type at head of list
651 typeDefHndl
= ( TypeDef
**) AsnListPrepend ( m
-> typeDefs
);
652 * typeDefHndl
= newDef
;
655 * what to do with tags? Use default universal type on
656 * newly defined type and adjust (new) reference's tags
659 * NOTE: may be simpler just to move all the tags to the
663 newDef
-> type
-> tags
= ( TagList
*) AsnListNew ( sizeof ( void *));
664 if ( LIBTYPE_GET_UNIV_TAG_CODE (( newDef
-> type
-> basicType
-> choiceId
))
667 tmpPtr
= ( Tag
**) AsnListAppend ( newDef
-> type
-> tags
);
668 * tmpPtr
= ( Tag
*) Malloc ( sizeof ( Tag
));
669 (* tmpPtr
)-> tclass
= UNIV
;
670 (* tmpPtr
)-> code
= LIBTYPE_GET_UNIV_TAG_CODE (( newDef
-> type
-> basicType
-> choiceId
));
673 /* adjust tags of new ref to new def */
674 if (( t
-> tags
!= NULL
) && (! LIST_EMPTY ( t
-> tags
)))
676 lastTag
= ( Tag
*) LAST_LIST_ELMT ( t
-> tags
);
677 if (( lastTag
-> tclass
== UNIV
) &&
679 LIBTYPE_GET_UNIV_TAG_CODE (( newDef
-> type
-> basicType
-> choiceId
))))
681 /* zap it since same as default universal tag */
682 SET_CURR_LIST_NODE ( t
-> tags
, LAST_LIST_NODE ( t
-> tags
));
683 AsnListRemove ( t
-> tags
);
688 t
-> implicit
= TRUE
; /* this will probably already be true */
694 * replace embeded CHOICE/SET/SEQ def with ref to newly defined type
696 t
-> basicType
= ( BasicType
*) Malloc ( sizeof ( BasicType
));
697 t
-> basicType
-> choiceId
= BASICTYPE_LOCALTYPEREF
;
698 t
-> basicType
-> a
. localTypeRef
= ( TypeRef
*) Malloc ( sizeof ( TypeRef
));
699 t
-> basicType
-> a
. localTypeRef
-> link
= newDef
;
700 t
-> basicType
-> a
. localTypeRef
-> typeName
=
702 t
-> basicType
-> a
. localTypeRef
-> moduleName
= NULL
;
707 } /* AddConsTypeDef */
711 NormalizeValueDef
PARAMS (( m
, vd
),
715 NormalizeValue ( m
, vd
, vd
-> value
, FALSE
);
719 NormalizeValue
PARAMS (( m
, vd
, v
, quiet
),
731 * convert linked oids into ENC_OID's
733 if ( v
-> basicValue
-> choiceId
== BASICVALUE_LINKEDOID
)
735 if (! FlattenLinkedOid ( v
-> basicValue
-> a
. linkedOid
, m
-> asn1SrcFileName
, v
-> lineNo
, quiet
))
737 eLen
= EncodedOidLen ( v
-> basicValue
-> a
. linkedOid
);
739 eoid
-> octetLen
= eLen
;
740 eoid
-> octs
= ( char *) Malloc ( eLen
);
741 BuildEncodedOid ( v
-> basicValue
-> a
. linkedOid
, eoid
);
743 /* free linked oid */
744 for ( o
= v
-> basicValue
-> a
. linkedOid
; o
!= NULL
; )
750 v
-> basicValue
-> choiceId
= BASICVALUE_OID
;
751 v
-> basicValue
-> a
. oid
= eoid
;
757 * replaces value refs with the value's number if poss
758 * returns TRUE if successfully done.
759 * returns FALSE if a value ref could not be traced
760 * (false should not happen if the value link succeeded)
761 * "quiet" parameter allows err msg to be turned off
762 * which prevents cascading errors by other oid's that
763 * reference a bad oid.
766 FlattenLinkedOid
PARAMS (( o
, asn1FileName
, lineNo
, quiet
),
768 char * asn1FileName _AND_
779 if ( oidRecursionCountG
> 100 )
781 PrintErrLoc ( asn1FileName
, lineNo
);
782 fprintf ( stderr
, "ERROR - recursive OBJECT IDENTIFIER value. \n " );
788 for (; o
!= NULL
; o
= o
-> next
)
790 valRef
= o
-> valueRef
;
791 if (( valRef
== NULL
) || ( o
-> arcNum
!= NULL_OID_ARCNUM
))
792 continue ; /* no linking nec for this one */
794 val
= GetValue ( o
-> valueRef
);
797 * if the very first component is an oid val ref
798 * then insert that value
800 if (( o
== firstElmt
) && ( val
-> basicValue
-> choiceId
== BASICVALUE_OID
))
802 UnbuildEncodedOid ( val
-> basicValue
-> a
. oid
, & refdOid
);
803 for ( tmpOid
= refdOid
; tmpOid
-> next
!= NULL
; tmpOid
= tmpOid
-> next
)
805 tmpOid
-> next
= o
-> next
;
806 memcpy ( firstElmt
, refdOid
, sizeof ( OID
));
807 Free ( refdOid
); /* free first component of OID since copied */
810 else if (( o
== firstElmt
) && ( val
-> basicValue
-> choiceId
== BASICVALUE_LINKEDOID
))
812 oidRecursionCountG
++;
813 if (! FlattenLinkedOid ( val
-> basicValue
-> a
. linkedOid
, asn1FileName
, lineNo
, TRUE
))
815 oidRecursionCountG
--;
818 oidRecursionCountG
--;
821 for ( tmpOid
= val
-> basicValue
-> a
. linkedOid
;
822 tmpOid
!= NULL
; tmpOid
= tmpOid
-> next
)
824 * nextOid
= ( OID
*) Malloc ( sizeof ( OID
));
825 (* nextOid
)-> arcNum
= tmpOid
-> arcNum
;
826 nextOid
= &(* nextOid
)-> next
;
828 (* nextOid
) = o
-> next
;
829 memcpy ( firstElmt
, refdOid
, sizeof ( OID
));
830 Free ( refdOid
); /* since copied into firstElmt */
833 else if (( val
-> basicValue
-> choiceId
== BASICVALUE_INTEGER
))
835 o
-> arcNum
= val
-> basicValue
-> a
. integer
;
836 if (( o
-> arcNum
< 0 ) && ! quiet
)
838 PrintErrLoc ( asn1FileName
, lineNo
);
839 fprintf ( stderr
, "ERROR - OBJECT IDENTIFIER arc values cannot be negative. \n " );
842 else /* bad arc value type */
846 PrintErrLoc ( asn1FileName
, lineNo
);
847 fprintf ( stderr
, "ERROR - type mismatch for an arc value. Values ref'd from an OBJECT IDENTIFIER value must be either an OBJECT IDENTIFIER (first oid elmt only) or INTEGER value (this may be reported twice!) \n " );
852 /* free mem assoc with value ref */
853 Free ( valRef
-> basicValue
-> a
. localValueRef
-> valueName
);
854 Free ( valRef
-> basicValue
-> a
. localValueRef
);
855 Free ( valRef
-> basicValue
);
860 } /* FlattenLinkedOid */