]>
git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/compiler/back-ends/idl-gen/types.c
fffb4b4748edcd8647b8b5a8a4a044ac336cc634
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 * compiler/back_ends/idl_gen/types.c - fills in IDL type information
23 * Copyright (C) 1991, 1992 Michael Sample
24 * and the University of British Columbia
26 * This program is free software; you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License as published by
28 * the Free Software Foundation; either version 2 of the License, or
29 * (at your option) any later version.
31 * $Header: /cvs/root/Security/SecuritySNACCRuntime/compiler/back-ends/idl-gen/Attic/types.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
33 * Revision 1.1.1.1 2001/05/18 23:14:09 mb
34 * Move from private repository to open source repository
36 * Revision 1.2 2001/05/05 00:59:29 rmurphy
37 * Adding darwin license headers
39 * Revision 1.1.1.1 1999/03/16 18:06:45 aram
40 * Originals from SMIME Free Library.
42 * Revision 1.1 1997/01/01 20:25:40 rj
52 #include "asn1module.h"
54 #include "snacc-util.h"
57 #include "c++-gen/kwd.h"
60 extern Module
*usefulTypeModG
;
62 static DefinedObj
*definedNamesG
;
64 /* unexported prototypes */
66 void FillIDLTypeDefInfo
PROTO ((IDLRules
*r
, Module
*m
, TypeDef
*td
));
68 static void FillIDLFieldNames
PROTO ((IDLRules
*r
, NamedTypeList
*firstSibling
));
70 static void FillIDLTypeRefInfo
PROTO ((IDLRules
*r
, Module
*m
, TypeDef
*td
, Type
*parent
, Type
*t
));
72 static void FillIDLStructElmts
PROTO ((IDLRules
*r
, Module
*m
, TypeDef
*td
, Type
*parent
, NamedTypeList
*t
));
74 static void FillIDLChoiceElmts
PROTO ((IDLRules
*r
, Module
*m
, TypeDef
*td
, Type
*parent
, NamedTypeList
*first
));
76 static int IsIDLPtr
PROTO ((IDLRules
*r
, TypeDef
*td
, Type
*parent
, Type
*t
));
78 void FillIDLTDIDefaults
PROTO ((IDLRules
*r
, IDLTDI
*ctdi
, TypeDef
*td
));
82 * allocates and fills all the idlTypeInfos
83 * in the type trees for every module in the list
86 FillIDLTypeInfo
PARAMS ((r
, modList
),
94 * go through each module's type defs and fill
95 * in the C type and enc/dec routines etc
99 /* do useful types first */
100 if (usefulTypeModG
!= NULL
)
102 FOR_EACH_LIST_ELMT (td
, usefulTypeModG
->typeDefs
)
103 FillIDLTypeDefInfo (r
, usefulTypeModG
, td
);
106 FOR_EACH_LIST_ELMT (m
, modList
)
108 FOR_EACH_LIST_ELMT (td
, m
->typeDefs
)
109 FillIDLTypeDefInfo (r
, m
, td
);
113 * now that type def info is filled in
114 * set up set/seq/list/choice elements that ref
118 /* do useful types first */
119 if (usefulTypeModG
!= NULL
)
121 FOR_EACH_LIST_ELMT (td
, usefulTypeModG
->typeDefs
)
122 FillIDLTypeRefInfo (r
, usefulTypeModG
, td
, NULL
, td
->type
);
125 FOR_EACH_LIST_ELMT (m
, modList
)
127 FOR_EACH_LIST_ELMT (td
, m
->typeDefs
)
128 FillIDLTypeRefInfo (r
, m
, td
, NULL
, td
->type
);
132 * modules compiled together (ie one call to snacc with
133 * multiple args) likely to be C compiled together so
134 * need a unique routines/types/defines/enum values
135 * since assuming they share same name space.
136 * All Typedefs, union, struct & enum Tags, and defined values
137 * (enum consts), #define names
138 * are assumed to share the same name space
141 /* done with checking for name conflicts */
142 FreeDefinedObjs (&definedNamesG
);
144 } /* FillIDLTypeInfo */
148 * allocates and fills structure holding C type definition information
149 * fo the given ASN.1 type definition. Does not fill CTRI for contained
153 FillIDLTypeDefInfo
PARAMS ((r
, m
, td
),
164 * if IDLTDI is present this type def has already been 'filled'
166 if (td
->idlTypeDefInfo
!= NULL
)
170 idltdi
= MT (IDLTDI
);
171 td
->idlTypeDefInfo
= idltdi
;
173 /* get default type def attributes from table for type on rhs of ::= */
175 FillIDLTDIDefaults (r
, idltdi
, td
);
179 * if defined by a ref to another type definition fill in that type
180 * def's IDLTDI so can inherit (actully completly replace default
181 * attributes) from it
183 if ((td
->type
->basicType
->choiceId
== BASICTYPE_LOCALTYPEREF
) ||
184 (td
->type
->basicType
->choiceId
== BASICTYPE_IMPORTTYPEREF
))
187 * Fill in IDLTDI for defining type if nec.
188 * this works for importTypeRef as well since both a.localTypeRef
189 * and a.importTypeRef are of type TypeRef
191 FillIDLTypeDefInfo (r
, td
->type
->basicType
->a
.localTypeRef
->module, td
->type
->basicType
->a
.localTypeRef
->link
);
193 tmpName
= idltdi
->typeName
; /* save typeName */
194 /* copy all type def info and restore name related stuff - hack*/
195 *idltdi
= *td
->type
->basicType
->a
.localTypeRef
->link
->idlTypeDefInfo
;
196 idltdi
->typeName
= tmpName
; /* restore typeName */
201 * check for any "--snacc" attributes that overide the current
204 ParseTypeDefAttribs (idltdi, td->attrList);
207 } /* FillIDLTypeDefInfo */
211 FillIDLTypeRefInfo
PARAMS ((r
, m
, td
, parent
, t
),
222 CNamedElmt
**cneHndl
;
229 enum BasicTypeChoiceId
233 * you must check for cycles yourself before calling this
235 if (t
->idlTypeRefInfo
== NULL
)
237 idltri
= MT (IDLTRI
);
238 t
->idlTypeRefInfo
= idltri
;
241 idltri
= t
->idlTypeRefInfo
;
243 basicTypeId
= t
->basicType
->choiceId
;
245 tmpidltdi
= &r
->typeConvTbl
[basicTypeId
];
247 /* get base type def info from the conversion table in the rules */
248 idltri
->isEnc
= tmpidltdi
->isEnc
;
249 idltri
->typeName
= tmpidltdi
->typeName
;
250 idltri
->optTestRoutineName
= tmpidltdi
->optTestRoutineName
;
254 * convert named elmts to IDL names.
255 * check for name conflict with other defined Types/Names/Values
257 if ((basicTypeId
== BASICTYPE_INTEGER
|| basicTypeId
== BASICTYPE_ENUMERATED
|| basicTypeId
== BASICTYPE_BITSTRING
) && !(LIST_EMPTY (t
->basicType
->a
.integer
)))
259 idltri
->namedElmts
= AsnListNew (sizeof (void *));
260 FOR_EACH_LIST_ELMT (namedElmt
, t
->basicType
->a
.integer
)
262 cneHndl
= (CNamedElmt
**)AsnListAppend (idltri
->namedElmts
);
263 cne
= *cneHndl
= MT (CNamedElmt
);
264 elmtName
= Asn1ValueName2CValueName (namedElmt
->definedName
);
266 if (basicTypeId
== BASICTYPE_BITSTRING
)
269 len
= strlen (elmtName
);
270 cne
->name
= Malloc (len
+ 1 + r
->maxDigitsToAppend
);
271 strcpy (cne
->name
, elmtName
);
276 len
= strlen (idltri
->typeName
) + 7 + strlen (elmtName
);
277 cne
->name
= Malloc (len
+ 1 + r
->maxDigitsToAppend
);
278 strcpy (cne
->name
, idltri
->typeName
);
279 strcat (cne
->name
, "Choice_");
280 strcat (cne
->name
, elmtName
);
283 Free (elmtName
); /* not very efficient */
285 if (namedElmt
->value
->basicValue
->choiceId
== BASICVALUE_INTEGER
)
286 cne
->value
= namedElmt
->value
->basicValue
->a
.integer
;
289 fprintf (stderr
, "Warning: unlinked defined value. Using -9999999\n");
290 cne
->value
= -9999999;
293 if (r
->capitalizeNamedElmts
)
294 Str2UCase (cne
->name
, len
);
297 * append digits if enum value name is a keyword
299 MakeCxxStrUnique (definedNamesG
, cne
->name
, r
->maxDigitsToAppend
, 1);
300 DefineObj (&definedNamesG
, cne
->name
);
304 /* fill in rest of type info depending on the type */
307 case BASICTYPE_BOOLEAN
: /* library types */
308 case BASICTYPE_INTEGER
:
309 case BASICTYPE_BITSTRING
:
310 case BASICTYPE_OCTETSTRING
:
314 case BASICTYPE_ENUMERATED
:
315 /* don't need to do anything else */
319 case BASICTYPE_SEQUENCEOF
: /* list types */
320 case BASICTYPE_SETOF
:
321 /* fill in component type */
322 FillIDLTypeRefInfo (r
, m
, td
, t
, t
->basicType
->a
.setOf
);
325 case BASICTYPE_IMPORTTYPEREF
: /* type references */
326 case BASICTYPE_LOCALTYPEREF
:
328 * grab class name from link (link is the def of the
331 if (t
->basicType
->a
.localTypeRef
->link
!= NULL
)
333 /* inherit attributes from referenced type */
334 tmpidltdi
= t
->basicType
->a
.localTypeRef
->link
->idlTypeDefInfo
;
335 idltri
->typeName
= tmpidltdi
->typeName
;
336 idltri
->isEnc
= tmpidltdi
->isEnc
;
337 idltri
->optTestRoutineName
= tmpidltdi
->optTestRoutineName
;
342 case BASICTYPE_ANYDEFINEDBY
: /* ANY types */
343 break; /* these are handled now */
347 PrintErrLoc (m
->asn1SrcFileName
, t
->lineNo
);
348 fprintf (stderr
, "Warning - generated code for the \"ANY\" type in type \"%s\" will need modification by YOU.", td
->definedName
);
349 fprintf (stderr
, " The source files will have a \"/* ANY - Fix Me! */\" comment before related code.\n\n");
354 case BASICTYPE_CHOICE
:
356 * must fill field names BEFORE filling choice elmts
357 * (allows better naming for choice ids)
359 FillIDLFieldNames (r
, t
->basicType
->a
.choice
);
360 FillIDLChoiceElmts (r
, m
, td
, t
, t
->basicType
->a
.choice
);
364 case BASICTYPE_SEQUENCE
:
365 FillIDLStructElmts (r
, m
, td
, t
, t
->basicType
->a
.set
);
366 FillIDLFieldNames (r
, t
->basicType
->a
.set
);
369 case BASICTYPE_COMPONENTSOF
:
370 case BASICTYPE_SELECTION
:
371 fprintf (stderr
, "Compiler error - COMPONENTS OF or SELECTION type slipped through normalizing phase.\n");
374 case BASICTYPE_UNKNOWN
:
375 case BASICTYPE_MACRODEF
:
376 case BASICTYPE_MACROTYPE
:
383 * figure out whether this is a ptr based on the enclosing
384 * type (if any) and optionality/default
386 idltri
->isPtr
= IsIDLPtr (r
, td
, parent
, t
);
388 /* let user overide any defaults with the --snacc attributes */
389 /* undefined for C++ ParseTypeRefAttribs (ctri, t->attrList); */
392 } /* FillIDLTypeRefInfo */
397 FillIDLStructElmts
PARAMS ((r
, m
, td
, parent
, elmts
),
402 NamedTypeList
*elmts
)
406 FOR_EACH_LIST_ELMT (et
, elmts
)
408 FillIDLTypeRefInfo (r
, m
, td
, parent
, et
->type
);
411 } /* FillIDLStructElmts */
416 * Figures out non-conflicting enum names for the
420 FillIDLChoiceElmts
PARAMS ((r
, m
, td
, parent
, elmts
),
425 NamedTypeList
*elmts
)
433 * fill in type info for elmt types first
435 FOR_EACH_LIST_ELMT (et
, elmts
)
436 FillIDLTypeRefInfo (r
, m
, td
, parent
, et
->type
);
439 * set choiceId Symbol & value
441 * Car ::= CHOICE { enum CarChoice {
442 * chev ChevCar, carChoice_chev,
443 * ford FordCar, carChoice_ford,
444 * toyota ToyotaCar carChoice_toyota
446 * union Car switch (CarChoice) {
449 * ToyotaCar *toyota; };
451 * NOTE that the union is anonymous
453 FOR_EACH_LIST_ELMT (et
, elmts
)
455 idltri
= et
->type
->idlTypeRefInfo
;
458 continue; /* wierd type */
460 idltri
->choiceIdValue
= idCount
++;
462 len
= strlen (td
->idlTypeDefInfo
->typeName
) + strlen (idltri
->fieldName
);
463 idltri
->choiceIdSymbol
= Malloc (len
+ 6 + 1);
464 strcpy (idltri
->choiceIdSymbol
, td
->idlTypeDefInfo
->typeName
);
465 strcat (idltri
->choiceIdSymbol
, "Choice_");
466 strcat (idltri
->choiceIdSymbol
, idltri
->fieldName
);
468 if (r
->capitalizeNamedElmts
)
469 Str2UCase (idltri
->choiceIdSymbol
, len
);
471 Str2LCase (idltri
->choiceIdSymbol
, 1);
474 } /* FillIDLChoiceElmts */
478 * takes a list of "sibling" (eg same level in a structure)
479 * ElmtTypes and fills sets up the c field names in
483 FillIDLFieldNames
PARAMS ((r
, elmts
),
485 NamedTypeList
*elmts
)
489 DefinedObj
*fieldNames
;
490 int len
, num
, digit
, i
, tmpLen
;
496 * Initialize fieldname data
497 * allocate (if nec) and fill in CTRI fieldname if poss
498 * from asn1 field name. leave blank otherwise
500 fieldNames
= NewObjList();
501 FOR_EACH_LIST_ELMT (et
, elmts
)
503 idltri
= et
->type
->idlTypeRefInfo
;
506 idltri
= MT (IDLTRI
);
507 et
->type
->idlTypeRefInfo
= idltri
;
509 if (et
->fieldName
!= NULL
)
512 * can assume that the field names are
513 * distinct because they have passed the
514 * error checking step.
515 * However, still call MakeCxxStrUnique
516 * to change any field names that
517 * conflict with C++ keywords
519 asn1FieldName
= et
->fieldName
;
520 tmpName
= Asn1FieldName2CFieldName (asn1FieldName
);
521 idltri
->fieldName
= Malloc (strlen (tmpName
) + 1 + r
->maxDigitsToAppend
);
522 strcpy (idltri
->fieldName
, tmpName
);
525 /* old idltri->fieldName = Asn1FieldName2CFieldName (asn1FieldName); */
527 MakeCxxStrUnique (fieldNames
, idltri
->fieldName
, r
->maxDigitsToAppend
, 1);
528 DefineObj (&fieldNames
, idltri
->fieldName
);
533 FOR_EACH_LIST_ELMT (et
, elmts
)
535 idltri
= et
->type
->idlTypeRefInfo
;
538 * generate field names for those without them
540 if (idltri
->fieldName
== NULL
)
542 if ((et
->type
->basicType
->choiceId
== BASICTYPE_LOCALTYPEREF
) ||
543 (et
->type
->basicType
->choiceId
== BASICTYPE_IMPORTTYPEREF
))
546 * take ref'd type name as field name
547 * convert first let to lower case
549 tmpName
= et
->type
->basicType
->a
.localTypeRef
->link
->idlTypeDefInfo
->typeName
;
550 tmpName
= Asn1TypeName2CTypeName (tmpName
);
551 cFieldName
= Malloc (strlen (tmpName
) + r
->maxDigitsToAppend
+1);
552 strcpy (cFieldName
, tmpName
);
554 if (isupper (cFieldName
[0]))
555 cFieldName
[0] = tolower (cFieldName
[0]);
560 * get default field name for this type
562 tmpName
= r
->typeConvTbl
[et
->type
->basicType
->choiceId
].defaultFieldName
;
563 cFieldName
= Malloc (strlen (tmpName
) + r
->maxDigitsToAppend
+1);
564 strcpy (cFieldName
, tmpName
);
566 if (isupper (cFieldName
[0]))
567 cFieldName
[0] = tolower (cFieldName
[0]);
571 len
= strlen (cFieldName
);
574 * try to use just the type name (with lower case first char).
575 * if that is already used in this type or a C++ keyword,
576 * append ascii digits to field name until unique
579 MakeCxxStrUnique (fieldNames
, cFieldName
, r
->maxDigitsToAppend
, 1);
580 DefineObj (&fieldNames
, cFieldName
);
581 idltri
->fieldName
= cFieldName
;
584 FreeDefinedObjs (&fieldNames
);
585 } /* FillIDLFieldNames */
590 * returns true if this c type for this type should be
594 IsIDLPtr
PARAMS ((r
, td
, parent
, t
),
604 * inherit ptr attriubutes from ref'd type if any
605 * otherwise grab lib c type def from the IDLRules
607 if ((t
->basicType
->choiceId
== BASICTYPE_LOCALTYPEREF
) ||
608 (t
->basicType
->choiceId
== BASICTYPE_IMPORTTYPEREF
))
610 idltdi
= t
->basicType
->a
.localTypeRef
->link
->idlTypeDefInfo
;
613 idltdi
= &r
->typeConvTbl
[GetBuiltinType (t
)];
615 /* no parent means t is the root of a typedef */
616 if ((parent
== NULL
) && (idltdi
->isPtrForTypeDef
))
619 else if ((parent
!= NULL
) &&
620 ((parent
->basicType
->choiceId
== BASICTYPE_SET
) ||
621 (parent
->basicType
->choiceId
== BASICTYPE_SEQUENCE
)) &&
622 (idltdi
->isPtrInSetAndSeq
))
625 else if ((parent
!= NULL
) &&
626 ((parent
->basicType
->choiceId
== BASICTYPE_SETOF
) ||
627 (parent
->basicType
->choiceId
== BASICTYPE_SEQUENCEOF
)) &&
628 (idltdi
->isPtrInList
))
631 else if ((parent
!= NULL
) &&
632 (parent
->basicType
->choiceId
== BASICTYPE_CHOICE
) &&
633 (idltdi
->isPtrInChoice
))
636 else if (((t
->optional
) || (t
->defaultVal
!= NULL
)) && (idltdi
->isPtrForOpt
))
644 /* fill given idltdi with defaults from table for given typedef */
646 FillIDLTDIDefaults
PARAMS ((r
, idltdi
, td
),
655 typeIndex
= GetBuiltinType (td
->type
);
660 tblidltdi
= &r
->typeConvTbl
[typeIndex
];
662 memcpy (idltdi
, tblidltdi
, sizeof (IDLTDI
));
664 /* make sure class name is unique wrt to previously defined classes */
665 tmpName
= Asn1TypeName2CTypeName (td
->definedName
);
666 idltdi
->typeName
= Malloc (strlen (tmpName
) + 2 + r
->maxDigitsToAppend
+1);
667 strcpy (idltdi
->typeName
, tmpName
);
668 if (tblidltdi
->asn1TypeId
!= BASICTYPE_CHOICE
)
669 strcat (idltdi
->typeName
, "_T");
672 MakeCxxStrUnique (definedNamesG
, idltdi
->typeName
, r
->maxDigitsToAppend
, 1);
673 DefineObj (&definedNamesG
, idltdi
->typeName
);
675 } /* FillIDLTDIDefaults */