NCBI C Toolkit Cross Reference

C/asnlib/asnlext.c


  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 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.