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