NCBI C Toolkit Cross Reference

C/asnlib/asncode.c


  1 /*
  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:  asncode.c
 27 *
 28 * Author:  Karl Sirotkin
 29 *
 30 * Version Creation Date: 7/8/93
 31 *
 32 * $Revision: 6.17 $
 33 *
 34 * File Description:
 35 *   Automatically generate C code from ASN.1 specifications
 36 *
 37 *       -l Loadable filename, not identical to string after -l in asntool
 38 *       -o name for generated code prefix
 39 *       -n hints file
 40 *       -b Size         (set AsnIo buffer size)
 41 *       -w Word length for #define
 42 *
 43 *
 44 * Modifications:  
 45 * --------------------------------------------------------------------------
 46 * Date     Name        Description of modification
 47 * -------  ----------  -----------------------------------------------------
 48 *
 49 * $Log: asncode.c,v $
 50 * Revision 6.17  2009/11/05 16:54:12  gouriano
 51 * Added option to use quoted syntax form to include headers. JIRA: CXX-1402
 52 *
 53 * Revision 6.16  2005/01/24 17:12:11  kans
 54 * added force_choice_struct (-V) to force struct plus object instead of ValNode for choices - for compatibility with old hand-coded object loaders
 55 *
 56 * Revision 6.15  2004/07/08 15:24:05  kans
 57 * needed a couple additional TESTNIL wrappers
 58 *
 59 * Revision 6.14  2002/03/07 21:36:27  beloslyu
 60 * typo fixed
 61 *
 62 * Revision 6.13  2001/11/05 20:25:34  madden
 63 * Fix (by Karl Sirotkin) for underscores (e.g., struct_BlastDefLine to struct_Blast_def_line)
 64 *
 65 * Revision 6.12  2001/06/28 02:14:40  juran
 66 * Fixed log message.
 67 * Testing how new MacCVS Pro handles multi-line comments.
 68 *
 69 * Revision 6.11  2001/06/28 01:53:32  juran
 70 * Mac compatibility:
 71 * Redefine NULL to 0L, which gets promoted to any pointer type.
 72 * Cast result of MemNew() to appropriate pointer type.
 73 *
 74 * Revision 6.10  2000/12/12 15:56:09  ostell
 75 * added support BigInt
 76 *
 77 * Revision 6.9  2000/05/05 19:28:31  kans
 78 * type for OCTET STRING really is ByteStorePtr, so this is now used instead of Pointer (KS)
 79 *
 80 * Revision 6.8  1999/08/02 14:18:55  sirotkin
 81 * some compiler nits.
 82 *
 83 * Revision 6.7  1999/07/30 17:23:30  sirotkin
 84 * removed.an.unused
 85 *
 86 * Revision 6.6  1999/03/08 15:20:22  kans
 87 * changed single ampersand to double ampersand
 88 *
 89 * Revision 6.5  1998/06/12 19:27:44  kans
 90 * fixed unix compiler warnings
 91 *
 92 * Revision 6.4  1998/05/02 18:54:27  kans
 93 * for Mac, use %LG instead of %lg, which is not legal C, and not supported by CodeWarrior
 94 *
 95 * Revision 6.3  1998/05/01 23:35:21  kans
 96 * use %lf on Mac, %lg elsewhere, sprintf bug reported
 97 *
 98 * Revision 6.2  1998/03/25 23:31:34  kans
 99 * params to register new object manager type, give optional non-default label
100 *
101 * Revision 6.1  1997/12/16 14:51:42  kans
102 * header needed for asntool/asncode merge
103 *
104 * Revision 6.0  1997/08/25 18:09:41  madden
105 * Revision changed to 6.0
106 *
107 * Revision 5.2  1997/01/02 17:57:47  epstein
108 * add more NLM_EXTERN logic per D. Vakatov
109 *
110  * Revision 5.1  1996/12/05  19:51:40  epstein
111  * add support for NLM_EXTERN
112  *
113  * Revision 5.0  1996/05/28  14:00:29  ostell
114  * Set to revision 5.0
115  *
116  * Revision 4.2  1995/11/07  20:07:29  epstein
117  * change quotes on #includes to angle-brackets
118  *
119  * Revision 4.1  1995/08/24  16:57:10  epstein
120  * remove stray backslashes per Peter Cartwright <Peter.Cartwright@genetics.utah.edu>
121  *
122  * Revision 4.0  1995/07/26  13:47:38  ostell
123  * force revision to 4.0
124  *
125  * Revision 1.20  1995/06/26  20:32:02  kans
126  * AsnCodeIsEnumType needed to be prototyped as static
127  *
128  * Revision 1.19  1995/05/15  18:38:28  ostell
129  * added Log line
130  *
131 *
132 *
133 * ==========================================================================
134 */
135 
136 #include "asnbuild.h"
137 #include "asntool.h"
138 
139 #undef NULL
140 #define NULL 0L
141 
142 /*****************************************************************************
143 *
144 *   prototypes
145 *
146 *****************************************************************************/
147 
148 static Boolean AsnCodeIsEnumType PROTO ((AsnTypePtr atp));
149 
150 static char     RCS_Rev [] = "$Revision: 6.17 $";
151 
152 /*******************
153  * Interator structure
154  ***********************/
155 
156 typedef struct struct_AsnCodeLines {
157    CharPtr line;
158    struct struct_AsnCodeLines PNTR next;
159 } AsnCodeLines, PNTR AsnCodeLinesPtr;
160 
161 typedef struct struct_spooled {
162    struct struct_AsnCodeLines PNTR head_line;
163    struct struct_AsnCodeLines PNTR tail_line;
164    struct struct_spooled PNTR next;
165    struct struct_spooled PNTR last;
166    Boolean finished;
167 } AsnCodeSpooled, PNTR AsnCodeSpooledPtr;
168 
169 typedef struct struct_AsnCodeNode {
170    AsnTypePtr atp;
171    CharPtr slot_name;
172    CharPtr asn_type_name;
173    CharPtr obj_name;
174    Int2 recur_type;
175    Int2 type;
176    Int2 slot_count;
177    Int2 opt_count;
178    struct struct_AsnCodeNode PNTR outer;
179    struct struct_AsnCodeNode PNTR inner;
180 } AsnCodeNode, PNTR AsnCodeNodePtr;
181 
182 #define ASNCODE_START 400
183 
184 typedef struct struct_asniter {
185    AsnCodeInfoPtr acip;
186    FILE * fp; 
187    Int2 mode;  /* so FnPtrs can be kept the same and this varied */
188    ValNodePtr bufs;
189    AsnCodeSpooledPtr routines;    /* head pointer */
190    AsnCodeSpooledPtr cur_routine; /* active pointer */
191    AsnCodeSpooledPtr last_routine;/* tail pointer */
192    AsnTypePtr atp;
193    Int2 depth;
194    struct struct_AsnCodeNode PNTR stack;
195    struct struct_AsnCodeNode PNTR base_of_stack;
196    char buf [1024];
197    char buf2 [60];
198    CharPtr module_name;
199    Int2 indent;
200    Boolean leadingspaces;
201    FnPtr basetype;
202    FnPtr choiceend;
203    FnPtr choicestart;
204    FnPtr less301err;
205    FnPtr seqend;
206    FnPtr seqstart; 
207    FnPtr setend;
208    FnPtr setstart;
209    FnPtr undef301err;
210    FnPtr userobj;
211    Boolean do_opt_bits;
212    Boolean do_chs_struct;
213 } AsnIter, PNTR AsnIterPtr;
214 
215 typedef void (* AsnCodeIterFunc) PROTO (( AsnIterPtr iter));
216 
217 /*****************
218 *
219 * OPTIONS
220 *
221 **************/
222 
223 #define OP_MAKE_LINKED 1
224 #define OP_HINTED 2
225 #define OP_SLOT_NAME 3 
226 #define OP_OBJ_NAME 4
227 
228 #define WASH 1
229 #define CLEAN_FOR_SLOT 1
230 
231 #define BUFF 2
232 #define CLEAN_FOR_OBJ_NAME 2
233 
234 #define SLOT_BUFF 3
235 #define SLOT_POLISH 4
236 #define CLEAN_FOR_ASN_TYPE 4
237 
238 #define ASNITER_USER_TYPE 1400
239 #define ASNITER_Pseudo_USER_TYPE 1450
240 #define ASNITER_LESS300 1300
241 #define ASNITER_BRANCH_TYPE 1500 
242 #define ASNITER_BASE_TYPE 1600 
243 
244 #define ASNITER_RECUR_NONE 0
245 #define ASNITER_RECUR_WAS_LAST 1
246 #define ASNITER_RECUR_SEQSET 2
247 #define ASNITER_RECUR_CHOICE 3 
248 #define ASNITER_RECUR_SETOF 4
249 
250 #define RECUR_OUTER 0
251 #define RECUR_SEQSET 1
252 #define RECUR_CHOICE 2
253 #define RECUR_SETOF_OUTER 3
254 #define RECUR_SETOF_SEQSET 4
255 #define RECUR_SETOF_CHOICE 5  
256 
257 #define ITER_ASSIGN 1
258 #define ITER_CHECK_LIST 2
259 #define ITER_OBJECTS 3
260 #define ITER_NEW 4
261 #define ITER_FREE 5
262 #define ITER_READ 6
263 #define ITER_WRITE 7
264 
265 #define BUF_LEN 100
266 
267 #define DEBUG
268 #define DEEP_DEBUG
269 #define CFG_FILE_NAME "NCBI"
270 #define CTX_ASNCODE 500
271 
272 #define TESTNIL(x) ((x) == NULL ? "(nil)" : x)
273 
274 #define AsnIterTakeBuf(x)  AsnIterTakeBufReal(x, __LINE__)
275 
276 #define USER_PSEUDOOBJECTS_STATIC
277 
278 CharPtr c_reserved_word[] = {
279    "asm", /* not part of ANSI, but commonly reserved */
280    "auto",
281    "break",
282    "case",
283    "catch", /* C++ (not ANSI C) */
284    "char",
285    "class", /* C++ (not ANSI C) */
286    "const",
287    "continue",
288    "default",
289    "defined",
290    "delete", /* C++ (not ANSI C) */
291    "do",
292    "double",
293    "else",
294    "enum",
295    "extern",
296    "float",
297    "for",
298    "fortran", /* not part of ANSI, but commonly reserved */
299    "friend", /* C++ (not ANSI C) */
300    "goto",
301    "if",
302    "inline", /* C++ (not ANSI C) */
303    "int",
304    "long",
305    "new", /* C++ (not ANSI C) */
306    "noalias", /* not part of ANSI standard? (part of pre-release standard) */
307    "operator", /* C++ (not ANSI C) */
308    "private", /* C++ (not ANSI C) */
309    "protected", /* C++ (not ANSI C) */
310    "public", /* C++ (not ANSI C) */
311    "register",
312    "return",
313    "short",
314    "signed"
315    "sizeof",
316    "static",
317    "struct",
318    "switch",
319    "template", /* C++ (not ANSI C) */
320    "this", /* C++ (not ANSI C) */
321    "throw", /* C++ (not ANSI C) */
322    "try", /* C++ (not ANSI C) */
323    "typedef",
324    "union",
325    "unsigned",
326    "virtual", /* C++ (not ANSI C) */
327    "void",
328    "volatile",
329    "while"};
330 
331 #define NUM_C_RESERVED_WORDS (sizeof(c_reserved_word)/sizeof(CharPtr))
332 
333 #ifdef TEST_AS_MAIN
334 
335 #define NUMARGS 9
336 
337 Args            asnargs[NUMARGS] = {
338    {"Loadable Filenames, for parsetrees [comma separated\nlist, only first used for objects],\
339 not quite identical to\nstring after -l to asntool", NULL, NULL, NULL, FALSE, 'l', ARG_FILE_IN, 0.0, 0, NULL},
340    {"Asnload directory [for parsetrees]", NULL, NULL, NULL, TRUE, 'd', ARG_FILE_IN, 0.0, 0, NULL},
341    {"filename, without extensions, for objects and code", NULL, NULL, NULL, FALSE, 'o', ARG_FILE_OUT, 0.0, 0, NULL},
342    {"Debugging level\n     0 - No debugging\n     1 - Shallow debugging\n     2 - Deep", "0", "0", "9", TRUE, 'v', ARG_INT, 0.0, 0, NULL},
343    {"Buffer Size", "1024", "512", "10000", TRUE, 'b', ARG_INT, 0.0, 0, NULL},
344    {"See debugging file", "stderr", NULL, NULL, TRUE, 's', ARG_FILE_OUT, 0.0, 0, NULL},
345    {"Include filename to include", NULL, NULL, NULL, TRUE, 'i', ARG_STRING, 0.0, 0, NULL},
346    {"Word length maximum for #defines","31","31","128",TRUE,'w',ARG_INT,0.0,0,NULL},
347    {"Bit twiddle for optional zero value base slots","F",NULL,NULL,TRUE,'t',ARG_BOOLEAN,0.0,0,NULL}
348 };
349 
350 #endif
351 
352 
353 CharPtr AsnCodeCleanName PROTO ((CharPtr name, char PNTR buf, int wash_or_buf, int maxlen));
354 void AsnCodeIter PROTO ((AsnIterPtr iter));
355 void AsnCodePop PROTO ((AsnIterPtr iter, AsnTypePtr atp, Int2 type));
356 void AsnCodePush PROTO ((AsnIterPtr iter, AsnTypePtr atp, Int2 type, Int2 recurtype));
357 void AsnCodeIterCall PROTO ((AsnIterPtr iter, FnPtr slot, AsnTypePtr atp, Int2 placetype));
358 static void AsnCodeShowStack PROTO ((AsnIterPtr iter));
359 
360 #define MACRO_SETARG(TAG,P) \
361    {\
362       P = Nlm_WhichArg (TAG, NUMARGS,asnargs);\
363       if ( P < 0){\
364          ErrPost(1,100,\
365          "Program error looking for arg %c\n", TAG);\
366          has_trouble = TRUE;\
367       }\
368    }
369 
370 static CharPtr  defptr = "ASNCODE_PTRVAL_SLOT";
371 static CharPtr  defint = "ASNCODE_INTVAL_SLOT";
372 static CharPtr  defbigint = "ASNCODE_BIGINTVAL_SLOT";
373 static CharPtr  defreal = "ASNCODE_REALVAL_SLOT";
374 static CharPtr  defbool = "ASNCODE_BOOLVAL_SLOT";
375 static CharPtr  defbyte = "ASNCODE_BYTEVAL_SLOT";
376 
377 Boolean AsnIterNeedsNullCheck PROTO((AsnIterPtr iter, AsnTypePtr final_atp));
378 
379 static void
380 AsnCodeShowDepth (AsnIterPtr iter)
381 {
382    int             dex;
383 
384    for (dex = 0; dex < iter->depth; dex++) {
385       fprintf ((iter->acip -> bug_fp), "|");
386    }
387 
388 }
389 
390 static CharPtr
391 SpanLengthyPrefix (CharPtr buf, int maxlen)
392 {
393    CharPtr         symbol;
394    int             dex;
395 
396    dex = maxlen;
397    symbol = &buf[StrLen (buf)];
398    while ((dex) && (symbol > buf)) {
399       dex--;
400       symbol--;
401    }
402    if (symbol != buf) {         /* longer than (acip -> maxDefineLength) */
403       while (*symbol != '_')    /* end neatly */
404          symbol++;
405       symbol++;
406    }
407    return symbol;
408 }
409 
410 static CharPtr
411 Append_EAndPrestrip (CharPtr inbuf, int maxlen)
412 {
413    static Char     the_name[160];
414 
415    sprintf (the_name, "%s_E", inbuf);
416    return SpanLengthyPrefix (the_name, maxlen);
417 }
418 
419 static CharPtr
420 GenerateTypeFromStack (AsnIterPtr iter, Boolean use_final_E)
421 {
422    static Char     the_name[160];
423    CharPtr         temp = the_name;
424    CharPtr         symbol;
425    int             dex;
426    AsnCodeNodePtr  node;
427    Boolean         first = TRUE;
428    Char            buf[120];
429    Boolean         needs_E = FALSE;
430 
431    for (dex = 0; dex < sizeof (the_name); dex++) {
432       the_name[dex] = '\0';
433    }
434    for (node = iter->base_of_stack; node; node = node->inner) {
435       if (node->atp->name == NULL)
436          continue;
437       if (node->type == ASNITER_Pseudo_USER_TYPE)
438          continue;
439       if (first) {
440          first = FALSE;
441          temp = StringMove (temp, AsnCodeCleanName (node->atp->name, buf,
442                                                     CLEAN_FOR_ASN_TYPE, iter -> acip -> maxDefineLength));
443       } else {
444          if (needs_E)
445             temp = StringMove (temp, "_E");
446          needs_E = FALSE;
447          temp = StringMove (temp, "_");
448          temp = StringMove (temp, AsnCodeCleanName (node->atp->name, buf,
449                                                     CLEAN_FOR_SLOT, iter -> acip -> maxDefineLength));
450       }
451       if (node->atp->type) {
452          if (node->atp->type->isa == SETOF_TYPE ||
453              node->atp->type->isa == SEQOF_TYPE) {
454             needs_E = TRUE;
455          }
456       }
457    }
458    if (needs_E && use_final_E)
459       temp = StringMove (temp, "_E");
460 
461    symbol = SpanLengthyPrefix (the_name, iter -> acip -> maxDefineLength);
462 
463    if ((iter -> acip->debug_level) > 3) {
464       AsnCodeShowStack (iter);
465       fprintf ((iter -> acip -> bug_fp), "YIELDED:(%c)%s\n", use_final_E ? 'T' : 'F', symbol);
466       fflush ((iter -> acip -> bug_fp));
467    }
468    return symbol;
469 }
470 
471 static void
472 AsnCodeShowStack (AsnIterPtr iter)
473 {
474    int             dex;
475    AsnCodeNodePtr  stack;
476 
477    for (dex = 0, stack = iter->stack; stack; stack = stack->outer,
478         dex++) {
479       fprintf ((iter -> acip -> bug_fp), "%d:%s-%d,%d", dex,
480                TESTNIL (stack->atp->name), (int) stack->recur_type,
481                (int) stack->type);
482       if (stack->atp)
483          if (stack->atp->type) {
484             fprintf ((iter -> acip -> bug_fp), "=%s", TESTNIL (stack->atp->type->name));
485          }
486       fprintf ((iter -> acip -> bug_fp), "\n");
487       fflush ((iter -> acip -> bug_fp));
488    }
489    fflush ((iter -> acip -> bug_fp));
490 
491 }
492 
493 #ifdef TEST_AS_MAIN
494 /*****************************************************************************
495 *
496 *   Nlm_WhichArg(ap)
497 *     returns array position for a tag
498 *
499 *****************************************************************************/
500 static Nlm_Int2
501 Nlm_WhichArg (Nlm_Char which, Nlm_Int2 numargs, Nlm_ArgPtr ap)
502 {
503    Nlm_Boolean     okay = FALSE;
504    Nlm_Int2        i;
505    Nlm_ArgPtr      curarg;
506    Nlm_Int2        retval = -1;
507 
508    if ((ap == NULL) || (numargs == 0))
509       return okay;
510 
511    curarg = ap;                 /* set defaults */
512 
513    for (i = 0; i < numargs; i++, curarg++) {
514       if (curarg->tag == which) {
515          retval = i;
516          break;
517       }
518    }
519 
520    return retval;
521 }
522 
523 Int2
524 Main (void)
525 {
526    AsnModulePtr    amp = NULL;
527    AsnTypePtr      atp = NULL;
528    AsnValxNodePtr  avn = NULL;
529    AsnModulePtr    last_amp = NULL;
530    CharPtr         filename = NULL, p, last_comma;
531    CharPtr         first_filename = NULL;
532    int             len;
533    Boolean         asnloadWasModified = FALSE;
534    Boolean         asnloadValExisted = FALSE;
535    Boolean         asnloadSectionExisted = FALSE;
536    Char            asnloadOldVal[PATH_MAX];
537    Char            buf[20];
538    Int2            debugarg, loadfilesarg, dirarg, outnamearg, bufarg, seearg,
539                    includearg, maxdefarg, bittwiddlearg;
540    Boolean         has_trouble = FALSE;
541    AsnCodeInfoPtr  acip = MemNew (sizeof(AsnCodeInfo));
542 
543    if (!GetArgs ("AsnCode 1", NUMARGS, asnargs))
544       return 1;
545 
546    MACRO_SETARG ('l', loadfilesarg)
547    MACRO_SETARG ('b', bufarg)
548    MACRO_SETARG ('i', includearg)
549    MACRO_SETARG ('o', outnamearg)
550    MACRO_SETARG ('v', debugarg)
551    MACRO_SETARG ('d', dirarg)
552    MACRO_SETARG ('s', seearg)
553    MACRO_SETARG ('t', bittwiddlearg)
554    MACRO_SETARG ('w', maxdefarg)
555 
556 
557 #ifdef USE_LOG_ERRPOST
558    /* log errors instead of die */
559    if (asnargs[seearg].strvalue != NULL) {
560       if (!ErrSetLog (asnargs[seearg].strvalue))
561          ErrShow ();
562       else
563          ErrSetOpts (ERR_TEE, ERR_LOG_ON);
564    }
565 #else
566    if (asnargs[seearg].strvalue != NULL) {
567       (acip -> bug_fp) = FileOpen (asnargs[seearg].strvalue, "w");
568    } else {
569       (acip -> bug_fp) = FileOpen ("stderr", "w");
570    }
571 #endif
572 
573    if (!AsnIoSetBufsize (NULL, (Int2) asnargs[bufarg].intvalue))
574       return 1;
575 
576 
577    (acip->debug_level) = asnargs[debugarg].intvalue;
578    (acip -> maxDefineLength) = asnargs[maxdefarg].intvalue;
579 
580    if (asnargs[dirarg].strvalue != NULL) {      /* temporarily set ASNLOAD
581                                                  * value */
582       asnloadValExisted = TRUE;
583       asnloadSectionExisted = TRUE;
584 
585       if (GetAppParam (CFG_FILE_NAME, "NCBI", "ASNLOAD", "", asnloadOldVal, sizeof asnloadOldVal) == 0) {
586          asnloadValExisted = FALSE;
587          if (GetAppParam (CFG_FILE_NAME, "NCBI", NULL, "", buf, sizeof buf) == 0) {
588             asnloadSectionExisted = FALSE;
589          }
590       }
591       SetAppParam (CFG_FILE_NAME, "NCBI", "ASNLOAD", asnargs[dirarg].strvalue);
592       asnloadWasModified = TRUE;
593    }
594    for (p = asnargs[loadfilesarg].strvalue; *p; p = last_comma + 1) {
595       for (last_comma = p; *last_comma; last_comma++) {
596          if (*last_comma == ',')
597             break;
598       }
599       len = last_comma - p;
600       filename = MemFree (filename);
601       filename = MemNew (len + 1);
602       StringNCpy (filename, p, len);
603       filename[len] = '\0';
604 #ifdef WIN_DUMB
605       printf ("Loading %s \n", filename);
606 #endif
607       amp = NULL;
608       if (!AsnTreeLoad (filename, &avn, &atp, &amp))
609          return 1;
610       amp = AsnAllModPtr ();
611       if (last_amp == NULL) {
612          for (last_amp = amp; last_amp->next; last_amp = last_amp->next);       /* empty body */
613       }
614       if (first_filename == NULL) {
615          first_filename = StringSave (filename);
616       }
617       if (!*last_comma)
618          break;
619    }
620 
621    if (has_trouble)
622       return (1);
623 
624 
625    acip ->  loadname = first_filename;
626    acip ->  filename = asnargs[outnamearg].strvalue;
627    acip ->  do_bit_twiddle = asnargs[bittwiddlearg].intvalue;
628    acip ->  include_filename = asnargs[includearg].strvalue;
629    acip ->  amp = amp ;
630    acip ->  last_amp = last_amp;
631 
632    AsnCode(acip);
633 
634    if (asnloadWasModified) {    /* restore ASNLOAD value */
635       if (asnloadValExisted) {
636          SetAppParam (CFG_FILE_NAME, "NCBI", "ASNLOAD", asnloadOldVal);
637       } else {
638          if (asnloadSectionExisted) {
639             SetAppParam (CFG_FILE_NAME, "NCBI", "ASNLOAD", NULL);
640          } else {
641             SetAppParam (CFG_FILE_NAME, "NCBI", NULL, NULL);
642          }
643       }
644    }
645    return 0;
646 }
647 #endif
648 
649 
650 void AsnCodeHeader PROTO ((AsnIterPtr iter, CharPtr name));
651 void AsnCodeFunctionHeader PROTO ((AsnIterPtr iter, CharPtr name, CharPtr type));
652 Int2 AsnCodeSafeIsa PROTO ((AsnTypePtr atp));
653 void AsnCodeGenerateProtos PROTO ((struct struct_asniter PNTR iter, CharPtr buf, Boolean from_choice));
654 Int2 AsnCodeIterRecurLevel PROTO ((AsnIterPtr iter));
655 static Int2 AsnCodeFinalType PROTO ((struct struct_asniter PNTR iter, AsnTypePtr atp, AsnTypePtr PNTR base_atpPt));
656 static void userobj_OUTER_typedefs PROTO ((AsnIterPtr iter, CharPtr type, Boolean has_pointer));
657 static CharPtr AsnCodeNeedFree PROTO ((AsnTypePtr atp));
658 CharPtr AsnCodeWhichValSlot PROTO ((AsnTypePtr atp, CharPtr PNTR whichvalslot));
659 static void AsnIterTakeBufReal PROTO ((struct struct_asniter PNTR iter, int lineno));
660 static CharPtr AsnCodeLookupType PROTO ((AsnTypePtr atp));
661 static void userobj_and_basetype_SETOF PROTO ((AsnIterPtr iter, AsnTypePtr final_atp, Int2 recur_level, Int2 base_or_user));
662 void AsnCodeFinishedRoutine PROTO ((struct struct_asniter PNTR iter));
663 void AsnCodeNewRoutine PROTO ((struct struct_asniter PNTR iter));
664 void AsnCodeFunctionReadFuncChoiceStart PROTO ((AsnIterPtr iter, Boolean doing_outer_setof));
665 void AsnCodeFunctionReadFuncSeqStart PROTO ((AsnIterPtr iter, Boolean go_outer));
666 void AsnCodeFunctionWriteFuncChoiceStart PROTO ((AsnIterPtr iter, Boolean doing_outer_setof_choice));
667 void AsnCodeFunctionWriteFuncSeqStart PROTO ((AsnIterPtr iter, Boolean no_write_braces));
668 static Boolean AsnCodeIsReallyChoice PROTO ((AsnTypePtr atp));
669 static void AsnCode_SETOF_base_or_user PROTO(( AsnIterPtr iter, Int2 base_or_user));
670 
671 
672 
673 DataVal         Dummy;
674 
675 
676 /*-----------AsnCodeSafeIsa()-------------*/
677 
678 Int2
679 AsnCodeSafeIsa (AsnTypePtr atp)
680 {
681    if (ISA_BASETYPE (atp->isa)) {
682       return atp->isa;
683    } else {
684       return atp->type->isa;
685    }
686 
687 }
688 
689 
690 /*****************************************************************************
691 *
692 *   AsnCode(acip)
693 *
694 *
695 *****************************************************************************/
696 /*-------------- AsnCode_RightOuter()--------------*/
697 
698 /*
699  * In the case of a Pseudo User type (The unnamed CHOICE and SEQUENCE groups
700  * that the author of this code has learned to love) the "owner" of the slot
701  * count and some names is moved one level deeper for this extra
702  * AsnIterCall's callback
703  * 
704  */
705 static AsnCodeNodePtr
706 AsnCode_RightOuter (AsnIterPtr iter, AsnCodeNodePtr outer)
707 {
708    AsnCodeNodePtr  retval = outer;
709 
710    if (iter->stack->type == ASNITER_Pseudo_USER_TYPE) {
711       retval = outer->outer;
712    }
713    return retval;
714 }
715 
716 /*--------------- AsnCode_RightChoiceNode()--------*/
717 
718 /*
719  * SET OF CHOICE names are located one node level out from other CHOICE
720  * names, so this function sets the correct node level.
721  * 
722  */
723 
724 static AsnCodeNodePtr
725 AsnCode_RightChoiceNode (AsnIterPtr iter, AsnCodeNodePtr start_node, Boolean PNTR in_setof_choicePt)
726 {
727    AsnCodeNodePtr  retval = start_node;
728    AsnTypePtr      atp;
729 
730    if ((iter -> acip->debug_level) > 3) {
731       AsnCodeShowStack (iter);
732       fprintf ((iter -> acip -> bug_fp), "start at %s-%d,%d\n\n", TESTNIL (retval->slot_name),
733                (int) retval->recur_type, (int) retval->type);
734    }
735    if (in_setof_choicePt != NULL)
736       *in_setof_choicePt = FALSE;
737 
738    atp = retval->atp;
739    if (atp->type->isa == CHOICE_TYPE) {
740       if (retval->outer) {
741          atp = retval->outer->atp;
742          if (atp != NULL)
743             if (atp->type != NULL)
744                if (atp->type->isa == SETOF_TYPE ||
745                    atp->type->isa == SETOF_TYPE) {
746                   retval = retval->outer;
747                   if (in_setof_choicePt) {
748                      *in_setof_choicePt = TRUE;
749                      if ((iter -> acip->debug_level) > 3) {
750                         fprintf ((iter -> acip -> bug_fp), ">>>>>>>  YES(%s)\n", TESTNIL (retval->obj_name));
751                      }
752                   }
753                }
754       }
755    }
756    if ((iter -> acip->debug_level) > 3) {
757       fflush ((iter -> acip -> bug_fp));
758    }
759    return retval;
760 }
761 
762 
763 /****************************************************************************
764 *
765 *   AsnCodeIterCaseInChoice(iter)
766 *
767 * WASH == CLEAN_FOR_SLOT
768 * BUFF == CLEAN_FOR_OBJ_NAME
769 *
770 * This node is the slot in the choice.
771 * The outer node was the CHOICE
772 *****************************************************************************/
773 static void
774 AsnCodeIterCaseInChoice (struct struct_asniter PNTR iter)
775 {
776 
777    /*
778     * JAE 4/6/94 AsnCodeNodePtr  which_node = AsnCode_RightChoiceNode (iter,
779     * iter->stack->outer, NULL);
780     */
781    AsnCodeNodePtr  which_node = AsnCode_RightChoiceNode (iter,
782                        AsnCode_RightOuter (iter, iter->stack->outer), NULL);
783 
784    sprintf (iter->buf, "      case %s_%s:\n",
785             which_node->obj_name,
786             iter->stack->slot_name);
787    AsnIterTakeBuf (iter);
788 }
789 
790 /****************************************************************************
791 *
792 *   AsnCodeGenEnumDefines(iter)
793 *
794 * Generates #defines for the values which an enumerated type may take on
795 *****************************************************************************/
796 static void
797 AsnCodeGenEnumDefines (struct struct_asniter PNTR iter)
798 {
799    AsnValxNodePtr avtp;
800    Char lclbuf[100];
801    Boolean first = TRUE;
802 
803    if (iter != NULL && iter->atp != NULL && iter->atp->branch != NULL) {
804       for (avtp = (AsnValxNodePtr) iter->atp->branch; avtp != NULL;
805            avtp = avtp->next) {
806          if (first) {
807             sprintf(iter->buf, "/* following #defines are for enumerated type, not used by object loaders */\n");
808             AsnIterTakeBuf (iter);
809             first = FALSE;
810          }
811          sprintf (iter->buf, "#define ");
812          AsnIterTakeBuf (iter);
813          if (iter->stack->outer != NULL)
814          {
815             sprintf (iter->buf, "%s_", AsnCodeCleanName(iter->stack->outer->atp->name, lclbuf, CLEAN_FOR_SLOT, iter -> acip -> maxDefineLength));
816             AsnIterTakeBuf (iter);
817          }
818          sprintf (iter->buf, "%s_", AsnCodeCleanName (iter->atp->name, lclbuf, CLEAN_FOR_SLOT, (int) (iter -> acip -> maxDefineLength) ));
819          AsnIterTakeBuf (iter);
820          sprintf (iter->buf, "%s %d\n", AsnCodeCleanName (avtp->name, lclbuf,
821                   CLEAN_FOR_SLOT, iter -> acip -> maxDefineLength), avtp->intvalue);
822          AsnIterTakeBuf (iter);
823       }
824       sprintf (iter->buf, "\n");
825       AsnIterTakeBuf (iter);
826    }
827 }
828 
829 /****************************************************************************
830 *
831 *   AsnCodeGenBitDefines(iter)
832 *
833 * Generates #defines for bitmasks used in determining which optional fields
834 * were instantiated when reading the object ... this data is also used when
835 * determined which fields should be written when writing the object.  The
836 * bit-fields may be manipulated by the application programmer.
837 *****************************************************************************/
838 static void
839 AsnCodeGenBitDefines (struct struct_asniter PNTR iter)
840 {
841    Char lclbuf[100];
842 
843     sprintf (iter->buf, "#define OB__");
844     AsnIterTakeBuf (iter);
845 
846     if (iter->stack->outer != NULL) {
847        sprintf (iter->buf, "%s_", AsnCodeCleanName(iter->stack->outer->atp->name, lclbuf, CLEAN_FOR_SLOT, iter -> acip -> maxDefineLength));
848        AsnIterTakeBuf (iter);
849     }
850 
851     sprintf (iter->buf, "%s %d\n", AsnCodeCleanName (iter -> atp->name, lclbuf,
852              CLEAN_FOR_SLOT, iter -> acip -> maxDefineLength), iter -> stack -> outer -> opt_count ++);
853     AsnIterTakeBuf (iter);
854     sprintf (iter->buf, "\n");
855     AsnIterTakeBuf (iter);
856 }
857 
858 
859 /*------------------------------CALLBACKS ARE HERE --------*/
860 
861 /***************************
862 *
863 * basetype_SEQSET(iter,final_atp)
864 *
865 * We have a basetype within  a SEQUENCE ::= group (or SET ::=)
866 *
867 *  such as:
868 *
869 *    ParentSeq ::= SEQUENCE {
870 *  ... other stuff before
871 *     we_are_here SomeBaseType  <<<<< dealing with this thing
872 * --- other stuff after
873 ************************/
874 static void
875 basetype_SEQSET (AsnIterPtr iter, AsnTypePtr final_atp)
876 {
877    CharPtr         freetype;
878    CharPtr         valslot;
879    Boolean         has_default = FALSE;
880    CharPtr         valslotdefine;
881 
882 
883    valslot = AsnCodeWhichValSlot (final_atp->type, &valslotdefine);
884    switch (iter->mode) {
885    case ITER_ASSIGN:
886    case ITER_CHECK_LIST:
887       break;
888    case ITER_OBJECTS:
889       if (iter -> atp -> optional && iter -> do_opt_bits &&
890           StringCmp (valslot, "ptrvalue") != 0) {
891          AsnCodeGenBitDefines(iter);
892       }
893       StringCpy (iter->buf2, AsnCodeLookupType (final_atp));
894       sprintf (iter->buf, "       %s ",
895                iter->buf2);
896       AsnIterTakeBuf (iter);
897       sprintf (iter->buf, "  %s;\n",
898                iter->stack->slot_name);
899       AsnIterTakeBuf (iter);
900       if (AsnCodeIsEnumType(iter->atp))
901       {
902          AsnCodeGenEnumDefines (iter);
903       }
904       break;
905    case ITER_NEW:
906       if (iter->atp->defaultvalue != NULL) {
907          if (StringCmp (valslot, "boolvalue") == 0
908              || StringCmp (valslot, "intvalue") == 0) {
909             sprintf (iter->buf2, "%d",
910                      (int) iter->atp->defaultvalue->intvalue);
911             has_default = TRUE;
912          } else if (StringCmp (valslot, "ptrvalue") == 0) {
913             sprintf (iter->buf2, "\"%s\"",
914                      (CharPtr) iter->atp->defaultvalue->name);
915             has_default = TRUE;
916          } else if (StringCmp (valslot, "realvalue") == 0) {
917 #ifdef OS_MAC
918             /* sprintf (iter->buf2, "%lf",
919                      (double) iter->atp->defaultvalue->realvalue); */
920             sprintf (iter->buf2, "%LG",
921                      (double) iter->atp->defaultvalue->realvalue);
922 #else
923             sprintf (iter->buf2, "%lg",
924                      (double) iter->atp->defaultvalue->realvalue);
925 #endif
926             has_default = TRUE;
927          }
928          if (has_default) {
929             sprintf (iter->buf, "        ptr -> %s = %s;\n",
930                      iter->stack->slot_name,
931                      iter->buf2);
932             AsnIterTakeBuf (iter);
933          }
934       }
935       break;
936    case ITER_FREE:
937       freetype = AsnCodeNeedFree (final_atp);
938       if (freetype != NULL) {
939          sprintf (iter->buf, "        %s(ptr -> %s);\n",
940                   freetype, iter->stack->slot_name);
941          AsnIterTakeBuf (iter);
942       }
943       break;
944    case ITER_READ:
945 #ifdef EXTRA_READIF_BUG
946       if (AsnCode_RightOuter (iter, iter->stack->outer) == 1) {
947          sprintf (iter->buf, "   atp = AsnReadId(aip,amp, atp);\n");
948          AsnIterTakeBuf (iter);
949       }
950 #endif
951       sprintf (iter->buf, "   if (atp == %s) {\n",      /* } */
952                GenerateTypeFromStack (iter, TRUE));
953       AsnIterTakeBuf (iter);
954       sprintf (iter->buf,
955             "    if ( AsnReadVal(aip, atp, &av) <= 0) {\ngoto erret;\n}\n");
956       AsnIterTakeBuf (iter);
957       sprintf (iter->buf, "      ptr -> %s = ",
958                iter->stack->slot_name);
959       AsnIterTakeBuf (iter);
960       sprintf (iter->buf, "av.%s;\n",
961                AsnCodeWhichValSlot (final_atp->type, NULL));
962       AsnIterTakeBuf (iter);
963 
964       if (iter -> atp -> optional && iter -> do_opt_bits &&
965           StringCmp (valslot, "ptrvalue") != 0 &&
966           iter -> stack -> outer -> opt_count <= 31){
967          sprintf (iter->buf, "      ptr -> OBbits__ |= 1<<%d;\n",
968                   iter->stack -> outer -> opt_count++);
969          AsnIterTakeBuf (iter);
970       }
971 
972 
973       sprintf (iter->buf, "   atp = AsnReadId(aip,amp, atp);\n");
974       AsnIterTakeBuf (iter);
975        /* { */ sprintf (iter->buf, "   }\n");
976       AsnIterTakeBuf (iter);
977       break;
978    case ITER_WRITE:
979       if (StringCmp (valslot, "ptrvalue") == 0) {
980          sprintf (iter->buf,
981                   "   if (ptr -> %s != NULL) {\n",      /* } */
982                   iter->stack->slot_name);
983          AsnIterTakeBuf (iter);
984       } else if (iter -> atp -> optional && iter -> do_opt_bits &&
985                  iter -> stack -> outer -> opt_count <=31 ){
986          sprintf (iter->buf, 
987                   "if (ptr -> %s || (ptr -> OBbits__ & (1<<%d) )){", /* } */
988                   iter->stack->slot_name, iter->stack -> outer -> opt_count++);
989          AsnIterTakeBuf (iter);
990       }
991 
992       sprintf (iter->buf, "   av.%s = ptr -> %s;\n",
993                valslot, iter->stack->slot_name);
994       AsnIterTakeBuf (iter);
995       sprintf (iter->buf,
996                "   retval = AsnWrite(aip, %s,  &av);\n",
997                GenerateTypeFromStack (iter, TRUE));
998 
999       AsnIterTakeBuf (iter);
1000 
1001       if (StringCmp (valslot, "ptrvalue") == 0 ||
1002           (iter -> atp -> optional && iter -> do_opt_bits &&
1003            iter -> stack -> outer -> opt_count <= 31)) {
1004          sprintf (iter->buf,
1005                    /* { */ "   }\n");
1006          AsnIterTakeBuf (iter);
1007       }
1008 
1009 
1010    }
1011 
1012 }
1013 
1014 /***************************
1015 *
1016 * basetype_CHOICE(iter,final_atp)
1017 *
1018 * We have a basetype within  a CHOICE ::=
1019 *
1020 *  such as:
1021 *
1022 *    ParentSeq ::= CHOICE {
1023 *  ... other stuff before
1024 *     we_are_here SomeBaseObject  <<<<< dealing with this thing
1025 * --- other stuff after
1026 ************************/
1027 static void
1028 basetype_CHOICE (AsnIterPtr iter, AsnTypePtr final_atp)
1029 {
1030    CharPtr         freetype;
1031    CharPtr         valslot;
1032    CharPtr         valslotdefine;
1033    Boolean         in_setof_choice;
1034    AsnCodeNodePtr  which_node = AsnCode_RightChoiceNode (iter,
1035                                       iter->stack->outer, &in_setof_choice);
1036 
1037    valslot = AsnCodeWhichValSlot (final_atp->type, &valslotdefine);
1038    switch (iter->mode) {
1039    case ITER_ASSIGN:
1040    case ITER_CHECK_LIST:
1041    case ITER_NEW:
1042       break;
1043    case ITER_OBJECTS:           /* no objects, as slot absorbed within
1044                                  * data.ptrvalue of ValNode, used for Choice
1045                                  * but need symbolic #defines for choice */
1046       sprintf (iter->buf, "#define %s_%s %d\n",
1047                which_node->obj_name,
1048                iter->stack->slot_name,
1049                AsnCode_RightOuter (iter, iter->stack->outer)->slot_count);
1050       AsnIterTakeBuf (iter);
1051       if (AsnCodeIsEnumType(iter->atp))
1052       {
1053          AsnCodeGenEnumDefines(iter);
1054       }
1055       break;
1056    case ITER_FREE:
1057       freetype = AsnCodeNeedFree (final_atp);
1058       if (freetype != NULL) {
1059          AsnCodeIterCaseInChoice (iter);
1060          sprintf (iter->buf, "        %s(anp -> data.%s);\nbreak;\n",
1061                   freetype, valslot);
1062          AsnIterTakeBuf (iter);
1063       }
1064       break;
1065    case ITER_WRITE:
1066       AsnCodeIterCaseInChoice (iter);
1067       sprintf (iter->buf,
1068                "av.%s = anp->data.%s;\nretval = AsnWrite(aip, %s, &av);\n",
1069                valslot, valslot, GenerateTypeFromStack (iter, TRUE));
1070       AsnIterTakeBuf (iter);
1071       sprintf (iter->buf, "            break;\n");
1072       AsnIterTakeBuf (iter);
1073       break;
1074    case ITER_READ:
1075       if (AsnCode_RightOuter (iter, iter->stack->outer)->slot_count != 1) {
1076          sprintf (iter->buf,
1077                   " else ");
1078          AsnIterTakeBuf (iter);
1079       }
1080       if ((iter -> acip->debug_level) > 3) {
1081          AsnCodeShowStack (iter);
1082          fflush ((iter -> acip -> bug_fp));
1083       }
1084       sprintf (iter->buf,
1085                "if (atp == %s) {\n",    /* } */
1086                GenerateTypeFromStack (iter, TRUE));
1087       AsnIterTakeBuf (iter);
1088       sprintf (iter->buf, "      choice = %s_%s;\n",
1089                which_node->obj_name,
1090                iter->stack->slot_name);
1091       AsnIterTakeBuf (iter);
1092       sprintf (iter->buf,
1093                "if (AsnReadVal(aip, atp, &av) <= 0) {\ngoto erret;\n}\n");
1094       AsnIterTakeBuf (iter);
1095          sprintf (iter->buf, "        anp->data.%s = av.%s;\n",
1096                   valslot, valslot);
1097       AsnIterTakeBuf (iter);
1098        /* { */ sprintf (iter->buf, "  }\n   ");
1099       AsnIterTakeBuf (iter);
1100       break;
1101    }
1102 
1103 }
1104 
1105 
1106 /***************************
1107 *
1108 * basetype_SETOF(iter,final_atp,recur_level)
1109 *
1110 * We have a SET OF user object within  a CHOICE ::=  or a SEQUENCE ::=
1111 *
1112 *  such as:
1113 *
1114 *    ParentSeq ::= CHOICE {
1115 *          or
1116 *    ParentSeq ::= SEQUENCE {
1117 *  ... other stuff before
1118 *     we_are_here SETOF SomeUserObject  <<<<< dealing with this thing
1119 * --- other stuff after
1120 ************************/
1121 static void
1122 basetype_SETOF (AsnIterPtr iter, AsnTypePtr final_atp, Int2 recur_level)
1123 {
1124    userobj_and_basetype_SETOF (iter, final_atp, recur_level,
1125                                ASNITER_BASE_TYPE);
1126 }
1127 
1128 
1129 /***************************
1130 *
1131 * AsnCode_basetype(iter)
1132 *
1133 ****************************/
1134 static void
1135 AsnCode_basetype (struct struct_asniter PNTR iter)
1136 {
1137    Int2            recur_level = AsnCodeIterRecurLevel (iter);
1138 
1139    switch (recur_level) {
1140    case RECUR_OUTER:
1141       if (iter->mode == ITER_OBJECTS && AsnCodeIsEnumType(iter->atp)) {
1142          AsnCodeGenEnumDefines(iter);
1143       }
1144       break;
1145    case RECUR_SEQSET:           /* basetype in a SEQUENCE or SET */
1146       basetype_SEQSET (iter, iter->atp);
1147       break;
1148    case RECUR_CHOICE:           /* basetype in a CHOICE */
1149       basetype_CHOICE (iter, iter->atp);
1150       break;
1151    case RECUR_SETOF_OUTER:
1152 /*  as     SetOfInteger ::= SET OF INTEGER */
1153                         AsnCode_SETOF_base_or_user (iter, ASNITER_BASE_TYPE);
1154       break;
1155    case RECUR_SETOF_SEQSET:
1156    case RECUR_SETOF_CHOICE:
1157 
1158       /*
1159        * basetypes within SETOF in parental SEQUENCE or CHOICE the name is at
1160        * the one level outer
1161        */
1162       basetype_SETOF (iter, iter->stack->outer->atp, recur_level);
1163       break;
1164    }
1165 }
1166 
1167 
1168 
1169 /***************************
1170 *
1171 * AsnCode_choiceend(iter)
1172 *
1173 *
1174 * action the same at all RecurLevels
1175 *
1176 ****************************/
1177 static void
1178 AsnCode_choiceend (struct struct_asniter PNTR iter)
1179 {
1180    Boolean         in_setof_choice;
1181    AsnCodeNodePtr  which_node = AsnCode_RightChoiceNode (iter,
1182                                              iter->stack, &in_setof_choice);
1183    char            setof_buf[120];
1184 
1185    if ((iter -> acip->debug_level) >= 2) {
1186       fprintf ((iter -> acip -> bug_fp), "  In AsnCode_choiceend, ASSIGN mode %dat  type = (%d)\n",
1187                iter->mode, (int) iter->atp->isa);
1188    }
1189    switch (iter->mode) {
1190    case ITER_ASSIGN:
1191       break;
1192    case ITER_CHECK_LIST:
1193       break;
1194    case ITER_OBJECTS:
1195 
1196       /*--------- PROTO TYPES ----------*/
1197       if (in_setof_choice) {
1198          sprintf (setof_buf, "%s_element", which_node->obj_name);
1199          AsnCodeGenerateProtos (iter, setof_buf, TRUE);
1200       } else {
1201          AsnCodeGenerateProtos (iter, which_node->obj_name, TRUE);
1202       }
1203       AsnCodeFinishedRoutine (iter);
1204       if (in_setof_choice) {
1205          AsnCodeNewRoutine (iter);
1206          sprintf (iter->buf,
1207                   "typedef ValNodePtr %sPtr;\n",
1208                   which_node->obj_name);
1209          AsnIterTakeBuf (iter);
1210          sprintf (iter->buf,
1211                   "typedef ValNode %s;\n",
1212                   which_node->obj_name);
1213          AsnIterTakeBuf (iter);
1214 
1215          AsnCodeGenerateProtos (iter, which_node->obj_name, TRUE);
1216          AsnCodeFinishedRoutine (iter);
1217       };
1218       break;
1219 
1220    case ITER_NEW:               /* valNode */
1221       break;
1222    case ITER_FREE:
1223        /* { { */ sprintf (iter->buf, "    }\n\
1224         return MemFree(anp);\n}\n");
1225 
1226       AsnIterTakeBuf (iter);
1227       AsnCodeFinishedRoutine (iter);
1228       if (in_setof_choice) {
1229          AsnCodeNewRoutine (iter);
1230          AsnCodeFunctionHeader (iter, "Free",
1231                                 which_node->obj_name);
1232          sprintf (iter->buf,
1233                   "ValNodePtr anp)\n{\n\n" /* } */ );
1234          AsnIterTakeBuf (iter);
1235          sprintf (iter->buf, "\
1236              if (anp == NULL) {\n\
1237         return NULL;\n}\n\
1238 \n");
1239          AsnIterTakeBuf (iter);
1240          sprintf (iter->buf,
1241           " AsnGenericChoiceSeqOfFree(anp, (AsnOptFreeFunc) %s_elementFree);",
1242                   which_node->obj_name);
1243          AsnIterTakeBuf (iter);
1244 
1245           /* { { */ sprintf (iter->buf, "    \n\
1246         return NULL;\n}\n");
1247 
1248          AsnIterTakeBuf (iter);
1249 
1250          AsnCodeFinishedRoutine (iter);
1251       }
1252       break;
1253    case ITER_READ:
1254 
1255       /* { */
1256       sprintf (iter->buf, "\
1257     anp->choice = choice;\n\
1258     if (func != NULL)\n\
1259     {\n\
1260         anp->data.ptrvalue = (* func)(aip, atp);\n\
1261                                 if (aip -> io_failure) goto erret;\n\n\
1262         if (nullIsError && anp->data.ptrvalue == NULL) {\n\
1263             goto erret;\n}\n\
1264     }\n\n\
1265 ret:\n\
1266         AsnUnlinkType(orig);       /* unlink local tree */\n\
1267         return anp;\n\n\
1268 erret:\n\
1269     anp = MemFree(anp);\n\
1270                 aip -> io_failure = TRUE;\n\
1271     goto ret;\n\
1272 }\n");
1273 
1274 
1275       AsnIterTakeBuf (iter);
1276 
1277       AsnCodeFinishedRoutine (iter);
1278       if (in_setof_choice) {
1279          AsnCodeNewRoutine (iter);
1280          AsnCodeFunctionHeader (iter, "AsnRead", which_node->obj_name);
1281          sprintf (iter->buf,
1282                   "AsnIoPtr aip, AsnTypePtr orig)\n{\n \n\n");  /* } */
1283          AsnIterTakeBuf (iter);
1284 
1285          sprintf (iter->buf, "\
1286         DataVal av;\n\
1287         AsnTypePtr atp;\n\
1288     ValNodePtr anp;\n\
1289     Uint1 choice;\n\
1290     Boolean isError = FALSE;\n\
1291     AsnReadFunc func;\n\n");
1292          AsnIterTakeBuf (iter);
1293          AsnCodeFunctionReadFuncChoiceStart (iter, TRUE);       /* making extra SET of
1294                                                                  * header */
1295 
1296          sprintf (iter->buf, "\
1297            anp =\n\
1298                AsnGenericChoiceSeqOfAsnRead(aip, amp, atp, &isError,\n\
1299                  (AsnReadFunc) %s_elementAsnRead, (AsnOptFreeFunc) %s_elementFree);\n\
1300                 if (isError) \ngoto erret;\n",
1301                   which_node->obj_name,
1302                   which_node->obj_name);
1303          AsnIterTakeBuf (iter);
1304 
1305          sprintf (iter->buf, "\
1306     \n\n\
1307 ret:\n\
1308         AsnUnlinkType(orig);       /* unlink local tree */\n\
1309         return anp;\n\n\
1310 erret:\n\
1311                 aip -> io_failure = TRUE;\n\
1312     goto ret;\n\
1313 }\n");
1314          AsnIterTakeBuf (iter);
1315 
1316 
1317          AsnCodeFinishedRoutine (iter);
1318       }
1319       break;
1320    case ITER_WRITE:
1321 
1322       /* { { */
1323       sprintf (iter->buf, "\
1324           }\n\
1325     if (writetype != NULL) {\n\
1326         retval = (* func)(pnt, aip, writetype);   /* write it out */\n}\n\
1327         if (!retval) {\ngoto erret;\n}\n        retval = TRUE;\n\nerret:\n\
1328         AsnUnlinkType(orig);       /* unlink local tree */\n\
1329         return retval;\n\
1330 }\n");
1331 
1332       AsnIterTakeBuf (iter);
1333       AsnCodeFinishedRoutine (iter);
1334       if (in_setof_choice) {
1335          AsnCodeNewRoutine (iter);
1336          AsnCodeNewRoutine (iter);
1337          AsnCodeFunctionHeader (iter, "AsnWrite", which_node->obj_name);
1338          sprintf (iter->buf,
1339                   "ValNodePtr anp, AsnIoPtr aip, AsnTypePtr orig)\n\n{\n");     /* } */
1340 
1341          AsnIterTakeBuf (iter);
1342          sprintf (iter->buf, "\
1343         DataVal av;\n\
1344         AsnTypePtr atp, writetype = NULL;\n\
1345     Pointer pnt;\n\
1346     AsnWriteFunc func = NULL;\n\
1347     Boolean retval = FALSE;\n\n");
1348          AsnIterTakeBuf (iter);
1349          AsnCodeFunctionWriteFuncChoiceStart (iter, TRUE);      /* extra call */
1350 
1351          sprintf (iter->buf,
1352                   "      retval = AsnGenericChoiceSeqOfAsnWrite(anp, \n\
1353          (AsnWriteFunc) %s_elementAsnWrite, aip, atp, %s);",
1354                   which_node->obj_name,
1355                   GenerateTypeFromStack (iter, TRUE));
1356          AsnIterTakeBuf (iter);
1357 
1358 
1359 
1360           /* {    */ sprintf (iter->buf, "\
1361 \nerret:\n\
1362         AsnUnlinkType(orig);       /* unlink local tree */\n\
1363         return retval;\n\
1364 }\n");
1365 
1366          AsnIterTakeBuf (iter);
1367 
1368 
1369          AsnCodeFinishedRoutine (iter);
1370       }
1371       break;
1372    }
1373 
1374 }
1375 
1376 /***************************
1377 *
1378 * AsnCode_choicestart(iter)
1379 * ****************************/
1380 
1381 static void
1382 AsnCode_choicestart (struct struct_asniter PNTR iter)
1383 {
1384    Int2            recur_level = AsnCodeIterRecurLevel (iter);
1385    DataVal         auto_hint;
1386    Boolean         in_setof_choice;
1387    AsnCodeNodePtr  which_node = AsnCode_RightChoiceNode (iter,
1388                                              iter->stack, &in_setof_choice);
1389    char            setof_buf[120];
1390    CharPtr         func_name = which_node->obj_name;
1391 
1392    if ((iter -> acip->debug_level) > 3) {
1393       fprintf ((iter -> acip -> bug_fp), "  In AsnCode_choicestart,  type = (%d)\n",
1394                (int) iter->atp->isa);
1395    }
1396    if (recur_level != RECUR_OUTER
1397        && recur_level != RECUR_SETOF_OUTER) {
1398       /*------if not at outer level, is internal and pseudo-user---*/
1399       AsnCodeIterCall (iter, iter->userobj, iter->atp,
1400                        ASNITER_Pseudo_USER_TYPE);
1401    }
1402    if (in_setof_choice) {
1403       sprintf (setof_buf, "%s_element", func_name);
1404       func_name = setof_buf;
1405    }
1406    if (iter->mode == ITER_ASSIGN) {
1407       /********************
1408       *
1409       * choicestart_ASSIGN
1410       *
1411       * At the start of a CHOICE :: and seeing if a name
1412       * must be assigned. (mainly for #defines....
1413       *
1414       * If at anything but top level and isa is zero, is an
1415       * unnamed sequence, so it must
1416       **********************/
1417 
1418       switch (recur_level) {
1419       case RECUR_OUTER:
1420          break;
1421       case RECUR_SETOF_OUTER:
1422          /*-treat SET OF CHOICE specially */
1423          if ((iter -> acip->debug_level) >= 2)
1424             AsnCodeShowDepth (iter);
1425 
1426          if ((iter -> acip->debug_level) > 0) {
1427             fprintf ((iter -> acip -> bug_fp), "  In AsnCode_choicestart, ASSIGN mode at %s, type = (%d)\n",
1428                      TESTNIL (func_name), (int) iter->atp->isa);
1429             if (iter->atp->isa == 0) {
1430                fprintf ((iter -> acip -> bug_fp), "TRY NAME: %s_choice\n", TESTNIL (func_name));
1431             }
1432          }
1433          if (iter->atp->isa == 0) {
1434             sprintf (iter->buf, "%s_choice", func_name);
1435             auto_hint.ptrvalue = StringSave (iter->buf);
1436             AsnOptionNew (&(iter->atp->hints),
1437                           OP_NCBIASNTOOL, OP_SLOT_NAME, auto_hint,
1438                           Nlm_MemFree);
1439             sprintf (iter->buf, "%s_choice", func_name);
1440             auto_hint.ptrvalue = StringSave (iter->buf);
1441             AsnOptionNew (&(iter->atp->hints),
1442                           OP_NCBIASNTOOL, OP_OBJ_NAME, auto_hint,
1443                           Nlm_MemFree);
1444          }
1445          break;
1446       case RECUR_SEQSET:
1447       case RECUR_CHOICE:
1448       case RECUR_SETOF_SEQSET:
1449       case RECUR_SETOF_CHOICE:
1450          if ((iter -> acip->debug_level) >= 2)
1451             AsnCodeShowDepth (iter);
1452 
1453          if ((iter -> acip->debug_level) > 0) {
1454             fprintf ((iter -> acip -> bug_fp), "  In AsnCode_choicestart, ASSIGN mode at %s, type = (%d)\n",
1455                      TESTNIL (func_name), (int) iter->atp->isa
1456                );
1457             if (iter->atp->isa == 0) {
1458                fprintf ((iter -> acip -> bug_fp), "TRY NAME: %s_%s\n",
1459                       TESTNIL (func_name), TESTNIL (which_node->slot_name));
1460             }
1461          }
1462          if (iter->atp->isa == 0) {
1463             sprintf (iter->buf, "%s_%s",
1464                      func_name, which_node->slot_name);
1465             auto_hint.ptrvalue = StringSave (iter->buf);
1466             AsnOptionNew (&(iter->atp->hints),
1467                           OP_NCBIASNTOOL, OP_SLOT_NAME, auto_hint,
1468                           Nlm_MemFree);
1469             sprintf (iter->buf, "%s_%s",
1470                      func_name, which_node->slot_name);
1471             auto_hint.ptrvalue = StringSave (iter->buf);
1472             AsnOptionNew (&(iter->atp->hints),
1473                           OP_NCBIASNTOOL, OP_OBJ_NAME, auto_hint,
1474                           Nlm_MemFree);
1475          }
1476       }
1477    } else {
1478       switch (iter->mode) {
1479       case ITER_ASSIGN:
1480          break;
1481       case ITER_CHECK_LIST:
1482          break;
1483       case ITER_OBJECTS:
1484 
1485          /*
1486           * ValNode, but need to match from with choice end because of
1487           * #defines and prototype generation.
1488           */
1489          AsnCodeNewRoutine (iter);
1490          if (iter->atp->isa == 0) {
1491             sprintf (iter->buf, "\n#ifdef NLM_GENERATED_CODE_PROTO\n\n");
1492             AsnIterTakeBuf (iter);
1493          }
1494          sprintf (iter->buf,
1495                   "typedef ValNodePtr %sPtr;\n",
1496                   func_name);
1497          AsnIterTakeBuf (iter);
1498          sprintf (iter->buf,
1499                   "typedef ValNode %s;\n",
1500                   func_name);
1501          AsnIterTakeBuf (iter);
1502          if (iter->atp->isa == 0) {
1503             sprintf (iter->buf, "\n#endif /* NLM_GENERATED_CODE_PROTO */\n\n");
1504             AsnIterTakeBuf (iter);
1505          }
1506          break;
1507       case ITER_NEW:            /* ValNode */
1508          break;
1509       case ITER_FREE:
1510          AsnCodeNewRoutine (iter);
1511          AsnCodeFunctionHeader (iter, "Free", func_name);
1512          sprintf (iter->buf,
1513                   "ValNodePtr anp)\n{\n   Pointer pnt;\n\n" /* } */ );
1514          AsnIterTakeBuf (iter);
1515          sprintf (iter->buf, "\
1516              if (anp == NULL) {\n\
1517         return NULL;\n}\n\
1518 \n\
1519     pnt = anp->data.ptrvalue;\n\
1520     switch (anp->choice)\n\
1521     {\n        default:\nbreak;\n");    /* } */
1522          AsnIterTakeBuf (iter);
1523          break;
1524       case ITER_READ:
1525          AsnCodeNewRoutine (iter);
1526          AsnCodeFunctionHeader (iter, "AsnRead", func_name);
1527          sprintf (iter->buf,
1528                   "AsnIoPtr aip, AsnTypePtr orig)\n{\n");       /* } */
1529          AsnIterTakeBuf (iter);
1530 
1531          sprintf (iter->buf, "\
1532         DataVal av;\n\
1533         AsnTypePtr atp;\n\
1534     ValNodePtr anp;\n\
1535     Uint1 choice;\n\
1536     Boolean isError = FALSE;\n\
1537                 Boolean nullIsError = FALSE;\n\
1538     AsnReadFunc func;\n\n");
1539          AsnIterTakeBuf (iter);
1540          AsnCodeFunctionReadFuncChoiceStart (iter, FALSE);
1541 
1542          break;
1543       case ITER_WRITE:
1544          AsnCodeNewRoutine (iter);
1545          AsnCodeFunctionHeader (iter, "AsnWrite", func_name);
1546          sprintf (iter->buf,
1547                   "%sPtr anp, AsnIoPtr aip, AsnTypePtr orig)\n\n{\n",
1548                   func_name);   /* } */
1549 
1550          AsnIterTakeBuf (iter);
1551          sprintf (iter->buf, "\
1552         DataVal av;\n\
1553         AsnTypePtr atp, writetype = NULL;\n\
1554     Pointer pnt;\n\
1555     AsnWriteFunc func = NULL;\n\
1556     Boolean retval = FALSE;\n\n");
1557          AsnIterTakeBuf (iter);
1558          AsnCodeFunctionWriteFuncChoiceStart (iter, FALSE);
1559 
1560          sprintf (iter->buf, "\
1561     pnt = anp->data.ptrvalue;\n\
1562     switch (anp->choice)\n\
1563     {\n");                      /* } */
1564          AsnIterTakeBuf (iter);
1565 
1566       }
1567 
1568    }
1569 
1570 }
1571 
1572 /*************************************
1573 *
1574 *   AsnIterGenericDie301(iter)
1575 *
1576 ****************************************/
1577 
1578 static void
1579 AsnIterGenericDie301 (struct struct_asniter PNTR iter)
1580 {
1581    ErrPost (CTX_NCBIASN1, 101, "Type for %s is < 301 (%d)",
1582             iter->atp->name, (int) (iter->atp->type->isa));
1583    exit (1);
1584 }
1585 
1586 
1587 
1588 
1589 
1590 
1591 
1592 /***************************
1593 *
1594 * AsnCode_SETOF_base_or_user(iter,base_or_user)
1595 *
1596 ****************************/
1597 static void
1598 AsnCode_SETOF_base_or_user (AsnIterPtr iter, Int2 base_or_user)
1599 {
1600    CharPtr         valslotdefine;
1601    CharPtr         valslot;
1602    Int2            real_type;
1603    AsnTypePtr      final_atp;
1604    Char            asntypename[128];
1605 
1606    sprintf (asntypename,
1607             "%s",
1608             GenerateTypeFromStack (iter, FALSE));
1609          real_type = AsnCodeFinalType (iter, iter->atp, &final_atp);
1610    if (base_or_user == ASNITER_BASE_TYPE) {
1611       if (AsnCodeIsEnumType (final_atp)) {
1612          valslot = "intvalue";
1613          valslotdefine = defint;
1614       } else {
1615          if (final_atp->type->isa == SETOF_TYPE ||
1616              final_atp->type->isa == SEQOF_TYPE) {
1617             valslot = AsnCodeWhichValSlot
1618                (((AsnTypePtr) final_atp->branch)->type,
1619                 &valslotdefine);
1620          } else {
1621             valslot = AsnCodeWhichValSlot
1622                ((AsnTypePtr) final_atp->type, &valslotdefine);
1623          }
1624       }
1625    }
1626       switch (iter->mode) {
1627       case ITER_ASSIGN:
1628       case ITER_CHECK_LIST:
1629          break;
1630       case ITER_OBJECTS:
1631          AsnCodeNewRoutine (iter);
1632          AsnCodeHeader (iter, iter->stack->outer -> obj_name);
1633          if (base_or_user == ASNITER_BASE_TYPE ||
1634              iter->stack->outer -> atp -> branch == NULL ||
1635              AsnCodeIsReallyChoice(iter -> atp)) {
1636             sprintf (iter->buf, "typedef ValNode %s;\n",
1637                      iter->stack->outer->obj_name);
1638             AsnIterTakeBuf (iter);
1639             sprintf (iter->buf, "typedef ValNodePtr %sPtr;\n",
1640                      iter->stack->outer->obj_name);
1641             AsnIterTakeBuf (iter);
1642             sprintf (iter->buf, "#define %sNew() ValNodeNew(NULL) \n",
1643                      iter->stack->outer->obj_name);
1644             AsnIterTakeBuf (iter);
1645             if (AsnOptionGet (iter->atp->hints,
1646                               OP_NCBIASNTOOL, OP_MAKE_LINKED, NULL) != NULL) {
1647                sprintf (iter->buf, "        struct struct_%s PNTR next;\n",
1648                         iter->stack->outer->obj_name);
1649                AsnIterTakeBuf (iter);
1650             }
1651          } else {
1652             AsnTypePtr atpb = (AsnTypePtr) iter->stack->outer -> atp -> branch;
1653             Char local_buf[60];
1654 
1655             AsnCodeCleanName (atpb -> type->name,
1656                               local_buf, CLEAN_FOR_SLOT, iter -> acip -> maxDefineLength);
1657             sprintf (iter->buf, "typedef struct struct_%s %s;\n",
1658                      local_buf, iter->stack->outer->obj_name);
1659             AsnIterTakeBuf (iter);
1660             sprintf (iter->buf, "typedef struct struct_%s PNTR %sPtr;\n",
1661                      local_buf, iter->stack->outer->obj_name);
1662             AsnIterTakeBuf (iter);
1663             sprintf (iter->buf, "#define %sNew() %sNew() \n",
1664                      iter->stack->outer->obj_name, local_buf);
1665             AsnIterTakeBuf (iter);
1666          }
1667          AsnCodeGenerateProtos(iter, iter->stack->outer->obj_name, FALSE);
1668          break;
1669       case ITER_NEW:
1670 /*  ValNode */
1671          break;
1672       case ITER_FREE:
1673          AsnCodeNewRoutine (iter);
1674          AsnCodeFunctionHeader (iter, "Free", iter->stack->outer -> obj_name);
1675          sprintf (iter->buf,
1676                   "%sPtr ptr)\n{\n\n    if(ptr == NULL) {\n\
1677         return NULL;\n}\n", iter->stack->outer->obj_name);      /* } */
1678          AsnIterTakeBuf (iter);
1679 
1680 
1681          if (base_or_user == ASNITER_BASE_TYPE) {
1682             sprintf (iter->buf, "     AsnGenericBaseSeqOfFree(ptr," );
1683             AsnIterTakeBuf (iter);
1684             sprintf (iter->buf, "%s);\n",
1685                      valslotdefine);
1686             AsnIterTakeBuf (iter);
1687          } else {
1688             /* user obj here */
1689 
1690             if (AsnCodeIsReallyChoice (iter->atp)) {
1691 
1692                sprintf (iter->buf,
1693             "      AsnGenericChoiceSeqOfFree(ptr," );
1694                AsnIterTakeBuf (iter);
1695             } else {
1696 
1697                sprintf (iter->buf, "      AsnGenericUserSeqOfFree(ptr, " );
1698                AsnIterTakeBuf (iter);
1699             }
1700 
1701             sprintf (iter->buf, " (AsnOptFreeFunc) %sFree);\n",
1702                      AsnCodeCleanName (final_atp->name,
1703                                        iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
1704             AsnIterTakeBuf (iter);
1705          }
1706 
1707          sprintf (iter->buf,
1708                   /* { */ "return NULL;\n}\n");
1709          AsnIterTakeBuf (iter);
1710          AsnCodeFinishedRoutine (iter);
1711          break;
1712       case ITER_READ:
1713          AsnCodeNewRoutine (iter);
1714          AsnCodeFunctionHeader (iter, "AsnRead", iter->stack->outer -> obj_name);
1715          sprintf (iter->buf,
1716                   "AsnIoPtr aip, AsnTypePtr orig)\n\
1717 {\n\
1718 DataVal av;\n\
1719         AsnTypePtr atp;\n\
1720     Boolean isError = FALSE;\n\
1721         AsnReadFunc func;\n\
1722     %sPtr ptr;\n\n", iter->stack->outer->obj_name);     /* } */
1723          AsnIterTakeBuf (iter);
1724 
1725          AsnCodeFunctionReadFuncSeqStart (iter, TRUE);
1726          sprintf (iter->buf, "      ptr  = ");
1727          AsnIterTakeBuf (iter);
1728          if (base_or_user == ASNITER_BASE_TYPE) {
1729             sprintf (iter->buf,
1730                      "AsnGenericBaseSeqOfAsnRead(aip, amp, atp, %s, &isError);\n ",
1731                      valslotdefine);
1732             AsnIterTakeBuf (iter);
1733          } else {
1734             sprintf (iter->buf,
1735                      "AsnGeneric%sSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) ",
1736                      AsnCodeIsReallyChoice (iter->atp) ? "Choice" : "User");
1737             AsnIterTakeBuf (iter);
1738             sprintf (iter->buf, "%sAsnRead,",
1739                      AsnCodeCleanName (final_atp->name,
1740                                        iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
1741             AsnIterTakeBuf (iter);
1742             sprintf (iter->buf,
1743                      " (AsnOptFreeFunc) ");
1744             AsnIterTakeBuf (iter);
1745             sprintf (iter->buf, "%sFree);\n",
1746                      AsnCodeCleanName (final_atp->name,
1747                                        iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
1748             AsnIterTakeBuf (iter);
1749          }
1750          sprintf (iter->buf,
1751                   "      if (isError && ptr  == NULL) {\ngoto erret;\n}\n" );
1752          AsnIterTakeBuf (iter);
1753 
1754          /* { */ sprintf (iter->buf, "\n\n\nret:\n\
1755         AsnUnlinkType(orig);       /* unlink local tree */\n\
1756         return ptr;\n\
1757 \nerret:\n\
1758                 aip -> io_failure = TRUE;\n\
1759     ptr = %sFree(ptr);\n\
1760     goto ret;\n\
1761 }\n\n", iter->stack->outer->obj_name);
1762       AsnIterTakeBuf (iter);
1763       AsnCodeFinishedRoutine (iter);
1764 
1765          break;
1766       case ITER_WRITE:
1767          AsnCodeNewRoutine (iter);
1768          AsnCodeFunctionHeader (iter, "AsnWrite", iter->stack->outer -> obj_name);
1769 
1770          sprintf (iter->buf,
1771                   "%sPtr ptr, AsnIoPtr aip, AsnTypePtr orig)\n\
1772 {\n\
1773         DataVal av;\n\
1774         AsnTypePtr atp;\n\
1775     Boolean retval = FALSE;\n\n",
1776                   iter->stack->outer->obj_name);        /* } */
1777          AsnIterTakeBuf (iter);
1778 
1779          AsnCodeFunctionWriteFuncSeqStart (iter, TRUE);
1780 
1781          if (base_or_user == ASNITER_BASE_TYPE) {
1782             sprintf (iter->buf,
1783           "     retval = AsnGenericBaseSeqOfAsnWrite(ptr, " );
1784             AsnIterTakeBuf (iter);
1785             sprintf (iter->buf, "%s",
1786                      valslotdefine);
1787             AsnIterTakeBuf (iter);
1788                sprintf (iter->buf, ", aip, atp, %s);\n",
1789                         Append_EAndPrestrip (asntypename, iter -> acip -> maxDefineLength));
1790             AsnIterTakeBuf (iter);
1791          } else {
1792             /* user obj here */
1793 
1794             if (AsnCodeIsReallyChoice (iter->atp)) {
1795 
1796                sprintf (iter->buf,
1797          "      retval = AsnGenericChoiceSeqOfAsnWrite(ptr ," );
1798                AsnIterTakeBuf (iter);
1799             } else {
1800 
1801                sprintf (iter->buf, 
1802            "      retval = AsnGenericUserSeqOfAsnWrite(ptr ," );
1803                AsnIterTakeBuf (iter);
1804             }
1805                sprintf (iter->buf, " (AsnWriteFunc) %sAsnWrite, aip, atp, %s);\n",
1806                         AsnCodeCleanName (final_atp->name,
1807                                           iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength),
1808                         Append_EAndPrestrip (asntypename, iter -> acip -> maxDefineLength));
1809             AsnIterTakeBuf (iter);
1810          }
1811 
1812 #ifdef EXTRA_READ_VAL_BUG_FROM_STRING
1813 Hey guy, this is not asncode code, but from the sprintf string below;
1814         if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {\n\
1815         goto erret;\n}\n\
1816 
1817 #endif
1818 
1819        /* { */ sprintf (iter->buf,"\
1820     retval = TRUE;\n\nerret:\n\
1821         AsnUnlinkType(orig);       /* unlink local tree */\n\
1822         return retval;\n\
1823 }\n\n");
1824       AsnIterTakeBuf (iter);
1825       AsnCodeFinishedRoutine (iter);
1826 
1827 
1828          break;
1829       }
1830 }
1831 
1832 
1833 
1834 
1835 
1836 
1837 /***************************
1838 *
1839 * AsnCode_seqend(iter)
1840 *
1841 ****************************/
1842 static void
1843 AsnCode_seqend (struct struct_asniter PNTR iter)
1844 {
1845    switch (iter->mode) {
1846       case ITER_ASSIGN:
1847       break;
1848    case ITER_CHECK_LIST:
1849       break;
1850    case ITER_OBJECTS:
1851        /* { */ sprintf (iter->buf, "} %s, PNTR %sPtr;\n",
1852                         iter->stack->obj_name, iter->stack->obj_name);
1853       AsnIterTakeBuf (iter);
1854       if (iter->atp->isa == 0) {
1855          sprintf (iter->buf, "#endif /* NLM_GENERATED_CODE_PROTO */\n");
1856          AsnIterTakeBuf (iter);
1857       }
1858       AsnCodeGenerateProtos (iter, iter->stack->obj_name, FALSE);
1859       AsnCodeFinishedRoutine (iter);
1860       break;
1861    case ITER_NEW:
1862        /* { */ sprintf (iter->buf, "    return ptr;\n\n}\n");
1863       AsnIterTakeBuf (iter);
1864       AsnCodeFinishedRoutine (iter);
1865 
1866       break;
1867    case ITER_FREE:
1868        /* { */ sprintf (iter->buf,
1869                         "return MemFree(ptr);\n}\n");
1870       AsnIterTakeBuf (iter);
1871       AsnCodeFinishedRoutine (iter);
1872       break;
1873    case ITER_READ:
1874        /* { */ sprintf (iter->buf,
1875                         "\n\
1876     if (AsnReadVal(aip, atp, &av) <= 0) {\ngoto erret;\n}\n   /* end struct */\n\
1877 \nret:\n\
1878         AsnUnlinkType(orig);       /* unlink local tree */\n\
1879         return ptr;\n\
1880 \nerret:\n\
1881                 aip -> io_failure = TRUE;\n\
1882     ptr = %sFree(ptr);\n\
1883     goto ret;\n\
1884 }\n\n", iter->stack->obj_name);
1885       AsnIterTakeBuf (iter);
1886       AsnCodeFinishedRoutine (iter);
1887       break;
1888    case ITER_WRITE:
1889        /* { */ sprintf (iter->buf,
1890                         "if (! AsnCloseStruct(aip, atp, (Pointer)ptr)) {\n\
1891         goto erret;\n}\n\
1892     retval = TRUE;\n\nerret:\n\
1893         AsnUnlinkType(orig);       /* unlink local tree */\n\
1894         return retval;\n\
1895 }\n\n");
1896       AsnIterTakeBuf (iter);
1897       AsnCodeFinishedRoutine (iter);
1898 
1899       break;
1900    }
1901 
1902 }
1903 
1904 /***************************
1905 *
1906 * AsnCode_seqstart(iter)
1907 *
1908 ****************************/
1909 static void
1910 AsnCode_seqstart (struct struct_asniter PNTR iter)
1911 {
1912    DataVal         auto_hint;
1913    Int2            recur_level = AsnCodeIterRecurLevel (iter);
1914    CharPtr         try_name = NULL, safe_name=NULL,temp;
1915    AsnCodeNodePtr  safe_node = NULL;
1916           static int      fail_count=0;
1917                 char      fail_buf[12];
1918                 
1919 
1920    if (recur_level != RECUR_OUTER
1921        && recur_level != RECUR_SETOF_OUTER) {
1922       /*------if not at outer level, is internal and pseudo-user---*/
1923       AsnCodeIterCall (iter, iter->userobj, iter->atp,
1924                        ASNITER_Pseudo_USER_TYPE);
1925    }
1926    if (iter->mode == ITER_ASSIGN) {
1927       /********************
1928       *
1929       * seqstart_ASSIGN
1930       *
1931       * At the start of a SEQUENCE :: and seeing if a name
1932       * must be assigned.
1933       *
1934       * If at anything but top level and isa is zero, is an
1935       * unnamed sequence, so it must
1936       **********************/
1937 
1938       switch (recur_level) {
1939       case RECUR_OUTER:
1940          break;
1941       case RECUR_SEQSET:
1942       case RECUR_CHOICE:
1943       case RECUR_SETOF_OUTER:
1944       case RECUR_SETOF_SEQSET:
1945       case RECUR_SETOF_CHOICE:
1946          if ((iter->acip->debug_level) >= 2)
1947             AsnCodeShowDepth (iter);
1948 
1949          if (iter->atp->isa == 0) {
1950             if (iter->stack->outer->obj_name == NULL) {
1951                try_name = iter->stack->outer->outer->obj_name;
1952             } else {
1953                try_name = iter->stack->outer->obj_name;
1954             }
1955                 for (safe_node = iter->stack; safe_node; safe_node = safe_node -> outer){
1956                         if (safe_node->obj_name){
1957                                 safe_name = StringSave(safe_node->obj_name);
1958                                 break;
1959                         }
1960                 }
1961                 if ( ! safe_node){
1962                         temp = safe_name = (char *)MemNew(30);
1963                         sprintf(fail_buf,"%d",fail_count++);
1964                         temp = StringMove(temp,"FAIL__NAME_");
1965                         temp = StringMove(temp,fail_buf);
1966                 }
1967          }
1968          if ((iter->acip->debug_level) > 0) {
1969             fprintf ((iter->acip -> bug_fp), "  In AsnCode_seqstart, ASSIGN mode at %s, type = (%d)\n",
1970                      TESTNIL (iter->atp->name), (int) iter->atp->isa
1971                );
1972             if ((iter->acip->debug_level) > 3) {
1973                AsnCodeShowStack (iter);
1974             }
1975             fprintf ((iter->acip -> bug_fp), "TRY seq NAME: %s_%s\n",
1976                      TESTNIL (try_name),
1977                      TESTNIL (  (safe_node -> obj_name)?safe_node -> obj_name:safe_name));
1978          }
1979          if (iter->atp->isa == 0) {
1980             sprintf (iter->buf, "%s_%s",
1981                      TESTNIL (try_name),
1982                      TESTNIL (  (safe_node -> obj_name)?safe_node -> obj_name:safe_name));
1983             auto_hint.ptrvalue = StringSave (iter->buf);
1984             AsnOptionNew (&(iter->atp->hints),
1985                           OP_NCBIASNTOOL, OP_SLOT_NAME, auto_hint,
1986                           Nlm_MemFree);
1987             sprintf (iter->buf, "%s_%s",
1988                      TESTNIL (try_name),
1989                      TESTNIL (  (safe_node -> slot_name)?safe_node -> slot_name:safe_name));
1990             auto_hint.ptrvalue = StringSave (iter->buf);
1991             AsnOptionNew (&(iter->atp->hints),
1992                           OP_NCBIASNTOOL, OP_OBJ_NAME, auto_hint,
1993                           Nlm_MemFree);
1994          }
1995       }
1996                 MemFree(safe_name);
1997    } else {
1998       switch (iter->mode) {     /* ITER_ASSIGN handled above */
1999       case ITER_CHECK_LIST:
2000          break;
2001       case ITER_OBJECTS:
2002          AsnCodeNewRoutine (iter);
2003          AsnCodeHeader (iter, iter->stack->obj_name);
2004          if (iter->atp->isa == 0) {
2005             sprintf (iter->buf, "\n#ifdef NLM_GENERATED_CODE_PROTO\n\n");
2006             AsnIterTakeBuf (iter);
2007          }
2008          sprintf (iter->buf, "typedef struct struct_%s {\n",
2009                   iter->stack->slot_name);      /* } */
2010          AsnIterTakeBuf (iter);
2011          if (AsnOptionGet (iter->atp->hints,
2012                            OP_NCBIASNTOOL, OP_MAKE_LINKED, NULL) != NULL) {
2013             sprintf (iter->buf, "        struct struct_%s PNTR next;\n",
2014                      iter->stack->slot_name);
2015             AsnIterTakeBuf (iter);
2016          }
2017          if (iter -> do_opt_bits){
2018                  sprintf (iter->buf, "  Uint4 OBbits__;\n");
2019                  AsnIterTakeBuf (iter);
2020         }
2021          break;
2022       case ITER_NEW:
2023          AsnCodeNewRoutine (iter);
2024          AsnCodeFunctionHeader (iter, "New", iter->stack->obj_name);
2025          sprintf (iter->buf, "void)\n{\n\
2026     %sPtr ptr = MemNew((size_t) sizeof(%s));\n\n",
2027                   iter->stack->obj_name,
2028                   iter->stack->obj_name);
2029          AsnIterTakeBuf (iter);
2030          /* } */
2031 
2032          break;
2033       case ITER_FREE:
2034          AsnCodeNewRoutine (iter);
2035          AsnCodeFunctionHeader (iter, "Free", iter->stack->obj_name);
2036          sprintf (iter->buf,
2037                   "%sPtr ptr)\n{\n\n    if(ptr == NULL) {\n\
2038         return NULL;\n}\n", iter->stack->obj_name);     /* } */
2039          AsnIterTakeBuf (iter);
2040          break;
2041       case ITER_READ:
2042          AsnCodeNewRoutine (iter);
2043          AsnCodeFunctionHeader (iter, "AsnRead", iter->stack->obj_name);
2044          sprintf (iter->buf,
2045                   "AsnIoPtr aip, AsnTypePtr orig)\n\
2046 {\n\
2047 DataVal av;\n\
2048         AsnTypePtr atp;\n\
2049     Boolean isError = FALSE;\n\
2050         AsnReadFunc func;\n\
2051     %sPtr ptr;\n\n", iter->stack->obj_name);    /* } */
2052          AsnIterTakeBuf (iter);
2053 
2054          AsnCodeFunctionReadFuncSeqStart (iter, FALSE);
2055          break;
2056       case ITER_WRITE:
2057          AsnCodeNewRoutine (iter);
2058          AsnCodeFunctionHeader (iter, "AsnWrite", iter->stack->obj_name);
2059 
2060          sprintf (iter->buf,
2061                   "%sPtr ptr, AsnIoPtr aip, AsnTypePtr orig)\n\
2062 {\n\
2063         DataVal av;\n\
2064         AsnTypePtr atp;\n\
2065     Boolean retval = FALSE;\n\n",
2066                   iter->stack->obj_name);       /* } */
2067          AsnIterTakeBuf (iter);
2068 
2069          AsnCodeFunctionWriteFuncSeqStart (iter, FALSE);
2070          break;
2071       }
2072    }
2073 }
2074 
2075 /***************************
2076 *
2077 * AsnCode_setstart(iter)
2078 *
2079 ****************************/
2080 static void
2081 AsnCode_setstart (struct struct_asniter PNTR iter)
2082 {
2083    AsnCode_seqstart (iter);     /* for now . . . */
2084 }
2085 
2086 /***************************
2087 *
2088 * AsnCode_setend(iter)
2089 *
2090 ****************************/
2091 static void
2092 AsnCode_setend (struct struct_asniter PNTR iter)
2093 {
2094    AsnCode_seqend (iter);       /* for now . . . */
2095 }
2096 
2097 
2098 /***************************
2099 *
2100 * AsnCode_under301err(iter)
2101 *
2102 ****************************/
2103 static void
2104 AsnCode_under301err (struct struct_asniter PNTR iter)
2105 {
2106 
2107    if (iter->atp->type == NULL)
2108       ErrPost (CTX_NCBIASN1, 101, "Type undef 301 error at %s < 301 (no type)",
2109                iter->atp->name);
2110    else
2111       ErrPost (CTX_NCBIASN1, 101, "Type undef 301 error at %s < 301 (%d)",
2112                iter->atp->name, (int) (iter->atp->type->isa));
2113    exit (1);
2114 
2115 
2116 }
2117 /***************************
2118 *
2119 * AsnIterNeedsNullCheck(iter,final_atp)
2120 *
2121 ***************************/
2122 Boolean
2123 AsnIterNeedsNullCheck(AsnIterPtr iter, AsnTypePtr final_atp)
2124 {
2125         return FALSE;
2126 }
2127 
2128 /***************************
2129 *
2130 * userobj_OUTER_typedefs(iter,type,has_pointer)
2131 *
2132 * Should we have prototypes as macro #defines?
2133 ***************************/
2134 static void
2135 userobj_OUTER_typedefs (AsnIterPtr iter, CharPtr type, Boolean has_pointer)
2136 {
2137    AsnCodeHeader (iter, iter->stack->obj_name);
2138    sprintf (iter->buf, "#define %s  %s\n",
2139             iter->stack->obj_name, type);
2140    AsnIterTakeBuf (iter);
2141    if (has_pointer) {
2142       sprintf (iter->buf, "#define %sPtr  %sPtr\n",
2143                iter->stack->obj_name, type);
2144       AsnIterTakeBuf (iter);
2145       /*--pseudo PROTOtypes as defines---*/
2146       sprintf (iter->buf, "#define %sFree  %sFree\n",
2147                iter->stack->obj_name, type);
2148       AsnIterTakeBuf (iter);
2149       sprintf (iter->buf, "#define %sNew  %sNew\n",
2150                iter->stack->obj_name, type);
2151       AsnIterTakeBuf (iter);
2152       sprintf (iter->buf, "#define %sAsnRead  %sAsnRead\n",
2153                iter->stack->obj_name, type);
2154       AsnIterTakeBuf (iter);
2155       sprintf (iter->buf, "#define %sAsnWrite  %sAsnWrite\n",
2156                iter->stack->obj_name, type);
2157       AsnIterTakeBuf (iter);
2158    }
2159 }
2160 
2161 /***************************
2162 *
2163 * userobj_CHECK_LIST(iter)
2164 *
2165 *  User objects are the only candidates for adding a next
2166 * slot, and only if in setof.  So regardless of whether
2167 * in SEQUENCE/SET, at OUTER level or in CHOICE, if we
2168 * have a user object in a SETOF, add the option to note need
2169 * to have a next slot.
2170 ************************/
2171 static void
2172 userobj_CHECK_LIST (AsnIterPtr iter)
2173 {
2174    AsnTypePtr      branch = iter->atp;
2175    AsnTypePtr      this_type, use_type;
2176    Int2            recur_level = AsnCodeIterRecurLevel (iter);
2177 
2178    switch (recur_level) {
2179    case RECUR_OUTER:
2180    case RECUR_SEQSET:
2181    case RECUR_CHOICE:
2182       break;                    /* no action, unless setof */
2183    case RECUR_SETOF_OUTER:
2184    case RECUR_SETOF_SEQSET:
2185    case RECUR_SETOF_CHOICE:
2186 
2187       if ((iter->acip->debug_level) >= 2)
2188          AsnCodeShowDepth (iter);
2189       if ((iter->acip->debug_level) > 0) {
2190          fprintf ((iter->acip -> bug_fp), "  In userobj CHECK LIST at %s, bag type = (%s)\n",
2191                   TESTNIL (iter->atp->name), TESTNIL (iter->atp->type->name)
2192             );
2193       }
2194       if (ISA_BASETYPE (branch->isa))
2195          return;
2196       this_type = branch->type;
2197       if (ISA_BASETYPE (this_type->isa) || this_type->isa == 0)
2198          return;
2199       if (this_type->imported) {
2200          if (this_type->type != (AsnTypePtr) NULL) {
2201             use_type = this_type->type;
2202          } else {
2203             ErrPost (CTX_NCBIASN1, 101,
2204                      "userobj CHECK LIST Unresolved imported type at %s.%s",
2205                      TESTNIL (iter->atp->name), TESTNIL (this_type->name));
2206             use_type = (AsnTypePtr) NULL;
2207          }
2208       } else {
2209          use_type = this_type;
2210       }
2211       if (use_type != NULL) {
2212          if (AsnOptionGet (use_type->hints,
2213                            OP_NCBIASNTOOL, OP_MAKE_LINKED, NULL) == NULL) {
2214 
2215             if ((iter->acip->debug_level) > 0) {
2216                fprintf ((iter->acip -> bug_fp), "userobj CHECK LIST: adding next slot for %s\n",
2217                         TESTNIL (use_type->name));
2218             }
2219             AsnOptionNew (&(use_type->hints),
2220                           OP_NCBIASNTOOL, OP_MAKE_LINKED, Dummy, NULL);
2221          }
2222       }
2223    }                            /* end switch */
2224 
2225 }
2226 
2227 /***************************
2228 *
2229 * userobj_OUTER(iter)
2230 *
2231 * We have a user object at the outer
2232 * recursion level.  This can only be if aliasing, as:
2233 *
2234 * ThisUserObject ::= ThatThing
2235 *
2236 * OBJECTS: Generally handled as a typedef.
2237 * REST:    no code, as "ThatThing" object to handle
2238 *          However, note that if ThisUserObject used, the code
2239 *          has to look up how to handle "ThatThing".
2240 *          ThatThing's type can be found with the function:
2241 *       AsnCodeFinalType (iter -> atp, &name_at_type)
2242 *       "name_at_type" is the AsnTypePointer for ThatThing.
2243 ************************/
2244 static void
2245 userobj_OUTER (AsnIterPtr iter)
2246 {
2247    AsnTypePtr      name_at_type;
2248    Int2            real_type;
2249 
2250    if (iter->mode == ITER_OBJECTS) {    /* other modes, no action */
2251 
2252       real_type = AsnCodeFinalType (iter, iter->atp, &name_at_type);
2253       AsnCodeCleanName (name_at_type->name, iter->buf2, BUFF, iter -> acip -> maxDefineLength);
2254       switch (real_type) {
2255       case ENUM_TYPE:
2256          userobj_OUTER_typedefs (iter, "Int2", FALSE);
2257          break;
2258 
2259       case SEQ_TYPE:
2260       case SET_TYPE:
2261          userobj_OUTER_typedefs (iter, iter->buf2, TRUE);
2262          break;
2263       case SEQOF_TYPE:
2264       case SETOF_TYPE:
2265       case CHOICE_TYPE:
2266          userobj_OUTER_typedefs (iter, "ValNode", TRUE);
2267          break;
2268       case ASNITER_BASE_TYPE:
2269          userobj_OUTER_typedefs (iter, AsnCodeLookupType (name_at_type),
2270                                  FALSE);
2271          break;
2272       }
2273    }
2274 }
2275 
2276 /***************************
2277 *
2278 * userobj_SEQSET(iter,final_atp)
2279 *
2280 * We have a user object within  a SEQUENCE ::= group (or SET ::=)
2281 *
2282 *  such as:
2283 *
2284 *    ParentSeq ::= SEQUENCE {
2285 *  ... other stuff before
2286 *     we_are_here SomeUserObject  <<<<< dealing with this thing
2287 * --- other stuff after
2288 *
2289 * for choice type, iter->do_chs_struct forces e.g., struct_Date PNTR instead of
2290 * newer default ValNodePtr, so old hand-coded object loaders can be linked with.
2291 *
2292 ************************/
2293 static void
2294 userobj_SEQSET (AsnIterPtr iter, AsnTypePtr final_atp)
2295 {
2296         Char buf_local[60];
2297 
2298    AsnCodeCleanName (final_atp->name, iter->buf2, CLEAN_FOR_SLOT, iter -> acip -> maxDefineLength);
2299    switch (iter->mode) {
2300    case ITER_ASSIGN:
2301    case ITER_CHECK_LIST:
2302       break;
2303    case ITER_OBJECTS:
2304       if ((AsnCodeIsReallyChoice (iter->atp) && (! iter->do_chs_struct)) || (final_atp != NULL &&
2305           final_atp->branch != NULL &&
2306           ((AsnTypePtr) final_atp->branch)->name == NULL &&
2307           ((AsnTypePtr) final_atp->branch)->type != NULL &&
2308           ISA_BASETYPE(((AsnTypePtr) final_atp->branch)->type->isa))) {
2309          sprintf (iter->buf, "       ValNodePtr ");
2310          AsnIterTakeBuf (iter);
2311       } else {
2312                                 if ((final_atp != NULL &&
2313                                                   final_atp->branch != NULL &&
2314                                                   ((AsnTypePtr) final_atp->branch)->name == NULL &&
2315                                                   ((AsnTypePtr) final_atp->branch)->type != NULL &&
2316                                                   (((AsnTypePtr) final_atp->branch)->type->isa) > 400 )) {
2317                                  sprintf (iter->buf, " struct struct_%s PNTR ",
2318                                                 AsnCodeCleanName ( ((AsnTypePtr) final_atp->branch)-> type ->name, 
2319                                                         buf_local, CLEAN_FOR_SLOT, iter -> acip -> maxDefineLength));
2320                                         }else{
2321                                  sprintf (iter->buf, " struct struct_%s PNTR ",
2322                                                          iter->buf2);
2323                                         }
2324                          AsnIterTakeBuf (iter);
2325       }
2326       sprintf (iter->buf, "  %s;\n",
2327                iter->stack->slot_name);
2328       AsnIterTakeBuf (iter);
2329       break;
2330    case ITER_NEW:
2331 
2332       /*
2333        * since user object, deafaults probably not really there, should they
2334        * be needed, see the basetype code
2335        */
2336 
2337       break;
2338    case ITER_FREE:
2339       sprintf (iter->buf, "        %sFree(ptr -> %s);\n",
2340                (iter->stack->type == ASNITER_Pseudo_USER_TYPE) ?
2341                iter->stack->obj_name :
2342                AsnCodeCleanName (final_atp->name,
2343                                  iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength),
2344                iter->stack->slot_name);
2345       AsnIterTakeBuf (iter);
2346       break;
2347    case ITER_READ:
2348 #ifdef EXTRA_READID_BUG
2349       AsnCode_RightOuter (iter, iter->stack->outer);
2350       ? ? ?
2351          if (iter->stack->outer->slot_count == 1) {
2352          sprintf (iter->buf, "   atp = AsnReadId(aip,amp, atp);\n");
2353          AsnIterTakeBuf (iter);
2354       }
2355 #endif
2356       if ((iter->acip->debug_level) > 3) {
2357          AsnCodeShowStack (iter);
2358          fflush ((iter->acip -> bug_fp));
2359       }
2360       sprintf (iter->buf, "   if (atp == %s) {\n",      /* } */
2361                GenerateTypeFromStack (iter, TRUE));
2362       AsnIterTakeBuf (iter);
2363       sprintf (iter->buf, "      ptr -> %s = ",
2364                iter->stack->slot_name);
2365       AsnIterTakeBuf (iter);
2366       sprintf (iter->buf, "%sAsnRead(aip, atp);\n",
2367                (iter->stack->type == ASNITER_Pseudo_USER_TYPE) ?
2368                iter->stack->obj_name :
2369                AsnCodeCleanName (final_atp->name,
2370                                  iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
2371       AsnIterTakeBuf (iter);
2372       sprintf (iter->buf,
2373                "      if (aip -> io_failure) {\ngoto erret;\n}\n",
2374                iter->stack->slot_name);
2375       AsnIterTakeBuf (iter);
2376 
2377       if (AsnIterNeedsNullCheck(iter, final_atp)) {
2378          sprintf (iter->buf,
2379                   "      if (ptr -> %s == NULL) {\ngoto erret;\n}\n",
2380                   iter->stack->slot_name);
2381          AsnIterTakeBuf (iter);
2382       }
2383 
2384       sprintf (iter->buf, "   atp = AsnReadId(aip,amp, atp);\n");
2385       AsnIterTakeBuf (iter);
2386        /* { */ sprintf (iter->buf, "   }\n");
2387       AsnIterTakeBuf (iter);
2388       break;
2389    case ITER_WRITE:
2390       sprintf (iter->buf,
2391                "   if (ptr -> %s != NULL) {\n", /* } */
2392                iter->stack->slot_name);
2393       AsnIterTakeBuf (iter);
2394 
2395       sprintf (iter->buf,
2396                "      if ( ! %sAsnWrite(ptr ->",
2397                (iter->stack->type == ASNITER_Pseudo_USER_TYPE) ?
2398                iter->stack->obj_name :
2399                AsnCodeCleanName (final_atp->name,
2400                                  iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
2401       AsnIterTakeBuf (iter);
2402       /* { */
2403       sprintf (iter->buf,
2404                " %s, aip, %s)) {\n         goto erret;\n}\n   }\n",
2405                iter->stack->slot_name,
2406                GenerateTypeFromStack (iter, TRUE));
2407       AsnIterTakeBuf (iter);
2408    }
2409 
2410 }
2411 
2412 /***************************
2413 *
2414 * userobj_CHOICE(iter,final_atp)
2415 *
2416 * We have a user object within  a CHOICE ::=
2417 *
2418 *  such as:
2419 *
2420 *    ParentSeq ::= CHOICE {
2421 *  ... other stuff before
2422 *     we_are_here SomeUserObject  <<<<< dealing with this thing
2423 * --- other stuff after
2424 ************************/
2425 static void
2426 userobj_CHOICE (AsnIterPtr iter, AsnTypePtr final_atp)
2427 {
2428    Boolean         in_setof_choice;
2429    AsnCodeNodePtr  which_node = AsnCode_RightChoiceNode (iter,
2430                               AsnCode_RightOuter (iter, iter->stack->outer),
2431                                                          &in_setof_choice);
2432 
2433    AsnCodeCleanName (final_atp->name, iter->buf2, CLEAN_FOR_SLOT, iter -> acip -> maxDefineLength);
2434    switch (iter->mode) {
2435    case ITER_ASSIGN:
2436    case ITER_CHECK_LIST:
2437    case ITER_NEW:
2438       break;
2439    case ITER_OBJECTS:           /* no objects, as slot absorbed within
2440                                  * data.ptrvalue of ValNode, used for Choice
2441                                  * but need symbolic #defines for choice */
2442       sprintf (iter->buf, "#define %s_%s %d\n",
2443                which_node->obj_name,
2444                iter->stack->slot_name,
2445                AsnCode_RightOuter (iter, iter->stack->outer)->slot_count);
2446       AsnIterTakeBuf (iter);
2447       break;
2448    case ITER_FREE:
2449       AsnCodeIterCaseInChoice (iter);
2450       sprintf (iter->buf, "        %sFree(anp -> data.ptrvalue);\n",
2451                (iter->stack->type == ASNITER_Pseudo_USER_TYPE) ?
2452                iter->stack->obj_name :
2453                AsnCodeCleanName (final_atp->name,
2454                                  iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
2455       AsnIterTakeBuf (iter);
2456       sprintf (iter->buf, "            break;\n");
2457       AsnIterTakeBuf (iter);
2458       break;
2459    case ITER_WRITE:
2460       AsnCodeIterCaseInChoice (iter);
2461       sprintf (iter->buf,
2462                "   writetype = %s;\n",
2463                GenerateTypeFromStack (iter, TRUE));
2464       AsnIterTakeBuf (iter);
2465       sprintf (iter->buf, "   func = (AsnWriteFunc) %sAsnWrite;\n",
2466                (iter->stack->type == ASNITER_Pseudo_USER_TYPE) ?
2467                iter->stack->obj_name :
2468                AsnCodeCleanName (final_atp->name,
2469                                  iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
2470 
2471       AsnIterTakeBuf (iter);
2472       sprintf (iter->buf, "            break;\n");
2473       AsnIterTakeBuf (iter);
2474       break;
2475    case ITER_READ:
2476       if (AsnCode_RightOuter (iter, iter->stack->outer)->slot_count != 1) {
2477          sprintf (iter->buf,
2478                   " else ");
2479          AsnIterTakeBuf (iter);
2480       }
2481       if ((iter->acip->debug_level) > 3) {
2482          AsnCodeShowStack (iter);
2483          fflush ((iter->acip -> bug_fp));
2484       }
2485       sprintf (iter->buf,
2486                "if (atp == %s) {\n",    /* } */
2487                GenerateTypeFromStack (iter, TRUE));
2488       AsnIterTakeBuf (iter);
2489       sprintf (iter->buf, "      choice = %s_%s;\n",
2490                which_node->obj_name,
2491                iter->stack->slot_name);
2492       AsnIterTakeBuf (iter);
2493 
2494 
2495       if (AsnIterNeedsNullCheck(iter, final_atp)) {
2496          sprintf (iter->buf,
2497                   "      nullIsError = TRUE;\n");
2498          AsnIterTakeBuf (iter);
2499       }
2500 
2501       sprintf (iter->buf,
2502                "      func = (AsnReadFunc) %sAsnRead;\n",
2503                (iter->stack->type == ASNITER_Pseudo_USER_TYPE) ?
2504                iter->stack->obj_name :
2505                AsnCodeCleanName (final_atp->name,
2506                                  iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
2507       AsnIterTakeBuf (iter);
2508        /* { */ sprintf (iter->buf, " }\n   ");
2509       AsnIterTakeBuf (iter);
2510       break;
2511    }
2512 
2513 }
2514 
2515 /***************************
2516 *
2517 * userobj_SETOF(iter,final_atp,recur_level)
2518 *
2519 * We have a SET OF user object within  a CHOICE ::=  or a SEQUENCE ::=
2520 *
2521 *  such as:
2522 *
2523 *    ParentSeq ::= CHOICE {
2524 *          or
2525 *    ParentSeq ::= SEQUENCE {
2526 *  ... other stuff before
2527 *     we_are_here SETOF SomeUserObject  <<<<< dealing with this thing
2528 * --- other stuff after
2529 ************************/
2530 static void
2531 userobj_SETOF (AsnIterPtr iter, AsnTypePtr final_atp, Int2 recur_level)
2532 {
2533    userobj_and_basetype_SETOF (iter, final_atp, recur_level,
2534                                ASNITER_USER_TYPE);
2535 
2536 }
2537 
2538 /***************************
2539 *
2540 * userobj_and_basetype_SETOF(iter,final_atp,recur_level,base_or_user)
2541 *
2542 * We have a SET OF object within  a CHOICE ::=  or a SEQUENCE ::=
2543 *
2544 *  such as:
2545 *
2546 *    ParentSeq ::= CHOICE {
2547 *          or
2548 *    ParentSeq ::= SEQUENCE {
2549 *  ... other stuff before
2550 *     we_are_here SETOF SomeObject  <<<<< dealing with this thing
2551 * --- other stuff after
2552 ************************/
2553 static void
2554 userobj_and_basetype_SETOF (AsnIterPtr iter, AsnTypePtr final_atp, Int2 recur_level, Int2 base_or_user)
2555 {
2556    CharPtr         valslot;
2557    CharPtr         valslotdefine;
2558    Boolean         in_setof_choice;
2559    AsnCodeNodePtr  which_node = AsnCode_RightChoiceNode (iter,
2560                                iter->stack->outer->outer, &in_setof_choice);
2561    Char            asntypename[128];
2562    AsnCodeNodePtr  right_outer_outer;
2563    AsnCodeNodePtr  right_outer =
2564    AsnCode_RightOuter (iter, iter->stack->outer);
2565 
2566    sprintf (asntypename,
2567             "%s",
2568             GenerateTypeFromStack (iter, FALSE));
2569 
2570    if (base_or_user == ASNITER_BASE_TYPE) {
2571       if (AsnCodeIsEnumType (final_atp)) {
2572          valslot = "intvalue";
2573          valslotdefine = defint;
2574       } else {
2575          if (final_atp->type->isa == SETOF_TYPE ||
2576              final_atp->type->isa == SEQOF_TYPE) {
2577             valslot = AsnCodeWhichValSlot
2578                (((AsnTypePtr) final_atp->branch)->type,
2579                 &valslotdefine);
2580          } else {
2581             valslot = AsnCodeWhichValSlot
2582                ((AsnTypePtr) final_atp->type, &valslotdefine);
2583          }
2584       }
2585    }
2586    AsnCodeCleanName (final_atp->name, iter->buf2, CLEAN_FOR_SLOT, iter -> acip -> maxDefineLength);
2587    switch (iter->mode) {
2588    case ITER_ASSIGN:
2589    case ITER_CHECK_LIST:
2590    case ITER_NEW:
2591       break;
2592    case ITER_OBJECTS:
2593       if (recur_level == RECUR_SETOF_SEQSET) {
2594 
2595          /*
2596           * Will be linked list, but if a choice, will be ValNode if not,
2597           * structure is to have next pointer...
2598           */
2599          if (AsnCodeIsReallyChoice (iter->atp)) {
2600             sprintf (iter->buf, "       ValNodePtr ");
2601             AsnIterTakeBuf (iter);
2602          } else {
2603             if (base_or_user == ASNITER_BASE_TYPE) {
2604                sprintf (iter->buf, " ValNodePtr ");
2605             } else {
2606                sprintf (iter->buf, " struct struct_%s PNTR ",
2607                         iter->buf2);
2608             }
2609             AsnIterTakeBuf (iter);
2610          }
2611          sprintf (iter->buf, "  %s;\n",
2612                   right_outer->slot_name);
2613          AsnIterTakeBuf (iter);
2614       } else {
2615          /* RECUR_SETOF_CHOICE:   */
2616          right_outer_outer =
2617             AsnCode_RightOuter (iter, iter->stack->outer->outer);
2618 
2619          /*
2620           * no objects, as slot absorbed within data.ptrvalue of ValNode,
2621           * used for Choice but need symbolic #defines for choice
2622           */
2623          sprintf (iter->buf, "#define %s_%s %d\n",
2624                   which_node->obj_name,
2625                   right_outer->slot_name,
2626                   right_outer_outer->slot_count);
2627          AsnIterTakeBuf (iter);
2628       }
2629       break;
2630    case ITER_FREE:
2631    case ITER_WRITE:
2632       if (recur_level == RECUR_SETOF_SEQSET) {
2633          /* -- in SEQUENCE ::= */
2634          if (base_or_user == ASNITER_BASE_TYPE) {
2635             sprintf (iter->buf, "     %sAsnGenericBaseSeqOf%s(ptr -> %s ",
2636                      iter->mode == ITER_FREE ?
2637                      "" : "retval = ",
2638                      iter->mode == ITER_FREE ?
2639                      "Free" : "AsnWrite",
2640                      right_outer->slot_name);
2641             AsnIterTakeBuf (iter);
2642             sprintf (iter->buf, ",%s",
2643                      valslotdefine);
2644             AsnIterTakeBuf (iter);
2645             if (iter->mode == ITER_FREE) {
2646                sprintf (iter->buf, ");\n");
2647             } else {
2648                sprintf (iter->buf, ", aip, %s, %s);\n",
2649                         asntypename,
2650                         Append_EAndPrestrip (asntypename, iter -> acip -> maxDefineLength));
2651             }
2652             AsnIterTakeBuf (iter);
2653          } else if (iter->stack->type == ASNITER_Pseudo_USER_TYPE) {
2654             if (iter->mode == ITER_FREE) {
2655                sprintf (iter->buf, "%sFree(ptr -> %s);\n",
2656                         right_outer->obj_name,
2657                         right_outer->slot_name);
2658             } else {
2659                sprintf (iter->buf,
2660                         "retval = %sAsnWrite(ptr -> %s, aip,%s);\n",
2661                         right_outer->obj_name,
2662                         right_outer->slot_name,
2663                         asntypename);
2664             }
2665             AsnIterTakeBuf (iter);
2666          } else {
2667             /* user obj here */
2668 
2669             if (AsnCodeIsReallyChoice (iter->atp)) {
2670 
2671                sprintf (iter->buf, "      AsnGenericChoiceSeqOf%s(ptr -> %s,",
2672                         iter->mode == ITER_FREE ?
2673                         "Free" : "AsnWrite",
2674                         right_outer->slot_name);
2675                AsnIterTakeBuf (iter);
2676             } else {
2677 
2678                sprintf (iter->buf, "      AsnGenericUserSeqOf%s(ptr -> %s,",
2679                         iter->mode == ITER_FREE ?
2680                         "Free" : "AsnWrite",
2681                         right_outer->slot_name);
2682                AsnIterTakeBuf (iter);
2683             }
2684             if (iter->mode == ITER_FREE) {
2685                sprintf (iter->buf, " (AsnOptFreeFunc) %sFree);\n",
2686                         AsnCodeCleanName (final_atp->name,
2687                                           iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength)
2688                   );
2689             } else {
2690                sprintf (iter->buf, " (AsnWriteFunc) %sAsnWrite, aip, %s, %s);\n",
2691                         AsnCodeCleanName (final_atp->name,
2692                                           iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength),
2693                         asntypename,
2694                         Append_EAndPrestrip (asntypename, iter -> acip -> maxDefineLength));
2695             }
2696             AsnIterTakeBuf (iter);
2697          }
2698       } else {
2699          /* RECUR_SETOF_CHOICE:   */
2700 
2701          sprintf (iter->buf, "      case %s_%s:\n",
2702                   which_node->obj_name,
2703                   right_outer->slot_name);
2704          AsnIterTakeBuf (iter);
2705          if (base_or_user == ASNITER_BASE_TYPE) {
2706             if (iter->mode == ITER_FREE) {
2707                sprintf (iter->buf,
2708                         "     AsnGenericBaseSeqOfFree((ValNodePtr) pnt,");
2709             } else {
2710                sprintf (iter->buf,
2711                  "      retval = AsnGenericBaseSeqOfAsnWrite((Pointer) pnt,");
2712             }
2713             AsnIterTakeBuf (iter);
2714             sprintf (iter->buf, "%s",
2715                      valslotdefine);
2716             AsnIterTakeBuf (iter);
2717             if (iter->mode == ITER_FREE) {
2718                sprintf (iter->buf, ");\n");
2719                AsnIterTakeBuf (iter);
2720             } else {
2721                sprintf (iter->buf, ", aip, %s, %s);",
2722                         asntypename,
2723                         Append_EAndPrestrip (asntypename, iter -> acip -> maxDefineLength));
2724                AsnIterTakeBuf (iter);
2725 
2726             }
2727          } else if (iter->stack->type == ASNITER_Pseudo_USER_TYPE) {
2728 
2729 
2730             if (iter->mode == ITER_FREE) {
2731                sprintf (iter->buf, "%sFree(ptr -> %s);\n",
2732                         right_outer->obj_name,
2733                         right_outer->slot_name);
2734             } else {
2735                sprintf (iter->buf,
2736                         "retval = %sAsnWrite(ptr -> %s, aip,%s);\n",
2737                         right_outer->obj_name,
2738                         right_outer->slot_name,
2739                         asntypename);
2740             }
2741             AsnIterTakeBuf (iter);
2742          } else {
2743             /* user type */
2744 
2745 
2746             if (AsnCodeIsReallyChoice (iter->atp)) {
2747 
2748                sprintf (iter->buf, "      %sAsnGenericChoiceSeqOf%s((Pointer) pnt,",
2749                         iter->mode == ITER_FREE ?
2750                         "" : "retval = ",
2751                         iter->mode == ITER_FREE ?
2752                         "Free" : "AsnWrite",
2753                         right_outer->slot_name);
2754                AsnIterTakeBuf (iter);
2755             } else {
2756 
2757                if (iter->mode == ITER_WRITE) {
2758                   sprintf (iter->buf,
2759                            "      retval = ");
2760                } else {
2761                   sprintf (iter->buf,
2762                            "      ");
2763                }
2764                AsnIterTakeBuf (iter);
2765                sprintf (iter->buf, "AsnGenericUserSeqOf%s((Pointer) pnt,",
2766                         iter->mode == ITER_FREE ?
2767                         "Free" : "AsnWrite",
2768                         right_outer->slot_name);
2769                AsnIterTakeBuf (iter);
2770             }
2771             if (iter->mode == ITER_FREE) {
2772                sprintf (iter->buf, " (AsnOptFreeFunc) %sFree);\n",
2773                         AsnCodeCleanName (final_atp->name,
2774                                           iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
2775                AsnIterTakeBuf (iter);
2776             } else {
2777                sprintf (iter->buf,
2778                         " (AsnWriteFunc) %sAsnWrite, aip, %s, %s);\n",
2779                         AsnCodeCleanName (final_atp->name,
2780                                           iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength),
2781                         asntypename,
2782                         Append_EAndPrestrip (asntypename, iter -> acip -> maxDefineLength));
2783                AsnIterTakeBuf (iter);
2784             }
2785          }
2786          sprintf (iter->buf, "            break;\n");
2787          AsnIterTakeBuf (iter);
2788       }
2789       break;
2790 
2791    case ITER_READ:
2792       if (recur_level == RECUR_SETOF_SEQSET) {
2793 #ifdef EXTRA_READIDBUG
2794          AsnCode_RightOuter (iter);
2795          ? ? ?
2796             if (iter->stack->outer->slot_count == 1) {
2797             sprintf (iter->buf, "   atp = AsnReadId(aip,amp, atp);\n");
2798             AsnIterTakeBuf (iter);
2799          }
2800 #endif
2801          if ((iter->acip->debug_level) > 3) {
2802             AsnCodeShowStack (iter);
2803             fflush ((iter->acip -> bug_fp));
2804          }
2805          sprintf (iter->buf, "   if (atp == %s) {\n",   /* } */
2806                   asntypename);
2807          AsnIterTakeBuf (iter);
2808          sprintf (iter->buf, "      ptr -> %s = ",
2809                   right_outer->slot_name);
2810          AsnIterTakeBuf (iter);
2811          if (base_or_user == ASNITER_BASE_TYPE) {
2812             sprintf (iter->buf,
2813                      "AsnGenericBaseSeqOfAsnRead(aip, amp, atp, %s, &isError);\n ",
2814                      valslotdefine);
2815             AsnIterTakeBuf (iter);
2816          } else if (iter->stack->type == ASNITER_Pseudo_USER_TYPE) {
2817             sprintf (iter->buf,
2818                      " %sAsnRead(aip, atp);\n", right_outer->obj_name);
2819             AsnIterTakeBuf (iter);
2820          } else {
2821             sprintf (iter->buf,
2822                      "AsnGeneric%sSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) ",
2823                      AsnCodeIsReallyChoice (iter->atp) ? "Choice" : "User");
2824             AsnIterTakeBuf (iter);
2825             sprintf (iter->buf, "%sAsnRead,",
2826                      AsnCodeCleanName (final_atp->name,
2827                                        iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
2828             AsnIterTakeBuf (iter);
2829             sprintf (iter->buf,
2830                      " (AsnOptFreeFunc) ");
2831             AsnIterTakeBuf (iter);
2832             sprintf (iter->buf, "%sFree);\n",
2833                      AsnCodeCleanName (final_atp->name,
2834                                        iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
2835             AsnIterTakeBuf (iter);
2836          }
2837          sprintf (iter->buf,
2838                   "      if (isError && ptr -> %s == NULL) {\ngoto erret;\n}\n",
2839                   right_outer->slot_name);
2840          AsnIterTakeBuf (iter);
2841          sprintf (iter->buf, "   atp = AsnReadId(aip,amp, atp);\n");
2842          AsnIterTakeBuf (iter);
2843           /* { */ sprintf (iter->buf, "   }\n");
2844          AsnIterTakeBuf (iter);
2845       } else {
2846          /* RECUR_SETOF_CHOICE:   */
2847          if (which_node->slot_count != 1) {
2848             sprintf (iter->buf, "  else ");
2849             AsnIterTakeBuf (iter);
2850          }
2851          if ((iter->acip->debug_level) > 3) {
2852             AsnCodeShowStack (iter);
2853             fflush ((iter->acip -> bug_fp));
2854          }
2855          sprintf (iter->buf, "if (atp == %s) {\n",      /* } */
2856                   asntypename);
2857          AsnIterTakeBuf (iter);
2858          sprintf (iter->buf, "      choice = %s_%s;\n",
2859                   which_node->obj_name,
2860                   right_outer->slot_name);
2861          AsnIterTakeBuf (iter);
2862          if (base_or_user == ASNITER_BASE_TYPE) {
2863             sprintf (iter->buf,
2864                      "          anp -> data.ptrvalue = \n");
2865             AsnIterTakeBuf (iter);
2866             sprintf (iter->buf,
2867                      "AsnGenericBaseSeqOfAsnRead(aip, amp, atp, %s, &isError);\n ",
2868                      valslotdefine);
2869             AsnIterTakeBuf (iter);
2870          } else if (iter->stack->type == ASNITER_Pseudo_USER_TYPE) {
2871             sprintf (iter->buf,
2872                      " %sAsnRead(aip, atp);\n", right_outer->obj_name);
2873             AsnIterTakeBuf (iter);
2874          } else {
2875             sprintf (iter->buf,
2876                      "          anp -> data.ptrvalue =\n\
2877                AsnGeneric%sSeqOfAsnRead(aip, amp, atp, &isError, (AsnReadFunc) ",
2878                      AsnCodeIsReallyChoice (iter->atp) ? "Choice" : "User");
2879             AsnIterTakeBuf (iter);
2880             sprintf (iter->buf, "%sAsnRead,",
2881                      AsnCodeCleanName (final_atp->name,
2882                                        iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
2883             AsnIterTakeBuf (iter);
2884             sprintf (iter->buf,
2885                      "             (AsnOptFreeFunc) ");
2886             AsnIterTakeBuf (iter);
2887             sprintf (iter->buf, "%sFree);\n",
2888                      AsnCodeCleanName (final_atp->name,
2889                                        iter->buf2, CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
2890             AsnIterTakeBuf (iter);
2891          }
2892          sprintf (iter->buf,
2893                "      if (isError && anp -> data.ptrvalue == NULL) {\ngoto erret;\n}\n");
2894          AsnIterTakeBuf (iter);
2895           /* { */ sprintf (iter->buf, "   }\n   ");
2896          AsnIterTakeBuf (iter);
2897       }
2898       break;
2899    }
2900 
2901 }
2902 
2903 
2904 /***************************
2905 *
2906 * AsnCode_userobj(iter)
2907 *
2908 ****************************/
2909 static void
2910 AsnCode_userobj (struct struct_asniter PNTR iter)
2911 {
2912    Int2            recur_level = AsnCodeIterRecurLevel (iter);
2913    Int2            real_type;
2914    AsnTypePtr      name_at_type;
2915 
2916    if (iter->mode == ITER_CHECK_LIST) {
2917       userobj_CHECK_LIST (iter);
2918    } else {
2919       switch (recur_level) {
2920       case RECUR_OUTER:
2921          userobj_OUTER (iter);
2922          break;
2923       case RECUR_SEQSET:        /* userobject in a SEQUENCE or SET */
2924          real_type = AsnCodeFinalType (iter, iter->atp, &name_at_type);
2925          switch (real_type) {
2926          case ENUM_TYPE:
2927          case ASNITER_BASE_TYPE:
2928             basetype_SEQSET (iter, name_at_type);
2929             break;
2930 
2931          case SEQOF_TYPE:
2932          case SETOF_TYPE:
2933          case SEQ_TYPE:
2934          case SET_TYPE:
2935          case CHOICE_TYPE:
2936 
2937             /*
2938              * user objects that are Sequences and Choices are handled
2939              * similarly from within sequences
2940              */
2941             userobj_SEQSET (iter, name_at_type);
2942             break;
2943          }
2944          break;
2945       case RECUR_CHOICE:
2946          real_type = AsnCodeFinalType (iter, iter->atp, &name_at_type);
2947          switch (real_type) {
2948          case ENUM_TYPE:
2949          case ASNITER_BASE_TYPE:
2950             basetype_CHOICE (iter, name_at_type);
2951             break;
2952 
2953          case SEQOF_TYPE:
2954          case SETOF_TYPE:
2955          case SEQ_TYPE:
2956          case SET_TYPE:
2957          case CHOICE_TYPE:
2958 
2959             /*
2960              * user objects that are Sequences and Choices are handled
2961              * similarly from within choices
2962              */
2963             userobj_CHOICE (iter, name_at_type);
2964             break;
2965          }
2966          break;
2967       case RECUR_SETOF_OUTER:
2968 
2969          /*
2970 as:     SupAtsRxnsStrs ::= SET OF SupAtRxnOrStr
2971           */
2972          real_type = AsnCodeFinalType (iter, iter->atp, &name_at_type);
2973          switch (real_type) {
2974          case ENUM_TYPE:
2975          case ASNITER_BASE_TYPE:
2976                         AsnCode_SETOF_base_or_user (iter, ASNITER_BASE_TYPE);
2977             break;
2978 
2979          case SEQOF_TYPE:
2980          case SETOF_TYPE:
2981          case SEQ_TYPE:
2982          case SET_TYPE:
2983          case CHOICE_TYPE:
2984 
2985             /*
2986              * user objects that are Sequences and Choices are handled
2987              * similarly from within choices
2988              */
2989                 AsnCode_SETOF_base_or_user (iter, ASNITER_USER_TYPE);
2990             break;
2991          }
2992 
2993 
2994          break;
2995       case RECUR_SETOF_SEQSET:
2996       case RECUR_SETOF_CHOICE:
2997          real_type = AsnCodeFinalType (iter, iter->atp, &name_at_type);
2998          switch (real_type) {
2999          case ENUM_TYPE:
3000          case ASNITER_BASE_TYPE:
3001             basetype_SETOF (iter, name_at_type, recur_level);
3002             break;
3003 
3004          case SEQOF_TYPE:
3005          case SETOF_TYPE:
3006          case SEQ_TYPE:
3007          case SET_TYPE:
3008          case CHOICE_TYPE:
3009 
3010             /*
3011              * user objects that are Sequences and Choices are handled
3012              * similarly from within SETOF in parental SEQUENCE or CHOICE
3013              */
3014             userobj_SETOF (iter, name_at_type, recur_level);
3015             break;
3016          }
3017          break;
3018       }
3019    }
3020 
3021 }
3022 
3023 /*************************
3024 *
3025 * AsnCodeFinalType(iter,atp,vase_atpPt)
3026 *
3027 * returns of meaning are:
3028 *
3029 *   ENUM_TYPE;
3030 *   SEQ_TYPE;
3031 *   SET_TYPE;
3032 *   CHOICE_TYPE;
3033 *   ASNITER_BASE_TYPE  (captures all other base types)
3034 ********************/
3035 static Int2
3036 AsnCodeFinalType (struct struct_asniter PNTR iter, AsnTypePtr atp, AsnTypePtr PNTR base_atpPt)
3037 {
3038    Int2            retval = 0;
3039 
3040    if ((iter->acip->debug_level) > 3) {
3041       AsnCodeShowStack (iter);
3042       fprintf ((iter->acip -> bug_fp), "In AsnCodeFinalType:atp name%s-%d\n",
3043                TESTNIL (atp->name), (int) atp->isa);
3044    }
3045    if (atp != NULL){
3046       if (atp->imported) {
3047          if (atp->type != NULL) {
3048             retval = AsnCodeFinalType (iter, atp->type, base_atpPt);
3049          } else {
3050             retval = 0;
3051             if (base_atpPt != NULL) {
3052                *base_atpPt = NULL;
3053             }
3054          }
3055       } else if (atp->type != NULL) {
3056 
3057          if (atp->type->isa == ENUM_TYPE) {
3058             retval = ENUM_TYPE;
3059             if (base_atpPt != NULL) {
3060                *base_atpPt = atp;
3061             }
3062          } else if (atp->type->isa < 301) {
3063             retval = 0;
3064             if (base_atpPt != NULL) {
3065                *base_atpPt = NULL;
3066             }
3067             /*------- USER OBJECTS -------*/
3068          } else if (atp->type->isa > 400) {
3069             /*------- USER OBJECTS -------*/
3070             retval = AsnCodeFinalType (iter, atp->type, base_atpPt);
3071             /*------SETs and SEQUENCEs ---*/
3072          } else if (atp->type->isa == SEQ_TYPE) {
3073             retval = SEQ_TYPE;
3074             if (base_atpPt != NULL) {
3075                *base_atpPt = atp;
3076             }
3077          } else if (atp->type->isa == SET_TYPE) {
3078             retval = SET_TYPE;
3079             if (base_atpPt != NULL) {
3080                *base_atpPt = atp;
3081             }
3082             /*-------- CHOICE ---*/
3083          } else if (atp->type->isa == CHOICE_TYPE) {
3084             retval = CHOICE_TYPE;
3085             if (base_atpPt != NULL) {
3086                *base_atpPt = atp;
3087             }
3088             /*----- SET OF or SEQ OF-------*/
3089          } else if (atp->type->isa == SETOF_TYPE ||
3090                     atp->type->isa == SEQOF_TYPE) {
3091             /*----- SET OF CHOICE is a special case */
3092             AsnTypePtr      test_branch = (AsnTypePtr) atp->branch;
3093             if (test_branch->type->isa == CHOICE_TYPE) {
3094                retval = CHOICE_TYPE;
3095                if (base_atpPt != NULL) {
3096                   *base_atpPt = atp;
3097                }
3098             } else {
3099                retval = atp->type->isa;
3100                if (base_atpPt != NULL) {
3101                   *base_atpPt = atp;
3102                }
3103             }
3104          } else if (ISA_BASETYPE (atp->type->isa)) {
3105             retval = ASNITER_BASE_TYPE;
3106             if (base_atpPt != NULL) {
3107                *base_atpPt = atp;
3108             }
3109          }
3110       }
3111    }
3112    if ((iter->acip->debug_level) > 3) {
3113       if (base_atpPt) {
3114          fprintf ((iter->acip -> bug_fp), " returning atp name %s-%d, retval %d\n",
3115                   (*base_atpPt)? TESTNIL ((*base_atpPt)->name):"NULL",
3116                   (int) ((*base_atpPt)? (*base_atpPt)->isa:0), (int) retval);
3117       }
3118       fflush ((iter->acip -> bug_fp));
3119    }
3120    return retval;
3121 }
3122 
3123 /*****************************************************************************
3124 *
3125 *   AsnCodeLookupType(atp)
3126 *
3127 *****************************************************************************/
3128 static CharPtr
3129 AsnCodeLookupType (AsnTypePtr atp)
3130 {
3131    CharPtr         retval = "Pointer";
3132 
3133 
3134    if (atp != NULL){
3135       if (atp->type != NULL){
3136         if (AsnCodeIsEnumType(atp)){
3137            retval = "Uint2";
3138         }else{
3139          switch (atp->type->isa) {
3140          case BOOLEAN_TYPE:
3141             retval = "Uint1";
3142             break;
3143          case BITS_TYPE:
3144             retval = "Uint1";
3145             break;
3146          case INTEGER_TYPE:
3147             retval = "Int4";
3148             break;
3149          case BIGINT_TYPE:
3150             retval = "Int8";
3151             break;
3152          case OCTETS_TYPE:
3153             retval = "ByteStorePtr";
3154             break;
3155          case NULL_TYPE:
3156             retval = "Uint1";
3157             break;
3158          case OBID_TYPE:
3159             retval = "Pointer";
3160             break;
3161          case OBDES_TYPE:
3162             retval = "Pointer";
3163             break;
3164          case REAL_TYPE:
3165             retval = "FloatHi";
3166             break;
3167          case ENUM_TYPE:
3168             retval = "Uint2";
3169             break;
3170          case ANY_TYPE:
3171             retval = "Pointer";
3172             break;
3173          case NUMERICSTRING_TYPE:
3174             retval = "CharPtr";
3175             break;
3176          case PRINTABLESTRING_TYPE:
3177             retval = "CharPtr";
3178             break;
3179          case TELETEXSTRING_TYPE:
3180             retval = "CharLenPtr";
3181             break;
3182          case VIDEOTEXSTRING_TYPE:
3183             retval = "CharLenPtr";
3184             break;
3185          case IA5STRING_TYPE:
3186             retval = "CharLenPtr";
3187             break;
3188          case GRAPHICSTRING_TYPE:
3189             retval = "CharLenPtr";
3190             break;
3191          case VISIBLESTRING_TYPE:
3192             retval = "CharPtr";
3193             break;
3194          case CHOICE_TYPE:
3195             retval = "ValNodePtr";
3196             break;
3197          case GENERALSTRING_TYPE:
3198             retval = "CharLenPtr";
3199             break;
3200          case CHARACTERSTRING_TYPE:
3201             retval = "CharLenPtr";
3202             break;
3203          case GENTIME_TYPE:
3204             retval = "Pointer"; /* Time types */
3205             break;
3206          case UTCTIME_TYPE:
3207             retval = "CharLenPtr";
3208             break;
3209          case STRSTORE_TYPE:
3210             retval = "StringStorePtr";
3211             break;
3212          }
3213         }
3214    }
3215 }
3216 
3217    return retval;
3218 }
3219 
3220 /*****************************************************************************
3221 *
3222 *   AsnCodeNeedFree(atp)
3223 *
3224 *****************************************************************************/
3225 static CharPtr
3226 AsnCodeNeedFree (AsnTypePtr atp)
3227 {
3228    CharPtr         retval = NULL;
3229    static CharPtr  mem = "MemFree";
3230    static CharPtr  byte = "BSFree";
3231 
3232 
3233    if (atp != NULL)
3234       if (atp->type != NULL)
3235          switch (atp->type->isa) {
3236          case BOOLEAN_TYPE:
3237          case BITS_TYPE:
3238          case INTEGER_TYPE:
3239          case BIGINT_TYPE:
3240          case NULL_TYPE:
3241          case REAL_TYPE:
3242          case ENUM_TYPE:
3243             retval = NULL;
3244             break;
3245          case OBID_TYPE:
3246          case OBDES_TYPE:
3247          case ANY_TYPE:
3248          case NUMERICSTRING_TYPE:
3249          case PRINTABLESTRING_TYPE:
3250          case TELETEXSTRING_TYPE:
3251          case VIDEOTEXSTRING_TYPE:
3252          case IA5STRING_TYPE:
3253          case GRAPHICSTRING_TYPE:
3254          case VISIBLESTRING_TYPE:
3255          case GENERALSTRING_TYPE:
3256          case CHARACTERSTRING_TYPE:
3257          case GENTIME_TYPE:
3258          case UTCTIME_TYPE:
3259             retval = mem;
3260             break;
3261          case CHOICE_TYPE:      /* questionable! */
3262             retval = mem;
3263             break;
3264          case STRSTORE_TYPE:
3265          case OCTETS_TYPE:
3266             retval = byte;
3267             break;
3268          };
3269 
3270    return retval;
3271 }
3272 
3273 /*****************************************************************
3274 *
3275 *       AsnCodeIsReallyChoice(atp)
3276 *
3277 *****************************************************************/
3278 
3279 static Boolean
3280 AsnCodeIsReallyChoice (AsnTypePtr atp)
3281 {
3282    Boolean         retval = FALSE;
3283    AsnTypePtr      now_atp = atp;
3284 
3285    if (now_atp)
3286       if (now_atp->imported) {
3287          if (now_atp->type != NULL) {
3288             retval = AsnCodeIsReallyChoice (now_atp->type);
3289          }
3290       } else if (now_atp->type->isa == CHOICE_TYPE) {
3291          retval = TRUE;
3292       } else if (now_atp->type->isa == SETOF_TYPE ||
3293                  now_atp->type->isa == SEQOF_TYPE) {
3294          AsnTypePtr      branch = (AsnTypePtr) atp->branch;
3295          retval = AsnCodeIsReallyChoice (branch);
3296       } else if (now_atp->type->isa > 400) {
3297          retval = AsnCodeIsReallyChoice (now_atp->type);
3298       }
3299    return retval;
3300 }
3301 
3302 /*****************************************************************
3303 *
3304 *       AsnCodeIsEnumType(atp)
3305 *
3306 *****************************************************************/
3307 
3308 static Boolean
3309 AsnCodeIsEnumType (AsnTypePtr atp)
3310 {
3311    Boolean         retval = FALSE;
3312    AsnTypePtr      now_atp;
3313 
3314    for (now_atp = atp; now_atp != NULL; now_atp = now_atp -> type){
3315       if (now_atp->isa == ENUM_TYPE) {
3316          retval = TRUE;
3317          break;
3318       } else if (now_atp->type != NULL) {
3319          if (now_atp->type->isa == ENUM_TYPE) {
3320             retval = TRUE;
3321             break;
3322          }
3323          if (now_atp->type->isa <= 400 && ! now_atp -> imported  ) {
3324             break;
3325          }
3326       }
3327    }
3328    return retval;
3329 }
3330 
3331 /***********************
3332 *
3333 * AsnCodeFinishedRoutine(iter)
3334 *
3335 ****************************/
3336 void
3337 AsnCodeFinishedRoutine (struct struct_asniter PNTR iter)
3338 {
3339    Boolean         use_last = FALSE;
3340 
3341    if (iter->cur_routine) {
3342       iter->cur_routine->finished = TRUE;
3343       if (iter->cur_routine->last) {
3344          if (!iter->cur_routine->last->finished) {
3345             /*--- last routine still active, make it current ---*/
3346             iter->cur_routine = iter->cur_routine->last;
3347             use_last = TRUE;
3348          }
3349       }
3350       if (!use_last) {
3351          /* -- last routine was not active, just say nothing active now */
3352          iter->cur_routine = NULL;
3353       }
3354    }
3355 }
3356 
3357 
3358 /***********************
3359 *
3360 * AsnCodeNewRoutine(iter)
3361 *
3362 *************************/
3363 void
3364 AsnCodeNewRoutine (struct struct_asniter PNTR iter)
3365 {
3366    AsnCodeSpooledPtr new_routine = (AsnCodeSpooledPtr)MemNew (sizeof (AsnCodeSpooled));
3367    AsnCodeSpooledPtr scanner;
3368 
3369    if (iter->cur_routine != NULL) {
3370       if (iter->cur_routine->finished) {
3371          iter->cur_routine = NULL;
3372       }
3373    }
3374    if (iter->routines == NULL) {
3375       iter->routines = iter->cur_routine =
3376          iter->last_routine = new_routine;
3377    } else if (iter->cur_routine == NULL) {
3378       /* no active routine, just add to end of chain */
3379       if (iter->last_routine == NULL) {
3380           /* refind tail */
3381             for (scanner = iter->routines; scanner; scanner = scanner->next) {
3382             iter->last_routine = scanner;
3383          }
3384       }
3385       new_routine->next = iter->last_routine->next;
3386       iter->last_routine->next = new_routine;
3387       iter->cur_routine = new_routine;
3388       new_routine->last = iter->last_routine;
3389       iter->last_routine = new_routine;
3390    } else {
3391       /* there is an active routine, insert this new one after it */
3392       new_routine->next = iter->cur_routine->next;
3393       new_routine->last = iter->cur_routine;
3394       if (iter->cur_routine->next) {
3395          iter->cur_routine->next->last = new_routine;
3396       }
3397       new_routine->next = iter->cur_routine->next;
3398       iter->cur_routine->next = new_routine;
3399       iter->cur_routine = new_routine;
3400       iter->last_routine = new_routine;
3401    }
3402 
3403 }
3404 
3405 /************************************
3406 *
3407 * AsnCodeDumpLine(iter, line)
3408 *
3409 ************************************/
3410 static void
3411 AsnCodeDumpLine (AsnIterPtr iter, CharPtr line)
3412 {
3413    CharPtr         p;
3414    CharPtr         maxChar = &line[StrLen (line)];
3415    Int2            i;
3416    Int2            oneLess;
3417 
3418    for (p = line; p < maxChar; p++) {
3419       if (iter->leadingspaces) {
3420          if (*p == ' ' || *p == '\t') {
3421             continue;
3422          } else {
3423             iter->leadingspaces = FALSE;
3424             if (*p != '\n') {
3425                if (*p == '}' || StrNCmp (p, "case ", 5) == 0 ||
3426                    StrNCmp (p, "default:", 8) == 0 ||
3427                    StrNCmp (p, "ret:", 4) == 0 ||
3428                    StrNCmp (p, "erret:", 6) == 0 ||
3429                    StrNCmp (p, "#define", 6) == 0)
3430                   oneLess = 1;
3431                else
3432                   oneLess = 0;
3433                for (i = oneLess; i < iter->indent; i++)
3434                   fprintf (iter->fp, "   ");
3435             }
3436          }
3437          /* fall through */
3438       }
3439       switch (*p) {
3440       case '{':
3441          iter->indent++;
3442          break;
3443       case '}':
3444          if (iter->indent > 0) {
3445             iter->indent--;
3446          }
3447          break;
3448       case '\n':
3449          iter->leadingspaces = TRUE;
3450          break;
3451       default:
3452          break;
3453       }
3454       putc (*p, iter->fp);
3455    }
3456 }
3457 
3458 /************************************
3459 *
3460 * AsnCodeCheckFileDoneRoutines(iter)
3461 *
3462 ************************************/
3463 static void
3464 AsnCodeCheckFileDoneRoutines (AsnIterPtr iter)
3465 {
3466    AsnCodeSpooledPtr routine, next_routine;
3467    AsnCodeLinesPtr line, next_line;
3468 
3469    for (routine = iter->routines; routine; routine = next_routine) {
3470       next_routine = routine->next;
3471       for (line = routine->head_line; line; line = next_line) {
3472          next_line = line->next;
3473          AsnCodeDumpLine (iter, line->line);
3474          if ((iter->acip->debug_level) > 2) {
3475             fprintf ((iter->acip -> bug_fp), "Dumping:%x<%s>\n", routine, TESTNIL (line->line));
3476          }
3477          if ((iter->acip->debug_level) > 0)
3478             fflush (iter->fp);
3479          MemFree (line->line);
3480          MemFree (line);
3481       }
3482       MemFree (routine);
3483    }
3484    iter->routines = NULL;
3485    iter->cur_routine = NULL;
3486 
3487 }
3488 
3489 
3490 /***********************
3491 *
3492 *    AsnIterTakeBuf(iter)
3493 *
3494 ************************/
3495 
3496 static void
3497 AsnIterTakeBufReal (struct struct_asniter PNTR iter, int lineno)
3498 {
3499    AsnCodeLinesPtr line =
3500    (AsnCodeLinesPtr) MemNew (sizeof (AsnCodeLines));
3501 
3502    if (iter->cur_routine == NULL) {
3503       AsnCodeNewRoutine (iter);
3504    }
3505    if (iter->cur_routine->head_line) {
3506       iter->cur_routine->tail_line->next = line;
3507    } else {
3508       iter->cur_routine->head_line = line;
3509    }
3510    iter->cur_routine->tail_line = line;
3511    if ((iter->acip->debug_level) > 2) {
3512       fprintf ((iter->acip -> bug_fp), "Buf (%d):%x<%s>\n", lineno, iter->cur_routine, TESTNIL (iter->buf));
3513       fflush ((iter->acip -> bug_fp));
3514    }
3515    line->line = StringSave (iter->buf);
3516    (iter->buf)[0] = '\0';
3517 
3518 }
3519 
3520 /*****************************************************************************
3521 *
3522 * AsnCodeStaticCandidate(iter)
3523 *
3524 *****************************************************************************/
3525 
3526 static Boolean
3527 AsnCodeStaticCandidate (AsnIterPtr iter)
3528 {
3529 #ifdef USER_PSEUDOOBJECTS_STATIC
3530    Int2            recur_level = AsnCodeIterRecurLevel (iter);
3531    Boolean         retval = FALSE;
3532 
3533    switch (recur_level) {
3534    case RECUR_SEQSET:
3535    case RECUR_CHOICE:
3536    case RECUR_SETOF_SEQSET:
3537    case RECUR_SETOF_CHOICE:
3538       if (iter->atp->isa == 0)
3539          retval = TRUE;
3540       break;
3541    default:
3542       break;
3543    }
3544    if ((iter->acip->debug_level) > 3 && iter->atp->isa == 0) {
3545       AsnCodeShowStack (iter);
3546       fprintf ((iter->acip -> bug_fp), "AsnCodeStaticCandidate: depth %d, recur-level %d, retval %d\n",
3547                iter->depth, AsnCodeIterRecurLevel (iter), (int) retval);
3548       fflush ((iter->acip -> bug_fp));
3549    }
3550    return retval;
3551 #else
3552    return FALSE;
3553 #endif
3554 }
3555 
3556 /*****************************************************************************
3557 *
3558 * AsnCodeGenerateProtos(iter,buf,from_choice)
3559 *
3560 *****************************************************************************/
3561 void
3562 AsnCodeGenerateProtos (struct struct_asniter PNTR iter, CharPtr buf, Boolean from_choice)
3563 {
3564    AsnCodeNewRoutine (iter);
3565    if (iter->atp->isa == 0) {
3566       sprintf (iter->buf, "\n#ifdef NLM_GENERATED_CODE_PROTO");
3567       AsnIterTakeBuf (iter);
3568    }
3569    /* -- Free -- */
3570    sprintf (iter->buf, "\n\n%s%sPtr%s ",
3571             AsnCodeStaticCandidate (iter) ? "static " : "NLM_EXTERN ", buf,
3572             " LIBCALL");
3573    AsnIterTakeBuf (iter);
3574    sprintf (iter->buf, "%sFree PROTO ((", buf);
3575    AsnIterTakeBuf (iter);
3576    sprintf (iter->buf, "%sPtr ));\n", buf);
3577    AsnIterTakeBuf (iter);
3578    if (!from_choice) {
3579       /* New */
3580       sprintf (iter->buf, "%s%sPtr%s ",
3581                AsnCodeStaticCandidate (iter) ? "static " : "NLM_EXTERN ", buf,
3582                " LIBCALL");
3583       AsnIterTakeBuf (iter);
3584       sprintf (iter->buf, "%sNew PROTO (( void ));\n", buf);
3585       AsnIterTakeBuf (iter);
3586    }
3587    /* --- Read --- */
3588    sprintf (iter->buf, "%s%sPtr%s ",
3589             AsnCodeStaticCandidate (iter) ? "static " : "NLM_EXTERN ", buf,
3590             " LIBCALL");
3591    AsnIterTakeBuf (iter);
3592    sprintf (iter->buf, "%sAsnRead PROTO (( AsnIoPtr, AsnTypePtr));\n", buf);
3593    AsnIterTakeBuf (iter);
3594    /* --- Write --- */
3595    sprintf (iter->buf,
3596       "%sBoolean%s %sAsnWrite PROTO (( %sPtr , AsnIoPtr, AsnTypePtr));\n\n",
3597             AsnCodeStaticCandidate (iter) ? "static " : "NLM_EXTERN ",
3598             " LIBCALL", buf, buf);
3599    AsnIterTakeBuf (iter);
3600    if (iter->atp->isa == 0) {
3601       sprintf (iter->buf, "#endif /* NLM_GENERATED_CODE_PROTO */\n\n");
3602       AsnIterTakeBuf (iter);
3603    }
3604    AsnCodeFinishedRoutine (iter);
3605 }
3606 
3607 /*****************************
3608 *
3609 *    AsnCodeCleanName(name,buf,wash_or_buf,maxlen)
3610 *
3611 * WASH == CLEAN_FOR_SLOT
3612 * BUFF == CLEAN_FOR_OBJ_NAME
3613 * SLOT_POLISH == CLEAN_FOR_ASN_TYPE
3614 *********************/
3615 
3616 CharPtr
3617 AsnCodeCleanName (CharPtr name, char buf[BUF_LEN], int wash_or_buf, int maxlen)
3618 {
3619    CharPtr         p;
3620    int             dex, target = 0;
3621    Boolean         is_word;
3622    CharPtr         symbol;
3623    Boolean         AllUpperCase = TRUE;
3624 
3625    if (wash_or_buf != SLOT_BUFF) {
3626       is_word = TRUE;
3627    } else {
3628       is_word = FALSE;
3629    }
3630    if (name)                    /* before pseudo-user types defined, might be
3631                                  * null */
3632       for (p = name, dex = 0, target = 0;
3633            *p && dex < BUF_LEN - 1; dex++, p++) {
3634          if (*p == '-') {
3635             is_word = TRUE;
3636             if (wash_or_buf == WASH || wash_or_buf == SLOT_POLISH) {
3637                buf[target++] = '_';
3638             }
3639             continue;
3640          }
3641          buf[target++] = *p;
3642          if ((is_word && wash_or_buf == BUFF)
3643              || wash_or_buf == SLOT_POLISH) {
3644             buf[target - 1] = TO_UPPER (buf[target - 1]);
3645          }
3646          if (! IS_UPPER(*p)) {
3647             AllUpperCase = FALSE;
3648          }
3649          is_word = FALSE;
3650       }
3651 
3652    if (AllUpperCase && wash_or_buf == BUFF) {
3653       buf[target++] = '_';
3654       buf[target++] = '_';
3655    }
3656    buf[target] = '\0';
3657    for (dex = 0; dex < NUM_C_RESERVED_WORDS; dex++) {
3658       if (StrCmp(buf, c_reserved_word[dex]) == 0) {
3659          buf[target++] = '_';
3660          buf[target++] = '_';
3661          buf[target] = '\0';
3662       }
3663    }
3664          
3665    symbol = buf;
3666    if (wash_or_buf == SLOT_POLISH) {
3667       symbol = SpanLengthyPrefix (buf, maxlen);
3668    }
3669    return (CharPtr) symbol;
3670 }
3671 
3672 /******************
3673 *
3674 *   AsnCodeHeader(iter)
3675 *
3676 ******************/
3677 
3678 void
3679 AsnCodeHeader (AsnIterPtr iter, CharPtr name)
3680 {
3681 
3682 
3683    sprintf (iter->buf, "\n\n/**************************************************\n");
3684    AsnIterTakeBuf (iter);
3685    sprintf (iter->buf, "*\n");
3686    AsnIterTakeBuf (iter);
3687    sprintf (iter->buf, "*    %s\n", name);
3688    AsnIterTakeBuf (iter);
3689    sprintf (iter->buf, "*\n");
3690    AsnIterTakeBuf (iter);
3691    sprintf (iter->buf, "**************************************************/\n");
3692    AsnIterTakeBuf (iter);
3693 }
3694 
3695 
3696 /****************************************
3697 *
3698 * AsnCodeFunctionWriteFuncChoiceStart(iter,doing_outer_setof_choice)
3699 *
3700 ****************************************/
3701 
3702 void
3703 AsnCodeFunctionWriteFuncChoiceStart (AsnIterPtr iter, Boolean doing_outer_setof_choice)
3704 {
3705    Boolean         in_setof_choice;
3706    AsnCodeNodePtr  which_node = AsnCode_RightChoiceNode (iter, iter->stack, &in_setof_choice);
3707    CharPtr         obj_use = which_node->obj_name;
3708    CharPtr         asn_type_use;
3709    char            setof_objbuf[120];
3710    char            setof_asnbuf[120];
3711 
3712    obj_use = which_node->obj_name;
3713    asn_type_use = GenerateTypeFromStack (iter, !doing_outer_setof_choice);
3714    if (in_setof_choice) {
3715       sprintf (setof_objbuf, "%s_element", which_node->obj_name);
3716       sprintf (setof_asnbuf, "%s", GenerateTypeFromStack (iter, !doing_outer_setof_choice));
3717       obj_use = setof_objbuf;
3718       asn_type_use = setof_asnbuf;
3719    }
3720    sprintf (iter->buf, "\
3721         if (! loaded)\n\
3722         {\n\
3723                 if (! %sAsnLoad())\n\
3724                         return FALSE;\n\
3725         }\n\n", iter->module_name);
3726    AsnIterTakeBuf (iter);
3727 
3728    sprintf (iter->buf, "\
3729         if (aip == NULL)\n\
3730                 return FALSE;\n\n");
3731    AsnIterTakeBuf (iter);
3732    sprintf (iter->buf, "\
3733         atp = AsnLinkType(orig, %s);   /* link local tree */\n\
3734     if (atp == NULL) {\n\
3735         return FALSE;\n}\n\n", asn_type_use);
3736 
3737    AsnIterTakeBuf (iter);
3738    sprintf (iter->buf, "\
3739         if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }\n\
3740 \n\
3741         av.ptrvalue = (Pointer)anp;\n");
3742    AsnIterTakeBuf (iter);
3743    if (!doing_outer_setof_choice) {
3744       sprintf (iter->buf, "\
3745         if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) {\n\
3746         goto erret;\n}\n\n");
3747          AsnIterTakeBuf (iter);
3748    }
3749 }
3750 
3751 /****************************************
3752 *
3753 * AsnCodeFunctionWriteFuncSeqStart(iter,no_write_braces)
3754 *
3755 ****************************************/
3756 
3757 void
3758 AsnCodeFunctionWriteFuncSeqStart (AsnIterPtr iter, Boolean no_write_braces)
3759 {
3760 
3761    sprintf (iter->buf, "\
3762         if (! loaded)\n\
3763         {\n\
3764                 if (! %sAsnLoad()) {\n\
3765                         return FALSE;\n}\n\
3766         }\n\n", iter->module_name);
3767    AsnIterTakeBuf (iter);
3768 
3769    sprintf (iter->buf, "\
3770         if (aip == NULL) {\n\
3771                 return FALSE;\n}\n\n");
3772    AsnIterTakeBuf (iter);
3773    sprintf (iter->buf, "\
3774         atp = AsnLinkType(orig, %s);   /* link local tree */\n\
3775     if (atp == NULL) {\n\
3776         return FALSE;\n}\n\n",
3777             GenerateTypeFromStack (iter, FALSE)
3778       );
3779 
3780    AsnIterTakeBuf (iter);
3781    sprintf (iter->buf, "\
3782             if (ptr == NULL) { AsnNullValueMsg(aip, atp); goto erret; }\n");
3783    AsnIterTakeBuf (iter);
3784 
3785    if (! no_write_braces){
3786    sprintf (iter->buf, "\
3787         if (! AsnOpenStruct(aip, atp, (Pointer) ptr)) {\n\
3788         goto erret;\n}\n\n");
3789    AsnIterTakeBuf (iter);
3790    }
3791 }
3792 
3793 /****************************************
3794 *
3795 * AsnCodeFunctionReadFuncChoiceStart(iter,doing_outer_setof_choice)
3796 *
3797 ****************************************/
3798 
3799 void
3800 AsnCodeFunctionReadFuncChoiceStart (AsnIterPtr iter, Boolean doing_outer_setof_choice)
3801 {
3802    Boolean         in_setof_choice;
3803    AsnCodeNodePtr  which_node = AsnCode_RightChoiceNode (iter, iter->stack, &in_setof_choice);
3804    CharPtr         obj_use;
3805    CharPtr         asn_type_use;
3806    char            setof_objbuf[120];
3807    char            setof_asnbuf[120];
3808 
3809    obj_use = which_node->obj_name;
3810    asn_type_use = GenerateTypeFromStack (iter, !doing_outer_setof_choice);
3811    if (in_setof_choice) {
3812       sprintf (setof_objbuf, "%s_element", which_node->obj_name);
3813       sprintf (setof_asnbuf, "%s", GenerateTypeFromStack (iter, !doing_outer_setof_choice));
3814       obj_use = setof_objbuf;
3815       asn_type_use = setof_asnbuf;
3816    }
3817    sprintf (iter->buf, "\
3818         if (! loaded)\n\
3819         {\n\
3820                 if (! %sAsnLoad()) {\n\
3821                         return NULL;\n}\n\
3822         }\n\n", iter->module_name);
3823    AsnIterTakeBuf (iter);
3824 
3825    sprintf (iter->buf, "\
3826         if (aip == NULL) {\n\
3827                 return NULL;\n}\n\n");
3828    AsnIterTakeBuf (iter);
3829 
3830    sprintf (iter->buf,
3831             "if (orig == NULL) {         /* %s ::= (self contained) */\n\
3832                 atp = AsnReadId(aip, amp, %s);\n} else {\n",
3833             obj_use, asn_type_use);
3834 
3835    AsnIterTakeBuf (iter);
3836 
3837    sprintf (iter->buf, "\
3838                 atp = AsnLinkType(orig, %s);    /* link in local tree */\n}\n\
3839     if (atp == NULL) {\n\
3840         return NULL;\n}\n\n", asn_type_use);
3841    AsnIterTakeBuf (iter);
3842 
3843    if (!doing_outer_setof_choice) {
3844       sprintf (iter->buf, "\
3845         anp = ValNodeNew(NULL);\n\
3846     if (anp == NULL) {\n\
3847         goto erret;\n}\n");
3848       AsnIterTakeBuf (iter);
3849       sprintf (iter->buf, "\
3850         if (AsnReadVal(aip, atp, &av) <= 0) { /* read the CHOICE or OpenStruct value (nothing) */\n\
3851         goto erret;\n}\n\n");
3852       AsnIterTakeBuf (iter);
3853 
3854       sprintf (iter->buf, "    func = NULL;\n\n");
3855       AsnIterTakeBuf (iter);
3856       sprintf (iter->buf, "\
3857         atp = AsnReadId(aip, amp, atp);  /* find the choice */\n\
3858     if (atp == NULL) {\n\
3859         goto erret;\n}\n");
3860       AsnIterTakeBuf (iter);
3861    }
3862 }
3863 
3864 /****************************************
3865 *
3866 * AsnCodeFunctionReadFuncSeqStart(iter,go_outer)
3867 *
3868 ****************************************/
3869 
3870 void
3871 AsnCodeFunctionReadFuncSeqStart (AsnIterPtr iter, Boolean go_outer)
3872 {
3873         AsnCodeNodePtr which_stack =
3874    go_outer? iter->stack -> outer :
3875    iter->stack;
3876 
3877    sprintf (iter->buf, "\
3878         if (! loaded)\n\
3879         {\n\
3880                 if (! %sAsnLoad()) {\n\
3881                         return NULL;\n}\n\
3882         }\n\n", iter->module_name);
3883    AsnIterTakeBuf (iter);
3884 
3885    sprintf (iter->buf, "\
3886         if (aip == NULL) {\n\
3887                 return NULL;\n}\n\n");
3888    AsnIterTakeBuf (iter);
3889 
3890    sprintf (iter->buf, "\
3891         if (orig == NULL) {         /* %s ::= (self contained) */\n\
3892                 atp = AsnReadId(aip, amp, %s);\n\
3893         } else {\n", which_stack->obj_name,
3894             GenerateTypeFromStack (iter, FALSE)  /* 11/7/94 CAS */
3895       );
3896    AsnIterTakeBuf (iter);
3897 
3898    sprintf (iter->buf, "\
3899                 atp = AsnLinkType(orig, %s);\n}\n    /* link in local tree */\n\
3900    if (atp == NULL) {\n\
3901         return NULL;\n}\n\n",
3902             GenerateTypeFromStack (iter, FALSE)
3903       );
3904    AsnIterTakeBuf (iter);
3905 
3906    if ( ! go_outer) {
3907       /* since not going to use generic set readers, need these... */
3908 
3909       sprintf (iter->buf, "\
3910         ptr = %sNew();\n\
3911         if (ptr == NULL) {\n\
3912         goto erret;\n}\n", which_stack->obj_name);
3913       AsnIterTakeBuf (iter);
3914       sprintf (iter->buf, "\
3915         if (AsnReadVal(aip, atp, &av) <= 0) { /* read the start struct */\n\
3916         goto erret;\n}\n\n");
3917       AsnIterTakeBuf (iter);
3918 
3919       sprintf (iter->buf, "   atp = AsnReadId(aip,amp, atp);\n");
3920       AsnIterTakeBuf (iter);
3921    }
3922 
3923    sprintf (iter->buf, "\
3924             func = NULL;\n\n");
3925    AsnIterTakeBuf (iter);
3926 }
3927 
3928 /****************************************************
3929 *
3930 * AsnCodeFunctionHeader(iter,type,name)
3931 *
3932 *****************************************/
3933 
3934 void
3935 AsnCodeFunctionHeader (AsnIterPtr iter, CharPtr type, CharPtr name)
3936 {
3937 
3938    sprintf (iter->buf, "\n\n/**************************************************\n");
3939    AsnIterTakeBuf (iter);
3940    sprintf (iter->buf, "*\n");
3941    AsnIterTakeBuf (iter);
3942    sprintf (iter->buf, "*    %s%s()\n", name, type);
3943    AsnIterTakeBuf (iter);
3944    sprintf (iter->buf, "*\n");
3945    AsnIterTakeBuf (iter);
3946    sprintf (iter->buf, "**************************************************/\n");
3947    AsnIterTakeBuf (iter);
3948 
3949    sprintf (iter->buf, "%s",
3950             AsnCodeStaticCandidate (iter) ? "static " : "NLM_EXTERN ");
3951    AsnIterTakeBuf (iter);
3952 
3953    if (StringCmp ("AsnWrite", type) == 0) {
3954       sprintf (iter->buf, "Boolean%s \n%s%s(", " LIBCALL", name, type); /* ) */
3955    } else {
3956       sprintf (iter->buf, "\n %sPtr%s\n%s%s(", name, " LIBCALL", name, type);   /* ) */
3957    }
3958    AsnIterTakeBuf (iter);
3959 }
3960 
3961 /*****************************
3962 *
3963 * AsnCodeWhichValSlot(atp,valdefine)
3964 *
3965 *****************************/
3966 
3967 CharPtr
3968 AsnCodeWhichValSlot (AsnTypePtr atp, CharPtr PNTR valdefine)
3969 {
3970    CharPtr         retval = NULL;
3971    static CharPtr  defptr = "ASNCODE_PTRVAL_SLOT";
3972    static CharPtr  defint = "ASNCODE_INTVAL_SLOT";
3973    static CharPtr  defbigint = "ASNCODE_BIGINTVAL_SLOT";
3974    static CharPtr  defreal = "ASNCODE_REALVAL_SLOT";
3975    static CharPtr  defbool = "ASNCODE_BOOLVAL_SLOT";
3976    static CharPtr  defbyte = "ASNCODE_BYTEVAL_SLOT";
3977 
3978    if (AsnCodeIsEnumType(atp)) {
3979       retval = "intvalue";
3980       if (valdefine != NULL) {
3981          *valdefine = defint;
3982       }
3983    } else {
3984       switch (atp->isa) {
3985          /********Uint1 types*******/
3986       case BOOLEAN_TYPE:
3987       case BITS_TYPE:
3988       case NULL_TYPE:
3989          retval = "boolvalue";
3990          if (valdefine != NULL) {
3991             *valdefine = defbool;
3992          }
3993          break;
3994          /********Int4**********/
3995       case INTEGER_TYPE:
3996          retval = "intvalue";
3997          if (valdefine != NULL) {
3998             *valdefine = defint;
3999          }
4000          break;
4001          /********Int8**********/
4002       case BIGINT_TYPE:
4003          retval = "bigintvalue";
4004          if (valdefine != NULL) {
4005             *valdefine = defbigint;
4006          }
4007          break;
4008          /*------Uint2---------*/
4009       case ENUM_TYPE:
4010          retval = "intvalue";
4011          if (valdefine != NULL) {
4012             *valdefine = defint;
4013          }
4014          break;
4015          /***********************************
4016           ****                           ****
4017           **** Pointer types, all are    ****
4018           **** handled by lower level    ****
4019           ****                           ****
4020           ***********************************/
4021       case OBID_TYPE:
4022       case OBDES_TYPE:
4023       case ANY_TYPE:
4024       case GENTIME_TYPE:
4025       default:
4026          retval = "ptrvalue";
4027          if (valdefine != NULL) {
4028             *valdefine = defptr;
4029          }
4030          break;
4031          /*********Real****/
4032       case REAL_TYPE:
4033          retval = "realvalue";
4034          if (valdefine != NULL) {
4035             *valdefine = defreal;
4036          }
4037          break;
4038          /*------CharPtr------*/
4039       case NUMERICSTRING_TYPE:
4040       case VISIBLESTRING_TYPE:
4041       case PRINTABLESTRING_TYPE:
4042          /*-------CharLenPtr, assume internally like CharPtr in C ---*/
4043       case TELETEXSTRING_TYPE:
4044       case VIDEOTEXSTRING_TYPE:
4045       case IA5STRING_TYPE:
4046       case GRAPHICSTRING_TYPE:
4047       case GENERALSTRING_TYPE:
4048       case CHARACTERSTRING_TYPE:
4049       case UTCTIME_TYPE:
4050          retval = "ptrvalue";
4051          if (valdefine != NULL) {
4052             *valdefine = defptr;
4053          }
4054          break;
4055          /*------String Store --- handled in lower level, as ptrvalue */
4056       case STRSTORE_TYPE:
4057       case OCTETS_TYPE:
4058          retval = "ptrvalue";
4059          if (valdefine != NULL) {
4060             *valdefine = defbyte;
4061          }
4062          break;
4063       }
4064    }
4065    return retval;
4066 }
4067 
4068 /***********************************************
4069 *
4070 * AsnCodeIterCall(iter, iter_SLOT,ATP,PLACETYPE)
4071 *
4072 **********************************8*/
4073 
4074 void
4075 AsnCodeIterCall (AsnIterPtr iter, FnPtr slot, AsnTypePtr atp, Int2 placetype)
4076 {
4077    AsnCodePush (iter, iter->atp, placetype, ASNITER_RECUR_NONE);
4078    if (slot != NULL) {
4079       ((AsnCodeIterFunc) slot) ((struct struct_asniter PNTR) iter);
4080    }
4081    AsnCodePop (iter, iter->atp, placetype);
4082 
4083 }
4084 
4085 /**********************************************************************************
4086 * AsnCodeIterRecursiveCall(iter, start_slot, end_slot, atp,placetype,recurtype)
4087 *******************/
4088 
4089 static void
4090 AsnCodeIterRecursiveCall (AsnIterPtr iter, FnPtr start_slot, FnPtr end_slot, AsnTypePtr atp, Int2 placetype, Int2 recurtype)
4091 {
4092    AsnTypePtr      branch_atp;
4093 
4094    if (start_slot != NULL) {
4095       ((AsnCodeIterFunc) start_slot) (iter);
4096    }
4097    /****************
4098     *  This recursive call is follow along SEQUENCE and CHOICE, etc.
4099     ***********/
4100    for (branch_atp = (AsnTypePtr) atp->branch; branch_atp != NULL;
4101         branch_atp = branch_atp->next) {
4102       iter->atp = branch_atp;
4103       iter->stack->slot_count++;
4104       AsnCodeIter (iter);       /* RECURSIVE CALL */
4105    }
4106 
4107    if (end_slot != NULL) {
4108       ((AsnCodeIterFunc) end_slot) (iter);
4109    }
4110 }
4111 
4112 
4113 /*******************************
4114 *
4115 * AsnCodePush(atp,type,recurtype)
4116 *
4117 *******************************/
4118 
4119 void
4120 AsnCodePush (AsnIterPtr iter, AsnTypePtr atp, Int2 type, Int2 recurtype)
4121 {
4122    AsnCodeNodePtr  node = (AsnCodeNodePtr)MemNew (sizeof (AsnCodeNode));
4123    char            buf[60];
4124    AsnOptionPtr    slot_option;
4125    AsnOptionPtr    obj_option;
4126 
4127    /*
4128     * only get >1 in the non-Push recursive call at the end of AsnCodeIter ()
4129     */
4130    node->slot_count = 0;
4131    node->opt_count = 0;
4132    if (atp->name) {
4133       slot_option = AsnOptionGet ((iter->atp->hints), OP_NCBIASNTOOL,
4134                                   OP_SLOT_NAME, (AsnOptionPtr) NULL);
4135       if (slot_option == (AsnOptionPtr) NULL) {
4136          node->slot_name =
4137             StringSave (AsnCodeCleanName (atp->name, buf,
4138                                           CLEAN_FOR_SLOT, iter -> acip -> maxDefineLength));
4139       } else {
4140          node->slot_name = StringSave ((char *)slot_option->data.ptrvalue);
4141          if ((iter->acip->debug_level) > 1) {
4142             AsnCodeShowDepth (iter);
4143             fprintf ((iter->acip -> bug_fp), "... override SLOT name %s found.\n",
4144                      (CharPtr) TESTNIL (node->slot_name));
4145          }
4146       }
4147       obj_option = AsnOptionGet ((iter->atp->hints), OP_NCBIASNTOOL,
4148                                  OP_OBJ_NAME, (AsnOptionPtr) NULL);
4149       if (obj_option == (AsnOptionPtr) NULL) {
4150          node->obj_name =
4151             StringSave (AsnCodeCleanName (atp->name, buf,
4152                                           CLEAN_FOR_OBJ_NAME, iter -> acip -> maxDefineLength));
4153       } else {
4154          node->obj_name = StringSave ((char *)obj_option->data.ptrvalue);
4155          if ((iter->acip->debug_level) > 1) {
4156             AsnCodeShowDepth (iter);
4157             fprintf ((iter->acip -> bug_fp), "... override OBJ name %s found.\n",
4158                      (CharPtr) TESTNIL (node->obj_name));
4159          }
4160       }
4161 
4162       node->asn_type_name =
4163          StringSave (AsnCodeCleanName (atp->name, buf,
4164                                        CLEAN_FOR_ASN_TYPE, iter -> acip -> maxDefineLength));
4165    }
4166    node->recur_type = recurtype;
4167    node->atp = atp;
4168    iter->atp = atp;
4169    iter->depth++;
4170    if ((iter->acip->debug_level) > 1) {
4171       AsnCodeShowDepth (iter);
4172       fprintf ((iter->acip -> bug_fp), "PUSH:%s(%d)=%s=%s\n",
4173                TESTNIL (node->slot_name), (int) type, TESTNIL (node->obj_name), TESTNIL (node->asn_type_name));
4174    }
4175    if (iter->stack != NULL) {
4176       iter->stack->inner = node;
4177    }
4178    node->outer = iter->stack;
4179    iter->stack = node;
4180    if (iter->base_of_stack == NULL) {
4181       iter->base_of_stack = node;
4182    }
4183    node->type = type;
4184 }
4185 
4186 
4187 /*******************************
4188 *
4189 * AsnCodePop(atp,type)
4190 *
4191 *******************************/
4192 
4193 void
4194 AsnCodePop (AsnIterPtr iter, AsnTypePtr atp, Int2 type)
4195 {
4196    AsnCodeNodePtr  node = iter->stack;
4197 
4198    if (node == NULL) {
4199       ErrPost (CTX_NCBIASN1, 101,
4200                "Poping empty stack");
4201       exit (2);
4202    }
4203    if (node->atp != atp || node->type != type) {
4204       ErrPost (CTX_NCBIASN1, 101,
4205                "AsnCodePop stack corrupted, expected: %s-%d , saw %s-%d",
4206                atp->name ? atp->name : "No atp name", (int) type,
4207                node->atp->name ? node->atp->name :
4208                "No node -> atp name", (int) type);
4209       exit (1);
4210    }
4211    iter->stack = iter->stack->outer;
4212    if (iter->stack == NULL) {
4213       iter->base_of_stack = NULL;
4214    } else {
4215       iter->stack->inner = NULL;
4216    }
4217    iter->atp = iter->stack ? iter->stack->atp : NULL;
4218    if ((iter->acip->debug_level) > 1) {
4219       AsnCodeShowDepth (iter);
4220       fprintf ((iter->acip -> bug_fp), "POP\n");
4221    }
4222    iter->depth--;
4223    MemFree (node->slot_name);
4224    MemFree (node->obj_name);
4225    MemFree (node->asn_type_name);
4226    MemFree (node);
4227 }
4228 
4229 /***************************************
4230 *
4231 * AsnIterNodeBack(node,recurPt)
4232 *
4233 ***************************************/
4234 
4235 static AsnCodeNodePtr
4236 AsnIterNodeBack (AsnCodeNodePtr node, Int2Ptr recurPt)
4237 {
4238    AsnCodeNodePtr  retval = NULL;
4239    if (node) {
4240       retval = node->outer;
4241       /*------- the context of the call is really one up from here
4242                is this is handling an unnamed SEQUENCE or CHOICE ---*/
4243       if (node->type == ASNITER_Pseudo_USER_TYPE)
4244          retval = retval->outer;
4245       if (retval == NULL)
4246          return retval;
4247       if (retval->recur_type == ASNITER_RECUR_WAS_LAST)
4248          retval = retval->outer;
4249       if (recurPt != NULL) {
4250          *recurPt = retval->recur_type;
4251       }
4252    }
4253    return retval;
4254 }
4255 
4256 /************************
4257 *
4258 * AsnCodeIterRecurLevel(iter)
4259 *
4260 ************************/
4261 
4262 Int2
4263 AsnCodeIterRecurLevel (AsnIterPtr iter)
4264 {
4265    Int2            retval = ASNITER_RECUR_NONE;
4266    AsnCodeNodePtr  node, back_node;
4267    Int2            recur = ASNITER_RECUR_NONE, previous_recur = ASNITER_RECUR_NONE;
4268 
4269    if (iter) {
4270       node = iter->stack;
4271       node = AsnIterNodeBack (node, &recur);
4272       back_node = AsnIterNodeBack (node, &previous_recur);
4273       switch (recur) {
4274       case ASNITER_RECUR_NONE:
4275          retval = RECUR_OUTER;
4276          break;
4277       case ASNITER_RECUR_SEQSET:
4278          retval = RECUR_SEQSET;
4279          break;
4280       case ASNITER_RECUR_CHOICE:
4281          retval = RECUR_CHOICE;
4282          break;
4283       case ASNITER_RECUR_SETOF:
4284 
4285          /*
4286           * If this while loop fires, we are unlikely to really handle this
4287           * case.  However, the form is so bad, we will let it pass, for now.
4288           */
4289          while (previous_recur == ASNITER_RECUR_SETOF)
4290             back_node = AsnIterNodeBack (back_node, &previous_recur);
4291 
4292          switch (previous_recur) {
4293          case ASNITER_RECUR_NONE:
4294             retval = RECUR_SETOF_OUTER;
4295             break;
4296          case ASNITER_RECUR_SEQSET:
4297             retval = RECUR_SETOF_SEQSET;
4298             break;
4299          case ASNITER_RECUR_CHOICE:
4300             retval = RECUR_SETOF_CHOICE;
4301             break;
4302          }
4303          break;
4304       }
4305    }
4306    return retval;
4307 }
4308 
4309 /******************************
4310 *
4311 *  AsnCodeIter(atp)
4312 *
4313 *******************************/
4314 void
4315 AsnCodeIter (AsnIterPtr iter)
4316 {
4317 
4318    if (iter == NULL)
4319       return;
4320 
4321    if (iter->atp != NULL)
4322       if (iter->atp->type != NULL) {
4323          if (AsnCodeIsEnumType (iter->atp->type)) {
4324             AsnCodeIterCall (iter, iter->basetype, iter->atp, ENUM_TYPE);
4325          } else if (iter->atp->type->isa < 301) {
4326             AsnCodeIterCall (iter, iter->less301err, NULL, 0);
4327             /*------- USER OBJECTS -------*/
4328          } else if (iter->atp->type->isa > 400) {
4329             AsnCodeIterCall (iter, iter->userobj, iter->atp,
4330                              ASNITER_USER_TYPE);
4331 
4332             /*------SETs and SEQUENCEs ---*/
4333 
4334          } else if (iter->atp->type->isa == SEQ_TYPE) {
4335             AsnCodePush (iter, iter->atp, SEQ_TYPE, ASNITER_RECUR_SEQSET);
4336             AsnCodeIterRecursiveCall (iter, iter->seqstart,
4337                                       iter->seqend, iter->atp, SEQ_TYPE,
4338                                       ASNITER_RECUR_SEQSET);
4339 
4340             AsnCodePop (iter, iter->atp, SEQ_TYPE);
4341          } else if (iter->atp->type->isa == SET_TYPE) {
4342             AsnCodePush (iter, iter->atp, SET_TYPE, ASNITER_RECUR_SEQSET);
4343             AsnCodeIterRecursiveCall (iter, iter->setstart, iter->setend,
4344                                  iter->atp, SET_TYPE, ASNITER_RECUR_SEQSET);
4345 
4346             AsnCodePop (iter, iter->atp, SET_TYPE);
4347 
4348             /*-------- CHOICE ---*/
4349 
4350          } else if (iter->atp->type->isa == CHOICE_TYPE) {
4351             AsnCodePush (iter, iter->atp, CHOICE_TYPE, ASNITER_RECUR_CHOICE);
4352             AsnCodeIterRecursiveCall (iter, iter->choicestart, iter->choiceend, iter->atp,
4353                                       CHOICE_TYPE, ASNITER_RECUR_CHOICE);
4354 
4355             AsnCodePop (iter, iter->atp, CHOICE_TYPE);
4356 
4357 
4358             /*----- SET OF or SEQ OF-------*/
4359          } else if (iter->atp->type->isa == SETOF_TYPE ||
4360                     iter->atp->type->isa == SEQOF_TYPE) {
4361             AsnCodePush (iter, iter->atp, iter->atp->type->isa, ASNITER_RECUR_SETOF);
4362             iter->atp = (AsnTypePtr) (iter->atp->branch);
4363             AsnCodeIter (iter);
4364             AsnCodePop (iter, iter->atp, iter->atp->type->isa);
4365          } else if (ISA_BASETYPE (iter->atp->type->isa)) {
4366             AsnCodeIterCall (iter, iter->basetype, iter->atp,
4367                              ASNITER_BASE_TYPE);
4368          }
4369       } else {
4370          AsnCodeIterCall (iter, iter->undef301err, NULL, ASNITER_LESS300);
4371       }
4372 
4373 
4374    return;
4375 }
4376 void
4377 AsnCode (AsnCodeInfoPtr acip)
4378 {
4379    FILE           *fp;
4380    int             numvalue = 0, numtype = 0, nummod = 0;
4381    AsnProc         p;
4382    AsnModulePtr    curr_mod;
4383    AsnTypePtr      curr_type, atp;
4384    AsnTmpTypePtr   attp;
4385    AsnTmpValuePtr  attvp;
4386    char            buf[BUF_LEN];
4387    CharPtr         pnt, hold_buf;
4388    CharPtr         include_name = NULL;
4389    AsnIterPtr      iter = (AsnIterPtr)MemNew (sizeof (AsnIter));
4390    Int2            mode;
4391    Char            dateTime[24];
4392 
4393    CharPtr loadname = acip -> loadname;
4394    CharPtr filename = acip -> filename;
4395    Boolean do_bit_twiddle  = acip -> do_bit_twiddle;
4396    Boolean force_choice_struct = acip -> force_choice_struct;
4397    CharPtr include_filename = acip ->  include_filename;
4398    CharPtr object_manager_entry = acip -> object_manager_entry;
4399    CharPtr objlabel = acip->object_label;
4400    CharPtr objnameuc = NULL, objnamemc = NULL, objnamety = NULL;
4401    char            objnamebuf[BUF_LEN];
4402    AsnModulePtr amp = acip -> amp;
4403    AsnModulePtr last_amp = acip -> last_amp;
4404 
4405    CharPtr         use_load = StringSave (loadname);
4406    Char include_open = acip->use_quoted_include ? '\"' : '<';
4407    Char include_close = acip->use_quoted_include ? '\"' : '>';
4408 
4409    iter -> acip = acip;
4410    iter -> do_opt_bits = do_bit_twiddle;
4411    iter -> do_chs_struct = force_choice_struct;
4412    StringCpy (buf, filename);
4413    /*-----remove any erroneous extension----*/
4414    pnt = buf;
4415    while (*pnt != '\0')
4416       pnt++;
4417    while ((pnt > buf) && (*pnt != '.'))
4418       pnt--;
4419    if (*pnt == '.')
4420       *pnt = '\0';
4421    hold_buf = StringSave (buf);
4422    StringCat (buf, ".h");
4423    include_name = StringSave (buf);
4424 
4425    fp = fopen (buf, "w");
4426 
4427    if (fp == NULL) {
4428       AsnIoErrorMsg (NULL, 82, buf);
4429       return;
4430    }
4431    curr_mod = amp;
4432    p.curr_tmptype = &p.root_tmptype;    /* fake node to start */
4433    p.curr_tmpvalue = &p.root_tmpvalue;
4434    p.root_tmptype.next = NULL;
4435    p.root_tmpvalue.next = NULL;
4436 
4437    while (curr_mod != NULL) {
4438       nummod++;
4439       curr_type = curr_mod->types;
4440       while (curr_type != NULL) {
4441          curr_type = AsnOutAddType (&p, curr_type);
4442       }
4443       curr_mod = curr_mod->next;
4444    }
4445 
4446    /******************** set index values ***************************/
4447 
4448    attvp = p.root_tmpvalue.next;
4449    while (attvp != NULL) {
4450       attvp->index = numvalue;
4451       numvalue++;
4452       attvp = attvp->next;
4453    }
4454 
4455    attp = p.root_tmptype.next;
4456    while (attp != NULL) {
4457       attp->index = numtype;
4458       numtype++;
4459       attp = attp->next;
4460    }
4461 
4462 
4463    iter->fp = fp;
4464 
4465    iter->indent = 0;
4466    iter->leadingspaces = TRUE;
4467    iter->basetype = (FnPtr) AsnCode_basetype;
4468    iter->choiceend = (FnPtr) AsnCode_choiceend;
4469    iter->choicestart = (FnPtr) AsnCode_choicestart;
4470    iter->less301err = (FnPtr) AsnIterGenericDie301;
4471    iter->seqend = (FnPtr) AsnCode_seqend;
4472    iter->seqstart = (FnPtr) AsnCode_seqstart;
4473    iter->setstart = (FnPtr) AsnCode_setstart;
4474    iter->setend = (FnPtr) AsnCode_setend;
4475    iter->undef301err = (FnPtr) AsnCode_under301err;
4476    iter->userobj = (FnPtr) AsnCode_userobj;
4477    AsnCodeNewRoutine (iter);
4478 
4479    /*
4480     * Pre generation analysis for assigning names to unnamed internal objects
4481     * and setting the flag to note that an object need be used as a linked
4482     * list.
4483     */
4484    for (curr_mod = amp; curr_mod; curr_mod = curr_mod->next) {
4485       for (mode = ITER_ASSIGN; mode <= ITER_CHECK_LIST; mode++) {
4486          iter->mode = mode;
4487          atp = curr_mod->types;
4488          /*------- loop through each TYPE ::= along the main list ---*/
4489          for (; atp != NULL; atp = atp->next) {
4490             if ((acip->debug_level) >= 1) {
4491                fprintf ((acip -> bug_fp), "MODE:%d:name=%s\n",
4492                      (int) mode, atp->name != NULL ? atp->name : "No NAME");
4493                fflush ((acip -> bug_fp));
4494             }
4495             if (!atp->imported) {       /* must be defined elsewhere */
4496                iter->atp = atp;
4497                AsnCodeIter (iter);
4498                fflush (fp);
4499             }
4500          }
4501          fflush (fp);
4502       }
4503       /* --- if just did last module in first filename, stop --- */
4504       if (curr_mod == last_amp && mode == ITER_ASSIGN)
4505          break;
4506    }
4507 
4508    /*
4509     * Object (*.h file with C object definitions) Generated here
4510     */
4511    mode = ITER_OBJECTS;
4512    iter->mode = mode;
4513 
4514    for (curr_mod = amp; curr_mod; curr_mod = curr_mod->next) {
4515       atp = curr_mod->types;
4516       if (curr_mod == amp) {
4517          iter->module_name = StringSave (hold_buf);
4518          sprintf (iter->buf, "#ifndef _%s_ \n", hold_buf);
4519          AsnIterTakeBuf (iter);
4520          sprintf (iter->buf, "#define _%s_ \n", hold_buf);
4521          AsnIterTakeBuf (iter);
4522          sprintf (iter->buf, "\n#undef NLM_EXTERN\n#ifdef NLM_IMPORT\n#define NLM_EXTERN NLM_IMPORT\n#else\n#define NLM_EXTERN extern\n#endif\n\n");
4523          AsnIterTakeBuf (iter);
4524          sprintf (iter->buf, "\n#ifdef __cplusplus\nextern \"C\" { /* } */\n#endif\n");
4525          AsnIterTakeBuf (iter);
4526       }
4527       sprintf (iter->buf, "\n\n/**************************************************\n");
4528       AsnIterTakeBuf (iter);
4529       sprintf (iter->buf, "*\n");
4530       AsnIterTakeBuf (iter);
4531       sprintf (iter->buf, "*    Generated objects for Module %s\n", curr_mod->modulename);
4532       AsnIterTakeBuf (iter);
4533       Nlm_DayTimeStr(dateTime, TRUE, TRUE);
4534       sprintf (iter->buf, "*    Generated using ASNCODE %sat %s\n", strtok(RCS_Rev, "$"), dateTime);
4535       AsnIterTakeBuf (iter);
4536       sprintf (iter->buf, "*\n");
4537       AsnIterTakeBuf (iter);
4538       sprintf (iter->buf, "**************************************************/\n");
4539       AsnIterTakeBuf (iter);
4540 
4541       if (curr_mod == amp) {
4542          sprintf (iter->buf, "\nNLM_EXTERN Boolean LIBCALL\n%sAsnLoad PROTO((void));\n",
4543                   iter->module_name);
4544          AsnIterTakeBuf (iter);
4545       }
4546 
4547       AsnCodeFinishedRoutine (iter);
4548       AsnCodeNewRoutine (iter);
4549 
4550       /*------- loop through each TYPE ::= along the main list ---*/
4551       for (; atp != NULL; atp = atp->next) {
4552          if ((acip->debug_level) >= 1) {
4553             fprintf ((acip -> bug_fp), "MODE:%d:name=%s\n",
4554                      (int) mode, atp->name != NULL ? atp->name : "No NAME");
4555             fflush ((acip -> bug_fp));
4556          }
4557          if (!atp->imported) {  /* must be defined elsewhere */
4558             iter->atp = atp;
4559             AsnCodeNewRoutine (iter);
4560             AsnCodeIter (iter);
4561             AsnCodeFinishedRoutine (iter);
4562             AsnCodeCheckFileDoneRoutines (iter);
4563             fflush (fp);
4564          }
4565       }
4566 
4567       if (curr_mod == last_amp) {
4568          AsnCodeNewRoutine (iter);
4569          sprintf (iter->buf, "#ifdef __cplusplus\n/* { */ }\n#endif\n\n");
4570          AsnIterTakeBuf (iter);
4571          sprintf (iter->buf, "#endif /* _%s_ */\n", hold_buf);
4572          AsnIterTakeBuf (iter);
4573          sprintf (iter->buf, "\n#undef NLM_EXTERN\n#ifdef NLM_EXPORT\n#define NLM_EXTERN NLM_EXPORT\n#else\n#define NLM_EXTERN\n#endif\n\n");
4574          AsnIterTakeBuf (iter);
4575          AsnCodeFinishedRoutine (iter);
4576          AsnCodeCheckFileDoneRoutines (iter);
4577       }
4578 
4579       fflush (fp);
4580 
4581       /* --- if just did last module in first filename, stop --- */
4582       if (curr_mod == last_amp)
4583          break;
4584    }
4585    fclose (fp);
4586    StringCpy (buf, hold_buf);
4587    StringCat (buf, ".c");
4588 
4589    fp = fopen (buf, "w");
4590    iter->fp = fp;
4591    AsnCodeNewRoutine (iter);
4592    if (fp == NULL) {
4593       AsnIoErrorMsg (NULL, 82, buf);
4594       return;
4595    }
4596    sprintf (iter->buf, "#include <asn.h>\n");
4597    AsnIterTakeBuf (iter);
4598    sprintf (iter->buf, "\n#define NLM_GENERATED_CODE_PROTO\n\n");
4599    AsnIterTakeBuf (iter);
4600    if (include_filename) {
4601       sprintf (iter->buf,
4602                "#include %c%s%c\n", include_open, include_filename, include_close);
4603       AsnIterTakeBuf (iter);
4604    }
4605    sprintf (iter->buf, "#include %c%s%c\n", include_open, include_name, include_close);
4606    AsnIterTakeBuf (iter);
4607    sprintf (iter->buf, "\nstatic Boolean loaded = FALSE;\n\n");
4608    AsnIterTakeBuf (iter);
4609    StringCpy (buf, use_load);
4610    /*-----remove any erroneous extension----*/
4611    pnt = buf;
4612    while (*pnt != '\0')
4613       pnt++;
4614    while ((pnt > buf) && (*pnt != '.'))
4615       pnt--;
4616    if (*pnt == '.')
4617       *pnt = '\0';
4618    hold_buf = StringSave (buf);
4619    StringCat (buf, ".h");
4620    include_name = StringSave (buf);
4621    sprintf (iter->buf, "#include %c%s%c\n\n", include_open, include_name, include_close);
4622    AsnIterTakeBuf (iter);
4623    if (object_manager_entry != NULL) {
4624      if (objlabel == NULL) {
4625        objlabel = object_manager_entry;
4626      }
4627      objnamety = StringSave (AsnCodeCleanName (object_manager_entry, objnamebuf, CLEAN_FOR_SLOT, sizeof (objnamebuf)));
4628      objnameuc = StringSave (AsnCodeCleanName (object_manager_entry, objnamebuf, SLOT_POLISH, sizeof (objnamebuf)));
4629      objnamemc = StringSave (AsnCodeCleanName (object_manager_entry, objnamebuf, CLEAN_FOR_OBJ_NAME, sizeof (objnamebuf)));
4630    }
4631    sprintf (iter->buf, "#ifndef NLM_EXTERN_LOADS\n#define NLM_EXTERN_LOADS {}\n#endif\n\n");
4632    AsnIterTakeBuf (iter);
4633    if (object_manager_entry != NULL) {
4634      sprintf (iter->buf, "static Pointer LIBCALLBACK %sNewFunc (void)\n{\n\treturn (Pointer) %sNew();\n}\n\n", objnamemc, objnamemc);
4635      AsnIterTakeBuf (iter);
4636      sprintf (iter->buf, "static Pointer LIBCALLBACK %sFreeFunc (Pointer data)\n{\n\treturn (Pointer) %sFree ((%sPtr) data);\n}\n\n", objnamemc, objnamemc, objnamemc);
4637      AsnIterTakeBuf (iter);
4638      sprintf (iter->buf, "static Boolean LIBCALLBACK %sAsnWriteFunc (Pointer data, AsnIoPtr aip, AsnTypePtr atp)\n{\n", objnamemc);
4639      AsnIterTakeBuf (iter);
4640      sprintf (iter->buf, "\treturn %sAsnWrite ((%sPtr) data, aip, atp);\n}\n\n", objnamemc, objnamemc);
4641      AsnIterTakeBuf (iter);
4642      sprintf (iter->buf, "static Pointer LIBCALLBACK %sAsnReadFunc (AsnIoPtr aip, AsnTypePtr atp)\n{\n", objnamemc);
4643      AsnIterTakeBuf (iter);
4644      sprintf (iter->buf, "\treturn (Pointer) %sAsnRead (aip, atp);\n}\n\n", objnamemc, objnamemc);
4645      AsnIterTakeBuf (iter);
4646      sprintf (iter->buf, "static Int2 LIBCALLBACK %sLabelFunc (Pointer data, CharPtr buffer, Int2 buflen, Uint1 content)\n{\n", objnamemc);
4647      AsnIterTakeBuf (iter);
4648      sprintf (iter->buf, "\treturn %sLabel ((%sPtr) data, buffer, buflen, content);\n}\n\n", objnamemc, objnamemc);
4649      AsnIterTakeBuf (iter);
4650    }
4651    sprintf (iter->buf, "NLM_EXTERN Boolean LIBCALL\n%sAsnLoad(void)\n{\n\n\tif ( ! loaded) {\n",
4652             iter->module_name);
4653    AsnIterTakeBuf (iter);
4654       sprintf (iter->buf, "\t\tNLM_EXTERN_LOADS\n\n\t\tif ( ! AsnLoad ())\n\t\t\treturn FALSE;\n");
4655    AsnIterTakeBuf (iter);
4656    sprintf (iter->buf, "\t\tloaded = TRUE;\n\t}\n\n");
4657    AsnIterTakeBuf (iter);
4658    if (object_manager_entry != NULL) {
4659      sprintf (iter->buf, "\tObjMgrTypeLoad (OBJ_%s, \"%s\", \"%s\", \"%s\",\n",
4660               objnameuc, object_manager_entry, objnamemc, objlabel);
4661      AsnIterTakeBuf (iter);
4662      sprintf (iter->buf, "\t\t%s, %sNewFunc, %sAsnReadFunc, %sAsnWriteFunc,\n",
4663               objnameuc, objnamemc, objnamemc, objnamemc);
4664      AsnIterTakeBuf (iter);
4665      sprintf (iter->buf, "\t\t%sFreeFunc, %sLabelFunc, %sSubTypeFunc);\n\n",
4666               objnamemc, objnamemc, objnamemc);
4667      AsnIterTakeBuf (iter);
4668    }
4669    sprintf (iter->buf, "\treturn TRUE;\n}\n\n");
4670    AsnIterTakeBuf (iter);
4671       sprintf (iter->buf, "\n\n/**************************************************\n");
4672    AsnIterTakeBuf (iter);
4673    sprintf (iter->buf, "*    Generated object loaders for Module %s\n",
4674             curr_mod->modulename);
4675    AsnIterTakeBuf (iter);
4676    Nlm_DayTimeStr(dateTime, TRUE, TRUE);
4677    sprintf (iter->buf, "*    Generated using ASNCODE %sat %s\n", strtok(RCS_Rev, "$"), dateTime);
4678    AsnIterTakeBuf (iter);
4679    sprintf (iter->buf, "*\n");
4680    AsnIterTakeBuf (iter);
4681    sprintf (iter->buf, "**************************************************/\n");
4682    AsnIterTakeBuf (iter);
4683 
4684    AsnCodeFinishedRoutine (iter);
4685    AsnCodeCheckFileDoneRoutines (iter);
4686 
4687 
4688    /*
4689     * Actual Object Loaders/Writers Generated here
4690     */
4691    for (curr_mod = amp; curr_mod; curr_mod = curr_mod->next) {
4692       /*------- loop through each TYPE ::= along the main list ---*/
4693       for (atp = curr_mod->types; atp != NULL; atp = atp->next) {
4694          if ((acip->debug_level) >= 1) {
4695             fprintf ((acip -> bug_fp), "MODE:%d:name=%s\n",
4696                      (int) mode, (atp->name != NULL ? atp->name : "No NAME"));
4697             fflush ((acip -> bug_fp));
4698          }
4699          for (mode = ITER_NEW; mode <= ITER_WRITE; mode++) {
4700             iter->mode = mode;
4701             iter->atp = atp;
4702             AsnCodeNewRoutine (iter);
4703             AsnCodeIter (iter);
4704             AsnCodeFinishedRoutine (iter);
4705          }
4706          /* Do all 4 modes for an atp, then produce output to file */
4707          AsnCodeCheckFileDoneRoutines (iter);
4708          fflush (fp);
4709       }
4710       if (curr_mod == last_amp)
4711          break;
4712    }
4713 
4714 
4715 
4716    MemFree (iter);
4717 
4718    fclose (fp);
4719    return;
4720 }
4721 

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.