]> git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/compiler/core/normalize.c
Security-54.tar.gz
[apple/security.git] / SecuritySNACCRuntime / compiler / core / normalize.c
1 /*
2 * compiler/core/normalize.c
3 *
4 * 1. swap COMPONENTS OF for actual types
5 * - do this since save lots of special case handling in
6 * code generation
7 *
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
12 *
13 * 3. change CHOICE defs within other constructed types
14 * into CHOICE refs
15 * - makes code production easier. can be changed
16 * with some work
17 *
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)
23 *
24 * 5. change SELECTION types to the actual field from the choice
25 *
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
28 *
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)).
33 *
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.
37 *
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.
41 *
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.
47 *
48 * Mike Sample
49 * 91/12/12
50 *
51 * Copyright (C) 1991, 1992 Michael Sample
52 * and the University of British Columbia
53 *
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.
58 *
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.
63 *
64 * Revision 1.1.1.1 1999/03/16 18:06:50 aram
65 * Originals from SMIME Free Library.
66 *
67 * Revision 1.3 1995/07/25 19:41:40 rj
68 * changed `_' to `-' in file names.
69 *
70 * Revision 1.2 1994/09/01 00:40:56 rj
71 * snacc_config.h removed.
72 *
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.
75 *
76 */
77
78 #include <stdio.h>
79
80 #include "asn-incl.h"
81 #include "mem.h"
82 #include "asn1module.h"
83 #include "oid.h"
84 #include "lib-types.h"
85 #include "snacc-util.h"
86 #include "normalize.h"
87
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"
98
99 long int oidRecursionCountG = 0;
100
101 void NormalizeTypeDef PROTO ((Module *m, TypeDef *td));
102
103 void NormalizeType PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *e, Type *t));
104
105 void NormalizeElmtTypes PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *e));
106
107 void NormalizeBasicType PROTO ((Module *m, TypeDef *td, Type *parent, NamedTypeList *e, Type *type, BasicType *bt));
108
109 TypeDef *AddListElmtTypeDef PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt));
110
111 TypeDef *AddConsTypeDef PROTO ((Module *m, TypeDef *td, Type *t, BasicType *bt, char *suffix));
112
113 void NormalizeValueDef PROTO ((Module *m, ValueDef *vd));
114
115 int FlattenLinkedOid PROTO ((OID *o, char *asn1FileName, AsnInt lineNo, int quiet));
116
117 /*
118 * looks through the given module and performs the operations
119 * mentioned above
120 */
121 void
122 NormalizeModule PARAMS ((m),
123 Module *m)
124 {
125 TypeDef *td;
126 ValueDef *vd;
127
128 /*
129 * go through each type in typeList
130 */
131 FOR_EACH_LIST_ELMT (td, m->typeDefs)
132 {
133 NormalizeTypeDef (m, td);
134 }
135
136 /*
137 * go through each value for types?
138 */
139 FOR_EACH_LIST_ELMT (vd, m->valueDefs)
140 {
141 NormalizeValueDef (m, vd);
142 }
143
144 } /* NormalizeModule */
145
146
147 void
148 NormalizeTypeDef PARAMS ((m, td),
149 Module *m _AND_
150 TypeDef *td)
151 {
152 if (td == NULL)
153 return;
154
155 NormalizeType (m, td, NULL, NULL, td->type);
156
157 } /* NormalizeTypeDef */
158
159
160 void
161 NormalizeType PARAMS ((m, td, parent, e, t),
162 Module *m _AND_
163 TypeDef *td _AND_
164 Type *parent _AND_
165 NamedTypeList *e _AND_
166 Type *t)
167 {
168 enum BasicTypeChoiceId typeId;
169 Type *tmpType;
170 Tag *lastTag;
171
172 if (t == NULL)
173 return;
174
175 NormalizeBasicType (m, td, parent, e, t, t->basicType);
176
177 /*
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).
181 */
182 if ((m->tagDefault == IMPLICIT_TAGS))
183 {
184 tmpType = ParanoidGetType (t);
185 typeId = tmpType->basicType->choiceId;
186
187 if ((t->tags != NULL) && (!LIST_EMPTY (t->tags)))
188 lastTag = (Tag*)LAST_LIST_ELMT (t->tags);
189 else
190 lastTag = NULL;
191
192 /*
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)
199 */
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))
204 {
205 t->implicit = TRUE;
206 }
207 }
208
209 } /* NormalizeType */
210
211
212
213 void
214 NormalizeElmtTypes PARAMS ((m, td, parent, e),
215 Module *m _AND_
216 TypeDef *td _AND_
217 Type *parent _AND_
218 NamedTypeList *e)
219 {
220 NamedType *nt;
221
222 FOR_EACH_LIST_ELMT (nt, e)
223 {
224 NormalizeType (m, td, parent, e, nt->type);
225 }
226 } /* NormalizeElmtTypes */
227
228
229 /*
230 * this is where most of the action happens
231 * assumes that "e"'s curr ptr is namedtype that holds "type"
232 */
233 void
234 NormalizeBasicType PARAMS ((m, td, parent, e, type, bt),
235 Module *m _AND_
236 TypeDef *td _AND_
237 Type *parent _AND_
238 NamedTypeList *e _AND_
239 Type *type _AND_
240 BasicType *bt)
241 {
242 int i, numElmtsAdded;
243 NamedType *newElmt;
244 NamedType **newElmtHndl;
245 NamedType *nt;
246 NamedTypeList *elmts;
247 NamedType *origNext;
248 Type *compType;
249 Type *parentType;
250 TypeDef *newDef;
251 BasicType *tmpBasicType;
252 TagList *tags;
253 Tag *tag;
254 Tag **tagHndl;
255
256 if (bt == NULL)
257 return;
258
259 switch (bt->choiceId)
260 {
261
262 case BASICTYPE_COMPONENTSOF:
263 /*
264 * copy elmts of COMPONENTS OF type into this type
265 */
266 if (parent == NULL)
267 {
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;
271 return;
272 }
273
274 compType = ParanoidGetType (bt->a.componentsOf);
275 parentType = ParanoidGetType (parent);
276
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))
280 {
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;
284 return;
285 }
286
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)))
292 {
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;
297 return;
298 }
299
300 /*
301 * replace "COMPONENTS OF" with elmts from ref'd set
302 */
303 elmts = compType->basicType->a.set;
304
305 if (elmts == NULL)
306 break;
307
308 /*
309 * add new list elmts that point to elmts
310 * of type ref'd by COMPONENTS OF
311 */
312 FOR_EACH_LIST_ELMT (nt, elmts)
313 {
314 newElmtHndl = (NamedType**)AsnListAdd (e);
315 *newElmtHndl = nt;
316 }
317
318 /*
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
323 */
324 numElmtsAdded = AsnListCount (elmts);
325 for (i = 0; i < numElmtsAdded; i++)
326 AsnListPrev (e);
327
328 /* remove the componets of ref since elmts copied in */
329 AsnListRemove (e);
330
331 break;
332
333
334 case BASICTYPE_SELECTION:
335 /*
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)
344 */
345 NormalizeType (m, type->basicType->a.selection->typeRef->basicType->a.localTypeRef->link, NULL, NULL, type->basicType->a.selection->typeRef->basicType->a.localTypeRef->link->type);
346
347 /*
348 * use SELECTION field name if this is an elmt type with no
349 * field name.
350 */
351 if ((e != NULL) &&
352 (((NamedType*) e->curr->data)->fieldName == NULL))
353 ((NamedType*) e->curr->data)->fieldName =
354 type->basicType->a.selection->link->fieldName;
355
356 /*
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.
360 */
361 tmpBasicType = type->basicType->a.selection->link->type->basicType;
362 tags = type->basicType->a.selection->link->type->tags;
363
364
365 FOR_EACH_LIST_ELMT (tag, tags)
366 {
367 if (!(((m->tagDefault == IMPLICIT_TAGS) || (type->implicit)) &&
368 (tag == (Tag*)FIRST_LIST_ELMT (tags))))
369 {
370 tagHndl = (Tag**) AsnListAppend (type->tags);
371 *tagHndl = tag;
372 }
373 type->implicit = FALSE;
374 }
375
376 if (type->basicType->a.selection->link->type->implicit)
377 type->implicit = TRUE;
378
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;
383
384 break;
385
386
387
388 case BASICTYPE_SEQUENCEOF:
389 case BASICTYPE_SETOF:
390 /* convert def inside other type into a ref */
391 if (td->type != type)
392 {
393 if (bt->choiceId == BASICTYPE_SETOF)
394 newDef = AddConsTypeDef (m, td, type, bt, SETOF_SUFFIX);
395 else
396 newDef = AddConsTypeDef (m, td, type, bt, SEQOF_SUFFIX);
397
398 NormalizeType (m, newDef, NULL, NULL, newDef->type);
399 }
400 else
401 NormalizeType (m, td, type, NULL, type->basicType->a.setOf);
402 break;
403
404 /* NOT NEEDED ANY MORE
405 * convert typdef after SET OF/SEQ OF to type REFS
406 switch (bt->a.setOf->basicType->choiceId)
407 {
408 case BASICTYPE_SEQUENCE:
409 case BASICTYPE_SET:
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);
416 break;
417
418 default:
419 NormalizeType (m, td, NULL, NULL, bt->a.setOf);
420 break;
421 }
422 */
423 break;
424
425
426 case BASICTYPE_CHOICE:
427 /*
428 * change CHOICE defs embedded in other types
429 * into type refs
430 */
431 if (td->type != type)
432 {
433 newDef = AddConsTypeDef (m, td, type, bt, CHOICE_SUFFIX);
434 NormalizeType (m, newDef, NULL, NULL, newDef->type);
435 }
436 else
437 NormalizeElmtTypes (m, td, type, bt->a.set);
438
439 break;
440
441
442 case BASICTYPE_SEQUENCE:
443 /*
444 * change SEQ defs embedded in other types
445 * into type refs
446 */
447 if (td->type != type)
448 {
449 newDef = AddConsTypeDef (m, td, type, bt, SEQ_SUFFIX);
450 NormalizeType (m, newDef, NULL, NULL, newDef->type);
451 }
452 else
453 NormalizeElmtTypes (m, td, type, bt->a.sequence);
454 break;
455
456
457 case BASICTYPE_SET:
458 /*
459 * change SET defs embedded in other types
460 * into type refs
461 */
462 if (td->type != type)
463 {
464 newDef = AddConsTypeDef (m, td, type, bt, SET_SUFFIX);
465 NormalizeType (m, newDef, NULL, NULL, newDef->type);
466 }
467 else
468 NormalizeElmtTypes (m, td, type, bt->a.set);
469 break;
470
471
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)))
476 {
477 newDef = AddConsTypeDef (m, td, type, bt, INT_SUFFIX);
478 }
479 break;
480
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)))
485 {
486 newDef = AddConsTypeDef (m, td, type, bt, ENUM_SUFFIX);
487 }
488 break;
489
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)))
494 {
495 newDef = AddConsTypeDef (m, td, type, bt, BITS_SUFFIX);
496 }
497 break;
498
499 case BASICTYPE_ANY:
500 case BASICTYPE_ANYDEFINEDBY:
501 m->hasAnys = TRUE;
502 /* NO LONGER DONE
503 * change ANY defs embedded in other types
504 * into type refs
505
506 if (td->type != type)
507 newDef = AddConsTypeDef (m, td, type, bt, ANY_SUFFIX);
508 */
509 break;
510
511 default:
512 /* the rest are not processed */
513 break;
514 }
515 } /* NormalizeBasicType */
516
517
518
519
520 /*
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.
524 */
525 TypeDef*
526 AddListElmtTypeDef PARAMS ((m, td, t, bt),
527 Module *m _AND_
528 TypeDef *td _AND_
529 Type *t _AND_
530 BasicType *bt)
531 {
532 TypeDef *newDef;
533 TypeDef **typeDefHndl;
534 int end;
535 int digit;
536
537 /*
538 * make new type def
539 */
540 newDef = (TypeDef*)Malloc (sizeof (TypeDef));
541 newDef->exported = FALSE;
542 newDef->type = bt->a.setOf;
543 /*
544 * make name for new type
545 * Foo ::= SET OF SEQUENCE {...}
546 * -->
547 * FooListElmt ::= SEQUENCE {...}
548 * Foo ::= SET OF FooListElmt
549 */
550 newDef->definedName =
551 Malloc (strlen (td->definedName) +
552 strlen (LIST_ELMT_SUFFIX) + 4);
553
554 strcpy (newDef->definedName, td->definedName);
555 strcat (newDef->definedName, LIST_ELMT_SUFFIX);
556 end = strlen (newDef->definedName);
557 digit = 1;
558 while (LookupType (m->typeDefs, newDef->definedName) != NULL)
559 {
560 newDef->definedName[end] = '\0';
561 AppendDigit (newDef->definedName, digit++);
562 }
563
564 /*
565 * now put new type at head of list
566 */
567 typeDefHndl = (TypeDef**)AsnListPrepend (m->typeDefs);
568 *typeDefHndl = newDef;
569
570
571
572 /*
573 * replace SET OF/SEQ OF body with type ref
574 */
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 =
584 newDef->definedName;
585 bt->a.setOf->basicType->a.localTypeRef->moduleName = NULL;
586
587
588 return newDef;
589
590 } /* AddListElmtTypeDefs */
591
592
593
594 /*
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
597 */
598 TypeDef*
599 AddConsTypeDef PARAMS ((m, td, t, bt, suffix),
600 Module *m _AND_
601 TypeDef *td _AND_
602 Type *t _AND_
603 BasicType *bt _AND_
604 char *suffix)
605 {
606 TypeDef *newDef;
607 TypeDef **typeDefHndl;
608 Tag **tmpPtr;
609 Tag *lastTag;
610 int end;
611 int digit;
612
613 /*
614 * make new type def
615 */
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;
624
625 /*
626 * make name for new choice/SET/SEQ
627 * Foo ::= SEQUENCE { .., bar CHOICE { ...}, ..}
628 * -->
629 * FooChoice ::= CHOICE { ...}
630 * Foo ::= SEQUENCE { .., bar FooChoice, .. }
631 */
632 newDef->definedName =
633 Malloc (strlen (td->definedName) +
634 strlen (suffix) + 4);
635
636 strcpy (newDef->definedName, td->definedName);
637 strcat (newDef->definedName, suffix);
638 end = strlen (newDef->definedName);
639 digit = 1;
640
641 /* keep name unique */
642 while (LookupType (m->typeDefs, newDef->definedName) != NULL)
643 {
644 newDef->definedName[end] = '\0';
645 AppendDigit (newDef->definedName, digit++);
646 }
647
648 /*
649 * now put new type at head of list
650 */
651 typeDefHndl = (TypeDef**)AsnListPrepend (m->typeDefs);
652 *typeDefHndl = newDef;
653
654 /*
655 * what to do with tags? Use default universal type on
656 * newly defined type and adjust (new) reference's tags
657 * appropriately
658 *
659 * NOTE: may be simpler just to move all the tags to the
660 * new def.
661 */
662
663 newDef->type->tags = (TagList*)AsnListNew (sizeof (void*));
664 if (LIBTYPE_GET_UNIV_TAG_CODE ((newDef->type->basicType->choiceId))
665 != NO_TAG_CODE)
666 {
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));
671
672
673 /* adjust tags of new ref to new def */
674 if ((t->tags != NULL) && (!LIST_EMPTY (t->tags)))
675 {
676 lastTag = (Tag*)LAST_LIST_ELMT (t->tags);
677 if ((lastTag->tclass == UNIV) &&
678 (lastTag->code ==
679 LIBTYPE_GET_UNIV_TAG_CODE ((newDef->type->basicType->choiceId))))
680 {
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);
684 t->implicit = FALSE;
685 }
686 else
687 {
688 t->implicit = TRUE; /* this will probably already be true */
689 }
690 }
691
692 }
693 /*
694 * replace embeded CHOICE/SET/SEQ def with ref to newly defined type
695 */
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 =
701 newDef->definedName;
702 t->basicType->a.localTypeRef->moduleName = NULL;
703
704
705 return newDef;
706
707 } /* AddConsTypeDef */
708
709
710 void
711 NormalizeValueDef PARAMS ((m, vd),
712 Module *m _AND_
713 ValueDef *vd)
714 {
715 NormalizeValue (m, vd, vd->value, FALSE);
716 }
717
718 void
719 NormalizeValue PARAMS ((m, vd, v, quiet),
720 Module *m _AND_
721 ValueDef *vd _AND_
722 Value *v _AND_
723 int quiet)
724 {
725 AsnOid *eoid;
726 OID *o;
727 OID *tmp;
728 int eLen;
729
730 /*
731 * convert linked oids into ENC_OID's
732 */
733 if (v->basicValue->choiceId == BASICVALUE_LINKEDOID)
734 {
735 if (!FlattenLinkedOid (v->basicValue->a.linkedOid, m->asn1SrcFileName, v->lineNo, quiet))
736 return;
737 eLen = EncodedOidLen (v->basicValue->a.linkedOid);
738 eoid = MT (AsnOid);
739 eoid->octetLen = eLen;
740 eoid->octs = (char*)Malloc (eLen);
741 BuildEncodedOid (v->basicValue->a.linkedOid, eoid);
742
743 /* free linked oid */
744 for (o = v->basicValue->a.linkedOid; o != NULL; )
745 {
746 tmp = o->next;
747 Free (o);
748 o = tmp;
749 }
750 v->basicValue->choiceId = BASICVALUE_OID;
751 v->basicValue->a.oid = eoid;
752 }
753 }
754
755
756 /*
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.
764 */
765 int
766 FlattenLinkedOid PARAMS ((o, asn1FileName, lineNo, quiet),
767 OID *o _AND_
768 char *asn1FileName _AND_
769 AsnInt lineNo _AND_
770 int quiet)
771 {
772 OID *firstElmt;
773 OID *refdOid;
774 OID *tmpOid;
775 OID **nextOid;
776 Value *val;
777 Value *valRef;
778
779 if (oidRecursionCountG > 100)
780 {
781 PrintErrLoc (asn1FileName, lineNo);
782 fprintf (stderr,"ERROR - recursive OBJECT IDENTIFIER value.\n");
783 return FALSE;
784 }
785
786 firstElmt = o;
787
788 for (; o != NULL; o = o->next)
789 {
790 valRef = o->valueRef;
791 if ((valRef == NULL) || (o->arcNum != NULL_OID_ARCNUM))
792 continue; /* no linking nec for this one */
793
794 val = GetValue (o->valueRef);
795
796 /*
797 * if the very first component is an oid val ref
798 * then insert that value
799 */
800 if ((o == firstElmt) && (val->basicValue->choiceId == BASICVALUE_OID))
801 {
802 UnbuildEncodedOid (val->basicValue->a.oid, &refdOid);
803 for (tmpOid = refdOid; tmpOid->next != NULL; tmpOid = tmpOid->next)
804 ;
805 tmpOid->next = o->next;
806 memcpy (firstElmt, refdOid, sizeof (OID));
807 Free (refdOid); /* free first component of OID since copied */
808 }
809
810 else if ((o == firstElmt) && (val->basicValue->choiceId == BASICVALUE_LINKEDOID))
811 {
812 oidRecursionCountG++;
813 if (!FlattenLinkedOid (val->basicValue->a.linkedOid, asn1FileName, lineNo, TRUE))
814 {
815 oidRecursionCountG--;
816 return FALSE;
817 }
818 oidRecursionCountG--;
819
820 nextOid = &refdOid;
821 for (tmpOid = val->basicValue->a.linkedOid;
822 tmpOid != NULL; tmpOid = tmpOid->next)
823 {
824 *nextOid = (OID*)Malloc (sizeof (OID));
825 (*nextOid)->arcNum = tmpOid->arcNum;
826 nextOid = &(*nextOid)->next;
827 }
828 (*nextOid) = o->next;
829 memcpy (firstElmt, refdOid, sizeof (OID));
830 Free (refdOid); /* since copied into firstElmt */
831 }
832
833 else if ((val->basicValue->choiceId == BASICVALUE_INTEGER))
834 {
835 o->arcNum = val->basicValue->a.integer;
836 if ((o->arcNum < 0) && !quiet)
837 {
838 PrintErrLoc (asn1FileName, lineNo);
839 fprintf (stderr,"ERROR - OBJECT IDENTIFIER arc values cannot be negative.\n");
840 }
841 }
842 else /* bad arc value type */
843 {
844 if (!quiet)
845 {
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");
848 }
849 return FALSE;
850 }
851
852 /* free mem assoc with value ref */
853 Free (valRef->basicValue->a.localValueRef->valueName);
854 Free (valRef->basicValue->a.localValueRef);
855 Free (valRef->basicValue);
856 Free (valRef);
857 o->valueRef = NULL;
858 }
859 return TRUE;
860 } /* FlattenLinkedOid */