NCBI C Toolkit Cross Reference

C/asnlib/asnprint.c


  1 /*  asnprint.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:  asnprint.c
 27 *
 28 * Author:  James Ostell
 29 *
 30 * Version Creation Date: 3/4/91
 31 *
 32 * $Revision: 6.27 $
 33 *
 34 * File Description:
 35 *   Routines for printing ASN.1 value notation (text) messages and
 36 *     ASN.1 module specifications
 37 *
 38 * Modifications:  
 39 * --------------------------------------------------------------------------
 40 * Date     Name        Description of modification
 41 * -------  ----------  -----------------------------------------------------
 42 *
 43 * ==========================================================================
 44 */
 45 
 46 /*****************************************************************************
 47 *
 48 *   asnprint.c
 49 *       print routines for asn1 objects
 50 *
 51 *****************************************************************************/
 52 
 53 #include "asnbuild.h"
 54 
 55 
 56 /********
 57      MakeXMLModuleName()
 58         makes module name into file name
 59         returns pointer to \0 at end of string
 60 ********/
 61 static CharPtr MakeXMLModuleName(AsnModulePtr amp, CharPtr buf)
 62 {
 63         CharPtr ptr;
 64         StringMove(buf, amp->modulename);
 65         for (ptr = buf; *ptr != '\0'; ptr++)
 66         {
 67                 if (*ptr == '-')
 68                         *ptr = '_';
 69         }
 70         return ptr;
 71 }
 72 
 73 
 74 /********
 75      MakeXMLPublicName()
 76         makes module name into name for PUBLIC declaration
 77         returns pointer to \0 at end of string
 78 ********/
 79 static CharPtr MakeXMLPublicName(CharPtr tobuf, CharPtr frombuf)
 80 {
 81         CharPtr ptr;
 82         StringMove(tobuf, frombuf);
 83         for (ptr = tobuf; *ptr != '\0'; ptr++)
 84         {
 85                 if (! IS_ALPHANUM(*ptr))
 86                         *ptr = ' ';
 87         }
 88         return ptr;
 89 }
 90 
 91         
 92 static CharPtr GetXMLModuleName(AsnTypePtr atp, CharPtr buf)
 93 {
 94         AsnModulePtr currmod;
 95         AsnTypePtr curratp, baseatp;
 96 
 97         currmod = AsnAllModPtr();  /* get loaded modules */
 98         baseatp = AsnFindBaseType(atp);
 99         if ((currmod == NULL) || (baseatp == NULL))
100                 return NULL;
101 
102         for (currmod; currmod != NULL; currmod = currmod->next)
103         {
104                 for (curratp = currmod->types; curratp != NULL; curratp = curratp->next)
105                 {
106                         if (curratp == baseatp)
107                         {
108                                 MakeXMLModuleName(currmod, buf);
109                                 return buf;
110                         }
111                 }
112         }
113         return NULL; /* didn't find it */
114 }
115 
116 static CharPtr GetXMLname(AsnTypePtr atp)
117 {
118         if (atp == NULL)
119                 return "NULL_PTR";
120         if (atp->XMLname != NULL)
121                 return atp->XMLname;
122         if (atp->name != NULL)
123                 return atp->name;
124         return "NO_NAME";
125 }
126 
127 static Boolean AsnXMLTag(AsnIoPtr aip, AsnTypePtr atp, Boolean term)
128 {
129         Char buf [100];
130         CharPtr tmp;
131         AsnTypePtr atp2;
132         Int2 isa;
133         Boolean noend = FALSE;
134 
135         tmp = StringMove(buf, "<");
136         if (term)
137                 tmp = StringMove(tmp, "/");
138         if (atp->XMLname != NULL)
139                 tmp = StringMove(tmp, atp->XMLname);
140         else
141                 tmp = StringMove(tmp, "NONAME_FOUND");
142 
143         if (! term) 
144     {
145         atp2 = AsnFindBaseType(atp);
146         
147         if ((atp == atp2) || (atp->name == NULL))
148         {
149             isa = AsnFindBaseIsa(atp);
150             switch (isa)
151             {
152                 case NULL_TYPE:
153                     tmp = StringMove(tmp, "/");
154                     break; /* done */
155                 case BOOLEAN_TYPE:
156                 case ENUM_TYPE:
157                 case INTEGER_TYPE:
158                 case BIGINT_TYPE:
159                     noend = TRUE;
160                     break;
161                 default:
162                     break;
163             }
164         }
165     }
166         if (! noend)
167                 tmp = StringMove(tmp, ">");
168 
169         AsnPrintCharBlock(buf, aip);
170         return noend;
171 }
172 
173 static Boolean AsnXMLBegin(AsnIoPtr aip, AsnTypePtr atp)
174 {
175         AsnTypePtr atp2;
176         Boolean noend;
177 
178         noend = AsnXMLTag(aip, atp, FALSE);
179 
180         atp2 = AsnFindBaseType(atp);
181         if ((atp2 != NULL) && (atp != atp2))
182         {
183                 if ((atp2->name != NULL) && (atp->name != NULL))
184                 {
185                         if (StringCmp(atp->name, atp2->name))
186                         {
187                                 AsnPrintIndent(TRUE, aip);
188                                 AsnPrintNewLine(aip);
189                                 noend = AsnXMLTag(aip, atp2, FALSE);
190                         }
191                 }
192         }
193         return noend;
194 }
195 
196 static void AsnXMLTerm(AsnIoPtr aip, AsnTypePtr atp)
197 {
198         AsnTypePtr atp2;
199 
200         atp2 = AsnFindBaseType(atp);
201         if ((atp2 != NULL) && (atp != atp2))
202         {
203                 if ((atp2->name != NULL) && (atp->name != NULL))
204                 {
205                         if (StringCmp(atp->name, atp2->name))
206                         {
207                                 AsnXMLTag(aip, atp2, TRUE);
208                                 AsnPrintIndent(FALSE, aip);
209                                 AsnPrintNewLine(aip);
210                         }
211                 }
212         }
213         AsnXMLTag(aip, atp, TRUE);
214 }
215 
216 static void AsnXMLTermEmpty(AsnIoPtr aip, AsnTypePtr atp)
217 {
218         AsnTypePtr atp2;
219         Boolean do_empty = TRUE;
220 
221         atp2 = AsnFindBaseType(atp);
222         if ((atp2 != NULL) && (atp != atp2))
223         {
224                 if ((atp2->name != NULL) && (atp->name != NULL))
225                 {
226                         if (StringCmp(atp->name, atp2->name))
227                         {
228                                 AsnPrintCharBlock("/>", aip);
229                                 AsnPrintIndent(FALSE, aip);
230                                 AsnPrintNewLine(aip);
231                                 do_empty = FALSE;
232                         }
233                 }
234         }
235         if (do_empty)
236         {
237                 AsnPrintCharBlock("/>", aip);
238                 AsnPrintNewLine(aip);
239         }
240         else
241                 AsnXMLTag(aip, atp, TRUE);
242 }
243 
244 static Boolean AsnPrintTypeXML (AsnTypePtr atp, AsnIoPtr aip);
245 
246 /*****************************************************************************
247 *
248 *   void AsnTxtWrite(aip, atp, valueptr)
249 *
250 *****************************************************************************/
251 NLM_EXTERN Boolean LIBCALL  AsnTxtWriteEx (AsnIoPtr aip, AsnTypePtr atp, DataValPtr dvp, AsnStreamStringFunc stream)
252 {
253         Int2 isa;
254         AsnTypePtr atp2;
255         AsnValxNodePtr avnp;
256         Boolean done, terminalvalue, firstvalue, isXML = FALSE;
257 
258         terminalvalue = TRUE;   /* most are terminal values */
259         if ((! aip->indent_level) && (aip->typestack[0].type == NULL))
260                 firstvalue = TRUE;    /* first call to this routine */
261         else
262                 firstvalue = FALSE;
263 
264         if (! AsnTypeValidateOut(aip, atp, dvp))
265                 return FALSE;
266 
267         if (aip->type & ASNIO_XML)
268                 isXML = TRUE;
269 
270         atp2 = AsnFindBaseType(atp);
271         isa = atp2->type->isa;
272         if (ISA_STRINGTYPE(isa))
273                 isa = GENERALSTRING_TYPE;
274         
275         if (((isa == SEQ_TYPE) || (isa == SET_TYPE) ||
276                  (isa == SEQOF_TYPE) || (isa == SETOF_TYPE))
277                  && (dvp->intvalue == END_STRUCT))
278         {
279                 AsnPrintCloseStruct(aip, atp);
280                 return TRUE;
281         }
282 
283         if (! aip->first[aip->indent_level]) {
284             AsnPrintNewLine(aip);
285         } else
286                 aip->first[aip->indent_level] = FALSE;
287 
288         atp2 = atp;
289         if (firstvalue)       /* first item, need ::= */
290         {
291                 if(isXML) {
292                         AsnPrintCharBlock("<?xml version=\"1.0\"?>", aip);
293                         AsnPrintNewLine(aip);
294                 }
295 
296                 while ((atp2->name == NULL) || (IS_LOWER(*atp2->name)))
297                         atp2 = atp2->type;    /* find a Type Reference */
298 
299                 if (isXML)
300                 {
301                         Char tbuf[250];
302                         Char tname[100], pname[100];
303                         CharPtr xmlname;
304 
305                         if (GetXMLModuleName(atp2, tname) == NULL)
306                         {
307                                 StringMove(tname, "Not_Found");
308                         }
309                         MakeXMLPublicName(pname, tname);
310                         xmlname = GetXMLname(atp2);
311                         sprintf(tbuf, "<!DOCTYPE %s PUBLIC \"-//NCBI//%s/EN\" \"%s%s.dtd\">",
312                                 xmlname, pname, AsnGetXMLmodulePrefix(), tname);
313                         AsnPrintCharBlock(tbuf, aip);
314                         AsnPrintNewLine(aip);
315                 }
316         }
317 
318         if(isXML)
319         {
320                 AsnXMLBegin(aip, atp2);
321     }
322         else if (atp2->name != NULL)
323         {
324                 AsnPrintString(atp2->name, aip);   /* put the element name */
325                 if (IS_LOWER(*atp2->name))
326                         AsnPrintChar(' ', aip);
327                 else
328                         AsnPrintString(" ::= ", aip);
329         }
330 
331         if (isa == CHOICE_TYPE)     /* show nothing but name on same line */
332         {
333                 if ((aip->type_indent))
334                 {
335                         isa = AsnFindBaseIsa(aip->typestack[aip->type_indent - 1].type);
336                         if ((isa != SEQOF_TYPE) && (isa != SETOF_TYPE))
337                         {
338                                 AsnPrintIndent(TRUE, aip);
339                                 AsnTypeSetIndent(TRUE, aip, atp);
340                                 AsnPrintNewLine(aip);
341                         }
342                         else
343                         {
344                         
345                                 if(isXML)
346                                         AsnPrintIndent(TRUE, aip);
347                         
348 
349                                 AsnTypeSetIndent(TRUE, aip, atp);
350 
351                                 if(isXML)
352                                         AsnPrintNewLine(aip);
353                         }
354                 }
355                 else
356                 {
357                         
358                         if(isXML)
359                                 AsnPrintIndent(TRUE, aip);
360                         
361 
362                         AsnTypeSetIndent(TRUE, aip, atp);
363 
364                         if(isXML)
365                                 AsnPrintNewLine(aip);
366                 }
367                 aip->first[aip->indent_level] = TRUE;
368                 return TRUE;
369         }
370 
371         switch (isa)
372         {
373                 case SEQ_TYPE:
374                 case SET_TYPE:
375                 case SEQOF_TYPE:
376                 case SETOF_TYPE:
377                         if (dvp->intvalue == START_STRUCT)   /* open brace */
378                                 AsnPrintOpenStruct(aip, atp);
379                         else
380                         {
381                                 AsnIoErrorMsg(aip, 18 );
382                                 return FALSE;
383                         }
384                         terminalvalue = FALSE;
385                         break;
386                 case BOOLEAN_TYPE:
387                         AsnPrintBoolean(dvp->boolvalue, aip);
388                         if (isXML)
389                                 AsnXMLTermEmpty(aip, atp);
390                         break;
391                 case INTEGER_TYPE:
392                 case ENUM_TYPE:
393                 case BIGINT_TYPE:
394                         atp2 = AsnFindBaseType(atp);  /* check for names */
395                         avnp = (AsnValxNodePtr) atp2->branch;
396                         done = FALSE;
397                         while (avnp != NULL)
398                         {
399                                 if (dvp->intvalue == avnp->intvalue)
400                                 {
401                                         if (isXML)
402                                         {
403                                                 AsnPrintString(" value=", aip);
404                                                 AsnPrintChar('\"', aip);
405                                         }
406                                         AsnPrintString(avnp->name, aip);
407                                         if (isXML)
408                                         {
409                                                 AsnPrintChar('\"', aip);
410                                                 if (isa == ENUM_TYPE)
411                                                 {
412                                                         AsnXMLTermEmpty(aip, atp);
413                                                         done = TRUE;
414                                                 }
415                                         }
416                                         else
417                                                 done = TRUE;
418                                         avnp = NULL;
419                                 }
420                                 else
421                                         avnp = avnp->next;
422                         }
423                         if (! done)    /* no name */
424                         {
425                                 if (isXML)
426                                         AsnPrintCharBlock(">", aip);
427                                 if (isa == BIGINT_TYPE)
428                                         AsnPrintBigInt(dvp->bigintvalue, aip);
429                                 else
430                                         AsnPrintInteger(dvp->intvalue, aip);
431                                 if(isXML) AsnXMLTerm(aip, atp);
432                         }
433                         break;
434                case REAL_TYPE:
435                         AsnPrintReal(dvp->realvalue, aip);
436                         if(isXML) AsnXMLTerm(aip, atp);
437                         break;
438                 case GENERALSTRING_TYPE:
439                         if(!(isXML)) AsnPrintChar('\"', aip);
440                         if (stream != NULL) {
441                                 if (! AsnPrintStream (dvp->ptrvalue, aip, stream))
442                                         return FALSE;
443                         } else {
444                                 if (! AsnPrintString((CharPtr) dvp->ptrvalue, aip))
445                                         return FALSE;
446                         }
447                         if(isXML) AsnXMLTerm(aip, atp);
448                         else AsnPrintChar('\"', aip);
449                         break;
450                 case NULL_TYPE:
451                         if (! (isXML))
452                                 AsnPrintString("NULL", aip);
453                         break;
454                 case OCTETS_TYPE:
455                         AsnPrintOctets((ByteStorePtr) dvp->ptrvalue, aip);
456                         if(isXML) AsnXMLTerm(aip, atp);
457                         break;
458                 case STRSTORE_TYPE:
459                         if (! AsnPrintStrStore((ByteStorePtr) dvp->ptrvalue, aip))
460                                 return FALSE;
461                         if(isXML) AsnXMLTerm(aip, atp);
462                         break;
463                 default:
464                         AsnIoErrorMsg(aip, 19, AsnErrGetTypeName(atp->name));
465                         return FALSE;
466         }
467 
468         if ((terminalvalue) && (aip->type_indent))   /* pop out of choice nests */
469         {
470                 done = FALSE;  /* added outer loop for XML pop not in */
471                                 /* AsnTypeSetIndent */
472                 while (! done)
473                 {
474                 if (AsnFindBaseIsa(aip->typestack[aip->type_indent - 1].type) 
475             == CHOICE_TYPE)
476                 {
477                         atp2 = aip->typestack[aip->type_indent - 1].type;
478                         if (aip->type_indent >= 2)
479                                 isa = AsnFindBaseIsa(aip->typestack[aip->type_indent-2].type);
480                         else
481                                 isa = NULL_TYPE;    /* just fake it */
482                         if (((isa != SETOF_TYPE) && (isa != SEQOF_TYPE)) ||
483                                 (isXML))
484                                 AsnPrintIndent(FALSE, aip);
485                         AsnTypeSetIndent(FALSE, aip, atp);
486                         if(isXML)
487                         {
488                                 AsnPrintNewLine(aip);
489                                 AsnXMLTerm(aip, atp2);
490                         }
491                         else
492                                 done = TRUE;
493                 }
494                 else
495                         done = TRUE;
496                 }
497         }
498         return TRUE;                                                                                                               
499 }
500 
501 NLM_EXTERN Boolean LIBCALL  AsnTxtWrite (AsnIoPtr aip, AsnTypePtr atp, DataValPtr dvp)
502 {
503         return AsnTxtWriteEx (aip, atp, dvp, NULL);
504 }
505 
506 /*****************************************************************************
507 *
508 *   void AsnPrintModule(amp, aip)
509 *
510 *****************************************************************************/
511 NLM_EXTERN void AsnPrintModule (AsnModulePtr amp, AsnIoPtr aip)
512 
513 {
514         AsnTypePtr atp;
515         Boolean firstone;
516         CharPtr from;
517 
518         aip->token = ISMODULE_TOKEN;   /* signal to AsnPrintIndent */
519         AsnPrintString(amp->modulename, aip);
520         AsnPrintString(" DEFINITIONS ::=", aip);
521         AsnPrintNewLine(aip);
522         AsnPrintString("BEGIN", aip);
523         AsnPrintNewLine(aip);
524         AsnPrintNewLine(aip);
525 
526         atp = amp->types;                   /* check for EXPORTS */
527         firstone = TRUE;
528         while (atp != NULL)
529         {
530                 if (atp->exported == TRUE)
531                 {
532                         if (firstone)
533                                 AsnPrintString("EXPORTS ", aip);
534                         else
535                         {
536                                 AsnPrintString(" ,", aip);
537                                 AsnPrintNewLine(aip);
538                                 AsnPrintString("        ", aip);
539                         }
540                         AsnPrintString(atp->name, aip);
541                         firstone = FALSE;
542                 }
543                 atp = atp->next;
544         }
545         if (! firstone)            /* got at least one */
546         {
547                 AsnPrintString(" ;", aip);
548                 AsnPrintNewLine(aip);
549                 AsnPrintNewLine(aip);
550         }
551 
552         atp = amp->types;                   /* check for IMPORTS */
553         firstone = TRUE;
554         from = NULL;
555         while (atp != NULL)
556         {
557                 if (atp->imported == TRUE)
558                 {
559                         if (firstone)
560                                 AsnPrintString("IMPORTS ", aip);
561                         else
562                         {
563                                 if (StringCmp((CharPtr) atp->branch, from))    /* new FROM */
564                                 {
565                                         AsnPrintString(" FROM ", aip);
566                                         AsnPrintString(from, aip);
567                                 }
568                                 else
569                                         AsnPrintString(" ,", aip);
570                                 AsnPrintNewLine(aip);
571                                 AsnPrintString("        ", aip);
572                         }
573                         AsnPrintString(atp->name, aip);
574                         firstone = FALSE;
575                         from = (CharPtr) atp->branch;
576                 }
577                 atp = atp->next;
578         }
579         if (! firstone)            /* got at least one */
580         {
581                 AsnPrintString(" FROM ", aip);
582                 AsnPrintString(from, aip);
583                 AsnPrintString(" ;", aip);
584                 AsnPrintNewLine(aip);
585                 AsnPrintNewLine(aip);
586         }
587 
588         atp = amp->types;
589         while (atp != NULL)
590         {
591                 if (! atp->imported)
592                 {
593                         AsnPrintString(atp->name, aip);
594                         AsnPrintString(" ::= ", aip);
595                         AsnPrintType(atp, aip);
596                         AsnPrintNewLine(aip);
597                         AsnPrintNewLine(aip);
598                 }
599                 atp = atp->next;
600         }
601         AsnPrintString("END", aip);
602         AsnPrintNewLine(aip);
603         return;
604 }
605 
606 /*****************************************************************************
607 *
608 *   void AsnPrintType(atp, aip)
609 *       prints a type starting at current line position
610 *       (assumes name already printed)
611 *
612 *****************************************************************************/
613 NLM_EXTERN void AsnPrintType (AsnTypePtr atp, AsnIoPtr aip)
614 
615 {
616         AsnValxNodePtr avnp;
617         AsnTypePtr atp2;
618         Boolean first;
619 
620         if (atp->tagclass != TAG_NONE)     /* print tag, if any */
621         {
622                 AsnPrintChar('[', aip);
623                 AsnPrintChar(' ', aip);
624                 switch (atp->tagclass)
625                 {
626                         case TAG_UNIVERSAL:
627                                 AsnPrintString("UNIVERSAL ", aip);
628                                 break;
629                         case TAG_APPLICATION:
630                                 AsnPrintString("APPLICATION ", aip);
631                                 break;
632                         case TAG_PRIVATE:
633                                 AsnPrintString("PRIVATE ", aip);
634                                 break;
635                         default:      /* context dependent, do nothing */
636                                 break;
637                 }
638                 AsnPrintInteger((Int4)atp->tagnumber, aip);
639                 AsnPrintChar(' ', aip);
640                 AsnPrintChar(']', aip);
641                 AsnPrintChar(' ', aip);
642 
643                 if (atp->implicit)
644                         AsnPrintString("IMPLICIT ", aip);
645         }
646 
647         AsnPrintString(atp->type->name, aip);   /* print the type name */
648 
649         if (atp->branch != NULL)       /* sub types ? */
650         {
651                 switch (atp->type->isa)
652                 {
653                         case SETOF_TYPE:
654                         case SEQOF_TYPE:
655                                 AsnPrintChar(' ', aip);
656                                 AsnPrintType((AsnTypePtr) atp->branch, aip);
657                                 break;
658                         case INTEGER_TYPE:
659                         case ENUM_TYPE:
660                                 AsnPrintChar(' ', aip);
661                                 AsnPrintOpenStruct(aip, atp);
662                                 avnp = (AsnValxNodePtr)atp->branch;
663                                 first = TRUE;
664                                 aip->first[aip->indent_level] = FALSE;
665                                 while (avnp != NULL)
666                                 {
667                                         if (! first)
668                                                 AsnPrintNewLine(aip);
669                                         else
670                                                 first = FALSE;
671                                         AsnPrintString(avnp->name, aip);
672                                         AsnPrintChar(' ', aip);
673                                         AsnPrintChar('(', aip);
674                                         AsnPrintInteger(avnp->intvalue, aip);
675                                         AsnPrintChar(')', aip);
676                                         avnp = avnp->next;
677                                 }
678                                 AsnPrintCloseStruct(aip, atp);
679                                 break;
680                         case SEQ_TYPE:
681                         case SET_TYPE:
682                         case CHOICE_TYPE:
683                                 AsnPrintChar(' ', aip);
684                                 AsnPrintOpenStruct(aip, atp);
685                                 atp2 = (AsnTypePtr) atp->branch;
686                                 first = TRUE;
687                                 aip->first[aip->indent_level] = FALSE;
688                                 while (atp2 != NULL)
689                                 {
690                                         if (! first)
691                                                 AsnPrintNewLine(aip);
692                                         else
693                                                 first = FALSE;
694 
695                                         if (atp2->name != NULL)
696                                         {
697                                                 AsnPrintString(atp2->name, aip);
698                                                 AsnPrintChar(' ', aip);
699                                         }
700                                         AsnPrintType(atp2, aip);
701                                         atp2 = atp2->next;
702                                 }
703                                 AsnPrintCloseStruct(aip, atp);
704                                 break;
705                         default:                        /* everything else */
706                                 break;          /* do nothing */
707                 }
708         }
709         
710         if (atp->optional)
711                 AsnPrintString(" OPTIONAL", aip);
712 
713         if (atp->hasdefault)
714         {
715                 AsnPrintString(" DEFAULT ", aip);
716                 avnp = atp->defaultvalue;
717                 while (! (VALUE_ISA_DEFAULT(avnp->valueisa)))
718                         avnp = avnp->next;
719                 switch (avnp->valueisa)
720                 {
721                         case VALUE_ISA_PTR:
722                                 AsnPrintChar('\"', aip);
723                                 AsnPrintString(avnp->name, aip);
724                                 AsnPrintChar('\"', aip);
725                                 break;
726                         case VALUE_ISA_BOOL:
727                                 AsnPrintBoolean((Boolean)avnp->intvalue, aip);
728                                 break;
729                         case VALUE_ISA_INT:
730                                 AsnPrintInteger(avnp->intvalue, aip);
731                                 break;
732                         case VALUE_ISA_REAL:
733                                 AsnPrintReal(avnp->realvalue, aip);
734                                 break;
735                         default:
736                                 AsnPrintString("Error", aip);
737                                 break;
738                 }
739         }
740 }
741 
742 /*****************************************************************************
743 *
744 *   Boolean AsnPrintStrStore(bsp, aip)
745 *
746 *****************************************************************************/
747 NLM_EXTERN Boolean AsnPrintStrStore (ByteStorePtr bsp, AsnIoPtr aip)
748 
749 {
750         Char buf[101];
751         Uint4 len, tlen;
752 
753         if (aip->type & ASNIO_CARRIER)           /* pure iterator */
754                 return TRUE;
755 
756         BSSeek(bsp, 0, SEEK_SET);      /* seek to start */
757         len = BSLen(bsp);
758         if(!(aip->type & ASNIO_XML))
759             AsnPrintChar('\"', aip);
760         while (len)
761         {
762                 if (len < 100)
763                         tlen = len;
764                 else
765                         tlen = 100;
766                 BSRead(bsp, buf, tlen);
767                 buf[tlen] = '\0';
768                 if (! AsnPrintString(buf, aip))
769                         return FALSE;
770                 len -= tlen;
771         }
772         if(!(aip->type & ASNIO_XML))
773             AsnPrintChar('\"', aip);
774         return TRUE;
775 }
776 /*****************************************************************************
777 *
778 *   void AsnPrintReal(realvalue, aip)
779 *
780 *****************************************************************************/
781 NLM_EXTERN void AsnPrintReal (FloatHi realvalue, AsnIoPtr aip)
782 
783 {
784         FloatHi thelog, mantissa;
785         int characteristic;
786         int     ic;
787         long    im;
788         char tbuf[30];
789         Boolean minus;
790 
791         if (aip->type & ASNIO_CARRIER)           /* pure iterator */
792                 return;
793 
794         if (aip->type & ASNIO_XML)
795         {
796                 sprintf(tbuf, "%g", (double)realvalue);
797                 AsnPrintString(tbuf, aip);
798                 return;
799         }
800                 
801 
802         if (realvalue == 0.0)
803         {
804                 ic = 0;
805                 im = 0;
806         }
807         else
808         {
809                 if (realvalue < 0.0)
810                 {
811                         minus = TRUE;
812                         realvalue = -realvalue;
813                 }
814                 else
815                         minus = FALSE;
816 
817                 thelog = log10((double)realvalue);
818                 if (thelog >= 0.0)
819                         characteristic = 8 - (int)thelog;/* give it 9 significant digits */
820                 else
821                         characteristic = 8 + (int)ceil(-thelog);
822 
823                 mantissa = realvalue * Nlm_Powi((double)10., characteristic);
824                 ic = -characteristic; /* reverse direction */
825 
826                 if(mantissa >= 1.79e+308)
827                     im = INT_MAX;
828                 else
829                     im = (long) mantissa;
830                 
831 
832                 /* strip trailing 0 */
833                 while ((im % 10L) == 0L)
834                 {
835                         im /= 10L;
836                         ic++;
837                 }
838 
839                 if (minus)
840                         im = -im;
841         }
842         sprintf(tbuf, "{ %ld, 10, %d }", im, ic);
843         AsnPrintString(tbuf, aip);
844         return;
845 }
846 
847 /*****************************************************************************
848 *
849 *   void AsnPrintInteger(theInt, aip)
850 *
851 *****************************************************************************/
852 NLM_EXTERN void AsnPrintInteger (Int4 theInt, AsnIoPtr aip)
853 
854 {
855         char tbuf[20];
856 
857         if (aip->type & ASNIO_CARRIER)           /* pure iterator */
858                 return;
859 
860         sprintf(tbuf, "%ld", (long)theInt);
861         AsnPrintString(tbuf, aip);
862         return;
863 }
864 
865 /*****************************************************************************
866 *
867 *   void AsnPrintBigInt(theInt, aip)
868 *
869 *****************************************************************************/
870 NLM_EXTERN void AsnPrintBigInt (Int8 theInt, AsnIoPtr aip)
871 
872 {
873         char tbuf[40];
874 
875         if (aip->type & ASNIO_CARRIER)           /* pure iterator */
876                 return;
877 
878         Int8ToString (theInt, tbuf, (size_t) 40);
879         AsnPrintString(tbuf, aip);
880         return;
881 }
882 
883 /*****************************************************************************
884 *
885 *   void AsnPrintChar(theChar, aip)
886 *       print a single character
887 *
888 *****************************************************************************/
889 NLM_EXTERN void AsnPrintChar (char theChar, AsnIoPtr aip)
890 
891 {
892         if (aip->type & ASNIO_CARRIER)           /* pure iterator */
893                 return;
894 
895         *(aip->linebuf + aip->linepos) = theChar;
896         aip->linepos++;
897         aip->offset++;
898         return;
899 }
900 
901 /*****************************************************************************
902 *
903 *   void AsnPrintBoolean(value, aip)
904 *
905 *****************************************************************************/
906 NLM_EXTERN void AsnPrintBoolean (Boolean value, AsnIoPtr aip)
907 
908 {
909         if (aip->type & ASNIO_CARRIER)           /* pure iterator */
910                 return;
911 
912         if (aip->type & ASNIO_XML)
913         {
914                 AsnPrintString(" value=", aip);
915                 AsnPrintChar('\"', aip);
916                 if (value)
917                         AsnPrintString("true", aip);
918                 else
919                         AsnPrintString("false", aip);
920                 AsnPrintChar('\"', aip);
921         }
922         else
923         {
924                 if (value)
925                         AsnPrintString("TRUE", aip);
926                 else
927                         AsnPrintString("FALSE", aip);
928         }
929         return;
930 }
931 
932 /*****************************************************************************
933 *
934 *   void AsnPrintOctets(ssp, aip)
935 *
936 *****************************************************************************/
937 NLM_EXTERN void AsnPrintOctets (ByteStorePtr ssp, AsnIoPtr aip)
938 
939 {
940         Int2 value, tval, ctr, actual, j;
941         Char buf[101];
942         Uint1 tmp [401];
943 
944         if (aip->type & ASNIO_CARRIER)           /* pure iterator */
945                 return;
946 
947         if (! (aip->type & ASNIO_XML))
948                 AsnPrintChar('\'', aip);
949 
950         BSSeek(ssp, 0, SEEK_SET);   /* go to start of bytestore */
951         ctr = 0;
952         buf[100] = '\0';
953 
954                                         /* break it up into lines if necessary */
955 
956         MemSet ((Pointer) tmp, 0, sizeof (tmp));
957         actual = (Int2) BSRead (ssp, tmp, (Int4) sizeof (tmp) - 1);
958         while (actual > 0) {
959                 for (j = 0; j < actual; j++) {
960                         value = (Int2) (Uint1) tmp [j];
961                         tval = value / 16;
962                         if (tval < 10)
963                                 buf[ctr] = (Char)(tval + '0');
964                         else
965                                 buf[ctr] = (Char)(tval - 10 + 'A');
966                         ctr++;
967                         tval = value - (tval * 16);
968                         if (tval < 10)
969                                 buf[ctr] = (Char)(tval + '0');
970                         else
971                                 buf[ctr] = (Char)(tval - 10 + 'A');
972                         ctr++;
973                         if (ctr == 100)
974                         {
975                             AsnPrintString(buf, aip);
976                                 ctr = 0;
977                         }
978                 }
979                 actual = (Int2) BSRead (ssp, tmp, (Int4) sizeof (tmp) - 1);
980     }
981 
982         /*
983         while ((value = BSGetByte(ssp)) != -1)
984         {
985                 tval = value / 16;
986                 if (tval < 10)
987                         buf[ctr] = (Char)(tval + '0');
988                 else
989                         buf[ctr] = (Char)(tval - 10 + 'A');
990                 ctr++;
991                 tval = value - (tval * 16);
992                 if (tval < 10)
993                         buf[ctr] = (Char)(tval + '0');
994                 else
995                         buf[ctr] = (Char)(tval - 10 + 'A');
996                 ctr++;
997                 if (ctr == 100)
998                 {
999                     AsnPrintString(buf, aip);
1000                         ctr = 0;
1001                 }
1002         }
1003         */
1004 
1005         if (ctr)
1006         {
1007                 buf[ctr] = '\0';
1008                 AsnPrintString(buf, aip);
1009         }
1010 
1011         if (! (aip->type & ASNIO_XML))
1012         {
1013                 AsnPrintChar('\'', aip);
1014                 AsnPrintChar('H', aip);
1015         }
1016         return;
1017 }
1018 
1019 /*****************************************************************************
1020 *
1021 *   void AsnPrintIndent(increase, aip)
1022 *      increase or decrease indent level
1023 *
1024 *****************************************************************************/
1025 NLM_EXTERN void AsnPrintIndent (Boolean increase, AsnIoPtr aip)
1026 
1027 {
1028         Int1    offset, curr_indent;
1029         BoolPtr tmp;
1030         int     decr, isa;
1031         
1032         if (increase)
1033     {
1034         aip->indent_level++;
1035         curr_indent = aip->indent_level;
1036         if (curr_indent == aip->max_indent)   /* expand indent levels */
1037         {
1038             tmp = aip->first;
1039             aip->first = (BoolPtr) MemNew((sizeof(Boolean) *
1040                                            (aip->max_indent + 10)));
1041             MemCopy(aip->first, tmp, (size_t)(sizeof(Boolean) * 
1042                                               aip->max_indent));
1043             MemFree(tmp);
1044             aip->max_indent += 10;
1045         }
1046         aip->first[curr_indent] = TRUE;     /* set to first time */
1047         offset = curr_indent * aip->tabsize;
1048         
1049         if (! (aip->type & ASNIO_CARRIER))
1050         {
1051             while (aip->linepos < offset)
1052             {
1053                 *(aip->linebuf + aip->linepos) = ' ';
1054                 aip->linepos++;
1055             }
1056             aip->offset = aip->linepos + (aip->linebuf - (CharPtr)aip->buf);
1057         }
1058     }
1059         else
1060     {
1061         offset = aip->indent_level * aip->tabsize;
1062         curr_indent = aip->type_indent;
1063         decr = 1;   /* always backup indent for named element */
1064         do
1065         {
1066             if (aip->indent_level)
1067                 aip->indent_level -= decr;
1068             if (curr_indent)
1069                 curr_indent--;
1070             isa = NULL_TYPE;        /* fake key */
1071             if ((aip->indent_level) && (curr_indent))
1072             {
1073                 isa = AsnFindBaseIsa(aip->typestack[curr_indent - 1].type);
1074                 if (aip->typestack[curr_indent-1].type->name != NULL)
1075                     decr = 1;       /* indent for named choices as elements */
1076                 else
1077                     decr = 0;       /* not referenced choice objects */
1078             }
1079         } while ((isa == CHOICE_TYPE) && (aip->token != ISMODULE_TOKEN) &&
1080                  (! (aip->type & ASNIO_XML)));
1081         
1082         if (aip->linepos == offset)    /* nothing written yet */
1083         {
1084             curr_indent = aip->indent_level * aip->tabsize;
1085             while (offset >= curr_indent)
1086             {
1087                 offset--;
1088                 if (! (aip->type & ASNIO_CARRIER))
1089                 {
1090                     if ((offset >= 0) && (aip->linebuf[offset] != ' '))
1091                         curr_indent = 127;
1092                 }
1093             }
1094             offset++;
1095             aip->linepos = offset;
1096             aip->offset = aip->linepos + (aip->linebuf - (CharPtr)aip->buf);
1097         }
1098         if (! aip->indent_level)   /* level 0 - no commas */
1099             aip->first[0] = TRUE;
1100     }
1101         return;
1102 }
1103 
1104 /*****************************************************************************
1105 *
1106 *   void AsnPrintNewLine(aip)
1107 *       end a line in the print buffer
1108 *       indent to the proper level on the next line
1109 *
1110 *****************************************************************************/
1111 static void AsnPrintNewLineInt (AsnIoPtr aip, Boolean addAsnComma)
1112 
1113 {
1114         Int1    tpos, indent;
1115         CharPtr tmp;
1116         Boolean do_print = TRUE;
1117 
1118         if (aip->linepos == 0)     /* nothing in buffer yet */
1119     {
1120         if ((aip->type & ASNIO_XML) && (aip->token == ISMODULE_TOKEN))
1121         {            /* print blank line */
1122             tmp = aip->linebuf;
1123             *tmp = ' ';
1124             tmp++;
1125             *tmp = '\0';
1126             aip->linepos = tmp - aip->linebuf;
1127             aip->offset = tmp - (CharPtr)aip->buf;
1128         }
1129         else
1130         {
1131             aip->no_newline = FALSE;      /* reset to normal */
1132             return;
1133         }
1134     }
1135                 
1136         if (! (aip->type & ASNIO_CARRIER))    /* really printing */
1137     {
1138         tpos = aip->indent_level * aip->tabsize;
1139         if (tpos == aip->linepos)         /* just an empty indent? */
1140         {
1141             if (! ((aip->type & ASNIO_XML) && (aip->token == ISMODULE_TOKEN)))
1142                 do_print = FALSE;         /* assume that's the case */
1143             for (tmp = aip->linebuf; tpos != 0; tpos--, tmp++)
1144             {
1145                 if (*tmp != ' ')
1146                 {
1147                     do_print = TRUE;      /* set sentinel */
1148                     break;
1149                 }
1150             }
1151         }
1152 
1153         if (do_print)   /* not an empty indent */
1154         {
1155             tmp = aip->linebuf + aip->linepos;
1156             
1157             /* not first line of struct */
1158             if (aip->first[aip->indent_level] == FALSE)
1159             {
1160                 if (!(aip->type & ASNIO_XML) && addAsnComma)   /* add commas */
1161                 {
1162                     *tmp = ' '; tmp++;
1163                     *tmp = ','; tmp++;
1164                 }
1165             }
1166             else if (!aip->no_newline && aip->linepos)
1167             /* is first line, remove trailing blanks if just indented */
1168             {
1169                 tmp--;
1170                 while ((*tmp == ' ') && (tmp > aip->linebuf))
1171                     tmp--;
1172                 tmp++;
1173             }
1174             if ((aip->type & ASNIO_XML) && 
1175                 (aip->token == ISMODULE_TOKEN) && (tmp == aip->linebuf))
1176             {   /* print an empty line for formatting */
1177                 *tmp = ' ';
1178                 tmp++;
1179             }
1180             *tmp = '\0';
1181             aip->linepos = tmp - aip->linebuf;
1182             aip->offset = tmp - (CharPtr)aip->buf;
1183             
1184             AsnIoPuts(aip);
1185         }
1186     }
1187     
1188         if ((do_print) && (aip->indent_level))       /* level 0 never has commas */
1189                 aip->first[aip->indent_level] = FALSE;
1190 
1191         if (! (aip->type & ASNIO_CARRIER)) /* really printing */
1192     {
1193          tmp = aip->linebuf;
1194          indent = aip->indent_level * aip->tabsize;
1195          for (tpos = 0; tpos < indent; tpos++, tmp++)
1196              *tmp = ' ';
1197          aip->linepos = tpos;
1198          aip->offset += tpos;
1199     }
1200         aip->no_newline = FALSE;   /* reset to normal */
1201         return;
1202 }
1203 
1204 NLM_EXTERN void AsnPrintNewLine (AsnIoPtr aip)
1205 
1206 {
1207   AsnPrintNewLineInt (aip, TRUE);
1208 }
1209 
1210 
1211 /*  XML transliteration table
1212  */
1213 
1214 typedef struct {
1215     const char*  str;
1216     unsigned int len;
1217 } SXmlChar;
1218 
1219 static const SXmlChar s_XmlChar[256] =
1220 {
1221     { "&#0;",    4 },   /*   0 */
1222     { "&#1;",    4 },   /*   1 */
1223     { "&#2;",    4 },   /*   2 */
1224     { "&#3;",    4 },   /*   3 */
1225     { "&#4;",    4 },   /*   4 */
1226     { "&#5;",    4 },   /*   5 */
1227     { "&#6;",    4 },   /*   6 */
1228     { "&#7;",    4 },   /*   7 */
1229     { "&#8;",    4 },   /*   8 */
1230     { "&#9;",    4 },   /*   9 */
1231     { "&#10;",   5 },   /*  10 */
1232     { "&#11;",   5 },   /*  11 */
1233     { "&#12;",   5 },   /*  12 */
1234     { "&#13;",   5 },   /*  13 */
1235     { "&#14;",   5 },   /*  14 */
1236     { "&#15;",   5 },   /*  15 */
1237     { "&#16;",   5 },   /*  16 */
1238     { "&#17;",   5 },   /*  17 */
1239     { "&#18;",   5 },   /*  18 */
1240     { "&#19;",   5 },   /*  19 */
1241     { "&#20;",   5 },   /*  20 */
1242     { "&#21;",   5 },   /*  21 */
1243     { "&#22;",   5 },   /*  22 */
1244     { "&#23;",   5 },   /*  23 */
1245     { "&#24;",   5 },   /*  24 */
1246     { "&#25;",   5 },   /*  25 */
1247     { "&#26;",   5 },   /*  26 */
1248     { "&#27;",   5 },   /*  27 */
1249     { "&#28;",   5 },   /*  28 */
1250     { "&#29;",   5 },   /*  29 */
1251     { "&#30;",   5 },   /*  30 */
1252     { "&#31;",   5 },   /*  31 */
1253     { " ",       1 },   /*  32 */
1254     { "!",       1 },   /*  33 */
1255     { "&quot;",  6 },   /*  34 */
1256     { "#",       1 },   /*  35 */
1257     { "$",       1 },   /*  36 */
1258     { "%",       1 },   /*  37 */
1259     { "&amp;",   5 },   /*  38 */
1260     { "&apos;",  6 },   /*  39 */
1261     { "(",       1 },   /*  40 */
1262     { ")",       1 },   /*  41 */
1263     { "*",       1 },   /*  42 */
1264     { "+",       1 },   /*  43 */
1265     { ",",       1 },   /*  44 */
1266     { "-",       1 },   /*  45 */
1267     { ".",       1 },   /*  46 */
1268     { "/",       1 },   /*  47 */
1269     { "0",       1 },   /*  48 */
1270     { "1",       1 },   /*  49 */
1271     { "2",       1 },   /*  50 */
1272     { "3",       1 },   /*  51 */
1273     { "4",       1 },   /*  52 */
1274     { "5",       1 },   /*  53 */
1275     { "6",       1 },   /*  54 */
1276     { "7",       1 },   /*  55 */
1277     { "8",       1 },   /*  56 */
1278     { "9",       1 },   /*  57 */
1279     { ":",       1 },   /*  58 */
1280     { ";",       1 },   /*  59 */
1281     { "&lt;",    4 },   /*  60 */
1282     { "=",       1 },   /*  61 */
1283     { "&gt;",    4 },   /*  62 */
1284     { "?",       1 },   /*  63 */
1285     { "@",       1 },   /*  64 */
1286     { "A",       1 },   /*  65 */
1287     { "B",       1 },   /*  66 */
1288     { "C",       1 },   /*  67 */
1289     { "D",       1 },   /*  68 */
1290     { "E",       1 },   /*  69 */
1291     { "F",       1 },   /*  70 */
1292     { "G",       1 },   /*  71 */
1293     { "H",       1 },   /*  72 */
1294     { "I",       1 },   /*  73 */
1295     { "J",       1 },   /*  74 */
1296     { "K",       1 },   /*  75 */
1297     { "L",       1 },   /*  76 */
1298     { "M",       1 },   /*  77 */
1299     { "N",       1 },   /*  78 */
1300     { "O",       1 },   /*  79 */
1301     { "P",       1 },   /*  80 */
1302     { "Q",       1 },   /*  81 */
1303     { "R",       1 },   /*  82 */
1304     { "S",       1 },   /*  83 */
1305     { "T",       1 },   /*  84 */
1306     { "U",       1 },   /*  85 */
1307     { "V",       1 },   /*  86 */
1308     { "W",       1 },   /*  87 */
1309     { "X",       1 },   /*  88 */
1310     { "Y",       1 },   /*  89 */
1311     { "Z",       1 },   /*  90 */
1312     { "[",       1 },   /*  91 */
1313     { "\\",      1 },   /*  92 */
1314     { "]",       1 },   /*  93 */
1315     { "^",       1 },   /*  94 */
1316     { "_",       1 },   /*  95 */
1317     { "`",       1 },   /*  96 */
1318     { "a",       1 },   /*  97 */
1319     { "b",       1 },   /*  98 */
1320     { "c",       1 },   /*  99 */
1321     { "d",       1 },   /* 100 */
1322     { "e",       1 },   /* 101 */
1323     { "f",       1 },   /* 102 */
1324     { "g",       1 },   /* 103 */
1325     { "h",       1 },   /* 104 */
1326     { "i",       1 },   /* 105 */
1327     { "j",       1 },   /* 106 */
1328     { "k",       1 },   /* 107 */
1329     { "l",       1 },   /* 108 */
1330     { "m",       1 },   /* 109 */
1331     { "n",       1 },   /* 110 */
1332     { "o",       1 },   /* 111 */
1333     { "p",       1 },   /* 112 */
1334     { "q",       1 },   /* 113 */
1335     { "r",       1 },   /* 114 */
1336     { "s",       1 },   /* 115 */
1337     { "t",       1 },   /* 116 */
1338     { "u",       1 },   /* 117 */
1339     { "v",       1 },   /* 118 */
1340     { "w",       1 },   /* 119 */
1341     { "x",       1 },   /* 120 */
1342     { "y",       1 },   /* 121 */
1343     { "z",       1 },   /* 122 */
1344     { "{",       1 },   /* 123 */
1345     { "|",       1 },   /* 124 */
1346     { "}",       1 },   /* 125 */
1347     { "~",       1 },   /* 126 */
1348     { "&#127;",  6 },   /* 127 */
1349     { "&#128;",  6 },   /* 128 */
1350     { "&#129;",  6 },   /* 129 */
1351     { "&#130;",  6 },   /* 130 */
1352     { "&#131;",  6 },   /* 131 */
1353     { "&#132;",  6 },   /* 132 */
1354     { "&#133;",  6 },   /* 133 */
1355     { "&#134;",  6 },   /* 134 */
1356     { "&#135;",  6 },   /* 135 */
1357     { "&#136;",  6 },   /* 136 */
1358     { "&#137;",  6 },   /* 137 */
1359     { "&#138;",  6 },   /* 138 */
1360     { "&#139;",  6 },   /* 139 */
1361     { "&#140;",  6 },   /* 140 */
1362     { "&#141;",  6 },   /* 141 */
1363     { "&#142;",  6 },   /* 142 */
1364     { "&#143;",  6 },   /* 143 */
1365     { "&#144;",  6 },   /* 144 */
1366     { "&#145;",  6 },   /* 145 */
1367     { "&#146;",  6 },   /* 146 */
1368     { "&#147;",  6 },   /* 147 */
1369     { "&#148;",  6 },   /* 148 */
1370     { "&#149;",  6 },   /* 149 */
1371     { "&#150;",  6 },   /* 150 */
1372     { "&#151;",  6 },   /* 151 */
1373     { "&#152;",  6 },   /* 152 */
1374     { "&#153;",  6 },   /* 153 */
1375     { "&#154;",  6 },   /* 154 */
1376     { "&#155;",  6 },   /* 155 */
1377     { "&#156;",  6 },   /* 156 */
1378     { "&#157;",  6 },   /* 157 */
1379     { "&#158;",  6 },   /* 158 */
1380     { "&#159;",  6 },   /* 159 */
1381     { "&#160;",  6 },   /* 160 */
1382     { "&#161;",  6 },   /* 161 */
1383     { "&#162;",  6 },   /* 162 */
1384     { "&#163;",  6 },   /* 163 */
1385     { "&#164;",  6 },   /* 164 */
1386     { "&#165;",  6 },   /* 165 */
1387     { "&#166;",  6 },   /* 166 */
1388     { "&#167;",  6 },   /* 167 */
1389     { "&#168;",  6 },   /* 168 */
1390     { "&#169;",  6 },   /* 169 */
1391     { "&#170;",  6 },   /* 170 */
1392     { "&#171;",  6 },   /* 171 */
1393     { "&#172;",  6 },   /* 172 */
1394     { "&#173;",  6 },   /* 173 */
1395     { "&#174;",  6 },   /* 174 */
1396     { "&#175;",  6 },   /* 175 */
1397     { "&#176;",  6 },   /* 176 */
1398     { "&#177;",  6 },   /* 177 */
1399     { "&#178;",  6 },   /* 178 */
1400     { "&#179;",  6 },   /* 179 */
1401     { "&#180;",  6 },   /* 180 */
1402     { "&#181;",  6 },   /* 181 */
1403     { "&#182;",  6 },   /* 182 */
1404     { "&#183;",  6 },   /* 183 */
1405     { "&#184;",  6 },   /* 184 */
1406     { "&#185;",  6 },   /* 185 */
1407     { "&#186;",  6 },   /* 186 */
1408     { "&#187;",  6 },   /* 187 */
1409     { "&#188;",  6 },   /* 188 */
1410     { "&#189;",  6 },   /* 189 */
1411     { "&#190;",  6 },   /* 190 */
1412     { "&#191;",  6 },   /* 191 */
1413     { "&#192;",  6 },   /* 192 */
1414     { "&#193;",  6 },   /* 193 */
1415     { "&#194;",  6 },   /* 194 */
1416     { "&#195;",  6 },   /* 195 */
1417     { "&#196;",  6 },   /* 196 */
1418     { "&#197;",  6 },   /* 197 */
1419     { "&#198;",  6 },   /* 198 */
1420     { "&#199;",  6 },   /* 199 */
1421     { "&#200;",  6 },   /* 200 */
1422     { "&#201;",  6 },   /* 201 */
1423     { "&#202;",  6 },   /* 202 */
1424     { "&#203;",  6 },   /* 203 */
1425     { "&#204;",  6 },   /* 204 */
1426     { "&#205;",  6 },   /* 205 */
1427     { "&#206;",  6 },   /* 206 */
1428     { "&#207;",  6 },   /* 207 */
1429     { "&#208;",  6 },   /* 208 */
1430     { "&#209;",  6 },   /* 209 */
1431     { "&#210;",  6 },   /* 210 */
1432     { "&#211;",  6 },   /* 211 */
1433     { "&#212;",  6 },   /* 212 */
1434     { "&#213;",  6 },   /* 213 */
1435     { "&#214;",  6 },   /* 214 */
1436     { "&#215;",  6 },   /* 215 */
1437     { "&#216;",  6 },   /* 216 */
1438     { "&#217;",  6 },   /* 217 */
1439     { "&#218;",  6 },   /* 218 */
1440     { "&#219;",  6 },   /* 219 */
1441     { "&#220;",  6 },   /* 220 */
1442     { "&#221;",  6 },   /* 221 */
1443     { "&#222;",  6 },   /* 222 */
1444     { "&#223;",  6 },   /* 223 */
1445     { "&#224;",  6 },   /* 224 */
1446     { "&#225;",  6 },   /* 225 */
1447     { "&#226;",  6 },   /* 226 */
1448     { "&#227;",  6 },   /* 227 */
1449     { "&#228;",  6 },   /* 228 */
1450     { "&#229;",  6 },   /* 229 */
1451     { "&#230;",  6 },   /* 230 */
1452     { "&#231;",  6 },   /* 231 */
1453     { "&#232;",  6 },   /* 232 */
1454     { "&#233;",  6 },   /* 233 */
1455     { "&#234;",  6 },   /* 234 */
1456     { "&#235;",  6 },   /* 235 */
1457     { "&#236;",  6 },   /* 236 */
1458     { "&#237;",  6 },   /* 237 */
1459     { "&#238;",  6 },   /* 238 */
1460     { "&#239;",  6 },   /* 239 */
1461     { "&#240;",  6 },   /* 240 */
1462     { "&#241;",  6 },   /* 241 */
1463     { "&#242;",  6 },   /* 242 */
1464     { "&#243;",  6 },   /* 243 */
1465     { "&#244;",  6 },   /* 244 */
1466     { "&#245;",  6 },   /* 245 */
1467     { "&#246;",  6 },   /* 246 */
1468     { "&#247;",  6 },   /* 247 */
1469     { "&#248;",  6 },   /* 248 */
1470     { "&#249;",  6 },   /* 249 */
1471     { "&#250;",  6 },   /* 250 */
1472     { "&#251;",  6 },   /* 251 */
1473     { "&#252;",  6 },   /* 252 */
1474     { "&#253;",  6 },   /* 253 */
1475     { "&#254;",  6 },   /* 254 */
1476     { "&#255;",  6 }    /* 255 */
1477 };
1478 
1479 
1480 /*****************************************************************************
1481 *
1482 *   Boolean AsnPrintString(str, aip)
1483 *
1484 *****************************************************************************/
1485 NLM_EXTERN Boolean AsnPrintString (CharPtr the_string, AsnIoPtr aip)
1486 {
1487         register CharPtr current, previous, current_save = NULL, str, str_begin;
1488         Boolean          isXML = FALSE;
1489         Boolean          indent_state;
1490         int              bad_char = 0, bad_char_ctr = 0;
1491     int              linepos_start = aip->linepos;
1492 
1493         if (the_string == NULL) {
1494                 AsnIoErrorMsg(aip, 106, bad_char, "");
1495                 return FALSE;
1496         }
1497 
1498     if (aip->type & ASNIO_XML)
1499                 isXML = TRUE;
1500 
1501         if (aip->type & ASNIO_CARRIER) {
1502         /* Post error if non-printing chars */
1503         if ((aip->fix_non_print == 0) || (aip->fix_non_print == 3)) {
1504             for (str = the_string; *str != '\0'; str++) {
1505                 if ((*str < ' ') || (*str > '~')) {
1506                     bad_char_ctr++;
1507                     bad_char = (int)(*str);
1508                 }
1509             }
1510         }
1511         goto ret;
1512     }
1513 
1514         str = the_string;
1515         indent_state = aip->first[aip->indent_level];
1516     
1517     /* Get current ptr to output */
1518     current = aip->linebuf + aip->linepos;
1519     str_begin = current;
1520 
1521     /* Break it up into lines and convert chars if necessary */
1522         while (*str)  {
1523         char ch = *str;
1524         previous = current;
1525 
1526         /* Fix non print char if necessary */
1527         if (aip->fix_non_print != 2  &&  (ch < ' '  ||  ch > '~')) {
1528             if ( !bad_char_ctr ) {
1529                 bad_char = (int) ch;
1530             }
1531             bad_char_ctr++;
1532             ch = '#';   /* replace with # */
1533         }
1534         
1535         /*  XML and double quotes fixes */
1536         if ( isXML ) {
1537             const SXmlChar* xml_char = &s_XmlChar[(unsigned int) ch];
1538             if (xml_char->len == 1) {
1539                 *current++ = ch;
1540             } else {
1541                 current = StringMove(current, xml_char->str);
1542             }
1543         } else {
1544             *current++ = ch;
1545             if (ch == '\"') {   /* must double quotes */
1546                 *current++ = ch;
1547             }
1548         }
1549 
1550         /* Correct position in the buffer */
1551         aip->linepos += (current - previous);
1552         aip->offset  += (current - previous);
1553 
1554         /* Check to necessety a new line */
1555 
1556         if ( (current >= aip->linebuf + aip->linelength) )  {
1557 
1558             /* Get word break */
1559 
1560             size_t pos;
1561             int cnt_save;
1562             
1563             *current = *(str+1) ? *(str+1) : *str;
1564             *(current+1) = 0;
1565             pos = AsnPrintGetWordBreak(str_begin, 
1566                                        aip->linepos - linepos_start);
1567 
1568             /* Save rest of string */
1569 
1570             cnt_save = current - str_begin - pos;
1571             if ( cnt_save < 0 ) 
1572                 cnt_save = 0;
1573 
1574             if ( cnt_save ) {
1575                 if ( !current_save )
1576                     current_save = MemNew(aip->linelength);
1577                 if ( !current_save ) 
1578                     return FALSE;
1579                 MemCopy(current_save, str_begin + pos, cnt_save);
1580                 aip->linepos -= cnt_save;
1581                 aip->offset  -= cnt_save;
1582             }
1583 
1584             /* Print new line */
1585 
1586             aip->first[aip->indent_level] = TRUE;   /* no commas */
1587             if ( isXML || aip->asn_no_newline )                /* don't split XML lines */
1588                 aip->no_newline = TRUE;
1589             AsnPrintNewLine(aip);       
1590             aip->offset = aip->offset - aip->linepos + cnt_save;
1591             aip->linepos = cnt_save;
1592             linepos_start = 0;
1593             
1594             /* Restore saved string and calculate current ptr to output */
1595             if ( current_save ) {
1596                 MemCopy(aip->linebuf, current_save, cnt_save);
1597             }
1598             current = aip->linebuf + aip->linepos;
1599             str_begin = aip->linebuf;
1600         }
1601 
1602         /* Move to next char */ 
1603         str++;
1604     }
1605     
1606     /* Reset indent state */
1607         aip->first[aip->indent_level] = indent_state;
1608 
1609 ret:
1610     if ( current_save )
1611         MemFree(current_save);
1612 
1613     /* Check on error */
1614         if ((bad_char_ctr) && 
1615         ((aip->fix_non_print == 0) || (aip->fix_non_print == 3))) {
1616         AsnIoErrorMsg(aip, 106, bad_char, the_string);
1617     }
1618         return TRUE;
1619 }
1620 
1621 /*****************************************************************************
1622 *
1623 *   Boolean AsnPrintStream(str, aip, stream)
1624 *
1625 *****************************************************************************/
1626 NLM_EXTERN Boolean AsnPrintStream (Pointer object, AsnIoPtr aip, AsnStreamStringFunc stream)
1627 
1628 {
1629         if (aip == NULL) return FALSE;
1630         if (object == NULL || stream == NULL) return FALSE;
1631 
1632         return stream (object, aip);
1633 }
1634 
1635 /*****************************************************************************
1636 *
1637 *   void AsnPrintCharBlock(str, aip)
1638 *      prints string on line if there is room
1639 *      if not prints on next line with no indent.
1640 *
1641 *      Now only used by XML printing
1642 *
1643 *****************************************************************************/
1644 NLM_EXTERN void AsnPrintCharBlock (CharPtr str, AsnIoPtr aip)
1645 
1646 {
1647         Uint4 stringlen;
1648         Boolean indent_state;
1649         Int1 templen;
1650         CharPtr current;
1651 
1652         if (aip->type & ASNIO_CARRIER)           /* pure iterator */
1653                 return;
1654 
1655         stringlen = StringLen(str);
1656         templen = (Int1)(aip->linelength - aip->linepos);
1657         indent_state = aip->first[aip->indent_level];
1658 
1659         if (!(aip->type & ASNIO_XML) && (stringlen > (Uint4)templen)) 
1660     {   /* won't fit on line -- don't split XML lines */
1661         aip->first[aip->indent_level] = TRUE;   /* no commas */
1662         AsnPrintNewLine(aip);       /* this call resets no_newline itself */
1663         aip->offset -= aip->linepos;
1664         aip->linepos = 0;
1665     }
1666 
1667         current = aip->linebuf + aip->linepos;
1668         MemCopy(current, str, (size_t)stringlen);
1669         aip->linepos += (Int2) stringlen;
1670         aip->offset += (Int2) stringlen;
1671         aip->first[aip->indent_level] = indent_state;   /* reset indent state */
1672         return;
1673 }
1674 
1675 /*****************************************************************************
1676 *
1677 *   int AsnPrintGetWordBreak(str, maxlen)
1678 *       return length (<= maxlen) of str to next white space
1679 *
1680 *****************************************************************************/
1681 NLM_EXTERN int AsnPrintGetWordBreak (CharPtr str, int maxlen)
1682 
1683 {
1684         CharPtr tmp;
1685         int len;
1686         Uint4 stringlen;
1687 
1688         stringlen = StringLen(str);
1689         if (stringlen <= (Uint4)maxlen)
1690                 return (int) stringlen;
1691 
1692         tmp = str + maxlen;    /* point just PAST the end of region */
1693         len = maxlen + 1;
1694         while ((len) && (! IS_WHITESP(*tmp)))
1695         {
1696             len--; tmp--;
1697         }
1698         while ((len) && (IS_WHITESP(*tmp)))
1699         {
1700             len--;             /* move past white space */
1701             tmp--;
1702         }
1703         if (len < 1)         /* never found any whitespace or only 1 space */
1704                 len = maxlen;    /* have to break a word */
1705 
1706         return len;
1707 }
1708 
1709 /*****************************************************************************
1710 *
1711 *   AsnPrintOpenStruct(aip, atp)
1712 *
1713 *****************************************************************************/
1714 NLM_EXTERN void AsnPrintOpenStruct (AsnIoPtr aip, AsnTypePtr atp)
1715 
1716 {
1717     if(aip->type & ASNIO_XML) {
1718         /* rework for indent? */
1719         AsnPrintIndent(TRUE, aip);
1720         AsnTypeSetIndent(TRUE, aip, atp);
1721         AsnPrintNewLine(aip);
1722         aip->first[aip->indent_level] = TRUE;
1723     } else {
1724         AsnPrintChar('{', aip);
1725         AsnPrintIndent(TRUE, aip);
1726         AsnTypeSetIndent(TRUE, aip, atp);
1727         AsnPrintNewLine(aip);
1728         aip->first[aip->indent_level] = TRUE;
1729     }
1730     return;
1731 }
1732 
1733 /*****************************************************************************
1734 *
1735 *   AsnPrintCloseStruct(aip, atp)
1736 *
1737 *****************************************************************************/
1738 NLM_EXTERN void AsnPrintCloseStruct (AsnIoPtr aip, AsnTypePtr atp)
1739 
1740 {
1741         AsnTypePtr atp2;
1742         Int2 isa;
1743 
1744     if(aip->type & ASNIO_XML) {
1745         AsnPrintIndent(FALSE, aip);
1746             AsnTypeSetIndent(FALSE, aip, atp);
1747                 AsnPrintNewLine(aip);
1748         AsnXMLTerm(aip, atp);
1749                 while ((aip->type_indent) && 
1750                (AsnFindBaseIsa(aip->typestack[aip->type_indent - 1].type) 
1751                 == CHOICE_TYPE))
1752                 {   /* pop out of choice nests */
1753                         atp2 = aip->typestack[aip->type_indent - 1].type;
1754             if (aip->type_indent >= 2)
1755                 isa = AsnFindBaseIsa(aip->typestack[aip->type_indent - 2].type);
1756             else
1757                 isa = NULL_TYPE;
1758             
1759             AsnPrintIndent(FALSE, aip);
1760             
1761             AsnTypeSetIndent(FALSE, aip, atp);
1762             AsnPrintNewLine(aip);
1763             AsnXMLTerm(aip, atp2);
1764             
1765                 }
1766     } else if (aip->asn_alt_struct) {
1767                 AsnPrintNewLineInt (aip, FALSE);
1768             AsnPrintIndent (FALSE, aip);
1769             AsnTypeSetIndent (FALSE, aip, atp);
1770             AsnPrintChar ('}', aip);
1771     } else {
1772             AsnPrintChar(' ', aip);
1773             AsnPrintChar('}', aip);
1774             AsnPrintIndent(FALSE, aip);
1775             AsnTypeSetIndent(FALSE, aip, atp);
1776     }
1777         return;
1778 }
1779 
1780 static void AsnXMLCommentBegin(AsnIoPtr aip)
1781 {
1782         AsnPrintCharBlock("<!-- ", aip);
1783         return;
1784 }
1785 
1786 static void AsnXMLCommentEnd(AsnIoPtr aip)
1787 {
1788         AsnPrintCharBlock(" -->", aip);
1789         AsnPrintNewLine(aip);
1790         return;
1791 }
1792 
1793 static void AsnXMLElementStart(AsnTypePtr atp, AsnIoPtr aip)
1794 {
1795         AsnTypePtr atp2;
1796         Int2 isa;
1797         AsnOptionPtr aop;
1798         Boolean didone = FALSE, doenum = FALSE, first = TRUE;
1799         AsnValxNodePtr avnp;
1800 
1801         aop = NULL;
1802         while ((aop = AsnOptionGet(atp->hints, OP_COMMENT, 0, aop)) != NULL)
1803         {
1804                 if (first)
1805                 {
1806                         first = FALSE;
1807                         AsnPrintNewLine(aip);
1808                         AsnXMLCommentBegin(aip);
1809                         AsnPrintNewLine(aip);
1810                 }
1811                 AsnPrintCharBlock((CharPtr)(aop->data.ptrvalue), aip);
1812                 AsnPrintNewLine(aip);
1813                 didone = TRUE;
1814         }
1815         
1816         isa = AsnFindBaseIsa(atp);
1817         if ((atp->branch != NULL) && (isa == INTEGER_TYPE) && (isa == ENUM_TYPE))
1818         {
1819                 for (avnp = (AsnValxNodePtr)(atp->branch); 
1820              avnp != NULL; 
1821              avnp = avnp->next)
1822                 {
1823                         if (avnp->aop != NULL)  /* comments here */
1824                         {
1825                                 doenum = TRUE;
1826                                 break;
1827                         }
1828                 }
1829                 if (doenum)
1830                 {
1831                         for (avnp = (AsnValxNodePtr)(atp->branch); 
1832                  avnp != NULL; 
1833                  avnp = avnp->next)
1834                         {
1835                                 if (avnp->name != NULL)
1836                                 {
1837                                         if (first)
1838                                         {
1839                                                 AsnXMLCommentBegin(aip);
1840                                                 AsnPrintNewLine(aip);
1841                                                 first = FALSE;
1842                                         }
1843                                         AsnPrintString(avnp->name, aip);
1844                                         if (avnp->aop != NULL)
1845                                         {
1846                                                 AsnPrintChar(' ', aip);
1847                                                 AsnPrintCharBlock((CharPtr)(avnp->aop->data.ptrvalue),
1848                                           aip);
1849                                         }
1850                                         AsnPrintNewLine(aip);
1851                                         didone = TRUE;
1852                                 }
1853                         }
1854                 }
1855         }
1856         if (didone)
1857         {
1858                 AsnXMLCommentEnd(aip);
1859         }
1860 
1861         AsnPrintCharBlock("<!ELEMENT ", aip);
1862 
1863         AsnPrintString(GetXMLname(atp), aip);
1864 
1865         atp2 = AsnFindBaseTypeDTD(atp);
1866         if (atp2 == atp)
1867         {
1868                 if ((isa == ENUM_TYPE) || (isa == BOOLEAN_TYPE) ||
1869                     (isa == NULL_TYPE))
1870                 {
1871                         AsnPrintString(" ", aip); /* EMPTY tag here */
1872                         return;
1873                 }
1874         }
1875         AsnPrintString(" ( ", aip);
1876         return;
1877 }
1878 
1879 static void AsnXMLElementAdd(CharPtr prev, AsnTypePtr atp, CharPtr repeat,
1880                              AsnIoPtr aip, Boolean do_newline)
1881 {
1882         Char buf[100];
1883         CharPtr tmp;
1884 
1885         tmp = buf;
1886         *tmp = '\0';
1887 
1888         if (prev != NULL)
1889         {
1890                 tmp = StringMove(tmp, " ");
1891                 tmp = StringMove(tmp, prev);
1892                 if (! do_newline)
1893                         tmp = StringMove(tmp, " ");
1894 
1895                 AsnPrintCharBlock(buf, aip);
1896         }
1897 
1898         if (do_newline)
1899         {
1900                 AsnPrintNewLine(aip);
1901                 tmp = StringMove(buf, "               ");
1902         }
1903         tmp = StringMove(tmp, GetXMLname(atp));
1904 
1905         if (repeat != NULL)
1906                 tmp = StringMove(tmp, repeat);
1907 
1908         AsnPrintString(buf, aip);
1909         return;
1910 }
1911 
1912 static void AsnXMLElementEnd(AsnIoPtr aip)
1913 {
1914         AsnPrintCharBlock(" )>", aip);
1915         AsnPrintNewLine(aip);
1916         return;
1917 }
1918 
1919 static void AsnPrintSubTypeXML(AsnTypePtr atp, AsnIoPtr aip)
1920 {
1921         AsnTypePtr atp2, atp3;
1922         Int2 isa;
1923         Boolean doit = FALSE;
1924 
1925         if (atp == NULL) return;
1926         if (atp->branch == NULL) return;
1927 
1928         isa = atp->type->isa;
1929         if ((isa == SEQ_TYPE) || (isa == SET_TYPE) || (isa == CHOICE_TYPE))
1930                 doit = TRUE;
1931         else if ((isa == SEQOF_TYPE) || (isa == SETOF_TYPE))
1932         {
1933                 atp2 = (AsnTypePtr)(atp->branch);
1934                 atp3 = AsnFindBaseType(atp2);
1935                 if (atp2 == atp3)
1936                         doit = TRUE;
1937         }
1938 
1939         if (doit)
1940         {
1941                 for (atp2 = (AsnTypePtr)(atp->branch); atp2 != NULL; atp2 = atp2->next)
1942                 {
1943                         AsnXMLElementStart(atp2, aip);
1944                         if (AsnPrintTypeXML(atp2, aip))
1945                                 AsnXMLElementEnd(aip);
1946                 }
1947                         /* check for nested CHOICE  */
1948                 for (atp2 = (AsnTypePtr)(atp->branch); atp2 != NULL; atp2 = atp2->next)
1949                 {
1950                         isa = AsnFindBaseIsa(atp2);
1951                         atp3 = AsnFindBaseType(atp2);
1952                         if (((isa == CHOICE_TYPE) ||
1953                              (isa == SEQOF_TYPE) || (isa == SETOF_TYPE) ||
1954                              (isa == SEQ_TYPE) || (isa == SET_TYPE)))
1955                         {
1956 /*                              atp3 = (AsnTypePtr)(atp2->branch);
1957                                 if ((atp3 != NULL) && (ISA_BASETYPE(atp3->type->isa)))
1958                                 { */
1959                                         AsnPrintNewLine(aip);
1960                                         AsnPrintSubTypeXML(atp2, aip);
1961                         /*      } */
1962                         }
1963                 }
1964 
1965         }
1966         return;
1967         
1968 }
1969 
1970 static void AsnPrintTopTypeXML (AsnIoPtr aip, AsnTypePtr atp)
1971 {
1972 
1973         AsnXMLCommentBegin(aip);
1974         AsnPrintString("Definition of ", aip);
1975         AsnPrintString(GetXMLname(atp), aip);
1976         AsnXMLCommentEnd(aip);
1977         AsnPrintNewLine(aip);
1978         AsnXMLElementStart(atp, aip);
1979         if (AsnPrintTypeXML(atp, aip))
1980                 AsnXMLElementEnd(aip);
1981         AsnPrintNewLine(aip);
1982         AsnPrintSubTypeXML(atp, aip);
1983         AsnPrintNewLine(aip);
1984         AsnPrintNewLine(aip);
1985         return;
1986 }
1987 
1988 #define AMPMAX 50
1989 
1990 typedef struct modulelist {
1991         Int2 num;    /* total number in list */
1992         AsnModulePtr amps[AMPMAX];
1993 }ModuleList, PNTR ModuleListPtr;
1994 
1995 static AsnModulePtr AsnModuleFind (CharPtr modname)
1996 {
1997         AsnModulePtr amp;
1998 
1999         for (amp = AsnAllModPtr(); amp != NULL; amp = amp->next)
2000         {
2001                 if (! StringCmp(amp->modulename, modname))
2002                         return amp;
2003         }
2004         return amp;
2005 }
2006 
2007 static void AsnModuleGetList (AsnModulePtr amp, ModuleListPtr mlp)
2008 {
2009         Int2 i;
2010         AsnTypePtr atp;
2011         CharPtr from;
2012         AsnModulePtr newmod;
2013 
2014         for (i = 0; i < mlp->num; i++)
2015         {
2016                 if (mlp->amps[i] == amp)  /* already have it */
2017                         return;
2018         }
2019 
2020         if (mlp->num == AMPMAX)
2021         {
2022                 ErrPostEx(SEV_ERROR,0,0,"Exceeded %d amps in AsnModuleGetList",
2023                           (int)(mlp->num));
2024                 return;
2025         }
2026 
2027         mlp->amps[mlp->num] = amp;
2028         mlp->num++;
2029 
2030         atp = amp->types;                   /* check for IMPORTS */
2031         from = NULL;
2032         while (atp != NULL)
2033         {
2034                 if (atp->imported == TRUE)
2035                 {
2036                         if (StringCmp((CharPtr) atp->branch, from))    /* new FROM */
2037                         {
2038                                 from = (CharPtr)(atp->branch);
2039                                 newmod = AsnModuleFind(from);
2040                                 if (newmod != NULL)
2041                                         AsnModuleGetList(newmod, mlp);
2042                                 else
2043                                         ErrPostEx(SEV_ERROR,0,0,"Can't find module %s",
2044                                                 from);
2045                         }
2046                 }
2047                 atp = atp->next;
2048         }
2049 
2050         return;
2051         
2052 }
2053 
2054 /**************************************************************************
2055 *
2056 *  AsnPrintModuleXMLInc (amp, name)
2057 *    prints the ENTITY includes for a DTD
2058 *
2059 **************************************************************************/
2060 NLM_EXTERN void AsnPrintModuleXMLInc (AsnModulePtr amp, CharPtr name)
2061 {
2062         ModuleList ml;
2063         CharPtr ptr;
2064         Char buf[200], buf2[200];
2065         FILE * fp;
2066         Int2 i;
2067         static char * f1 = "\n<!ENTITY %% %s_module PUBLIC \"-//NCBI//%s Module//EN\" \"%s%s.mod\">\n";
2068         static char * f2 = "%%%s_module;\n";
2069 
2070         ml.num = 0;
2071 
2072         AsnModuleGetList(amp, &ml);
2073 
2074         fp = FileOpen(name, "w");
2075 
2076         fprintf(fp, "<!-- %s\n", name);
2077         fprintf(fp, "  This file is built from a series of basic modules.\n");
2078         fprintf(fp, "  The actual ELEMENT and ENTITY declarations are in the modules.\n");
2079         fprintf(fp, "  This file is used to put them together.\n");
2080         fprintf(fp, "-->\n");
2081 
2082         fprintf(fp, f1, "NCBI_Entity", "NCBI Entity",AsnGetXMLmodulePrefix(),  "NCBI_Entity");
2083         fprintf(fp, f2, "NCBI_Entity");
2084 
2085         for (i = 0; i < ml.num; i++)
2086         {
2087                 ptr = MakeXMLModuleName(ml.amps[i], buf);
2088                 ptr = MakeXMLPublicName(buf2, buf);
2089                 
2090                 fprintf(fp, f1, buf, buf2, AsnGetXMLmodulePrefix(), buf);
2091                 fprintf(fp, f2, buf);
2092         }
2093 
2094         FileClose(fp);
2095         return;
2096 }
2097 
2098 /*****************************************************************************
2099 *
2100 *   void AsnPrintModuleXML(amp, aip)
2101 *
2102 *****************************************************************************/
2103 NLM_EXTERN void AsnPrintModuleXML (AsnModulePtr amp, AsnIoPtr aip)
2104 
2105 {
2106         AsnTypePtr atp;
2107         Boolean firstone, done;
2108         CharPtr from;
2109         AsnOptionPtr aop;
2110         Int4 ctr, highest;
2111         
2112 
2113         if (! aip->XMLModuleWritten)   /* first module to XML DTD? */
2114         {
2115                 aip->XMLModuleWritten = TRUE;
2116                 aip->token = ISMODULE_TOKEN;   /* signal to AsnPrintIndent */
2117         
2118                 /**** now a separate module **
2119                 AsnPrintCharBlock("<!-- ======================== -->", aip);
2120                 AsnPrintNewLine(aip);
2121                 AsnPrintCharBlock("<!-- NCBI DTD                 -->", aip);
2122                 AsnPrintNewLine(aip);
2123                 AsnPrintCharBlock("<!-- NCBI ASN.1 mapped to XML -->", aip);
2124                 AsnPrintNewLine(aip);
2125                 AsnPrintCharBlock("<!-- ======================== -->", aip);
2126                 AsnPrintNewLine(aip);
2127                 AsnPrintNewLine(aip);
2128                 AsnPrintCharBlock("<!-- Entities used to give specificity to #PCDATA -->", aip);
2129                 AsnPrintNewLine(aip);
2130                 AsnPrintCharBlock("<!ENTITY % INTEGER '#PCDATA'>", aip);
2131                 AsnPrintNewLine(aip);
2132                 AsnPrintCharBlock("<!ENTITY % ENUM 'EMPTY'>", aip);
2133                 AsnPrintNewLine(aip);
2134                 AsnPrintCharBlock("<!ENTITY % BOOLEAN 'EMPTY'>", aip);
2135                 AsnPrintNewLine(aip);
2136                 AsnPrintCharBlock("<!ENTITY % NULL 'EMPTY'>", aip);
2137                 AsnPrintNewLine(aip);
2138                 AsnPrintCharBlock("<!ENTITY % REAL '#PCDATA'>", aip);
2139                 AsnPrintNewLine(aip);
2140                 AsnPrintCharBlock("<!ENTITY % OCTETS '#PCDATA'>", aip);
2141                 AsnPrintNewLine(aip);
2142                 AsnPrintCharBlock("<!-- ============================================ -->", aip);
2143                 AsnPrintNewLine(aip);
2144                 AsnPrintNewLine(aip);
2145                 *****************************/
2146 
2147         }
2148 
2149         AsnPrintCharBlock("<!-- ============================================ -->", aip);
2150         AsnPrintNewLine(aip);
2151         AsnXMLCommentBegin(aip);
2152         AsnPrintString("This section mapped from ASN.1 module ", aip);
2153         AsnPrintString(amp->modulename, aip);
2154         AsnXMLCommentEnd(aip);
2155         AsnPrintNewLine(aip);
2156 
2157 
2158         atp = amp->types;                   /* check for EXPORTS */
2159         firstone = TRUE;
2160         while (atp != NULL)
2161         {
2162                 if (atp->exported == TRUE)
2163                 {
2164                         if (firstone)
2165                         {
2166                                 AsnXMLCommentBegin(aip);
2167                                 AsnPrintString("Elements used by other modules:", aip);
2168                                 AsnPrintNewLine(aip);
2169                         }
2170                         else
2171                         {
2172                                 AsnPrintString(" ,", aip);
2173                                 AsnPrintNewLine(aip);
2174                         }
2175                         AsnPrintString("          ", aip);
2176                         AsnPrintString(GetXMLname(atp), aip);
2177                         firstone = FALSE;
2178                 }
2179                 atp = atp->next;
2180         }
2181         if (! firstone)            /* got at least one */
2182         {
2183                 AsnXMLCommentEnd( aip);
2184                 AsnPrintNewLine(aip);
2185                 AsnPrintNewLine(aip);
2186         }
2187 
2188         atp = amp->types;                   /* check for IMPORTS */
2189         firstone = TRUE;
2190         from = NULL;
2191         while (atp != NULL)
2192         {
2193                 if (atp->imported == TRUE)
2194                 {
2195                         if (firstone)
2196                         {
2197                                 AsnXMLCommentBegin(aip);
2198                                 AsnPrintString("Elements referenced from other modules:  ", 
2199                                aip);
2200                                 AsnPrintNewLine(aip);
2201                         }
2202                         else
2203                         {
2204                                 if (StringCmp((CharPtr) atp->branch, from))    /* new FROM */
2205                                 {
2206                                         AsnPrintString(" FROM ", aip);
2207                                         AsnPrintString(from, aip);
2208                                 }
2209                                 else
2210                                         AsnPrintString(" ,", aip);
2211                                 AsnPrintNewLine(aip);
2212                         }
2213                         AsnPrintString("          ", aip);
2214                         AsnPrintString(GetXMLname(atp), aip);
2215                         firstone = FALSE;
2216                         from = (CharPtr) atp->branch;
2217                 }
2218                 atp = atp->next;
2219         }
2220         if (! firstone)            /* got at least one */
2221         {
2222                 AsnPrintString(" FROM ", aip);
2223                 AsnPrintString(from, aip);
2224                 AsnXMLCommentEnd(aip);
2225                 AsnPrintNewLine(aip);
2226                 AsnPrintNewLine(aip);
2227         }
2228 
2229         AsnPrintCharBlock("<!-- ============================================ -->", aip);
2230         AsnPrintNewLine(aip);
2231 
2232         aop = NULL;    /* check for order information */
2233         highest = 0;
2234         for (atp = amp->types; atp != NULL; atp = atp->next)
2235         {
2236                 aop = AsnOptionGet(atp->hints, OP_TYPEORDER, 0, NULL);
2237                 if (aop != NULL)
2238                 {
2239                         if (aop->data.intvalue > highest)
2240                                 highest = aop->data.intvalue;
2241                 }
2242         }
2243 
2244         if (highest)     /* we do have ordering info */
2245         {
2246                 for (ctr = 1; ctr <= highest; ctr++)
2247                 {
2248                         done = FALSE;
2249                         for (atp = amp->types;
2250                              (! done) && ( atp != NULL); atp = atp->next)
2251                         {
2252                                 aop = AsnOptionGet(atp->hints, OP_TYPEORDER,
2253                                                    0, NULL);
2254                                 if (aop != NULL)
2255                                 {
2256                                         if (aop->data.intvalue == ctr)
2257                                         {
2258                                                 AsnPrintTopTypeXML(aip, atp);
2259                                                 done = TRUE;
2260                                         }
2261                                 }
2262                         }
2263                 }
2264         }
2265         else             /* nope, just do the default order */
2266         {
2267                 atp = amp->types;
2268                 while (atp != NULL)
2269                 {
2270                         if (! atp->imported)
2271                         {
2272                                 AsnPrintTopTypeXML(aip, atp);
2273                         }
2274                 }
2275                 atp = atp->next;
2276         }
2277 
2278         AsnPrintNewLine(aip);
2279         return;
2280 }
2281 
2282 /*****************************************************************************
2283 *
2284 *   Boolean AsnPrintTypeXML(atp, aip)
2285 *       prints a type starting at current line position
2286 *       (assumes name already printed)
2287 *       returns TRUE if AsnElementXMLEnd() needs to be called
2288 *
2289 *****************************************************************************/
2290 static Boolean AsnPrintTypeXML (AsnTypePtr atp, AsnIoPtr aip)
2291 
2292 {
2293         AsnValxNodePtr avnp;
2294         AsnTypePtr atp2;
2295         Boolean first;
2296         Int2 isa;
2297         Char buf[100], tbuf[20];
2298         CharPtr tmp, repeat = NULL;
2299         Boolean retval = TRUE, gotone, isimplied = FALSE;
2300 
2301         isa = atp->type->isa;
2302         tmp = buf;
2303         *tmp = '\0';
2304         gotone = FALSE;    /* assume no default attribute found */
2305 
2306         if (atp->branch != NULL)       /* sub types ? */
2307         {
2308                 switch (isa)
2309                 {
2310                         case SETOF_TYPE:
2311                         case SEQOF_TYPE:
2312                                 if ((atp->optional) || (atp->hasdefault))
2313                                         repeat = "*";
2314                                 else
2315                                         repeat = "*";
2316 /*                                      repeat = "+"; */
2317                                 AsnXMLElementAdd(NULL, atp->branch, repeat, aip, FALSE);
2318                                 break;
2319                         case INTEGER_TYPE:
2320                                 tmp = StringMove(tmp, "%INTEGER;");
2321                                 AsnPrintString(buf, aip);
2322                                 AsnXMLElementEnd(aip);
2323                                 isimplied = TRUE;   /* don't need named attributes */
2324                         case ENUM_TYPE:
2325                                 if (*buf == '\0')   /* not INTEGER */
2326                                 {
2327                                         tmp = StringMove(tmp, "%ENUM; >");
2328                                         AsnPrintCharBlock(buf, aip);
2329                                         AsnPrintNewLine(aip);
2330                                 }
2331 
2332                                 tmp = buf;
2333                                 AsnPrintCharBlock("<!ATTLIST", aip);
2334                                 tmp = StringMove(tmp, " ");
2335                                 tmp = StringMove(tmp, GetXMLname(atp));
2336                                 tmp = StringMove(tmp, " value ( ");
2337                                 AsnPrintString(buf, aip);
2338                                 avnp = (AsnValxNodePtr)atp->branch;
2339                                 first = TRUE;
2340                                 /*
2341                                 aip->first[aip->indent_level] = FALSE;
2342                                 */
2343                                 while (avnp != NULL)
2344                                 {
2345                                         tmp = buf;
2346                                         *tmp = '\0';
2347                                         if (! first)
2348                                                 AsnPrintCharBlock(" |", aip);
2349                                         else
2350                                                 first = FALSE;
2351                                         AsnPrintNewLine(aip);
2352                                         tmp = StringMove(tmp, "               ");
2353                                         if (avnp->name != NULL)
2354                                                 tmp = StringMove(tmp, avnp->name);
2355                                         else
2356                                         {
2357                                                 sprintf(tbuf, "%d", (int)(avnp->intvalue));
2358                                                 tmp = StringMove(tmp, tbuf);
2359                                         }
2360                                         AsnPrintString(buf, aip);
2361                                         avnp = avnp->next;
2362                                 }
2363                                 AsnPrintCharBlock(" ) ", aip);
2364                                 if (atp->hasdefault)
2365                                 {
2366                                         tmp = buf;
2367                                         *tmp = '\0';
2368                                         avnp = atp->defaultvalue;
2369                                         while (! (VALUE_ISA_DEFAULT(avnp->valueisa)))
2370                                                 avnp = avnp->next;
2371                                         switch (avnp->valueisa)
2372                                         {
2373                                                 case VALUE_ISA_PTR:
2374                                                         AsnPrintChar('\"', aip);
2375                                                         AsnPrintString(avnp->name, aip);
2376                                                         AsnPrintChar('\"', aip);
2377                                                         gotone = TRUE;
2378                                                         break;
2379                                                 default:
2380                                                         break;
2381                                         }
2382                                 }
2383                                 if (! gotone)    /* no default value */
2384                                 {
2385                                         if (isimplied)
2386                                                 AsnPrintString(" #IMPLIED", aip);
2387                                         else
2388                                                 AsnPrintString(" #REQUIRED", aip);
2389                                 }
2390                                 AsnPrintCharBlock(" >", aip);
2391                                 AsnPrintNewLine(aip);
2392                                 retval = FALSE;
2393                                 break;
2394                         case SEQ_TYPE:
2395                         case SET_TYPE:
2396                                 atp2 = (AsnTypePtr) atp->branch;
2397                                 first = TRUE;
2398                                 aip->first[aip->indent_level] = FALSE;
2399                                 tmp = NULL;
2400                                 while (atp2 != NULL)
2401                                 {
2402                                         if (! first)
2403                                                 tmp = ",";
2404                                         else
2405                                                 first = FALSE;
2406                                         
2407                                         if ((atp2->optional) || (atp2->hasdefault))
2408                                                 repeat = "?";
2409                                         else
2410                                                 repeat = NULL;
2411 
2412                                         AsnXMLElementAdd(tmp, atp2, repeat, aip, TRUE);
2413 
2414                                         atp2 = atp2->next;
2415                                 }
2416 
2417                                 break;
2418                         case CHOICE_TYPE:
2419                                 atp2 = (AsnTypePtr) atp->branch;
2420                                 first = TRUE;
2421                                 aip->first[aip->indent_level] = FALSE;
2422                                 tmp = NULL;
2423                                 while (atp2 != NULL)
2424                                 {
2425                                         if (! first)
2426                                                 tmp = "|";
2427                                         else
2428                                                 first = FALSE;
2429                                         
2430                                         if ((atp2->optional) || (atp2->hasdefault))
2431                                                 repeat = "?";
2432                                         else
2433                                                 repeat = NULL;
2434 
2435                                         AsnXMLElementAdd(tmp, atp2, repeat, aip, TRUE);
2436 
2437                                         atp2 = atp2->next;
2438                                 }
2439 
2440                                 break;
2441                         default:                        /* everything else */
2442                                 AsnPrintString(" DEFAULT_BRANCH ", aip);
2443                                 break;          /* do nothing */
2444                 }
2445         }
2446         else  /* primitive.. all text */
2447         {
2448                 atp2 = AsnFindBaseTypeDTD(atp);
2449                 if (atp2 != NULL)
2450                 {
2451                         isa = AsnFindBaseIsa(atp);
2452                         if (atp2 == atp)   /* this is the bottom */
2453                         {
2454                                 switch (isa)
2455                                 {
2456                                         case NULL_TYPE:
2457                                                 tmp = StringMove(tmp, "%NULL; >");
2458                                                 AsnPrintCharBlock(buf, aip);
2459                                                 AsnPrintNewLine(aip);
2460                                                 return FALSE;
2461 
2462                                         case BOOLEAN_TYPE:
2463                                                 tmp = StringMove(tmp, "%BOOLEAN; >");
2464                                                 AsnPrintCharBlock(buf, aip);
2465                                                 AsnPrintNewLine(aip);
2466 
2467                                                 tmp = buf;
2468                                                 *tmp = '\0';
2469                                                 AsnPrintCharBlock("<!ATTLIST ", aip);
2470                                                 tmp = StringMove(tmp, GetXMLname(atp));
2471                                                 tmp = StringMove(tmp, " value ( true | false ) ");
2472                                                 AsnPrintString(buf, aip);
2473                                                 gotone = FALSE;
2474                                                 if (atp->hasdefault)
2475                                                 {
2476                                                         avnp = atp->defaultvalue;
2477                                                         while (! (VALUE_ISA_DEFAULT(avnp->valueisa)))
2478                                                                 avnp = avnp->next;
2479                                                         switch (avnp->valueisa)
2480                                                         {
2481                                                                 case VALUE_ISA_BOOL:
2482                                                                         AsnPrintChar('\"', aip);
2483                                                                         if (avnp->intvalue)
2484                                                                                 AsnPrintString("true",aip);
2485                                                                         else
2486                                                                                 AsnPrintString("false",aip);
2487                                                                         AsnPrintChar('\"', aip);
2488                                                                         gotone = TRUE;
2489                                                                         break;
2490                                                                 default:
2491                                                                         break;
2492                                                         }
2493                                                 }
2494                                                 if (! gotone)
2495                                                         AsnPrintString(" #REQUIRED", aip);
2496                                                 AsnPrintCharBlock(" >", aip);
2497                                                 AsnPrintNewLine(aip);
2498                                                 *buf = '\0';
2499                                                 retval = FALSE;
2500                                                 break;
2501                                         case INTEGER_TYPE:
2502                                                 tmp = StringMove(tmp, "%INTEGER;");
2503                                                 break;
2504                                         case BIGINT_TYPE:
2505                                                 tmp = StringMove(tmp, "%INTEGER;");
2506                                                 break;
2507                                         case REAL_TYPE:
2508                                                 tmp = StringMove(tmp, "%REAL;");
2509                                                 break;
2510                                         case OCTETS_TYPE:
2511                                                 tmp = StringMove(tmp, "%OCTETS;");
2512                                                 break;
2513                                         default:
2514                                                 tmp = StringMove(tmp, "#PCDATA");
2515                                                 break;
2516                                 }
2517                         }
2518                         else
2519                         {
2520                                 tmp = StringMove(tmp, GetXMLname(atp2));
2521                         }
2522                 }
2523                 else
2524                         tmp = StringMove(tmp, "#PCDATA");
2525 
2526                 if (*buf != '\0')
2527                         AsnPrintString(buf, aip);
2528         }
2529         return retval;
2530 }
2531 
2532 static void AsnPrintTreeType(Int2 indent, AsnTypePtr atp, CharPtr prefix, FILE *fp)
2533 {
2534         Int2 isa;
2535         Uint4 ptr;
2536         CharPtr tmp;
2537         Char buf[1000];
2538         Int2 i;
2539         AsnTypePtr atp2;
2540 
2541         if (atp == NULL) return;
2542 
2543         ptr = (Uint4)(atp);
2544         isa = atp->isa;
2545 
2546         for (i = 0; i < indent; i++)
2547         {
2548                 buf[i] = '.';
2549         }
2550         tmp = buf + indent;
2551         *tmp = '\0';
2552         fprintf(fp, "%s", buf);
2553         if ((indent) && (atp->hints != NULL))  /* primary def */
2554                 fprintf(fp, "#>");
2555         if (atp->been_here)
2556                 fprintf(fp,"&>");
2557 
2558         if (prefix != NULL)
2559                 fprintf(fp,"%s", prefix);
2560         fprintf(fp,"[%lu] ", (unsigned long)ptr);
2561         fprintf(fp,"%d ", (int)isa);
2562         if (atp->name == NULL)
2563                 fprintf(fp,"(null) ");
2564         else
2565                 fprintf(fp,"(%s) ", atp->name);
2566         if (atp->XMLname == NULL)
2567                 fprintf(fp,"|null| ");
2568         else
2569                 fprintf(fp,"|%s| ", atp->XMLname);
2570         if (atp->type != NULL)
2571                 fprintf(fp,"type ");
2572         else
2573                 fprintf(fp,"notype ");
2574         if (atp->imported)
2575                 fprintf(fp,"import ");
2576         else
2577                 fprintf(fp,"notimport ");
2578         if (atp->branch != NULL)
2579                 fprintf(fp,"branch\n");
2580         else
2581                 fprintf(fp,"nobranch\n");
2582 
2583         if (atp->been_here)
2584                 return;
2585 
2586         if ((indent) && (atp->hints != NULL))  /* primary def */
2587                 return;
2588 
2589         atp->been_here = TRUE;
2590         AsnPrintTreeType((Int2)(indent + 1), atp->type, "TYPE=", fp);
2591 
2592         isa = AsnFindBaseIsa(atp);
2593         if (((isa == SEQOF_TYPE) || (isa == SETOF_TYPE) ||
2594             (isa == SEQ_TYPE) || (isa == SET_TYPE) ||
2595             (isa == CHOICE_TYPE) || (isa > 400)) && (! atp->imported))
2596         for (atp2 = (AsnTypePtr)(atp->branch); atp2 != NULL; atp2 = atp2->next)
2597                 AsnPrintTreeType((Int2)(indent + 1), atp2, "Branch=", fp);
2598 
2599         atp->been_here = FALSE;  /* just prevent recursion */
2600         return;
2601 
2602 }
2603 
2604 NLM_EXTERN void AsnPrintTreeModule(AsnModulePtr amp, FILE * fp)
2605 {
2606         Int4 highest, ctr;
2607         AsnOptionPtr aop;
2608         AsnTypePtr atp;
2609         Boolean done;
2610 
2611         aop = NULL;    /* check for order information */
2612         highest = 0;
2613         for (atp = amp->types; atp != NULL; atp = atp->next)
2614         {
2615                 aop = AsnOptionGet(atp->hints, OP_TYPEORDER, 0, NULL);
2616                 if (aop != NULL)
2617                 {
2618                         if (aop->data.intvalue > highest)
2619                                 highest = aop->data.intvalue;
2620                 }
2621         }
2622 
2623         if (highest)     /* we do have ordering info */
2624         {
2625                 for (ctr = 1; ctr <= highest; ctr++)
2626                 {
2627                         done = FALSE;
2628                         for (atp = amp->types;
2629                              (! done) && ( atp != NULL); atp = atp->next)
2630                         {
2631                                 aop = AsnOptionGet(atp->hints, OP_TYPEORDER,
2632                                                    0, NULL);
2633                                 if (aop != NULL)
2634                                 {
2635                                         if (aop->data.intvalue == ctr)
2636                                         {
2637                                                 AsnPrintTreeType((Int2)0, atp, NULL, fp);
2638                                                 fprintf(fp,"\n");
2639                                                 done = TRUE;
2640                                         }
2641                                 }
2642                         }
2643                 }
2644         }
2645 
2646 }
2647 

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.