1 /* asnlext.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * File Name: asnlext.c
27 *
28 * Author: James Ostell
29 *
30 * Version Creation Date: 3/4/91
31 *
32 * $Revision: 6.10 $
33 *
34 * File Description:
35 * Routines for parsing ASN.1 module definitions. Extends asnlex.c
36 *
37 * Modifications:
38 * --------------------------------------------------------------------------
39 * Date Name Description of modification
40 * ------- ---------- -----------------------------------------------------
41 * 2/11/91 Ostell AsnModuleLink - corrected bug linking imported types
42 * to other imported types.
43 * 3/4/91 Kans Stricter typecasting for GNU C and C++
44 * 04-20-93 Schuler LIBCALL calling convention
45 *
46 * ==========================================================================
47 */
48
49 /*****************************************************************************
50 *
51 * asnlext.c
52 * routines of type AsnLexT..()
53 * Lexxer routines for Asn.1 specifications
54 *
55 *****************************************************************************/
56
57 #include "asnbuild.h"
58
59 #define NUMASNWORD 59 /* number of asnwords */
60
61 static CharPtr asnwords[NUMASNWORD] = { /* primitives from asn.1 */
62 "BOOLEAN", /* 1 */
63 "INTEGER", /* 2 */
64 "BIT", /* 3 */
65 "OCTET", /* 4 */
66 "NULL", /* 5 */
67 "OBJECT", /* 6 */
68 "ObjectDescriptor", /* 7 */
69 "EXTERNAL", /* 8 */
70 "REAL", /* 9 */
71 "ENUMERATED", /* 10 */
72 "SEQUENCE", /* 11 */
73 "STRING", /* 12 */
74 "SET", /* 13 */
75 "OF", /* 14 */
76 "CHOICE", /* 15 */
77 "ANY", /* 16 */
78 "NumericString", /* 17 */
79 "PrintableString", /* 18 */
80 "TeletexString", /* 19 */
81 "UTF8String", /* 20 */
82 "IA5String", /* 21 */
83 "GraphicString", /* 22 */
84 "VisibleString", /* 23 */
85 "GeneralString", /* 24 */
86 "CharacterString", /* 25 */
87 "GeneralizedTime", /* 26 */
88 "UTCTime", /* 27 */
89 "DEFINITIONS", /* 28 */
90 "BEGIN", /* 29 */
91 "END", /* 30 */
92 "APPLICATION", /* 31 */
93 "PRIVATE", /* 32 */
94 "UNIVERSAL", /* 33 */
95 "COMPONENTS", /* 34 */
96 "DEFAULT" , /* 35 */
97 "FALSE", /* 36 */
98 "TRUE", /* 37 */
99 "IMPLICIT", /* 38 */
100 "OPTIONAL", /* 39 */
101 "EXPORTS", /* 40 */
102 "IMPORTS", /* 41 */
103 "ABSENT", /* 42 */
104 "BY", /* 43 */
105 "COMPONENT", /* 44 */
106 "DEFINED", /* 45 */
107 "FROM", /* 46 */
108 "INCLUDES", /* 47 */
109 "MIN", /* 48 */
110 "MINUS-INFINITY", /* 49 */
111 "MAX", /* 50 */
112 "PRESENT", /* 51 */
113 "PLUS-INFINITY", /* 52 */
114 "SIZE", /* 53 */
115 "TAGS", /* 54 */
116 "WITH", /* 55 */
117 "IDENTIFIER", /* 56 */
118 "StringStore", /* 57 */ /* NCBI application type */
119 "$Revision:", /* 58 */ /* NCBI asn versions */
120 "BigInt" /* 59 */ /* NCBI application type */
121 };
122
123 static AsnPrimType asnprimtypes[] = {
124 {BOOLEAN_TYPE, "BOOLEAN", 0, 1 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
125 {INTEGER_TYPE, "INTEGER", 0, 2 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
126 {BITS_TYPE, "BIT STRING", 0, 3 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
127 {OCTETS_TYPE, "OCTET STRING", 0, 4 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
128 {NULL_TYPE, "NULL", 0, 5 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
129 {OBID_TYPE, "OBJECT IDENTIFIER", 0, 6 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
130 {OBDES_TYPE, "ObjectDescriptor", 0, 7 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
131 {EXTERNAL_TYPE, "EXTERNAL", 0, 8 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
132 {REAL_TYPE, "REAL", 0, 9 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
133 {ENUM_TYPE, "ENUMERATED", 0, 10 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
134 {SEQ_TYPE, "SEQUENCE", 0, 16 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
135 {SEQOF_TYPE, "SEQUENCE OF", 0, 16 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
136 {SET_TYPE, "SET", 0, 17 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
137 {SETOF_TYPE, "SET OF", 0, 17 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
138 {CHOICE_TYPE, "CHOICE", 0, -1 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
139 {ANY_TYPE, "ANY", 0, -1 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
140 {NUMERICSTRING_TYPE, "NumericString", 0, 18 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
141 {PRINTABLESTRING_TYPE, "PrintableString", 0, 19 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
142 {TELETEXSTRING_TYPE, "TeletexString", 0, 20 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
143 {UTF8STRING_TYPE, "UTF8String", 0, 12 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
144 {IA5STRING_TYPE, "IA5String", 0, 22 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
145 {GRAPHICSTRING_TYPE, "GraphicString", 0, 25 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
146 {VISIBLESTRING_TYPE, "VisibleString", 0, 26 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
147 {GENERALSTRING_TYPE, "GeneralString", 0, 27 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
148 {CHARACTERSTRING_TYPE, "CharacterString", 0, 28 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
149 {GENTIME_TYPE, "GeneralizedTime", 0, 24 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
150 {UTCTIME_TYPE, "UTCTime", 0, 23 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL}};
151
152 static AsnPrimType asnapptypes[] = { /* application wide types */
153 {STRSTORE_TYPE, "StringStore", 64, 1 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL},
154 {BIGINT_TYPE, "BigInt", 64, 2 , 0, 0, 0, 0, 0, 0, NULL, NULL,NULL,0,NULL, NULL}
155 };
156
157
158 /*****************************************************************************
159 *
160 * AsnLoadModules(aip)
161 * reads and links several modules
162 *
163 *****************************************************************************/
AsnLoadModules(AsnIoPtr aip)164 NLM_EXTERN AsnModulePtr LIBCALL AsnLoadModules (AsnIoPtr aip)
165 {
166 AsnModulePtr amp, nextmod, currentmod = NULL;
167
168 amp = NULL;
169 while ((nextmod = AsnLexTReadModule(aip)) != NULL )
170 {
171 if (amp == NULL)
172 amp = nextmod;
173 else
174 currentmod->next = nextmod;
175 currentmod = nextmod;
176 }
177
178 AsnModuleLink(amp); /* link up modules where possible */
179 return amp;
180 }
181
182 /*****************************************************************************
183 *
184 * AsnLexTReadModule(aip)
185 *
186 *****************************************************************************/
AsnLexTReadModule(AsnIoPtr aip)187 NLM_EXTERN AsnModulePtr AsnLexTReadModule (AsnIoPtr aip)
188 {
189 AsnModulePtr amp;
190 AsnOptionPtr aop;
191 DataVal dv;
192
193 /* get name and look for valid start */
194
195 amp = AsnLexTStartModule(aip);
196 if (amp == NULL)
197 return amp;
198
199 aop = AsnIoOptionGet(aip, OP_TYPEORDER, 0, NULL);
200 if (aop == NULL)
201 {
202 MemSet(&dv, 0, sizeof(DataVal));
203 aop = AsnIoOptionNew(aip, OP_TYPEORDER, 0, dv, NULL);
204 }
205 aop->data.intvalue = 1; /* start the order counter */
206
207 /* scan declarations */
208
209 while (aip->token != END_TOKEN) /* END */
210 {
211 if (aip->token == REF) /* its a type assignment */
212 aip->token = AsnLexTReadTypeAssign(aip, amp);
213 /**************************** not implemented yet ********
214 else if (token == IDENT)
215 aip->token = AsnReadDefinedValue(aip, amp);
216 **********************************************************/
217 else
218 {
219 AsnIoErrorMsg(aip, 60, aip->linenumber, aip->word);
220 return NULL;
221 }
222 }
223
224 amp = AsnCheckModule(amp, aip);
225
226 return amp;
227 }
228
229 /*****************************************************************************
230 *
231 * Int2 AsnLexTReadTypeAssign(aip, amp)
232 * reads a type assignment for one type
233 * assumes has read name already
234 * returns token to following item
235 * returns 0 on error
236 *
237 *****************************************************************************/
AsnLexTReadTypeAssign(AsnIoPtr aip,AsnModulePtr amp)238 NLM_EXTERN Int2 AsnLexTReadTypeAssign (AsnIoPtr aip, AsnModulePtr amp)
239 {
240 AsnTypePtr atp;
241 Int2 token;
242 AsnOptionPtr aop;
243
244 /* store the typereference */
245
246 atp = AsnTypeNew(aip, amp);
247 aop = AsnIoOptionGet(aip, OP_TYPEORDER, 0, NULL);
248 if (aop != NULL) /* add ordered display */
249 {
250 AsnOptionNew(&(atp->hints), OP_TYPEORDER, 0, aop->data, NULL);
251 aop->data.intvalue++;
252 }
253
254 if ((token = AsnLexTWord(aip)) != ISDEF)
255 {
256 AsnIoErrorMsg(aip, 28, aip->linenumber);
257 return 0;
258 }
259
260 token = AsnLexTWord(aip); /* get next element */
261
262 token = AsnLexTReadType(aip, amp, atp);
263
264 return token;
265 }
266
AsnLexTAddTypeComment(AsnIoPtr aip,AsnOptionPtr PNTR aopp)267 static void AsnLexTAddTypeComment(AsnIoPtr aip, AsnOptionPtr PNTR aopp)
268 {
269 AsnOptionPtr aop, aop2;
270 DataVal dv;
271
272 aop = NULL; /* check for comments before this type */
273 aop2 = NULL;
274 while ((aop = AsnIoOptionGet(aip, OP_COMMENT, 0, aop)) != NULL)
275 {
276 dv.ptrvalue = aop->data.ptrvalue;
277 aop->data.ptrvalue = NULL;
278 aop2 = AsnOptionNew(aopp, OP_COMMENT, 0, dv, DefAsnOptionFree);
279 }
280 if (aop2 != NULL) /* got some */
281 AsnIoOptionFree(aip, OP_COMMENT, 0); /* clear them out */
282 }
283 /*****************************************************************************
284 *
285 * Int2 AsnLexTReadType(aip, amp, atp)
286 * reads a type assignment for one type
287 * assumes has read name already
288 * assumes has read next input item after name
289 * returns token to following item
290 * returns 0 on error
291 *
292 *****************************************************************************/
AsnLexTReadType(AsnIoPtr aip,AsnModulePtr amp,AsnTypePtr atp)293 NLM_EXTERN Int2 AsnLexTReadType (AsnIoPtr aip, AsnModulePtr amp, AsnTypePtr atp)
294 {
295 Int2 isa;
296 Boolean first;
297 AsnValxNodePtr avnp, prevavnp;
298 Int2 token;
299
300 token = aip->token;
301
302 if (token == COMMENT_TOKEN)
303 {
304 AsnLexTAddTypeComment(aip, &(atp->hints));
305 token = AsnLexTWord(aip);
306 }
307
308 if (token == IMPLICIT_TOKEN)
309 {
310 atp->implicit = TRUE;
311 token = AsnLexTWord(aip);
312 }
313
314 if (token == START_TAG) /* TAG */
315 {
316 token = AsnLexTWord(aip);
317 if (ISA_TAGCLASS(token))
318 {
319 switch (token)
320 {
321 case UNIV_TAG_TOKEN:
322 atp->tagclass = TAG_UNIVERSAL;
323 break;
324 case PRIV_TAG_TOKEN:
325 atp->tagclass = TAG_PRIVATE;
326 break;
327 case AP_TAG_TOKEN:
328 atp->tagclass = TAG_APPLICATION;
329 break;
330 }
331 token = AsnLexTWord(aip);
332 }
333 else
334 atp->tagclass = TAG_CONTEXT;
335
336 if (token == NUMBER)
337 {
338 atp->tagnumber = (Int2) AsnLexInteger(aip);
339 token = AsnLexTWord(aip);
340 if (token != END_TAG)
341 {
342 AsnIoErrorMsg(aip, 61, aip->linenumber);
343 return 0;
344 }
345 else
346 token = AsnLexTWord(aip);
347 }
348 else if (token == IDENT)
349 {
350 AsnIoErrorMsg(aip, 62, aip->linenumber);
351 return 0;
352 }
353 else
354 {
355 AsnIoErrorMsg(aip, 63, aip->linenumber);
356 return 0;
357 }
358 }
359
360 atp->type = AsnGetType(aip, amp);
361 isa = atp->type->isa;
362
363 token = AsnLexTWord(aip); /* read next token */
364
365 AsnLexTAddTypeComment(aip, &(atp->hints)); /* check for stored comments */
366
367 if (token == COMMENT_TOKEN)
368 token = AsnLexTWord(aip);
369
370 /*********** SubType Processing *********************/
371 if (token == OPEN_PAREN)
372 {
373 AsnIoErrorMsg(aip, 64, aip->linenumber);
374 return 0;
375 }
376 /******************* process various types *********/
377
378 if (isa < 400) /* operate on builtin types */
379 switch (isa)
380 {
381 case INTEGER_TYPE: /* check for named integers */
382 if (token != START_STRUCT)
383 break;
384 case ENUM_TYPE:
385 if (token != START_STRUCT)
386 {
387 AsnIoErrorMsg(aip, 65, aip->linenumber);
388 return 0;
389 }
390
391 /* read named integers */
392 first = TRUE;
393 avnp = NULL;
394 prevavnp = NULL;
395 token = AsnLexTWord(aip);
396 if (token == COMMENT_TOKEN)
397 {
398 AsnLexTAddTypeComment(aip, &(atp->hints)); /* check for stored comments */
399 token = AsnLexTWord(aip);
400 }
401
402 while (token != END_STRUCT)
403 {
404 avnp = AsnValxNodeNew(avnp, VALUE_ISA_NAMED_INT);
405
406 if (! first)
407 {
408 if (token != COMMA)
409 {
410 AsnIoErrorMsg(aip, 66, aip->linenumber);
411 return 0;
412 }
413 else
414 {
415 token = AsnLexTWord(aip);
416 if (token == COMMENT_TOKEN)
417 {
418 AsnLexTAddTypeComment(aip, &(prevavnp->aop));
419 token = AsnLexTWord(aip);
420 }
421 }
422
423 }
424 else
425 {
426 first = FALSE;
427 atp->branch = avnp;
428 }
429
430 if (token != IDENT)
431 {
432 AsnIoErrorMsg(aip, 86, aip->linenumber);
433 return 0;
434 }
435 avnp->name = AsnLexSaveWord(aip);
436 token = AsnLexTWord(aip);
437 if (token != OPEN_PAREN)
438 {
439 AsnIoErrorMsg(aip, 87, aip->linenumber);
440 return 0;
441 }
442 avnp->intvalue = AsnLexReadInteger(aip, atp);
443 token = AsnLexTWord(aip);
444 if (token != CLOSE_PAREN)
445 {
446 AsnIoErrorMsg(aip, 88, aip->linenumber);
447 return 0;
448 }
449 token = AsnLexTWord(aip);
450 if (token == COMMENT_TOKEN)
451 token = AsnLexTWord(aip);
452
453 AsnLexTAddTypeComment(aip, &(avnp->aop)); /* check for stored comments */
454 prevavnp = avnp;
455 }
456 token = AsnLexTWord(aip);
457 if (token == COMMENT_TOKEN)
458 {
459 AsnLexTAddTypeComment(aip, &(prevavnp->aop));
460 token = AsnLexTWord(aip);
461 }
462 break;
463 case SETOF_TYPE: /* create branch for type */
464 case SEQOF_TYPE:
465 atp->branch = AsnElementTypeNew(NULL); /* get unnamed element for type */
466 token = AsnLexTReadType(aip, amp, (AsnTypePtr) atp->branch);
467 break;
468 case SEQ_TYPE:
469 case SET_TYPE:
470 atp->branch = AsnLexTReadElementTypeList(aip, amp, atp);
471 token = aip->token;
472 break;
473 case CHOICE_TYPE:
474 atp->branch = AsnLexTReadAlternativeTypeList(aip, amp, atp);
475 token = aip->token;
476 break;
477 }
478 atp->resolved = TRUE;
479 return token;
480 }
481
482 /*****************************************************************************
483 *
484 * AsnTypePtr AsnLexTReadElementTypeList(aip, amp)
485 * assumes has read first { already
486 * returns token to following element
487 *
488 *****************************************************************************/
AsnLexTReadElementTypeList(AsnIoPtr aip,AsnModulePtr amp,AsnTypePtr parent)489 NLM_EXTERN AsnTypePtr AsnLexTReadElementTypeList (AsnIoPtr aip, AsnModulePtr amp, AsnTypePtr parent)
490 {
491 Int2 token;
492 AsnTypePtr atp, atp1, atplast, atp2;
493 AsnValxNodePtr avnp;
494
495 token = aip->token;
496 atp1 = NULL;
497 atplast = NULL;
498
499 if (token != START_STRUCT)
500 {
501 AsnIoErrorMsg(aip, 37, aip->linenumber);
502 return NULL;
503 }
504 token = AsnLexTWord(aip);
505 if (token == COMMENT_TOKEN)
506 {
507 if (parent != NULL)
508 AsnLexTAddTypeComment(aip, &(parent->hints));
509 token = AsnLexTWord(aip);
510 }
511
512 while (token != END_STRUCT)
513 {
514 if (atp1 != NULL) /* not the first */
515 {
516 if (token != COMMA)
517 {
518 AsnIoErrorMsg(aip, 66, aip->linenumber);
519 return NULL;
520 }
521 else
522 {
523 token = AsnLexTWord(aip);
524 if (token == COMMENT_TOKEN)
525 {
526 if (atplast != NULL)
527 AsnLexTAddTypeComment(aip, &(atplast->hints));
528 token = AsnLexTWord(aip);
529 }
530 }
531 }
532
533 if (token == COMPS_TOKEN) /* COMPONENTS OF */
534 {
535 AsnIoErrorMsg(aip, 93, aip->linenumber);
536 return NULL;
537 }
538 else if (token != IDENT) /* not named */
539 {
540 atp = AsnElementTypeNew(NULL);
541 }
542 else /* named Type */
543 {
544 atp = AsnElementTypeNew(aip);
545 token = AsnLexTWord(aip);
546 if (token == COMMENT_TOKEN)
547 {
548 AsnLexTAddTypeComment(aip, &(atp->hints));
549 token = AsnLexTWord(aip);
550 }
551 }
552 /* add to chain */
553 if (atp1 == NULL)
554 atp1 = atp;
555 else
556 atplast->next = atp;
557
558 token = AsnLexTReadType(aip, amp, atp);
559
560 if (token == OPTIONAL_TOKEN) /* OPTIONAL */
561 {
562 atp->optional = TRUE;
563 token = AsnLexTWord(aip);
564 }
565 else if (token == DEFAULT_TOKEN) /* DEFAULT */
566 {
567 atp->hasdefault = TRUE;
568 avnp = AsnValxNodeNew(NULL, VALUE_ISA_BOOL);
569 atp->defaultvalue = avnp;
570 /* read the default value */
571 atp2 = AsnFindBaseType(atp);
572
573 if (atp2 == NULL)
574 {
575 AsnIoErrorMsg(aip, 95, AsnErrGetTypeName(atp->name), aip->linenumber);
576 return NULL;
577 }
578
579 switch (atp2->type->isa)
580 {
581 case BOOLEAN_TYPE:
582 avnp->intvalue = (Int4) AsnLexReadBoolean(aip, atp2);
583 break;
584 case INTEGER_TYPE:
585 case ENUM_TYPE:
586 avnp->valueisa = VALUE_ISA_INT;
587 avnp->intvalue = AsnLexReadInteger(aip, atp2);
588 break;
589 case VISIBLESTRING_TYPE:
590 avnp->valueisa = VALUE_ISA_PTR;
591 avnp->name = (CharPtr) AsnLexReadString(aip, atp2);
592 break;
593 case REAL_TYPE:
594 avnp->valueisa = VALUE_ISA_REAL;
595 avnp->realvalue = AsnLexReadReal(aip, atp2);
596 break;
597 default:
598 AsnIoErrorMsg(aip, 94, AsnErrGetTypeName(atp->name));
599 return NULL;
600 }
601 token = AsnLexTWord(aip);
602 }
603 atplast = atp;
604
605 AsnLexTAddTypeComment(aip, &(atplast->hints));
606 if (token == COMMENT_TOKEN)
607 token = AsnLexTWord(aip);
608
609 }
610 token = AsnLexTWord(aip); /* read following item */
611 if (token == COMMENT_TOKEN)
612 {
613 if (atplast != NULL)
614 AsnLexTAddTypeComment(aip, &(atplast->hints));
615 token = AsnLexTWord(aip);
616 }
617 return atp1;
618 }
619
620 /*****************************************************************************
621 *
622 * AsnTypePtr AsnLexTReadAlternativeTypeList(aip, amp, parent)
623 * assumes has read first { already
624 * returns token to following element
625 *
626 *****************************************************************************/
AsnLexTReadAlternativeTypeList(AsnIoPtr aip,AsnModulePtr amp,AsnTypePtr parent)627 NLM_EXTERN AsnTypePtr AsnLexTReadAlternativeTypeList (AsnIoPtr aip, AsnModulePtr amp, AsnTypePtr
628 parent)
629 {
630 Int2 token;
631 AsnTypePtr atp, atp1, atplast;
632
633 token = aip->token;
634 atp1 = NULL;
635 atplast = NULL;
636
637 if (token != START_STRUCT)
638 {
639 AsnIoErrorMsg(aip, 37, aip->linenumber);
640 return NULL;
641 }
642 token = AsnLexTWord(aip);
643 if (token == COMMENT_TOKEN)
644 {
645 if (parent != NULL)
646 AsnLexTAddTypeComment(aip, &(parent->hints));
647 token = AsnLexTWord(aip);
648 }
649
650 while (token != END_STRUCT)
651 {
652 if (atp1 != NULL) /* not the first */
653 {
654 if (token != COMMA)
655 {
656 AsnIoErrorMsg(aip, 66, aip->linenumber);
657 return NULL;
658 }
659 else
660 {
661 token = AsnLexTWord(aip);
662 if (token == COMMENT_TOKEN)
663 {
664 if (atplast != NULL)
665 AsnLexTAddTypeComment(aip, &(atplast->hints));
666 token = AsnLexTWord(aip);
667 }
668 }
669 }
670
671 if (token != IDENT) /* not named */
672 {
673 atp = AsnElementTypeNew(NULL);
674 }
675 else /* named Type */
676 {
677 atp = AsnElementTypeNew(aip);
678 token = AsnLexTWord(aip);
679 if (token == COMMENT_TOKEN)
680 {
681 AsnLexTAddTypeComment(aip, &(atp->hints));
682 token = AsnLexTWord(aip);
683 }
684 }
685 /* add to chain */
686 if (atp1 == NULL)
687 atp1 = atp;
688 else
689 atplast->next = atp;
690
691 token = AsnLexTReadType(aip, amp, atp);
692 atplast = atp;
693
694 AsnLexTAddTypeComment(aip, &(atplast->hints));
695 if (token == COMMENT_TOKEN)
696 token = AsnLexTWord(aip);
697 }
698 token = AsnLexTWord(aip); /* read following item */
699 if (token == COMMENT_TOKEN)
700 {
701 if (atplast != NULL)
702 AsnLexTAddTypeComment(aip, &(atplast->hints));
703 token = AsnLexTWord(aip);
704 }
705 return atp1;
706 }
707
708 /*****************************************************************************
709 *
710 * AsnModulePtr AsnLexTStartModule(aip)
711 * if $Revision: in comment in first line of file, puts the string
712 * containing the revision number in amp->filename
713 * if --$Revision: X.YY
714 * stores "YY"
715 * if --$Revision: X.Y stores "XY"
716 * if --$Revision: X
717 * stores "X"
718 *
719 *****************************************************************************/
AsnLexTStartModule(AsnIoPtr aip)720 NLM_EXTERN AsnModulePtr AsnLexTStartModule (AsnIoPtr aip)
721 {
722 Int2 token;
723 AsnModulePtr amp;
724 Int2 asntype;
725 AsnTypePtr atp;
726 Boolean wasref;
727 Char buf[10];
728 CharPtr from, to;
729 Int2 len;
730
731 amp = (AsnModulePtr) MemNew(sizeof(AsnModule));
732
733 token = AsnLexTWord(aip); /* get the module name or $Revision: */
734
735 while (token == COMMENT_TOKEN)
736 {
737 token = AsnLexTWord(aip);
738 }
739
740
741 if (token == REVISION_TOKEN) /* revision of file */
742 {
743 to = buf;
744 *to = '\0';
745 len = (Int2)(aip->wordlen);
746 if (len == 4) /* x.yy */
747 {
748 from = aip->word + 2;
749 len -= 2;
750 }
751 else
752 from = aip->word;
753
754 if (len)
755 {
756 if (IS_DIGIT(*from))
757 {
758 *to = *from; to++; from++;len--;
759 }
760 while ((len) && (! IS_DIGIT(*from)))
761 {
762 len--; from++;
763 }
764 if ((len) && (IS_DIGIT(*from)))
765 {
766 *to = *from; to++;
767 }
768 *to = '\0';
769 amp->filename = StringSave(buf);
770 }
771
772 token = AsnLexTWord(aip); /* get the module name */
773
774 while (token == COMMENT_TOKEN)
775 {
776 token = AsnLexTWord(aip);
777 }
778 }
779
780 if (token != REF)
781 {
782 MemFree(amp->filename);
783 amp = (AsnModulePtr) MemFree(amp);
784 return amp;
785 }
786
787 if ((asntype = AsnLexTMatchToken(aip)) != 0) /* any predefined value is wrong */
788 {
789 AsnIoErrorMsg(aip, 67, asnwords[asntype -1], aip->linenumber);
790 return NULL;
791 }
792
793 /* create a new module */
794
795
796 amp->modulename = AsnLexSaveWord(aip);
797 amp->lasttype = 400;
798 amp->lastvalue = 10000;
799
800 token = AsnLexTWord(aip);
801
802 while (token == COMMENT_TOKEN)
803 {
804 token = AsnLexTWord(aip);
805 }
806
807 if (token == START_STRUCT) /* it has an object identifier */
808 {
809 AsnIoErrorMsg(aip, 68);
810 /* skip object identifier */
811 AsnLexSkipStruct(aip);
812 token = AsnLexTWord(aip); /* next token */
813 }
814
815 while (token == COMMENT_TOKEN)
816 {
817 token = AsnLexTWord(aip);
818 }
819
820 if (token != DEF_TOKEN) /* DEFINITIONS */
821 {
822 AsnIoErrorMsg(aip, 69, asnwords[DEF_TOKEN - 401], aip->linenumber);
823 return NULL;
824 }
825 else
826 token = AsnLexTWord(aip);
827
828 while (token == COMMENT_TOKEN)
829 {
830 token = AsnLexTWord(aip);
831 }
832 while (token != ISDEF && token != BEGIN_TOKEN && token != ERROR_TOKEN)
833 {
834 token = AsnLexTWord(aip);
835 }
836 if (token != ISDEF) /* ::= */
837 {
838 AsnIoErrorMsg(aip, 69, "::=", aip->linenumber);
839 return NULL;
840 }
841 else
842 token = AsnLexTWord(aip);
843
844 while (token == COMMENT_TOKEN)
845 {
846 token = AsnLexTWord(aip);
847 }
848
849 if (token != BEGIN_TOKEN) /* BEGIN */
850 {
851 AsnIoErrorMsg(aip, 69, asnwords[BEGIN_TOKEN - 401], aip->linenumber);
852 return NULL;
853 }
854 else
855 token = AsnLexTWord(aip);
856
857 while (token == COMMENT_TOKEN)
858 {
859 token = AsnLexTWord(aip);
860 }
861
862 if (token == EXPORTS_TOKEN) /* read any EXPORTS */
863 {
864 wasref = FALSE;
865 while ((token = AsnLexTWord(aip)) != SEMI_COLON)
866 {
867 if (token == REF) /* should be REF */
868 {
869 if (wasref)
870 {
871 AsnIoErrorMsg(aip, 66, aip->linenumber);
872 return NULL;
873 }
874 atp = AsnTypeNew(aip, amp);
875 atp->exported = TRUE;
876 wasref = TRUE;
877 }
878 else if (token == COMMA)
879 {
880 if (! wasref)
881 {
882 AsnIoErrorMsg(aip, 70, aip->linenumber);
883 return NULL;
884 }
885 wasref = FALSE;
886 }
887 else if (token != COMMENT_TOKEN)
888 {
889 AsnIoErrorMsg(aip, 59, ' ', aip->linenumber);
890 return NULL;
891 }
892 }
893 /* get next after semi-colon */
894
895 token = AsnLexTWord(aip);
896 }
897
898 while (token == COMMENT_TOKEN)
899 {
900 token = AsnLexTWord(aip);
901 }
902
903 if (token == IMPORTS_TOKEN) /* IMPORTS */
904 {
905 wasref = FALSE;
906 token = AsnLexTWord(aip);
907
908 while (token != SEMI_COLON)
909 {
910 if (token == REF) /* should be REF */
911 {
912 atp = AsnTypeNew(aip, amp);
913 atp->imported = TRUE;
914 wasref = TRUE;
915 }
916 else if (token == COMMA)
917 {
918 if (! wasref)
919 {
920 AsnIoErrorMsg(aip, 70, aip->linenumber);
921 return NULL;
922 }
923 wasref = FALSE;
924 }
925 else if (token == FROM_TOKEN)
926 {
927 if (! wasref)
928 {
929 AsnIoErrorMsg(aip, 71, aip->linenumber);
930 return NULL;
931 }
932 else /* read source module */
933 token = AsnLexTWord(aip);
934
935 if (token != REF)
936 {
937 AsnIoErrorMsg(aip, 72, aip->linenumber);
938 return NULL;
939 }
940 else
941 {
942 atp = amp->types;
943 while (atp != NULL)
944 {
945 if ((atp->imported == TRUE) && (atp->branch == NULL))
946 atp->branch = AsnLexSaveWord(aip);
947 atp = atp->next;
948 }
949 }
950 wasref = FALSE;
951 }
952 else if (token == START_STRUCT)
953 {
954 AsnIoErrorMsg(aip, 73, aip->linenumber);
955 AsnLexSkipStruct(aip);
956 token = AsnLexTWord(aip);
957 wasref = FALSE;
958 }
959 else if (token != COMMENT_TOKEN)
960 AsnIoErrorMsg(aip, 96, aip->linenumber);
961
962 token = AsnLexTWord(aip);
963 }
964 /* get next after semi-colon */
965 token = AsnLexTWord(aip);
966 }
967
968 while (token == COMMENT_TOKEN)
969 {
970 token = AsnLexTWord(aip);
971 }
972
973 if (token == EXPORTS_TOKEN) /* EXPORTS out of place */
974 AsnIoErrorMsg(aip, 97, aip->linenumber);
975
976 return amp;
977 }
978
979
980 /*****************************************************************************
981 *
982 * Int2 AsnLexTMatchToken(aip)
983 *
984 *****************************************************************************/
AsnLexTMatchToken(AsnIoPtr aip)985 NLM_EXTERN Int2 AsnLexTMatchToken (AsnIoPtr aip)
986 {
987 CharPtr word;
988 register int i;
989 Int2 len;
990
991 word = aip->word;
992 len = aip->wordlen;
993
994 for (i = 0; i < NUMASNWORD; i++)
995 {
996 if (StrMatch(asnwords[i], word, len))
997 return i+1;
998 }
999 return 0; /* not found */
1000 }
AsnLexTAddComment(CharPtr cbeg,CharPtr cend,AsnIoPtr aip)1001 static void AsnLexTAddComment(CharPtr cbeg, CharPtr cend, AsnIoPtr aip)
1002 {
1003 Char tchar;
1004 CharPtr comment;
1005 DataVal dv;
1006
1007 tchar = *cend;
1008 *cend = '\0';
1009 comment = StringSave(cbeg);
1010 *cend = tchar;
1011 dv.ptrvalue = comment;
1012
1013 AsnIoOptionNew(aip, OP_COMMENT, 0, dv, NULL);
1014 return;
1015 }
1016 /*****************************************************************************
1017 *
1018 * Int2 AsnLexTWord(aip)
1019 * reads words, punctuation, and asn keywords with 2 parts
1020 * returns tokens defined at top
1021 *
1022 *****************************************************************************/
AsnLexTWord(AsnIoPtr aip)1023 NLM_EXTERN Int2 AsnLexTWord (AsnIoPtr aip)
1024 {
1025 register CharPtr pos;
1026 register int len;
1027 Int1 state;
1028 Int2 token, asntype, linepos;
1029 int done;
1030 Boolean first = FALSE, hitnewline = FALSE;
1031 CharPtr commentptr;
1032
1033 if (! aip->bytes) /* no data loaded */
1034 {
1035 hitnewline = TRUE;
1036 first = TRUE;
1037 AsnIoGets(aip);
1038 }
1039
1040 linepos = aip->linepos;
1041 pos = aip->linebuf + linepos;
1042 state = aip->state;
1043 len = 0;
1044 token = -1;
1045
1046 while (*pos == '\n' || *pos == '\r') /* skip empty lines */
1047 {
1048 hitnewline = TRUE;
1049 pos = AsnIoGets(aip);
1050
1051 if (pos == NULL)
1052 return EOF_TOKEN;
1053 }
1054
1055 if (state == IN_STRING_STATE)
1056 {
1057 aip->word = pos;
1058 if (* pos == '\"') /* end of string */
1059 {
1060 token = END_STRING;
1061 pos++;
1062 state = 0; /* reset state */
1063 }
1064 else
1065 {
1066 token = IN_STRING;
1067 while ((* pos != '\"') && (* pos != '\n') && (* pos != '\r'))
1068 {
1069 pos++; len++;
1070 }
1071
1072 if ((*pos != '\n') && (*pos != '\r') && (* (pos + 1) == '\"')) /* internal quote */
1073 {
1074 len++; /* include in previous string */
1075 pos += 2; /* point to rest of string */
1076 }
1077 }
1078 }
1079 else if (state == IN_BITHEX_STATE)
1080 {
1081 aip->word = pos;
1082 if (*pos == '\'') /* end of binhex */
1083 {
1084 state = 0; /* set to normal */
1085 pos++; /* move past quote */
1086 while (IS_WHITESP(*pos))
1087 pos++;
1088 if (* pos == 'H')
1089 token = OCTETS;
1090 else if (* pos == 'B')
1091 token = ASNBITS;
1092 else
1093 {
1094 AsnIoErrorMsg(aip, 58, aip->linenumber);
1095 token = ERROR_TOKEN;
1096 }
1097 }
1098 else
1099 {
1100 token = IN_BITHEX;
1101 while ((* pos != '\'') && (* pos != '\n') && (* pos != '\r'))
1102 {
1103 pos++; len++;
1104 }
1105 }
1106 }
1107 else /* normal scanning */
1108 {
1109 done = 0;
1110 while (! done)
1111 {
1112 while (* pos <= ' ') /* skip leading white space */
1113 {
1114 if (*pos == '\n' || *pos == '\r')
1115 {
1116 hitnewline = TRUE;
1117 pos = AsnIoGets(aip);
1118
1119 if (pos == NULL)
1120 return EOF_TOKEN;
1121 }
1122 else
1123 pos++;
1124 }
1125 done = 1;
1126
1127 while (done && (*pos == '-') && (*(pos+1) == '-')) /* skip comments */
1128 {
1129 pos += 2;
1130 if (first) /* could be revision */
1131 {
1132 first = FALSE;
1133 if (StrMatch(asnwords[57], pos, 10)) /* $Revision: */
1134 {
1135 token = REVISION_TOKEN;
1136 pos += 10;
1137 while (IS_WHITESP(*pos))
1138 pos++;
1139 aip->word = pos;
1140 while (IS_DIGIT(*pos)) /* eg. 1.2 */
1141 {
1142 len++;
1143 pos++;
1144 }
1145 if (*pos == '.') /* take after . if present */
1146 {
1147 pos++;
1148 len++;
1149 while (IS_DIGIT(*pos))
1150 {
1151 len++;
1152 pos++;
1153 }
1154 }
1155 }
1156 }
1157 commentptr = pos;
1158
1159 done = 0;
1160 while (! done) /* skip to end of comment */
1161 {
1162 if ((*pos == '-') && (*(pos +1) == '-'))
1163 {
1164 if (token != REVISION_TOKEN)
1165 {
1166 AsnLexTAddComment(commentptr, pos, aip);
1167 if ((! hitnewline) && (aip->token != COMMENT_TOKEN))
1168 token = COMMENT_TOKEN;
1169 }
1170 pos += 2;
1171 done = 1;
1172 }
1173 else if (*pos == '\n' || *pos == '\r')
1174 {
1175 if (token != REVISION_TOKEN)
1176 {
1177 AsnLexTAddComment(commentptr, pos, aip);
1178 if ((! hitnewline) && (aip->token != COMMENT_TOKEN))
1179 token = COMMENT_TOKEN;
1180 }
1181
1182 done = 1;
1183 }
1184 else
1185 pos++;
1186 }
1187
1188 if ((token == REVISION_TOKEN) || (token == COMMENT_TOKEN))
1189 {
1190 aip->linepos = pos - aip->linebuf;
1191 aip->state = state;
1192 aip->wordlen = len;
1193 aip->token = token;
1194 return token;
1195 }
1196
1197 if (*pos <= ' ')
1198 done = 0;
1199 else
1200 done = 1;
1201 }
1202 }
1203
1204 aip->word = pos;
1205 if (* pos == '\"')
1206 {
1207 token = START_STRING;
1208 state = IN_STRING_STATE;
1209 }
1210 else if (* pos == '\'')
1211 {
1212 token = START_BITHEX;
1213 state = IN_BITHEX_STATE;
1214 }
1215 else if (* pos == ',')
1216 token = COMMA;
1217 else if (* pos == '{')
1218 token = START_STRUCT;
1219 else if (* pos == '}')
1220 token = END_STRUCT;
1221 else if (* pos == '[')
1222 token = START_TAG;
1223 else if (* pos == ']')
1224 token = END_TAG;
1225 else if (* pos == '(')
1226 token = OPEN_PAREN;
1227 else if (* pos == ')')
1228 token = CLOSE_PAREN;
1229 else if (* pos == ';')
1230 token = SEMI_COLON;
1231 else if (* pos == ':')
1232 {
1233 if ((*(pos + 1) == ':') && (*(pos + 2) == '='))
1234 {
1235 token = ISDEF;
1236 pos += 2;
1237 len = 3;
1238 }
1239 else
1240 {
1241 AsnIoErrorMsg(aip, 59, *pos, aip->linenumber);
1242 token = ERROR_TOKEN;
1243 }
1244 }
1245 else if (IS_UPPER(*pos)) /* a reference or keyword */
1246 {
1247 token = REF;
1248 while ((IS_ALPHANUM(*pos)) || (*pos == '-'))
1249 {
1250 pos++; len++;
1251 }
1252
1253 aip->wordlen = len;
1254 asntype = AsnLexTMatchToken(aip); /* check types */
1255 if (asntype) /* did it match ? */
1256 {
1257 if ((asntype > 27) && (asntype < 57)) /* not a primitive type */
1258 {
1259 token = asntype + 400; /* make a keyword type */
1260 if (asntype == COMPS_TOKEN) /* COMPONENTS OF */
1261 {
1262 if ((*(pos + 1) == 'O') &&
1263 (*(pos + 2) == 'F') &&
1264 (IS_WHITESP(*(pos+3))))
1265 {
1266 pos += 3; /* move past OF */
1267 len += 3;
1268 }
1269 else
1270 AsnIoErrorMsg(aip, 89, aip->linenumber);
1271 }
1272 }
1273 else if (asntype == 57) /* StringStore */
1274 token = STRSTORE_TYPE;
1275 else if (asntype == 59) /* BitInt */
1276 token = BIGINT_TYPE;
1277 else
1278 {
1279 switch (asntype)
1280 {
1281 case 3: /* BIT */
1282 case 4: /* OCTET */
1283 if (! StrMatch(asnwords[11], (pos+1), 6))
1284 AsnIoErrorMsg(aip, 90, aip->linenumber);
1285 pos += 7; /* move past STRING */
1286 len += 7;
1287 break;
1288 case 11: /* SEQUENCE */
1289 case 13: /* SET */
1290 if ((*(pos + 1) == 'O') &&
1291 (*(pos + 2) == 'F'))
1292 {
1293 asntype++; /* SET or SEQ OF */
1294 pos += 3;
1295 len += 3;
1296 if (! IS_WHITESP(*pos))
1297 AsnIoErrorMsg(aip, 91, aip->linenumber);
1298 }
1299 break;
1300 case 6: /* OBJECT */
1301 if ((! StrMatch(asnwords[55], (pos+1), 10))) /* IDENTIFIER */
1302 AsnIoErrorMsg(aip, 92, aip->linenumber);
1303 pos += 11;
1304 len += 11;
1305 break;
1306 default:
1307 break;
1308 }
1309 token = asntype + 300; /* change to point at type */
1310 }
1311 }
1312 pos--; /* move back for increment at end */
1313 len--;
1314 }
1315 else if (IS_LOWER(*pos)) /* an identifier or valuereference */
1316 {
1317 token = IDENT;
1318 while ((IS_ALPHANUM(*pos)) || (*pos == '-'))
1319 {
1320 pos++; len++;
1321 }
1322 pos--; /* move back for increment at end */
1323 len--;
1324 }
1325 else if ((IS_DIGIT(*pos)) || ((*pos == '-') && (IS_DIGIT(*(pos+1)))))
1326 {
1327 token = NUMBER;
1328 if (*pos == '-')
1329 {
1330 pos++; len++;
1331 }
1332
1333 while (IS_DIGIT(*pos))
1334 {
1335 pos++; len++;
1336 }
1337 pos--; /* move back for increment at end */
1338 len--;
1339 }
1340 else
1341 {
1342 AsnIoErrorMsg(aip, 59, *pos, aip->linenumber);
1343 token = ERROR_TOKEN;
1344 }
1345 len++; pos++; /* move over last symbol */
1346 }
1347 aip->linepos = pos - aip->linebuf;
1348 aip->state = state;
1349 aip->wordlen = len;
1350 aip->token = token;
1351 return token;
1352 }
1353
1354 /*****************************************************************************
1355 *
1356 * AsnTypePtr AsnGetType(aip, amp)
1357 * return pointer to type of last element read
1358 *
1359 *****************************************************************************/
AsnGetType(AsnIoPtr aip,AsnModulePtr amp)1360 NLM_EXTERN AsnTypePtr AsnGetType (AsnIoPtr aip, AsnModulePtr amp)
1361 {
1362 AsnTypePtr atp;
1363 AsnPrimTypePtr aptp;
1364 Int2 wordlen;
1365 Int2 token;
1366
1367 wordlen = aip->wordlen;
1368 token = aip->token;
1369
1370 if (ISA_ASNTYPE(aip->token)) /* a primitive */
1371 {
1372 aptp = asnprimtypes;
1373 while (aptp->isa != token)
1374 aptp++;
1375 return (AsnTypePtr)aptp;
1376 }
1377 else if (ISA_BASETYPE(aip->token)) /* an application type */
1378 {
1379 aptp = asnapptypes;
1380 while (aptp->isa != token)
1381 aptp++;
1382 return (AsnTypePtr)aptp;
1383 }
1384
1385 if (aip->token != REF) /* not a type */
1386 {
1387 AsnIoErrorMsg(aip, 98, aip->word, aip->linenumber);
1388 return NULL;
1389 }
1390
1391 /**************** not a primitive - do we have it already? *******/
1392
1393 atp = amp->types;
1394 while (atp != NULL)
1395 {
1396 if (StrMatch(atp->name, aip->word, wordlen)) /* it matches */
1397 {
1398 if (atp->imported == TRUE) /* reference to imported type */
1399 atp->resolved = TRUE;
1400 return atp;
1401 }
1402 else
1403 atp = atp->next;
1404 }
1405
1406 /*************** not defined - add unresolved node *************/
1407
1408 atp = AsnTypeNew(aip, amp);
1409
1410 return atp;
1411 }
1412
1413 /*****************************************************************************
1414 *
1415 * AsnTypePtr AsnTypeNew(aip, amp)
1416 *
1417 *****************************************************************************/
AsnTypeNew(AsnIoPtr aip,AsnModulePtr amp)1418 NLM_EXTERN AsnTypePtr AsnTypeNew (AsnIoPtr aip, AsnModulePtr amp)
1419 {
1420 AsnTypePtr atp, next;
1421 Int2 token;
1422
1423 next = amp->types;
1424 atp = amp->types;
1425
1426 if ((token = AsnLexTMatchToken(aip)) != 0) /* it's a reserved word */
1427 AsnIoErrorMsg(aip, 67, asnwords[token - 1], aip->linenumber);
1428
1429 while (next != NULL)
1430 {
1431 atp = next;
1432 next = atp->next;
1433 if (StrMatch(atp->name, aip->word, aip->wordlen)) /* already used name */
1434 {
1435 if (! atp->resolved) /* needs to be resolved yet, so OK */
1436 return atp;
1437 else /* already defined */
1438 {
1439 AsnIoErrorMsg(aip, 99, AsnErrGetTypeName(atp->name), aip->linenumber);
1440 }
1441 }
1442 }
1443
1444 next = (AsnTypePtr) MemNew(sizeof(AsnType));
1445 next->tagclass = TAG_NONE; /* default tag class */
1446 next->name = AsnLexSaveWord(aip);
1447 amp->lasttype++; /* increment defined types isa */
1448 next->isa = amp->lasttype;
1449
1450 if (atp == NULL) /* first one */
1451 amp->types = next;
1452 else
1453 atp->next = next;
1454
1455 return next;
1456 }
1457
1458 /*****************************************************************************
1459 *
1460 * AsnTypePtr AsnElementTypeNew(aip)
1461 *
1462 *****************************************************************************/
AsnElementTypeNew(AsnIoPtr aip)1463 NLM_EXTERN AsnTypePtr AsnElementTypeNew (AsnIoPtr aip)
1464 {
1465 AsnTypePtr atp;
1466
1467 atp = (AsnTypePtr) MemNew(sizeof(AsnType));
1468 atp->tagclass = TAG_NONE; /* default tag class */
1469 atp->tagnumber = -1; /* not yet assigned */
1470 if (aip != NULL)
1471 atp->name = AsnLexSaveWord(aip);
1472
1473 return atp;
1474 }
1475
1476 /*****************************************************************************
1477 *
1478 * AsnModulePtr AsnCheckModule(amp, aip)
1479 *
1480 *****************************************************************************/
AsnCheckModule(AsnModulePtr amp,AsnIoPtr aip)1481 NLM_EXTERN AsnModulePtr AsnCheckModule (AsnModulePtr amp, AsnIoPtr aip)
1482 {
1483 AsnTypePtr atp;
1484 Boolean ok = TRUE;
1485
1486 atp = amp->types; /* check that everything got resolved */
1487 while (atp != NULL)
1488 {
1489 if (atp->resolved != TRUE)
1490 {
1491 if (atp->imported != TRUE) /* only imported not resolved */
1492 {
1493 AsnIoErrorMsg(aip, 100, AsnErrGetTypeName(atp->name), amp->modulename);
1494 ok = FALSE;
1495 }
1496 else
1497 AsnIoErrorMsg(aip, 101, AsnErrGetTypeName(atp->name), amp->modulename);
1498 }
1499
1500 if (atp->imported == TRUE)
1501 {
1502 if (atp->branch == NULL)
1503 {
1504 AsnIoErrorMsg(aip, 102, AsnErrGetTypeName(atp->name), amp->modulename);
1505 ok = FALSE;
1506 }
1507 }
1508
1509 atp = atp->next;
1510 }
1511
1512 AsnSetTags(amp->types); /* assign tags */
1513
1514 if (ok)
1515 return amp;
1516 else
1517 return NULL;
1518 }
1519
1520 /*****************************************************************************
1521 *
1522 * void AsnSetTags(atp)
1523 * automatically assign CONTEXT tags to named elements
1524 * if (tagnumer == -1) then not explicitly assigned in spec
1525 * if (>= 0) then tag is assumed already assigned and not reassigned
1526 *
1527 *****************************************************************************/
AsnSetTags(AsnTypePtr atp)1528 NLM_EXTERN void AsnSetTags (AsnTypePtr atp)
1529 {
1530 int ctr = 0;
1531 Int2 isa;
1532 AsnTypePtr orig;
1533
1534 if (atp == NULL) return;
1535 /* find highest set tag */
1536
1537 for (orig = atp; atp != NULL; atp = atp->next)
1538 {
1539 if (atp->name != NULL)
1540 {
1541 if (IS_LOWER(*atp->name)) /* identifier, not Type */
1542 {
1543 if ((atp->tagclass == TAG_NONE) || /* context tag set? */
1544 (atp->tagclass == TAG_CONTEXT))
1545 {
1546 atp->tagclass = TAG_CONTEXT;
1547 if (atp->tagnumber > ctr) /* set default higher */
1548 ctr = (int)(atp->tagnumber + 1);
1549 }
1550 }
1551 }
1552
1553 }
1554
1555 atp = orig;
1556
1557 while (atp != NULL)
1558 {
1559 if (atp->type != NULL)
1560 {
1561 isa = atp->type->isa;
1562 switch (isa)
1563 {
1564 case SEQOF_TYPE:
1565 case SETOF_TYPE: /* check subtypes */
1566 case SEQ_TYPE:
1567 case SET_TYPE:
1568 case CHOICE_TYPE:
1569 AsnSetTags((AsnTypePtr) atp->branch);
1570 break;
1571 default:
1572 break;
1573 }
1574 }
1575 if (atp->name != NULL)
1576 {
1577 if (IS_LOWER(*atp->name)) /* identifier, not Type */
1578 {
1579 if (atp->tagclass == TAG_CONTEXT) /* assign it */
1580 {
1581 if (atp->tagnumber < 0) /* not assigned */
1582 {
1583 atp->tagnumber = ctr;
1584 ctr++;
1585 }
1586 }
1587 }
1588 }
1589 atp = atp->next;
1590 }
1591 return;
1592 }
1593
1594 /*****************************************************************************
1595 *
1596 * AsnValxNodePtr AsnValxNodeNew(anvp, type)
1597 *
1598 *****************************************************************************/
AsnValxNodeNew(AsnValxNodePtr avnp,Int2 type)1599 NLM_EXTERN AsnValxNodePtr AsnValxNodeNew (AsnValxNodePtr avnp, Int2 type)
1600 {
1601 AsnValxNodePtr newnode;
1602
1603 newnode = (AsnValxNodePtr) MemNew((sizeof(AsnValxNode)));
1604 newnode->valueisa = type;
1605 if (avnp != NULL) /* add to chain */
1606 {
1607 while (avnp->next != NULL)
1608 avnp = avnp->next;
1609 avnp->next = newnode;
1610 }
1611 return newnode;
1612 }
1613
1614
1615
1616
1617