]>
Commit | Line | Data |
---|---|---|
bac41a7b A |
1 | /* |
2 | * compiler/core/gen_tbls.c | |
3 | * | |
4 | * generates type tables and writes them to a file. | |
5 | * | |
6 | * MS | |
7 | * 93/02/07 | |
8 | * | |
9 | * Copyright (C) 1993 Michael Sample | |
10 | * and the University of British Columbia | |
11 | * | |
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. | |
16 | * | |
a66d0d4a | 17 | * $Header: /cvs/root/Security/SecuritySNACCRuntime/compiler/core/Attic/gen-tbls.c,v 1.1 2001/06/20 21:27:57 dmitch Exp $ |
bac41a7b A |
18 | * $Log: gen-tbls.c,v $ |
19 | * Revision 1.1 2001/06/20 21:27:57 dmitch | |
20 | * Adding missing snacc compiler files. | |
21 | * | |
22 | * Revision 1.1.1.1 1999/03/16 18:06:48 aram | |
23 | * Originals from SMIME Free Library. | |
24 | * | |
25 | * Revision 1.5 1997/06/19 09:17:16 wan | |
26 | * Added isPdu flag to tables. Added value range checks during parsing. | |
27 | * | |
28 | * Revision 1.4 1997/05/07 15:18:34 wan | |
29 | * Added (limited) size constraints, bitstring and enumeration names to tables | |
30 | * | |
31 | * Revision 1.3 1995/07/25 19:41:28 rj | |
32 | * changed `_' to `-' in file names. | |
33 | * | |
34 | * Revision 1.2 1994/09/01 00:33:41 rj | |
35 | * snacc_config.h removed. | |
36 | * | |
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. | |
39 | * | |
40 | */ | |
41 | ||
42 | #include <stdio.h> | |
43 | ||
44 | #include "asn-incl.h" | |
45 | #include "asn1module.h" | |
46 | #include "tbl.h" | |
47 | #include "gen-tbls.h" | |
48 | ||
49 | extern Module *usefulTypeModG; | |
50 | ||
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)); | |
57 | ||
58 | ||
59 | static int abortTblTypeDefG; | |
60 | static int tblTypesTotalG; | |
61 | static int tblTagsTotalG; | |
62 | static int tblStringsTotalG; | |
63 | static int tblStringLenTotalG; | |
64 | ||
65 | static int tableFileVersionG; | |
66 | ||
67 | void | |
68 | GenTypeTbls PARAMS ((mods, fileName, tableFileVersion), | |
69 | ModuleList *mods _AND_ | |
70 | char *fileName _AND_ | |
71 | int tableFileVersion) | |
72 | { | |
73 | TBL tbl; | |
74 | TBLModule *newTblMod; | |
75 | FILE *tblFile; | |
76 | ExpBuf *buf; | |
77 | ExpBuf *tmpBuf; | |
78 | Module *m; | |
79 | ||
80 | tableFileVersionG = tableFileVersion; | |
81 | ||
82 | tbl.modules = AsnListNew (sizeof (void*)); | |
83 | tbl.totalNumModules = 0; | |
84 | tbl.totalNumTypeDefs = 0; | |
85 | tbl.totalNumTypes = 0; | |
86 | tbl.totalNumTags = 0; | |
87 | tbl.totalNumStrings = 0; | |
88 | tbl.totalLenStrings = 0; | |
89 | ||
90 | /* | |
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 | |
96 | */ | |
97 | FOR_EACH_LIST_ELMT (m, mods) | |
98 | { | |
99 | GenTypeDefIds (&tbl, m); | |
100 | } | |
101 | ||
102 | /* number useful types if they are there any */ | |
103 | if (usefulTypeModG != NULL) | |
104 | GenTypeDefIds (&tbl, usefulTypeModG); | |
105 | ||
106 | /* convert each module from parse format to simpler table format */ | |
107 | FOR_EACH_LIST_ELMT (m, mods) | |
108 | { | |
109 | if (!GenTblModule (&tbl, m, &newTblMod)) | |
110 | { | |
111 | fprintf (stderr,"ERROR: type table generator failed for module \"%s\", so file \"%s\" will not be written.\n", m->modId->name, fileName); | |
112 | return; | |
113 | } | |
114 | } | |
115 | ||
116 | /* | |
117 | * convert useful type mod from parse format to | |
118 | * simpler table format, if one was given | |
119 | */ | |
120 | if (usefulTypeModG != NULL) | |
121 | { | |
122 | if (!GenTblModule (&tbl, usefulTypeModG, &newTblMod)) | |
123 | { | |
124 | fprintf (stderr,"ERROR: type table generator failed for useful types module, file \"%s\" will not be written.\n",fileName); | |
125 | return; | |
126 | } | |
127 | /* mark the module as useful */ | |
128 | newTblMod->isUseful = TRUE; | |
129 | } | |
130 | ||
131 | /* encode the TBLModules */ | |
132 | ExpBufInit (1024); | |
133 | buf = ExpBufAllocBufAndData(); | |
134 | ||
135 | BEncTBL (&buf, &tbl); | |
136 | ||
137 | if (ExpBufWriteError (&buf)) | |
138 | { | |
139 | fprintf (stderr,"ERROR: buffer write error during encoding of type table.\n", fileName); | |
140 | return; | |
141 | } | |
142 | ||
143 | ||
144 | /* open & truncate or create as file with given filename */ | |
145 | tblFile = fopen (fileName,"w"); | |
146 | ||
147 | if (tblFile == NULL) | |
148 | { | |
149 | fprintf (stderr,"ERROR: Could not open file \"%s\" for the type table.\n", fileName); | |
150 | return; | |
151 | } | |
152 | ||
153 | ||
154 | /* | |
155 | * go through buffer (s) and write encoded value | |
156 | * to stdout | |
157 | */ | |
158 | buf->curr = buf->dataStart; | |
159 | for (tmpBuf = buf; tmpBuf != NULL; tmpBuf = tmpBuf->next) | |
160 | { | |
161 | fwrite (tmpBuf->dataStart, tmpBuf->dataEnd - tmpBuf->dataStart, 1, tblFile); | |
162 | } | |
163 | ||
164 | fclose (tblFile); | |
165 | ||
166 | } /* GenTypeTbls */ | |
167 | ||
168 | ||
169 | /* | |
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. | |
174 | * | |
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. | |
180 | * | |
181 | * tbl.totalNumModules and tbl.totalNumTypeDefs are updated. | |
182 | * | |
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. | |
188 | * | |
189 | * (the type ids range from 0 to tbl->totalNumTypeDefs-1 (inclusive)) | |
190 | */ | |
191 | void | |
192 | GenTypeDefIds PARAMS ((tbl,m), | |
193 | TBL *tbl _AND_ | |
194 | Module *m) | |
195 | { | |
196 | TypeDef *td; | |
197 | ||
198 | tbl->totalNumModules++; | |
199 | FOR_EACH_LIST_ELMT (td, m->typeDefs) | |
200 | { | |
201 | td->tmpRefCount = tbl->totalNumTypeDefs; | |
202 | tbl->totalNumTypeDefs++; | |
203 | } | |
204 | ||
205 | } /* GenTypeDefIds */ | |
206 | ||
207 | ||
208 | /* | |
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. | |
213 | */ | |
214 | int | |
215 | GenTblModule PARAMS ((tbl, m, newTblMod), | |
216 | TBL *tbl _AND_ | |
217 | Module *m _AND_ | |
218 | TBLModule **newTblMod) | |
219 | { | |
220 | TBLModule **mHndl; | |
221 | TBLModule *tblMod; | |
222 | int eLen; | |
223 | AsnOid *result; | |
224 | ||
225 | mHndl = AsnListAppend (tbl->modules); | |
226 | ||
227 | tblMod = MT (TBLModule); | |
228 | *newTblMod = *mHndl = tblMod; | |
229 | ||
230 | /* copy the name */ | |
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; | |
236 | ||
237 | /* copy the OBJECT IDENTIFIER (if any) */ | |
238 | if (m->modId->oid != NULL) | |
239 | { | |
240 | /* convert the (linked) OID into a (encoded) AsnOid */ | |
241 | if (FlattenLinkedOid (m->modId->oid)) | |
242 | { | |
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; | |
249 | } | |
250 | } | |
251 | ||
252 | /* | |
253 | * useful defaults to false | |
254 | * (ie assume the it is not the usefultypes modules) | |
255 | */ | |
256 | tblMod->isUseful = FALSE; | |
257 | ||
258 | /* now copy each of the type defs */ | |
259 | return GenTblTypeDefs (tbl, m, tblMod); | |
260 | ||
261 | } /* GenTblModule */ | |
262 | ||
263 | ||
264 | /* | |
265 | * converts typeDefs in Module format to TBLModule format | |
266 | * returns TRUE for success, FALSE for failure. | |
267 | */ | |
268 | int | |
269 | GenTblTypeDefs PARAMS ((tbl, m, tblMod), | |
270 | TBL *tbl _AND_ | |
271 | Module *m _AND_ | |
272 | TBLModule *tblMod) | |
273 | { | |
274 | TypeDef *td; | |
275 | TBLTypeDef **tblTdHndl; | |
276 | TBLTypeDef *tblTd; | |
277 | int isOk = TRUE; /* init to no errors */ | |
278 | ||
279 | tblMod->typeDefs = AsnListNew (sizeof (void*)); | |
280 | FOR_EACH_LIST_ELMT (td, m->typeDefs) | |
281 | { | |
282 | ||
283 | tblTd = MT (TBLTypeDef); | |
284 | ||
285 | /* set type def id */ | |
286 | tblTd->typeDefId = td->tmpRefCount; | |
287 | ||
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; | |
294 | ||
295 | /* | |
296 | if (td->isPdu) | |
297 | tblTd->isPdu = MT (AsnNull); | |
298 | */ | |
299 | if (m!=usefulTypeModG) | |
300 | { | |
301 | MyString attr; | |
302 | char* attrName; | |
303 | char* attrValue; | |
304 | int result = FALSE; | |
305 | FOR_EACH_LIST_ELMT(attr,td->attrList) | |
306 | { | |
307 | int loc = 0; | |
308 | while (TRUE) | |
309 | { | |
310 | ParseAttr(attr,&loc,&attrName,&attrValue); | |
311 | if (!attrName) | |
312 | break; | |
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); | |
316 | Free(attrValue); | |
317 | } | |
318 | } | |
319 | if (result) | |
320 | tblTd->isPdu = MT (AsnNull); | |
321 | } | |
322 | ||
323 | ||
324 | /* fill in type portion */ | |
325 | if (!GenTblTypes (tbl, m, tblMod, td, tblTd) && !abortTblTypeDefG) | |
326 | isOk = FALSE; | |
327 | ||
328 | ||
329 | /* | |
330 | * add TBLtypeDef to TBLModule | |
331 | * if no weird types were found | |
332 | * (weird types are skipped) | |
333 | */ | |
334 | if (!abortTblTypeDefG) | |
335 | { | |
336 | tblTdHndl = AsnListAppend (tblMod->typeDefs); | |
337 | *tblTdHndl = tblTd; | |
338 | tbl->totalNumTypes += tblTypesTotalG; | |
339 | tbl->totalNumTags += tblTagsTotalG; | |
340 | tbl->totalNumStrings += tblStringsTotalG; | |
341 | tbl->totalLenStrings += tblStringLenTotalG; | |
342 | } | |
343 | /* else could free it */ | |
344 | ||
345 | } | |
346 | return isOk; | |
347 | } /* GenTblTypeDefs */ | |
348 | ||
349 | ||
350 | /* | |
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. | |
354 | */ | |
355 | int | |
356 | GenTblTypes PARAMS ((tbl, m, tblMod, td, tblTd), | |
357 | TBL *tbl _AND_ | |
358 | Module *m _AND_ | |
359 | TBLModule *tblMod _AND_ | |
360 | TypeDef *td _AND_ | |
361 | TBLTypeDef *tblTd) | |
362 | { | |
363 | abortTblTypeDefG = FALSE; | |
364 | tblTypesTotalG = 0; | |
365 | tblTagsTotalG = 0; | |
366 | tblStringsTotalG = 0; | |
367 | tblStringLenTotalG = 0; | |
368 | ||
369 | tblTd->type = GenTblTypesRec (tbl, m, tblMod, td, tblTd, td->type); | |
370 | ||
371 | if (tblTd->type == NULL) | |
372 | return FALSE; /* failed */ | |
373 | else | |
374 | return TRUE; | |
375 | ||
376 | } /* GenTblTypes */ | |
377 | ||
378 | BasicValue* | |
379 | GetTblValue PARAMS ((v), | |
380 | Value* v) | |
381 | { | |
382 | switch (v->basicValue->choiceId) | |
383 | { | |
384 | case BASICVALUE_INTEGER: | |
385 | return v->basicValue; | |
386 | default: | |
387 | return NULL; | |
388 | } | |
389 | } | |
390 | ||
391 | enum BasicTypeChoiceId | |
392 | GetTblBasicType PARAMS ((bt), | |
393 | BasicType* bt) | |
394 | { | |
395 | switch (bt->choiceId) | |
396 | { | |
397 | case BASICTYPE_LOCALTYPEREF: | |
398 | case BASICTYPE_IMPORTTYPEREF: | |
399 | return GetTblBasicType (bt->a.localTypeRef->link->type->basicType); | |
400 | default: | |
401 | return bt->choiceId; | |
402 | } | |
403 | } | |
404 | ||
405 | TBLRange* | |
406 | GenTblValueRange PARAMS ((tbl, m, tblMod, s, doSize), | |
407 | TBL *tbl _AND_ | |
408 | Module *m _AND_ | |
409 | TBLModule *tblMod _AND_ | |
410 | Subtype *s _AND_ | |
411 | int doSize) | |
412 | { | |
413 | TBLRange* range; | |
414 | BasicValue* from; | |
415 | BasicValue* to; | |
416 | ||
417 | if (tableFileVersionG<=1) | |
418 | return NULL; | |
419 | ||
420 | switch (s->choiceId) | |
421 | { | |
422 | case SUBTYPE_SINGLE: | |
423 | switch (s->a.single->choiceId) | |
424 | { | |
425 | case SUBTYPEVALUE_SINGLEVALUE: | |
426 | if (doSize) | |
427 | return NULL; | |
428 | from = to = GetTblValue (s->a.single->a.singleValue); | |
429 | break; | |
430 | case SUBTYPEVALUE_VALUERANGE: | |
431 | if (doSize) | |
432 | return NULL; | |
433 | from =GetTblValue(s->a.single->a.valueRange->lowerEndValue); | |
434 | to = GetTblValue (s->a.single->a.valueRange->upperEndValue); | |
435 | break; | |
436 | case SUBTYPEVALUE_SIZECONSTRAINT: | |
437 | if (!doSize) | |
438 | return NULL; | |
439 | return GenTblValueRange (tbl, m, tblMod, | |
440 | s->a.single->a.sizeConstraint, 0); | |
441 | break; | |
442 | default: | |
443 | return NULL; | |
444 | } | |
445 | break; | |
446 | case SUBTYPE_AND: | |
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); | |
450 | return NULL; | |
451 | case SUBTYPE_OR: | |
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); | |
455 | return NULL; | |
456 | case SUBTYPE_NOT: | |
457 | return NULL; | |
458 | } | |
459 | if (!from || !to) | |
460 | return NULL; | |
461 | range = MT (TBLRange); | |
462 | range->from = from->a.integer; | |
463 | range->to = to->a.integer; | |
464 | return range; | |
465 | } | |
466 | ||
467 | TBLNamedNumberList* | |
468 | GenTblValues PARAMS ((tbl, m, tblMod, list), | |
469 | TBL *tbl _AND_ | |
470 | Module *m _AND_ | |
471 | TBLModule *tblMod _AND_ | |
472 | NamedNumberList* list) | |
473 | { | |
474 | TBLNamedNumberList* tnnl = NULL; | |
475 | ||
476 | if (tableFileVersionG<=1) | |
477 | return NULL; | |
478 | ||
479 | if (list && !LIST_EMPTY(list)) | |
480 | { | |
481 | ValueDef* vd; | |
482 | tnnl = (TBLNamedNumberList*) AsnListNew(sizeof(void*)); | |
483 | FOR_EACH_LIST_ELMT(vd,list) | |
484 | { | |
485 | BasicValue* bv = GetTblValue(vd->value); | |
486 | if (bv) | |
487 | { | |
488 | TBLNamedNumber* tnn = MT(TBLNamedNumber); | |
489 | *(TBLNamedNumber**)AsnListAppend(tnnl) = tnn; | |
490 | tnn->value = bv->a.integer; | |
491 | if (vd->definedName) | |
492 | { | |
493 | tnn->name.octetLen = strlen(vd->definedName); | |
494 | tnn->name.octs = Malloc(tnn->name.octetLen+1); | |
495 | strcpy(tnn->name.octs,vd->definedName); | |
496 | tblStringsTotalG++; | |
497 | tblStringLenTotalG += tnn->name.octetLen; | |
498 | } | |
499 | } | |
500 | } | |
501 | ||
502 | } | |
503 | return tnnl; | |
504 | } | |
505 | ||
506 | TBLType* | |
507 | GenTblTypesRec PARAMS ((tbl, m, tblMod, td, tblTd, t), | |
508 | TBL *tbl _AND_ | |
509 | Module *m _AND_ | |
510 | TBLModule *tblMod _AND_ | |
511 | TypeDef *td _AND_ | |
512 | TBLTypeDef *tblTd _AND_ | |
513 | Type *t) | |
514 | { | |
515 | TBLType *tblT; | |
516 | NamedType *e; | |
517 | TBLType **tblTHndl; | |
518 | Tag *tag; | |
519 | TBLTag **tblTagHndl; | |
520 | ||
521 | tblTypesTotalG++; | |
522 | tblT = MT (TBLType); | |
523 | tblT->content = MT (TBLTypeContent); | |
524 | switch (t->basicType->choiceId) | |
525 | { | |
526 | case BASICTYPE_BOOLEAN: | |
527 | tblT->typeId = TBL_BOOLEAN; | |
528 | tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; | |
529 | break; | |
530 | ||
531 | case BASICTYPE_INTEGER: | |
532 | tblT->typeId = TBL_INTEGER; | |
533 | tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; | |
534 | break; | |
535 | ||
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); | |
540 | break; | |
541 | ||
542 | case BASICTYPE_OCTETSTRING: | |
543 | tblT->typeId = TBL_OCTETSTRING; | |
544 | tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; | |
545 | if (t->subtypes) | |
546 | tblT->constraint = GenTblValueRange(tbl, m, tblMod,t->subtypes,1); | |
547 | break; | |
548 | ||
549 | case BASICTYPE_NULL: | |
550 | tblT->typeId = TBL_NULL; | |
551 | tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; | |
552 | break; | |
553 | ||
554 | case BASICTYPE_OID: | |
555 | tblT->typeId = TBL_OID; | |
556 | tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; | |
557 | break; | |
558 | ||
559 | case BASICTYPE_REAL: | |
560 | tblT->typeId = TBL_REAL; | |
561 | tblT->content->choiceId = TBLTYPECONTENT_PRIMTYPE; | |
562 | break; | |
563 | ||
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); | |
568 | break; | |
569 | ||
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) | |
575 | { | |
576 | tblTHndl = AsnListAppend (tblT->content->a.elmts); | |
577 | *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, e->type); | |
578 | ||
579 | if (*tblTHndl == NULL) | |
580 | break; | |
581 | ||
582 | if (e->fieldName != NULL) | |
583 | { | |
584 | (**tblTHndl).fieldName.octetLen = strlen (e->fieldName); | |
585 | (**tblTHndl).fieldName.octs = | |
586 | Malloc ((**tblTHndl).fieldName.octetLen + 1); | |
587 | strcpy ((**tblTHndl).fieldName.octs, e->fieldName); | |
588 | tblStringsTotalG++; | |
589 | tblStringLenTotalG += (**tblTHndl).fieldName.octetLen; | |
590 | } | |
591 | ||
592 | (**tblTHndl).optional = | |
593 | ((e->type->optional) || (e->type->defaultVal != NULL)); | |
594 | } | |
595 | ||
596 | break; | |
597 | ||
598 | case BASICTYPE_SET: | |
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) | |
603 | { | |
604 | tblTHndl = AsnListAppend (tblT->content->a.elmts); | |
605 | *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, e->type); | |
606 | ||
607 | if (*tblTHndl == NULL) | |
608 | break; | |
609 | ||
610 | if (e->fieldName != NULL) | |
611 | { | |
612 | (**tblTHndl).fieldName.octetLen = strlen (e->fieldName); | |
613 | (**tblTHndl).fieldName.octs = | |
614 | Malloc ((**tblTHndl).fieldName.octetLen + 1); | |
615 | strcpy ((**tblTHndl).fieldName.octs, e->fieldName); | |
616 | tblStringsTotalG++; | |
617 | tblStringLenTotalG += (**tblTHndl).fieldName.octetLen; | |
618 | } | |
619 | ||
620 | (**tblTHndl).optional = | |
621 | ((e->type->optional) || (e->type->defaultVal != NULL)); | |
622 | ||
623 | } | |
624 | break; | |
625 | ||
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); | |
632 | if (t->subtypes) | |
633 | tblT->constraint = GenTblValueRange(tbl, m, tblMod,t->subtypes,1); | |
634 | break; | |
635 | ||
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); | |
642 | if (t->subtypes) | |
643 | tblT->constraint = GenTblValueRange(tbl, m, tblMod,t->subtypes,1); | |
644 | break; | |
645 | ||
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) | |
651 | { | |
652 | tblTHndl = AsnListAppend (tblT->content->a.elmts); | |
653 | *tblTHndl = GenTblTypesRec (tbl, m, tblMod, td, tblTd, e->type); | |
654 | ||
655 | if (*tblTHndl == NULL) | |
656 | break; | |
657 | ||
658 | if (e->fieldName != NULL) | |
659 | { | |
660 | (**tblTHndl).fieldName.octetLen = strlen (e->fieldName); | |
661 | (**tblTHndl).fieldName.octs = | |
662 | Malloc ((**tblTHndl).fieldName.octetLen + 1); | |
663 | strcpy ((**tblTHndl).fieldName.octs, e->fieldName); | |
664 | tblStringsTotalG++; | |
665 | tblStringLenTotalG += (**tblTHndl).fieldName.octetLen; | |
666 | } | |
667 | ||
668 | (**tblTHndl).optional = | |
669 | ((e->type->optional) || (e->type->defaultVal != NULL)); | |
670 | ||
671 | } | |
672 | break; | |
673 | ||
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; | |
682 | break; | |
683 | ||
684 | default: | |
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); | |
689 | Free (tblT); | |
690 | tblT = NULL; | |
691 | break; | |
692 | } | |
693 | ||
694 | /* handle constraints */ | |
695 | if (t->subtypes) | |
696 | { | |
697 | switch (GetTblBasicType(t->basicType)) | |
698 | { | |
699 | case BASICTYPE_INTEGER: | |
700 | tblT->constraint = GenTblValueRange(tbl,m,tblMod,t->subtypes,0); | |
701 | break; | |
702 | case BASICTYPE_OCTETSTRING: | |
703 | case BASICTYPE_SEQUENCEOF: | |
704 | tblT->constraint = GenTblValueRange(tbl,m,tblMod,t->subtypes,1); | |
705 | break; | |
706 | default: | |
707 | break; | |
708 | } | |
709 | } | |
710 | ||
711 | /* copy the tags */ | |
712 | if ((tblT != NULL) && | |
713 | ((t->tags != NULL) && (!LIST_EMPTY (t->tags)))) | |
714 | { | |
715 | tblT->tagList = AsnListNew (sizeof (void*)); | |
716 | FOR_EACH_LIST_ELMT (tag, t->tags) | |
717 | { | |
718 | tblTagsTotalG++; | |
719 | tblTagHndl = AsnListAppend (tblT->tagList); | |
720 | *tblTagHndl = MT (TBLTag); | |
721 | switch (tag->tclass) | |
722 | { | |
723 | case UNIV: | |
724 | (**tblTagHndl).tclass = UNIVERSAL; | |
725 | break; | |
726 | case APPL: | |
727 | (**tblTagHndl).tclass = APPLICATION; | |
728 | break; | |
729 | case CNTX: | |
730 | (**tblTagHndl).tclass = CONTEXT; | |
731 | break; | |
732 | case PRIV: | |
733 | (**tblTagHndl).tclass = PRIVATE; | |
734 | break; | |
735 | } | |
736 | (**tblTagHndl).code = tag->code; | |
737 | } | |
738 | } | |
739 | ||
740 | return tblT; | |
741 | } /* GenTblTypesRec */ |