2 * compiler/core/gen_tbls.c
4 * generates type tables and writes them to a file.
9 * Copyright (C) 1993 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/Darwin/Security/SecuritySNACCRuntime/compiler/core/gen-tbls.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $
18 * $Log: gen-tbls.c,v $
19 * Revision 1.1 2001/06/20 21:27:57 dmitch
20 * Adding missing snacc compiler files.
22 * Revision 1.1.1.1 1999/03/16 18:06:48 aram
23 * Originals from SMIME Free Library.
25 * Revision 1.5 1997/06/19 09:17:16 wan
26 * Added isPdu flag to tables. Added value range checks during parsing.
28 * Revision 1.4 1997/05/07 15:18:34 wan
29 * Added (limited) size constraints, bitstring and enumeration names to tables
31 * Revision 1.3 1995/07/25 19:41:28 rj
32 * changed `_' to `-' in file names.
34 * Revision 1.2 1994/09/01 00:33:41 rj
35 * snacc_config.h removed.
37 * Revision 1.1 1994/08/28 09:49:10 rj
38 * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
45 #include "asn1module.h"
49 extern Module
*usefulTypeModG
;
51 /* non-exported routine protos */
52 void GenTypeDefIds
PROTO ((TBL
*tbl
, Module
*m
));
53 int GenTblModule
PROTO ((TBL
*tbl
, Module
*m
, TBLModule
**newTbl
));
54 int GenTblTypeDefs
PROTO ((TBL
*tbl
, Module
*m
, TBLModule
*tblMod
));
55 int GenTblTypes
PROTO ((TBL
*tbl
, Module
*m
, TBLModule
*tblMod
, TypeDef
*td
, TBLTypeDef
*tblTd
));
56 TBLType
*GenTblTypesRec
PROTO ((TBL
*tbl
,Module
*m
, TBLModule
*tblMod
, TypeDef
*td
, TBLTypeDef
*tblTd
, Type
*t
));
59 static int abortTblTypeDefG
;
60 static int tblTypesTotalG
;
61 static int tblTagsTotalG
;
62 static int tblStringsTotalG
;
63 static int tblStringLenTotalG
;
65 static int tableFileVersionG
;
68 GenTypeTbls
PARAMS ((mods
, fileName
, tableFileVersion
),
69 ModuleList
*mods _AND_
80 tableFileVersionG
= tableFileVersion
;
82 tbl
.modules
= AsnListNew (sizeof (void*));
83 tbl
.totalNumModules
= 0;
84 tbl
.totalNumTypeDefs
= 0;
85 tbl
.totalNumTypes
= 0;
87 tbl
.totalNumStrings
= 0;
88 tbl
.totalLenStrings
= 0;
91 * Give each type def a unique id
92 * Id is stored in TypeDef's "tmpRefCount" since
93 * it was only used in the recursion pass.
94 * Also updates tbl.totalNumModules and
95 * tbl.totalNumTypeDefs appropriately
97 FOR_EACH_LIST_ELMT (m
, mods
)
99 GenTypeDefIds (&tbl
, m
);
102 /* number useful types if they are there any */
103 if (usefulTypeModG
!= NULL
)
104 GenTypeDefIds (&tbl
, usefulTypeModG
);
106 /* convert each module from parse format to simpler table format */
107 FOR_EACH_LIST_ELMT (m
, mods
)
109 if (!GenTblModule (&tbl
, m
, &newTblMod
))
111 fprintf (stderr
,"ERROR: type table generator failed for module \"%s\", so file \"%s\" will not be written.\n", m
->modId
->name
, fileName
);
117 * convert useful type mod from parse format to
118 * simpler table format, if one was given
120 if (usefulTypeModG
!= NULL
)
122 if (!GenTblModule (&tbl
, usefulTypeModG
, &newTblMod
))
124 fprintf (stderr
,"ERROR: type table generator failed for useful types module, file \"%s\" will not be written.\n",fileName
);
127 /* mark the module as useful */
128 newTblMod
->isUseful
= TRUE
;
131 /* encode the TBLModules */
133 buf
= ExpBufAllocBufAndData();
135 BEncTBL (&buf
, &tbl
);
137 if (ExpBufWriteError (&buf
))
139 fprintf (stderr
,"ERROR: buffer write error during encoding of type table.\n", fileName
);
144 /* open & truncate or create as file with given filename */
145 tblFile
= fopen (fileName
,"w");
149 fprintf (stderr
,"ERROR: Could not open file \"%s\" for the type table.\n", fileName
);
155 * go through buffer (s) and write encoded value
158 buf
->curr
= buf
->dataStart
;
159 for (tmpBuf
= buf
; tmpBuf
!= NULL
; tmpBuf
= tmpBuf
->next
)
161 fwrite (tmpBuf
->dataStart
, tmpBuf
->dataEnd
- tmpBuf
->dataStart
, 1, tblFile
);
170 * The typeDefIds start at zero. They are used as "portable"
171 * pointers. Each TBLTypeDef has a unique typeDefId.
172 * The typeDefIds in a given TBLModule will be consecutive
173 * and increasing from the first typedef to the last.
175 * This routine gives each type def in the given module a unique
176 * integer identifier.
177 * This id is temporarily stored in the tmpRefCount field of the TypeDef
178 * (in the big parse tree). The typeDefId is transfered
179 * to the TBL data structure after this.
181 * tbl.totalNumModules and tbl.totalNumTypeDefs are updated.
183 * ASSUMES: that tbl->totalNumModules is initialized to zero
184 * and that tbl->totalNumTypeDefs is initialized to zero
185 * on the first call to this routine.
186 * This allows subsequent calls to give out the proper ids
187 * to the types in the next module.
189 * (the type ids range from 0 to tbl->totalNumTypeDefs-1 (inclusive))
192 GenTypeDefIds
PARAMS ((tbl
,m
),
198 tbl
->totalNumModules
++;
199 FOR_EACH_LIST_ELMT (td
, m
->typeDefs
)
201 td
->tmpRefCount
= tbl
->totalNumTypeDefs
;
202 tbl
->totalNumTypeDefs
++;
205 } /* GenTypeDefIds */
209 * builds a TBLModule from the given module and appends it to
210 * the given TBL's module list. Also updates the TBLs
211 * totals for modules, tags, typedefs and types.
212 * Returns TRUE is succeeded. FALSE is failed.
215 GenTblModule
PARAMS ((tbl
, m
, newTblMod
),
218 TBLModule
**newTblMod
)
225 mHndl
= AsnListAppend (tbl
->modules
);
227 tblMod
= MT (TBLModule
);
228 *newTblMod
= *mHndl
= tblMod
;
231 tblMod
->name
.octetLen
= strlen (m
->modId
->name
);
232 tblMod
->name
.octs
= Malloc (tblMod
->name
.octetLen
+ 1);
233 strcpy (tblMod
->name
.octs
, m
->modId
->name
);
234 tbl
->totalNumStrings
++;
235 tbl
->totalLenStrings
+= tblMod
->name
.octetLen
;
237 /* copy the OBJECT IDENTIFIER (if any) */
238 if (m
->modId
->oid
!= NULL
)
240 /* convert the (linked) OID into a (encoded) AsnOid */
241 if (FlattenLinkedOid (m
->modId
->oid
))
243 eLen
= EncodedOidLen (m
->modId
->oid
);
244 tblMod
->id
.octetLen
= eLen
;
245 tblMod
->id
.octs
= (char*)Malloc (eLen
);
246 BuildEncodedOid (m
->modId
->oid
, &tblMod
->id
);
247 tbl
->totalNumStrings
++;
248 tbl
->totalLenStrings
+= eLen
;
253 * useful defaults to false
254 * (ie assume the it is not the usefultypes modules)
256 tblMod
->isUseful
= FALSE
;
258 /* now copy each of the type defs */
259 return GenTblTypeDefs (tbl
, m
, tblMod
);
265 * converts typeDefs in Module format to TBLModule format
266 * returns TRUE for success, FALSE for failure.
269 GenTblTypeDefs
PARAMS ((tbl
, m
, tblMod
),
275 TBLTypeDef
**tblTdHndl
;
277 int isOk
= TRUE
; /* init to no errors */
279 tblMod
->typeDefs
= AsnListNew (sizeof (void*));
280 FOR_EACH_LIST_ELMT (td
, m
->typeDefs
)
283 tblTd
= MT (TBLTypeDef
);
285 /* set type def id */
286 tblTd
->typeDefId
= td
->tmpRefCount
;
288 /* copy type def name */
289 tblTd
->typeName
.octetLen
= strlen (td
->definedName
);
290 tblTd
->typeName
.octs
= Malloc (tblTd
->typeName
.octetLen
+ 1);
291 strcpy (tblTd
->typeName
.octs
, td
->definedName
);
292 tbl
->totalNumStrings
++;
293 tbl
->totalLenStrings
+= tblTd
->typeName
.octetLen
;
297 tblTd->isPdu = MT (AsnNull);
299 if (m
!=usefulTypeModG
)
305 FOR_EACH_LIST_ELMT(attr
,td
->attrList
)
310 ParseAttr(attr
,&loc
,&attrName
,&attrValue
);
313 if (!strcmp(attrName
,"isPdu"))
314 if (ParseBool(attrValue
,&result
)<0)
315 fprintf(stderr
,"Warning: ignoring attribute with improper value (%s/%s)\n",attrName
,attrValue
);
320 tblTd
->isPdu
= MT (AsnNull
);
324 /* fill in type portion */
325 if (!GenTblTypes (tbl
, m
, tblMod
, td
, tblTd
) && !abortTblTypeDefG
)
330 * add TBLtypeDef to TBLModule
331 * if no weird types were found
332 * (weird types are skipped)
334 if (!abortTblTypeDefG
)
336 tblTdHndl
= AsnListAppend (tblMod
->typeDefs
);
338 tbl
->totalNumTypes
+= tblTypesTotalG
;
339 tbl
->totalNumTags
+= tblTagsTotalG
;
340 tbl
->totalNumStrings
+= tblStringsTotalG
;
341 tbl
->totalLenStrings
+= tblStringLenTotalG
;
343 /* else could free it */
347 } /* GenTblTypeDefs */
351 * converts Module Type to a TBLModule Type. attaches converted
352 * type info to the given tblTd.
353 * Returns TRUE for success, FALSE for failure.
356 GenTblTypes
PARAMS ((tbl
, m
, tblMod
, td
, tblTd
),
359 TBLModule
*tblMod _AND_
363 abortTblTypeDefG
= FALSE
;
366 tblStringsTotalG
= 0;
367 tblStringLenTotalG
= 0;
369 tblTd
->type
= GenTblTypesRec (tbl
, m
, tblMod
, td
, tblTd
, td
->type
);
371 if (tblTd
->type
== NULL
)
372 return FALSE
; /* failed */
379 GetTblValue
PARAMS ((v
),
382 switch (v
->basicValue
->choiceId
)
384 case BASICVALUE_INTEGER
:
385 return v
->basicValue
;
391 enum BasicTypeChoiceId
392 GetTblBasicType
PARAMS ((bt
),
395 switch (bt
->choiceId
)
397 case BASICTYPE_LOCALTYPEREF
:
398 case BASICTYPE_IMPORTTYPEREF
:
399 return GetTblBasicType (bt
->a
.localTypeRef
->link
->type
->basicType
);
406 GenTblValueRange
PARAMS ((tbl
, m
, tblMod
, s
, doSize
),
409 TBLModule
*tblMod _AND_
417 if (tableFileVersionG
<=1)
423 switch (s
->a
.single
->choiceId
)
425 case SUBTYPEVALUE_SINGLEVALUE
:
428 from
= to
= GetTblValue (s
->a
.single
->a
.singleValue
);
430 case SUBTYPEVALUE_VALUERANGE
:
433 from
=GetTblValue(s
->a
.single
->a
.valueRange
->lowerEndValue
);
434 to
= GetTblValue (s
->a
.single
->a
.valueRange
->upperEndValue
);
436 case SUBTYPEVALUE_SIZECONSTRAINT
:
439 return GenTblValueRange (tbl
, m
, tblMod
,
440 s
->a
.single
->a
.sizeConstraint
, 0);
447 if (s
->a
.and && LIST_COUNT(s
->a
.and)==1)
448 return GenTblValueRange (tbl
, m
, tblMod
,
449 FIRST_LIST_ELMT(s
->a
.and), doSize
);
452 if (s
->a
.and && LIST_COUNT(s
->a
.or)==1)
453 return GenTblValueRange (tbl
, m
, tblMod
,
454 FIRST_LIST_ELMT(s
->a
.or), doSize
);
461 range
= MT (TBLRange
);
462 range
->from
= from
->a
.integer
;
463 range
->to
= to
->a
.integer
;
468 GenTblValues
PARAMS ((tbl
, m
, tblMod
, list
),
471 TBLModule
*tblMod _AND_
472 NamedNumberList
* list
)
474 TBLNamedNumberList
* tnnl
= NULL
;
476 if (tableFileVersionG
<=1)
479 if (list
&& !LIST_EMPTY(list
))
482 tnnl
= (TBLNamedNumberList
*) AsnListNew(sizeof(void*));
483 FOR_EACH_LIST_ELMT(vd
,list
)
485 BasicValue
* bv
= GetTblValue(vd
->value
);
488 TBLNamedNumber
* tnn
= MT(TBLNamedNumber
);
489 *(TBLNamedNumber
**)AsnListAppend(tnnl
) = tnn
;
490 tnn
->value
= bv
->a
.integer
;
493 tnn
->name
.octetLen
= strlen(vd
->definedName
);
494 tnn
->name
.octs
= Malloc(tnn
->name
.octetLen
+1);
495 strcpy(tnn
->name
.octs
,vd
->definedName
);
497 tblStringLenTotalG
+= tnn
->name
.octetLen
;
507 GenTblTypesRec
PARAMS ((tbl
, m
, tblMod
, td
, tblTd
, t
),
510 TBLModule
*tblMod _AND_
512 TBLTypeDef
*tblTd _AND_
523 tblT
->content
= MT (TBLTypeContent
);
524 switch (t
->basicType
->choiceId
)
526 case BASICTYPE_BOOLEAN
:
527 tblT
->typeId
= TBL_BOOLEAN
;
528 tblT
->content
->choiceId
= TBLTYPECONTENT_PRIMTYPE
;
531 case BASICTYPE_INTEGER
:
532 tblT
->typeId
= TBL_INTEGER
;
533 tblT
->content
->choiceId
= TBLTYPECONTENT_PRIMTYPE
;
536 case BASICTYPE_BITSTRING
:
537 tblT
->typeId
= TBL_BITSTRING
;
538 tblT
->content
->choiceId
= TBLTYPECONTENT_PRIMTYPE
;
539 tblT
->values
= GenTblValues(tbl
,m
,tblMod
,t
->basicType
->a
.bitString
);
542 case BASICTYPE_OCTETSTRING
:
543 tblT
->typeId
= TBL_OCTETSTRING
;
544 tblT
->content
->choiceId
= TBLTYPECONTENT_PRIMTYPE
;
546 tblT
->constraint
= GenTblValueRange(tbl
, m
, tblMod
,t
->subtypes
,1);
550 tblT
->typeId
= TBL_NULL
;
551 tblT
->content
->choiceId
= TBLTYPECONTENT_PRIMTYPE
;
555 tblT
->typeId
= TBL_OID
;
556 tblT
->content
->choiceId
= TBLTYPECONTENT_PRIMTYPE
;
560 tblT
->typeId
= TBL_REAL
;
561 tblT
->content
->choiceId
= TBLTYPECONTENT_PRIMTYPE
;
564 case BASICTYPE_ENUMERATED
:
565 tblT
->typeId
= TBL_ENUMERATED
;
566 tblT
->content
->choiceId
= TBLTYPECONTENT_PRIMTYPE
;
567 tblT
->values
= GenTblValues(tbl
,m
,tblMod
,t
->basicType
->a
.enumerated
);
570 case BASICTYPE_SEQUENCE
:
571 tblT
->typeId
= TBL_SEQUENCE
;
572 tblT
->content
->choiceId
= TBLTYPECONTENT_ELMTS
;
573 tblT
->content
->a
.elmts
= AsnListNew (sizeof (void*));
574 FOR_EACH_LIST_ELMT (e
, t
->basicType
->a
.sequence
)
576 tblTHndl
= AsnListAppend (tblT
->content
->a
.elmts
);
577 *tblTHndl
= GenTblTypesRec (tbl
, m
, tblMod
, td
, tblTd
, e
->type
);
579 if (*tblTHndl
== NULL
)
582 if (e
->fieldName
!= NULL
)
584 (**tblTHndl
).fieldName
.octetLen
= strlen (e
->fieldName
);
585 (**tblTHndl
).fieldName
.octs
=
586 Malloc ((**tblTHndl
).fieldName
.octetLen
+ 1);
587 strcpy ((**tblTHndl
).fieldName
.octs
, e
->fieldName
);
589 tblStringLenTotalG
+= (**tblTHndl
).fieldName
.octetLen
;
592 (**tblTHndl
).optional
=
593 ((e
->type
->optional
) || (e
->type
->defaultVal
!= NULL
));
599 tblT
->typeId
= TBL_SET
;
600 tblT
->content
->choiceId
= TBLTYPECONTENT_ELMTS
;
601 tblT
->content
->a
.elmts
= AsnListNew (sizeof (void*));
602 FOR_EACH_LIST_ELMT (e
, t
->basicType
->a
.set
)
604 tblTHndl
= AsnListAppend (tblT
->content
->a
.elmts
);
605 *tblTHndl
= GenTblTypesRec (tbl
, m
, tblMod
, td
, tblTd
, e
->type
);
607 if (*tblTHndl
== NULL
)
610 if (e
->fieldName
!= NULL
)
612 (**tblTHndl
).fieldName
.octetLen
= strlen (e
->fieldName
);
613 (**tblTHndl
).fieldName
.octs
=
614 Malloc ((**tblTHndl
).fieldName
.octetLen
+ 1);
615 strcpy ((**tblTHndl
).fieldName
.octs
, e
->fieldName
);
617 tblStringLenTotalG
+= (**tblTHndl
).fieldName
.octetLen
;
620 (**tblTHndl
).optional
=
621 ((e
->type
->optional
) || (e
->type
->defaultVal
!= NULL
));
626 case BASICTYPE_SEQUENCEOF
:
627 tblT
->typeId
= TBL_SEQUENCEOF
;
628 tblT
->content
->choiceId
= TBLTYPECONTENT_ELMTS
;
629 tblT
->content
->a
.elmts
= AsnListNew (sizeof (void*));
630 tblTHndl
= AsnListAppend (tblT
->content
->a
.elmts
);
631 *tblTHndl
= GenTblTypesRec (tbl
, m
, tblMod
, td
, tblTd
, t
->basicType
->a
.sequenceOf
);
633 tblT
->constraint
= GenTblValueRange(tbl
, m
, tblMod
,t
->subtypes
,1);
636 case BASICTYPE_SETOF
:
637 tblT
->typeId
= TBL_SETOF
;
638 tblT
->content
->choiceId
= TBLTYPECONTENT_ELMTS
;
639 tblT
->content
->a
.elmts
= AsnListNew (sizeof (void*));
640 tblTHndl
= AsnListAppend (tblT
->content
->a
.elmts
);
641 *tblTHndl
= GenTblTypesRec (tbl
, m
, tblMod
, td
, tblTd
, t
->basicType
->a
.setOf
);
643 tblT
->constraint
= GenTblValueRange(tbl
, m
, tblMod
,t
->subtypes
,1);
646 case BASICTYPE_CHOICE
:
647 tblT
->typeId
= TBL_CHOICE
;
648 tblT
->content
->choiceId
= TBLTYPECONTENT_ELMTS
;
649 tblT
->content
->a
.elmts
= AsnListNew (sizeof (void*));
650 FOR_EACH_LIST_ELMT (e
, t
->basicType
->a
.set
)
652 tblTHndl
= AsnListAppend (tblT
->content
->a
.elmts
);
653 *tblTHndl
= GenTblTypesRec (tbl
, m
, tblMod
, td
, tblTd
, e
->type
);
655 if (*tblTHndl
== NULL
)
658 if (e
->fieldName
!= NULL
)
660 (**tblTHndl
).fieldName
.octetLen
= strlen (e
->fieldName
);
661 (**tblTHndl
).fieldName
.octs
=
662 Malloc ((**tblTHndl
).fieldName
.octetLen
+ 1);
663 strcpy ((**tblTHndl
).fieldName
.octs
, e
->fieldName
);
665 tblStringLenTotalG
+= (**tblTHndl
).fieldName
.octetLen
;
668 (**tblTHndl
).optional
=
669 ((e
->type
->optional
) || (e
->type
->defaultVal
!= NULL
));
674 case BASICTYPE_LOCALTYPEREF
:
675 case BASICTYPE_IMPORTTYPEREF
:
676 tblT
->typeId
= TBL_TYPEREF
;
677 tblT
->content
->choiceId
= TBLTYPECONTENT_TYPEREF
;
678 tblT
->content
->a
.typeRef
= MT (TBLTypeRef
);
679 tblT
->content
->a
.typeRef
->implicit
= t
->implicit
;
680 tblT
->content
->a
.typeRef
->typeDef
=
681 t
->basicType
->a
.localTypeRef
->link
->tmpRefCount
;
685 if (!abortTblTypeDefG
) /* only print first time */
686 fprintf (stderr
,"WARNING: Type definition \"%s\" will not be included in the type table because it contains a weird type.\n",td
->definedName
);
687 abortTblTypeDefG
= TRUE
;
688 Free (tblT
->content
);
694 /* handle constraints */
697 switch (GetTblBasicType(t
->basicType
))
699 case BASICTYPE_INTEGER
:
700 tblT
->constraint
= GenTblValueRange(tbl
,m
,tblMod
,t
->subtypes
,0);
702 case BASICTYPE_OCTETSTRING
:
703 case BASICTYPE_SEQUENCEOF
:
704 tblT
->constraint
= GenTblValueRange(tbl
,m
,tblMod
,t
->subtypes
,1);
712 if ((tblT
!= NULL
) &&
713 ((t
->tags
!= NULL
) && (!LIST_EMPTY (t
->tags
))))
715 tblT
->tagList
= AsnListNew (sizeof (void*));
716 FOR_EACH_LIST_ELMT (tag
, t
->tags
)
719 tblTagHndl
= AsnListAppend (tblT
->tagList
);
720 *tblTagHndl
= MT (TBLTag
);
724 (**tblTagHndl
).tclass
= UNIVERSAL
;
727 (**tblTagHndl
).tclass
= APPLICATION
;
730 (**tblTagHndl
).tclass
= CONTEXT
;
733 (**tblTagHndl
).tclass
= PRIVATE
;
736 (**tblTagHndl
).code
= tag
->code
;
741 } /* GenTblTypesRec */