1 /*  subutil.c
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *               National Center for Biotechnology Information
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government have not placed any restriction on its use or reproduction.
13 *
14 *  Although all reasonable efforts have been taken to ensure the accuracy
15 *  and reliability of the software and data, the NLM and the U.S.
16 *  Government do not and cannot warrant the performance or results that
17 *  may be obtained by using this software or data. The NLM and the U.S.
18 *  Government disclaim all warranties, express or implied, including
19 *  warranties of performance, merchantability or fitness for any particular
20 *  purpose.
21 *
22 *  Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * File Name:  subutil.c
27 *
28 * Author:  James Ostell
29 *
30 * Version Creation Date: 11/3/93
31 *
32 * $Revision: 6.104 $
33 *
34 * File Description: Utilities for creating ASN.1 submissions
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date       Name        Description of modification
39 * -------  ----------  -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44 
45 /** for ErrPostEx() ****/
46 
47 static char *this_module = "ncbiapi";
48 #define THIS_MODULE this_module
49 static char *this_file = __FILE__;
50 #define THIS_FILE this_file
51 
52 /**********************/
53 
54 #include <subutil.h>
55 #include <valid.h>
56 #include <seqport.h>
57 #include <utilpars.h>
58 #include <sqnutils.h>
59 #include <explore.h>
60 
61 /*****************************************************************************
62 *
63 *   prototypes for internal functions
64 *
65 *****************************************************************************/
66 static BioseqPtr NCBISubNewBioseq (
67     NCBISubPtr submission ,
68     CharPtr local_name ,
69     CharPtr genbank_locus ,
70     CharPtr genbank_accession ,
71     Int4 gi_number ,
72     Int2 molecule_class,
73     Int2 molecule_type ,
74     Int4 length ,
75     Int2 topology ,
76     Int2 strandedness );
77 
78 static Boolean StripNonAsciiChars (CharPtr str);
79 static BioseqPtr GetBioseqFromChoice (NCBISubPtr nsp, SeqEntryPtr the_seq,
80                                       CharPtr local_name, CharPtr the_routine);
81 static Boolean AddFeatureToEntry (
82     NCBISubPtr submission,
83     SeqEntryPtr entry ,
84     SeqFeatPtr feature );
85 
86 
87 /*****************************************************************************
88 *
89 *   DefaultSubErrorFunc(msg)
90 *       default error handler
91 *
92 *****************************************************************************/
DefaultSubErrorFunc(CharPtr msg)93 NLM_EXTERN Boolean DefaultSubErrorFunc (CharPtr msg)
94 {
95     Message(MSG_ERROR, msg);
96     return TRUE;
97 }
98 
99 /*****************************************************************************
100 *
101 *   Create/Free the SubmitBlock
102 *
103 *****************************************************************************/
NCBISubCreate(CharPtr last_name,CharPtr first_name,CharPtr middle_name,CharPtr initials,CharPtr suffix,CharPtr affil,CharPtr div,CharPtr street,CharPtr city,CharPtr sub,CharPtr country,CharPtr postal_code,CharPtr phone,CharPtr fax,CharPtr email,Boolean hold_until_publish,Int2 release_month,Int2 release_day,Int2 release_year)104 NLM_EXTERN NCBISubPtr NCBISubCreate (
105     CharPtr last_name,
106     CharPtr first_name,
107     CharPtr middle_name,
108     CharPtr initials,  /* separated by periods, no initial for last name */
109     CharPtr suffix,    /* Jr. Sr. III */
110     CharPtr affil,        /* e.g. "Xyz University" */
111     CharPtr div,          /* e.g. "Dept of Biology" */
112     CharPtr street,       /* e.g. "123 Academic Road" */
113     CharPtr city,         /* e.g. "Metropolis" */
114     CharPtr sub,          /* e.g. "Massachusetts" */
115     CharPtr country ,     /* e.g. "USA" */
116     CharPtr postal_code,  /* e.g."02133" */
117     CharPtr phone ,
118     CharPtr fax ,
119     CharPtr email,
120     Boolean hold_until_publish ,
121     Int2 release_month ,
122     Int2 release_day ,
123     Int2 release_year )
124 {
125     NCBISubPtr nsp;
126     SeqSubmitPtr ssp;
127     SubmitBlockPtr sbp;
128     ContactInfoPtr cip;
129     DatePtr dp;
130     AuthorPtr aup;
131     PersonIdPtr pip;
132     AffilPtr ap;
133     NameStdPtr nmstdp;
134 
135     ErrSetOpts(ERR_ADVISE, ERR_LOG_OFF);
136 
137     if (! SeqEntryLoad())     /* can't find ncbi files */
138     {
139         Message(MSG_ERROR, "Can't load NCBI data files");
140         return NULL;
141     }
142 
143     nsp = MemNew(sizeof(NCBISub));
144 
145     ssp = SeqSubmitNew();
146     nsp->ssp = ssp;
147     ssp->datatype = 1;    /* seqentrys */
148 
149     sbp = SubmitBlockNew();
150     ssp->sub = sbp;
151     sbp->hup = hold_until_publish;
152 
153     if (release_year != 0) {
154             dp = DateNew();
155             if (! DateWrite(dp, release_year, release_month,
156                             release_day, NULL)) {
157                 ErrShow();
158                 DateFree(dp);
159             } else {
160                 sbp->reldate = dp;
161             }
162     } else if(hold_until_publish) {
163             dp = DateCurr();
164             if (dp != NULL) {
165                 dp->data [3] = 0; /* force to end of month */
166                 sbp->reldate = DateAdvance(dp, 12); /* one year from now */
167             }
168         }
169 
170     cip = ContactInfoNew();
171     sbp->contact = cip;
172 
173     nmstdp = NameStdNew();
174     nmstdp->names[0] = StringSaveNoNull(last_name);
175     nmstdp->names[1] = StringSaveNoNull(first_name);
176     nmstdp->names[2] = StringSaveNoNull(middle_name);
177     nmstdp->names[4] = StringSaveNoNull(initials);
178     nmstdp->names[5] = StringSaveNoNull(suffix);
179 
180     pip = PersonIdNew();
181     pip->choice = 2;   /* name */
182     pip->data = (Pointer)nmstdp;
183 
184     aup = AuthorNew();
185     aup->name = pip;
186 
187     cip->contact = aup;
188 
189     ap = AffilNew();
190     aup->affil = ap;
191     ap->choice = 2;    /* std affil */
192     ap->affil = StringSaveNoNull(affil);
193     ap->div = StringSaveNoNull(div);
194     ap->city = StringSaveNoNull(city);
195     ap->sub = StringSaveNoNull(sub);
196     ap->country = StringSaveNoNull(country);
197     ap->street = StringSaveNoNull(street);
198     ap->postal_code = StringSaveNoNull(postal_code);
199     ap->phone = StringSaveNoNull(phone);
200     ap->fax = StringSaveNoNull(fax);
201     ap->email = StringSaveNoNull(email);
202 
203     return nsp;
204 }
205 
206 /***********************************************************************
207 *
208 *   submittor key is used for the Dbtag.db field, if not NULL.
209 *      local_name of the sequence will be type general in this case, not
210 *      type local
211 *
212 ************************************************************************/
213 
DefineSubmittorKey(NCBISubPtr nsp,CharPtr submittor_key)214 NLM_EXTERN Boolean DefineSubmittorKey(
215     NCBISubPtr nsp,
216     CharPtr submittor_key )
217 {
218     if (nsp == NULL)
219         return FALSE;
220     if (nsp->submittor_key != NULL)
221         return FALSE;
222     nsp->submittor_key = StringSaveNoNull(submittor_key);
223     return TRUE;
224 }
225 
226 /**** This function is obsolete.. replaced by NCBISubCreate() ****/
227 
NCBISubBuild(CharPtr name,CharPtr PNTR address,CharPtr phone,CharPtr fax,CharPtr email,Boolean hold_until_publish,Int2 release_month,Int2 release_day,Int2 release_year)228 NLM_EXTERN NCBISubPtr NCBISubBuild (
229     CharPtr name,
230     CharPtr PNTR address ,
231     CharPtr phone ,
232     CharPtr fax ,
233     CharPtr email,
234     Boolean hold_until_publish ,
235     Int2 release_month,              /* all 0 if no hold date */
236     Int2 release_day,
237     Int2 release_year )
238 {
239     NCBISubPtr nsp;
240     SeqSubmitPtr ssp;
241     SubmitBlockPtr sbp;
242     ContactInfoPtr cip;
243     DatePtr dp;
244     ValNodePtr vnp;
245 
246     ErrSetOpts(ERR_ADVISE, ERR_LOG_OFF);
247 
248     if (! SeqEntryLoad())     /* can't find ncbi files */
249     {
250         Message(MSG_ERROR, "Can't load NCBI data files");
251         return NULL;
252     }
253 
254     nsp = MemNew(sizeof(NCBISub));
255 
256     ssp = SeqSubmitNew();
257     nsp->ssp = ssp;
258     ssp->datatype = 1;    /* seqentrys */
259 
260     sbp = SubmitBlockNew();
261     ssp->sub = sbp;
262     sbp->hup = hold_until_publish;
263 
264     if (release_year != 0)
265     {
266         dp = DateNew();
267         if (! DateWrite(dp, release_year, release_month, release_day, NULL))
268         {
269             ErrShow();
270             DateFree(dp);
271         }
272         else
273             sbp->reldate = dp;
274     }
275 
276     cip = ContactInfoNew();
277     sbp->contact = cip;
278 
279     cip->name = StringSaveNoNull(name);
280     while (* address != NULL)
281     {
282         vnp = ValNodeNew(cip->address);
283         if (cip->address == NULL)
284             cip->address = vnp;
285         vnp->data.ptrvalue = (Pointer)(StringSaveNoNull(*address));
286         address++;
287     }
288 
289     cip->phone = StringSaveNoNull(phone);
290     cip->fax = StringSaveNoNull(fax);
291     cip->email = StringSaveNoNull(email);
292 
293     return nsp;
294 }
295 
296 /*****************************************************************************
297 *
298 *   ADD tool to the Submission
299 *
300 *****************************************************************************/
AddToolToSub(NCBISubPtr nsp,CharPtr tool)301 NLM_EXTERN Boolean AddToolToSub (
302     NCBISubPtr nsp,
303     CharPtr tool )
304 {
305     SeqSubmitPtr ssp;
306     SubmitBlockPtr sbp;
307 
308     if (nsp == NULL) {
309         return FALSE;
310     }
311     ssp = nsp->ssp;
312     if (ssp == NULL) {
313         return FALSE;
314     }
315     sbp = ssp->sub;
316     sbp->tool = Nlm_StringSave(tool);
317 
318     return TRUE;
319 }
320 
321 /*****************************************************************************
322 *
323 *   ADD comments to the Submission
324 *
325 *****************************************************************************/
AddCommentToSub(NCBISubPtr nsp,CharPtr comment)326 NLM_EXTERN Boolean AddCommentToSub (
327     NCBISubPtr nsp,
328     CharPtr comment )
329 {
330     SeqSubmitPtr ssp;
331     SubmitBlockPtr sbp;
332 
333     if (nsp == NULL) {
334         return FALSE;
335     }
336     ssp = nsp->ssp;
337     if (ssp == NULL) {
338         return FALSE;
339     }
340     sbp = ssp->sub;
341     sbp->comment = Nlm_StringSave(comment);
342 
343     return TRUE;
344 }
345 /*****************************************************************************
346 *
347 *   ADD submission type to the Submission
348 *
349 *****************************************************************************/
AddTypeToSub(NCBISubPtr nsp,Uint1 type)350 NLM_EXTERN Boolean AddTypeToSub (
351     NCBISubPtr nsp,
352     Uint1 type )
353 {
354     SeqSubmitPtr ssp;
355     SubmitBlockPtr sbp;
356 
357     if (nsp == NULL) {
358         return FALSE;
359     }
360     ssp = nsp->ssp;
361     if (ssp == NULL) {
362         return FALSE;
363     }
364     sbp = ssp->sub;
365     sbp->subtype = type;
366 
367     return TRUE;
368 }
369 
370 /*****************************************************************************
371 *
372 *   Write the Submission to a disk file
373 *
374 *****************************************************************************/
NCBISubWrite(NCBISubPtr ssp,CharPtr filename)375 NLM_EXTERN Boolean NCBISubWrite (
376     NCBISubPtr ssp,
377     CharPtr filename )
378 {
379     AsnIoPtr aip;
380     Boolean retval = FALSE;
381 
382     aip = AsnIoOpen(filename, "w");
383     if (aip == NULL)
384     {
385         ErrShow();
386         return retval;
387     }
388 
389     if (! SeqSubmitAsnWrite(ssp->ssp, aip, NULL))
390     {
391         ErrShow();
392     }
393     else
394         retval = TRUE;
395     AsnIoClose(aip);
396     return retval;
397 }
398 
399 /*****************************************************************************
400 *
401 *   Free the NCBISub and associated data
402 *
403 *****************************************************************************/
NCBISubFree(NCBISubPtr ssp)404 NLM_EXTERN NCBISubPtr NCBISubFree (
405     NCBISubPtr ssp )
406 {
407     SeqSubmitFree(ssp->ssp);
408     MemFree(ssp->submittor_key);
409     return (NCBISubPtr)(MemFree(ssp));
410 }
411 
412 /*****************************************************************************
413 *
414 *   add the Cit-sub to the submission
415 *
416 *****************************************************************************/
CitSubForSubmission(NCBISubPtr submission,PubPtr cit_sub)417 NLM_EXTERN Boolean CitSubForSubmission (
418     NCBISubPtr submission,
419     PubPtr cit_sub )
420 {
421     if ((submission == NULL) || (cit_sub == NULL)) return FALSE;
422 
423     if ((cit_sub->choice != PUB_Sub) || (cit_sub->data.ptrvalue == NULL))
424     {
425         Message(MSG_ERROR, "You must give a Cit-sub to CitSubForSubmission()");
426         return FALSE;
427     }
428     submission->ssp->sub->cit = (CitSubPtr)(cit_sub->data.ptrvalue);
429     ValNodeFree(cit_sub);   /* free just the Pub part */
430     return TRUE;
431 }
432 
433 /*****************************************************************************
434 *
435 *   Add Entries to the Submission
436 *   Add Sequences to the Entries
437 *
438 *****************************************************************************/
439 
440 /*****************************************************************************
441 *
442 *   utility function for making all new Bioseqs here
443 *
444 *****************************************************************************/
NCBISubNewBioseq(NCBISubPtr submission,CharPtr local_name,CharPtr genbank_locus,CharPtr genbank_accession,Int4 gi_number,Int2 molecule_class,Int2 molecule_type,Int4 length,Int2 topology,Int2 strandedness)445 static BioseqPtr NCBISubNewBioseq (
446     NCBISubPtr submission ,
447     CharPtr local_name ,
448     CharPtr genbank_locus ,
449     CharPtr genbank_accession ,
450     Int4 gi_number ,
451     Int2 molecule_class,
452     Int2 molecule_type ,
453     Int4 length ,
454     Int2 topology ,
455     Int2 strandedness )
456 {
457     BioseqPtr bsp;
458     TextSeqIdPtr tsip;
459     ValNodePtr vnp;
460     ObjectIdPtr oip;
461     DbtagPtr dbt;
462     Int2 i;
463     CharPtr tmp;
464     Boolean fail;
465     MolInfoPtr mip;
466 
467     bsp = BioseqNew();
468     bsp->mol = (Uint1) molecule_class;
469     bsp->repr = Seq_repr_raw;   /* default case */
470 /*    if (molecule_type != 0)
471     {
472         vnp = SeqDescrNew(NULL);
473         bsp->descr = vnp;
474         vnp->choice = Seq_descr_mol_type;
475         vnp->data.intvalue = molecule_type;
476     }
477 */
478     if (molecule_type != 0)
479     {
480         vnp = SeqDescrNew(NULL);
481         bsp->descr = vnp;
482         vnp->choice = Seq_descr_molinfo;
483         mip = (MolInfoPtr) vnp->data.ptrvalue;
484         if (mip == NULL)
485             mip = MolInfoNew();
486         mip->biomol = (Uint1)molecule_type;
487         vnp->data.ptrvalue =  (Pointer) mip;
488     }
489     bsp->length = length;
490     bsp->topology = (Uint1)topology;
491     bsp->strand = (Uint1)strandedness;
492 
493     vnp = NULL;
494 
495     if (local_name != NULL)
496     {
497         vnp = ValNodeNew(bsp->id);
498         if (bsp->id == NULL)
499             bsp->id = vnp;
500         oip = ObjectIdNew();
501         oip->str = StringSaveNoNull(local_name);
502         if (submission->submittor_key == NULL)   /* make a local id */
503         {
504             vnp->choice = SEQID_LOCAL;
505             vnp->data.ptrvalue = oip;
506         }
507         else
508         {
509             vnp->choice = SEQID_GENERAL;
510             dbt = DbtagNew();
511             vnp->data.ptrvalue = dbt;
512             dbt->db = StringSave(submission->submittor_key);
513             dbt->tag = oip;
514         }
515     }
516 
517     if (genbank_locus != NULL)
518     {
519         fail = FALSE;
520         if (! IS_UPPER(*genbank_locus))
521             fail = TRUE;
522 
523         i = 0;
524         for (tmp = genbank_locus; *tmp != '\0'; tmp++, i++)
525         {
526             if (! ((IS_UPPER(*tmp)) || (IS_DIGIT(*tmp))))
527             {
528                 fail = TRUE;
529                 break;
530             }
531         }
532         if ((i < 1) || (i > 10))
533             fail = TRUE;
534         if (fail)
535         {
536             Message(MSG_ERROR,
537                 "A GenBank LOCUS is an upper case letter, then up to 9 upper case letters or digits [%s]",
538                 genbank_locus);
539             genbank_locus = NULL;
540         }
541     }
542     if (genbank_accession != NULL)
543     {
544         fail = FALSE;
545         if (! IS_UPPER(*genbank_accession))
546             fail = TRUE;
547         tmp = genbank_accession + 1;
548         for (i = 0; i < 5; i++, tmp++)
549         {
550             if (! IS_DIGIT(*tmp))
551                 fail = TRUE;
552         }
553         if (*tmp != '\0')
554             fail = TRUE;
555         if (fail)   /* not 1 + 5, could be 2 + 6 */
556         {
557             fail = FALSE;
558             tmp = genbank_accession;
559             for (i = 0; i < 2; i++, tmp++)
560             {
561                 if (! IS_UPPER(*genbank_accession))
562                     fail = TRUE;
563             }
564 
565             for (i = 0; i < 6; i++, tmp++)
566             {
567                 if (! IS_DIGIT(*tmp))
568                     fail = TRUE;
569             }
570             if (*tmp != '\0')
571                 fail = TRUE;
572         }
573 
574         if (fail)
575         {
576             Message(MSG_ERROR, "A GenBank accession is either an\
577 upper case letter + 5 digits, or 2 upper case letters + 6 digits [%s]",
578                 genbank_accession);
579             genbank_accession = NULL;
580         }
581     }
582 
583     if ((genbank_locus != NULL) || (genbank_accession != NULL))
584     {
585         vnp = ValNodeNew(bsp->id);
586         if (bsp->id == NULL)
587             bsp->id = vnp;
588         vnp->choice = SEQID_GENBANK;
589         tsip = TextSeqIdNew();
590         vnp->data.ptrvalue = tsip;
591         if (genbank_locus != NULL)
592             tsip->name = StringSaveNoNull(genbank_locus);
593         if (genbank_accession != NULL)
594             tsip->accession = StringSaveNoNull(genbank_accession);
595     }
596 
597     if (gi_number > 0)
598     {
599         vnp = ValNodeNew(bsp->id);
600         if (bsp->id == NULL)
601             bsp->id = vnp;
602         vnp->choice = SEQID_GI;
603         vnp->data.intvalue = gi_number;
604     }
605 
606     if (vnp == NULL)   /* no ids */
607     {
608         Message(MSG_ERROR, "You must have some type of ID to create a Bioseq");
609         bsp = BioseqFree(bsp);
610     }
611 
612     return bsp;
613 }
614 
615 /*****************************************************************************
616 *
617 *   One raw Bioseq in the entry
618 *
619 *****************************************************************************/
AddSeqOnlyToSubmission(NCBISubPtr submission,CharPtr local_name,CharPtr genbank_locus,CharPtr genbank_accession,Int4 gi_number,Int2 molecule_class,Int2 molecule_type,Int4 length,Int2 topology,Int2 strandedness)620 NLM_EXTERN SeqEntryPtr AddSeqOnlyToSubmission (
621     NCBISubPtr submission,
622     CharPtr local_name ,
623     CharPtr genbank_locus ,
624     CharPtr genbank_accession ,
625     Int4 gi_number ,
626     Int2 molecule_class,
627     Int2 molecule_type ,
628     Int4 length ,
629     Int2 topology ,
630     Int2 strandedness )
631 {
632     BioseqPtr bsp;
633     BioseqSetPtr targetbssp;
634     SeqEntryPtr sep, tmp;
635 
636     sep = SeqEntryNew();
637     sep->choice = 1;    /* Bioseq */
638 
639     if (submission->ssp->data == NULL)
640         submission->ssp->data = (Pointer)sep;
641     else
642     {
643         tmp = (SeqEntryPtr) submission->ssp->data;
644         if (tmp != NULL && tmp->choice == 2 && tmp->data.ptrvalue != NULL) {
645             targetbssp = (BioseqSetPtr) tmp->data.ptrvalue;
646             if (targetbssp->_class == 7 ||
647                 (targetbssp->_class >= 13 && targetbssp->_class <= 16) ||
648                 targetbssp->_class == BioseqseqSet_class_wgs_set ||
649                 targetbssp->_class == BioseqseqSet_class_small_genome_set) {
650                 tmp = targetbssp->seq_set;
651             }
652         }
653         for (; tmp->next != NULL; tmp = tmp->next)
654             continue;
655         tmp->next = sep;
656     }
657 
658     bsp = NCBISubNewBioseq (submission , local_name, genbank_locus,
659         genbank_accession, gi_number, molecule_class, molecule_type,
660         length, topology, strandedness);
661 
662     sep->data.ptrvalue = bsp;
663     SeqMgrSeqEntry(SM_BIOSEQ, (Pointer)bsp, sep);
664 
665     return sep;
666 }
667 
668 /*****************************************************************************
669 *
670 *   One delta Bioseq in the entry
671 *
672 *****************************************************************************/
AddDeltaSeqOnlyToSubmission(NCBISubPtr submission,CharPtr local_name,CharPtr genbank_locus,CharPtr genbank_accession,Int4 gi_number,Int2 molecule_class,Int2 molecule_type,Int4 length,Int2 topology,Int2 strandedness)673 NLM_EXTERN SeqEntryPtr AddDeltaSeqOnlyToSubmission (
674     NCBISubPtr submission,
675     CharPtr local_name ,
676     CharPtr genbank_locus ,
677     CharPtr genbank_accession ,
678     Int4 gi_number ,
679     Int2 molecule_class,
680     Int2 molecule_type ,
681     Int4 length ,
682     Int2 topology ,
683     Int2 strandedness )
684 {
685     BioseqPtr bsp;
686     SeqEntryPtr sep;
687 
688     sep = AddSeqOnlyToSubmission(
689         submission,
690         local_name ,
691          genbank_locus ,
692          genbank_accession ,
693          gi_number ,
694          molecule_class,
695          molecule_type ,
696          length ,
697          topology ,
698          strandedness );
699 
700     if (sep == NULL) return sep;
701 
702     bsp = (BioseqPtr)(sep->data.ptrvalue);
703 
704     bsp->repr = Seq_repr_delta;
705     bsp->seq_ext_type = 4;    /* delta extension */
706 
707     return sep;
708 }
709 
710 /* extended SeqLit that adjusts attached SeqGraphs - internal for subutil only */
711 
712 typedef struct extseqlit {
713     SeqLit slp;
714     BioseqPtr parentbsp;
715     SeqGraphPtr graph;
716 } ExtSeqLit, PNTR ExtSeqLitPtr;
717 
ReadjustSeqLitGraphs(BioseqPtr bsp)718 static void ReadjustSeqLitGraphs (BioseqPtr bsp)
719 
720 {
721   Int4          curroffset = 0;
722   DeltaSeqPtr   dsp;
723   SeqGraphPtr   sgp;
724   SeqIntPtr     sintp;
725   SeqLocPtr     slocp;
726   SeqLitPtr     slp;
727   ExtSeqLitPtr  xslp;
728 
729   if (bsp == NULL || bsp->repr != Seq_repr_delta) return;
730   for (dsp = (DeltaSeqPtr) (bsp->seq_ext); dsp != NULL; dsp = dsp->next) {
731     switch (dsp->choice) {
732       case 1 :
733         slocp = (SeqLocPtr) dsp->data.ptrvalue;
734         if (slocp == NULL) break;
735         if (slocp->choice != SEQLOC_NULL) {
736           curroffset += SeqLocLen (slocp);
737         }
738         break;
739       case 2 :
740         slp = (SeqLitPtr) dsp->data.ptrvalue;
741         if (slp == NULL) break;
742         xslp = (ExtSeqLitPtr) slp;
743         sgp = xslp->graph;
744         if (sgp != NULL) {
745           slocp = sgp->loc;
746           if (slocp != NULL && slocp->choice == SEQLOC_INT) {
747             sintp = (SeqIntPtr) slocp->data.ptrvalue;
748             if (sintp != NULL) {
749               sintp->from = curroffset;
750               sintp->to = slp->length + curroffset - 1;
751             }
752           }
753         }
754         curroffset += slp->length;
755         break;
756       default :
757         break;
758     }
759   }
760 }
761 
AddSeqLitToBioseq(NCBISubPtr submission,SeqEntryPtr delta_seq_entry,Int4 length,Boolean isa_gap)762 static SeqLitPtr AddSeqLitToBioseq(
763     NCBISubPtr submission,
764     SeqEntryPtr delta_seq_entry,
765     Int4 length ,
766     Boolean isa_gap)
767 {
768     BioseqPtr bsp;
769     ValNodePtr vnp;
770     SeqLitPtr slp;
771     IntFuzzPtr ifp;
772     ExtSeqLitPtr xslp;
773 
774     if (delta_seq_entry == NULL) return FALSE;
775     if (IS_Bioseq_set(delta_seq_entry)) return FALSE;
776     if (delta_seq_entry->data.ptrvalue == NULL) return FALSE;
777 
778     bsp = (BioseqPtr)(delta_seq_entry->data.ptrvalue);
779     if (bsp->repr != Seq_repr_delta)
780     {
781         Message(MSG_ERROR, "AddToDeltaSeq: no delta seq found");
782         return FALSE;
783     }
784 
785     if ((length > 0) || ((length == 0) && (isa_gap)))
786     {
787         /* slp = SeqLitNew(); */
788         slp = (SeqLitPtr) MemNew (sizeof (ExtSeqLit));
789         slp->length = length;
790         vnp = ValNodeAddPointer((ValNodePtr PNTR)&(bsp->seq_ext),(Int2) 2, (Pointer)slp);
791         if ((length == 0) && (isa_gap)) /* gap of unknown length */
792         {
793             ifp = IntFuzzNew();
794             ifp->choice = 4;    /* lim - unk*/
795             slp->fuzz = ifp;
796         }
797         xslp = (ExtSeqLitPtr) slp;
798         xslp->parentbsp = bsp;
799 
800         SpreadGapsInDeltaSeq(bsp);   /* distribute the unknown gap sizes */
801 
802         ReadjustSeqLitGraphs (bsp);  /* adjust seqlit graph positions */
803 
804         return slp;
805     }
806 
807     return (SeqLitPtr)NULL;
808 }
809 
AddGapToDeltaSeq(NCBISubPtr submission,SeqEntryPtr delta_seq_entry,Int4 length_of_gap)810 NLM_EXTERN Boolean AddGapToDeltaSeq (
811     NCBISubPtr submission,
812     SeqEntryPtr delta_seq_entry,
813     Int4 length_of_gap )    /** 0 if not known */
814 {
815     if (AddSeqLitToBioseq(submission, delta_seq_entry, length_of_gap, TRUE) == NULL)
816         return FALSE;
817     else
818         return TRUE;
819 }
820 
AddFakeGapToDeltaSeq(NCBISubPtr submission,SeqEntryPtr delta_seq_entry,Int4 length_of_gap)821 NLM_EXTERN SeqLitPtr AddFakeGapToDeltaSeq (
822     NCBISubPtr submission,
823     SeqEntryPtr delta_seq_entry,
824     Int4 length_of_gap )
825 {
826     return AddSeqLitToBioseq(submission, delta_seq_entry, length_of_gap, TRUE);
827 }
828 
829 
830 
AddLiteralToDeltaSeq(NCBISubPtr submission,SeqEntryPtr delta_seq_entry,Int4 length_of_sequence)831 NLM_EXTERN SeqLitPtr AddLiteralToDeltaSeq (
832     NCBISubPtr submission,
833     SeqEntryPtr delta_seq_entry,
834     Int4 length_of_sequence )
835 {
836     return AddSeqLitToBioseq(submission, delta_seq_entry, length_of_sequence, FALSE);
837 }
838 
839 
840 /*****************************************************************************
841 *
842 *   Segmented Set
843 *
844 *****************************************************************************/
AddSegmentedSeqToSubmission(NCBISubPtr submission,CharPtr local_name,CharPtr genbank_locus,CharPtr genbank_accession,Int4 gi_number,Int2 molecule_class,Int2 molecule_type,Int4 length,Int2 topology,Int2 strandedness)845 NLM_EXTERN SeqEntryPtr AddSegmentedSeqToSubmission (
846     NCBISubPtr submission ,
847     CharPtr local_name ,
848     CharPtr genbank_locus ,
849     CharPtr genbank_accession ,
850     Int4 gi_number ,
851     Int2 molecule_class,
852     Int2 molecule_type ,
853     Int4 length ,
854     Int2 topology ,
855     Int2 strandedness )
856 {
857     BioseqPtr bsp;
858     BioseqSetPtr bssp, targetbssp;
859     SeqEntryPtr sep, the_set, tmp;
860 
861     bssp = BioseqSetNew();
862     bssp->_class = 2;       /* segset */
863     the_set = SeqEntryNew();
864     the_set->choice = 2;    /* set */
865     the_set->data.ptrvalue = bssp;
866     SeqMgrSeqEntry(SM_BIOSEQSET, (Pointer)bssp, the_set);
867 
868     bsp = NCBISubNewBioseq (submission , local_name, genbank_locus,
869         genbank_accession, gi_number, molecule_class, molecule_type,
870         length, topology, strandedness);
871     bsp->repr = Seq_repr_seg;
872     bsp->seq_ext_type = 1;
873 
874     sep = SeqEntryNew();
875     sep->choice = 1;   /* Bioseq */
876     sep->data.ptrvalue = bsp;
877     SeqMgrSeqEntry(SM_BIOSEQ, (Pointer)bsp, sep);
878 
879     bssp->seq_set = sep;
880     SeqMgrConnect(SM_BIOSEQ, (Pointer)bsp, SM_BIOSEQSET, (Pointer)bssp);
881 
882     if (submission->ssp->data == NULL)
883         submission->ssp->data = (Pointer)the_set;
884     else
885     {
886         tmp = (SeqEntryPtr) submission->ssp->data;
887         if (tmp != NULL && tmp->choice == 2 && tmp->data.ptrvalue != NULL) {
888             targetbssp = (BioseqSetPtr) tmp->data.ptrvalue;
889             if (targetbssp->_class == 7 ||
890                 (targetbssp->_class >= 13 && targetbssp->_class <= 16) ||
891                 targetbssp->_class == BioseqseqSet_class_wgs_set ||
892                 targetbssp->_class == BioseqseqSet_class_small_genome_set) {
893                 tmp = targetbssp->seq_set;
894             }
895         }
896         for (; tmp->next != NULL; tmp = tmp->next)
897             continue;
898         tmp->next = the_set;
899     }
900 
901     return the_set;
902 }
903 
AddSeqToSegmentedEntry(NCBISubPtr submission,SeqEntryPtr segmented_seq_entry,CharPtr local_name,CharPtr genbank_locus,CharPtr genbank_accession,Int4 gi_number,Int2 molecule_class,Int2 molecule_type,Int4 length,Int2 topology,Int2 strandedness)904 NLM_EXTERN SeqEntryPtr AddSeqToSegmentedEntry (
905     NCBISubPtr submission,
906     SeqEntryPtr segmented_seq_entry,
907     CharPtr local_name ,
908     CharPtr genbank_locus ,
909     CharPtr genbank_accession ,
910     Int4 gi_number ,
911     Int2 molecule_class,
912     Int2 molecule_type ,
913     Int4 length ,
914     Int2 topology ,
915     Int2 strandedness )
916 {
917     BioseqSetPtr segset, parts = NULL, tp;
918     BioseqPtr bsp, segseq= NULL;
919     SeqEntryPtr sep, tmp, prev;
920     SeqLocPtr slp, curr;
921     SeqIntPtr sip;
922 
923     if (segmented_seq_entry == NULL) return NULL;
924     if (IS_Bioseq(segmented_seq_entry)) return NULL;
925     if (segmented_seq_entry->data.ptrvalue == NULL) return NULL;
926 
927     segset = (BioseqSetPtr)(segmented_seq_entry->data.ptrvalue);
928     if (segset->_class != 2) return NULL;
929 
930     prev = NULL;
931     for (tmp = segset->seq_set; tmp != NULL; tmp = tmp->next)
932     {
933         if (IS_Bioseq(tmp))
934         {
935             bsp = (BioseqPtr)(tmp->data.ptrvalue);
936             if (bsp->repr == Seq_repr_seg)
937                 segseq = bsp;
938         }
939         else
940         {
941             tp = (BioseqSetPtr)(tmp->data.ptrvalue);
942             if (tp->_class == 4)
943                 parts = tp;
944         }
945         prev = tmp;
946     }
947 
948     if (segseq == NULL)
949     {
950         Message(MSG_ERROR, "AddSeqToSegmentedEntry: no seg seq found");
951         return NULL;
952     }
953 
954     if (parts == NULL)   /* first member of segset */
955     {
956         parts = BioseqSetNew();
957         parts->_class = 4;
958         sep = SeqEntryNew();
959         sep->choice = 2;
960         sep->data.ptrvalue = (Pointer)parts;
961         SeqMgrSeqEntry(SM_BIOSEQSET, (Pointer)parts, sep);
962         SeqMgrConnect(SM_BIOSEQSET, (Pointer)parts, SM_BIOSEQSET, (Pointer)segset);
963         prev->next = sep;
964     }
965 
966     prev = NULL;
967     for (tmp = parts->seq_set; tmp != NULL; tmp = tmp->next)
968     {
969         if (! IS_Bioseq(tmp))
970         {
971             Message(MSG_ERROR, "BioseqSet in Parts");
972             return NULL;
973         }
974 
975         prev = tmp;
976     }
977 
978     sep = SeqEntryNew();
979     if (prev == NULL)      /* first one */
980         parts->seq_set = sep;
981     else
982         prev->next = sep;
983 
984     bsp = NCBISubNewBioseq (submission , local_name, genbank_locus,
985         genbank_accession, gi_number, molecule_class, molecule_type,
986         length, topology, strandedness);
987     sep->choice = 1;
988     sep->data.ptrvalue = (Pointer)bsp;
989 
990     SeqMgrSeqEntry(SM_BIOSEQ, (Pointer)bsp, sep);
991     SeqMgrConnect(SM_BIOSEQ, (Pointer)bsp, SM_BIOSEQSET, (Pointer)parts);
992                         /* add pointer to segmented seq */
993     if (segseq->seq_ext != NULL)
994     {
995         for (curr = (SeqLocPtr)segseq->seq_ext; curr->next != NULL; curr = curr->next)
996             continue;
997     }
998     else
999         curr = NULL;
1000 
1001     slp = ValNodeNew(NULL);
1002     if (curr == NULL)
1003         segseq->seq_ext = slp;
1004     else
1005         curr->next = slp;
1006     slp->choice = SEQLOC_INT;
1007     sip = SeqIntNew();
1008     slp->data.ptrvalue = sip;
1009     sip->id = SeqIdDup(bsp->id);
1010     sip->from = 0;
1011     sip->to = length - 1;
1012 
1013     segseq->length += length;   /* add the segment */
1014 
1015     return sep;
1016 }
1017 
AddGapToSegmentedEntry(NCBISubPtr submission,SeqEntryPtr segmented_seq_entry,Int4 length_of_gap)1018 NLM_EXTERN Boolean AddGapToSegmentedEntry (
1019     NCBISubPtr submission,
1020     SeqEntryPtr segmented_seq_entry,
1021     Int4 length_of_gap )    /** 0 if not known */
1022 {
1023     BioseqSetPtr segset, parts = NULL, tp;
1024     BioseqPtr bsp, segseq= NULL;
1025     SeqEntryPtr sep, tmp, prev;
1026     ValNodePtr vnp;
1027     SeqLocPtr slp, curr;
1028     SeqIntPtr sip;
1029     Char local_name[40];
1030     Int2 mol_type=0;
1031 
1032     if (segmented_seq_entry == NULL) return FALSE;
1033     if (IS_Bioseq(segmented_seq_entry)) return FALSE;
1034     if (segmented_seq_entry->data.ptrvalue == NULL) return FALSE;
1035 
1036     segset = (BioseqSetPtr)(segmented_seq_entry->data.ptrvalue);
1037     if (segset->_class != 2) return FALSE;
1038 
1039     prev = NULL;
1040     for (tmp = segset->seq_set; tmp != NULL; tmp = tmp->next)
1041     {
1042         if (IS_Bioseq(tmp))
1043         {
1044             bsp = (BioseqPtr)(tmp->data.ptrvalue);
1045             if (bsp->repr == Seq_repr_seg)
1046                 segseq = bsp;
1047         }
1048         else
1049         {
1050             tp = (BioseqSetPtr)(tmp->data.ptrvalue);
1051             if (tp->_class == 4)
1052                 parts = tp;
1053         }
1054         prev = tmp;
1055     }
1056 
1057     if (segseq == NULL)
1058     {
1059         Message(MSG_ERROR, "AddGapToSegmentedEntry: no seg seq found");
1060         return FALSE;
1061     }
1062 
1063     if ((parts == NULL) && (length_of_gap <= 0))
1064     {
1065         Message(MSG_ERROR, "Do not start or end a segmented set with unknown gaps");
1066         return FALSE;
1067     }
1068 
1069     if (length_of_gap > 0)     /* add a virtual sequence */
1070     {
1071         if (parts == NULL)   /* first member of segset */
1072         {
1073             parts = BioseqSetNew();
1074             parts->_class = 4;
1075             sep = SeqEntryNew();
1076             sep->choice = 2;
1077             sep->data.ptrvalue = (Pointer)parts;
1078             prev->next = sep;
1079         }
1080 
1081         prev = NULL;
1082         for (tmp = parts->seq_set; tmp != NULL; tmp = tmp->next)
1083         {
1084             if (! IS_Bioseq(tmp))
1085             {
1086                 Message(MSG_ERROR, "BioseqSet in Parts");
1087                 return FALSE;
1088             }
1089 
1090             prev = tmp;
1091         }
1092 
1093         sep = SeqEntryNew();
1094         if (prev == NULL)      /* first one */
1095             parts->seq_set = sep;
1096         else
1097             prev->next = sep;
1098 
1099         for (vnp = segseq->descr; vnp != NULL; vnp = vnp->next)
1100         {
1101             if (vnp->choice == Seq_descr_mol_type)
1102             {
1103                 mol_type = (Int2)(vnp->data.intvalue);
1104                 break;
1105             }
1106         }
1107 
1108         submission->gap_count++;
1109         sprintf(local_name, "Gap_%d", (int)(submission->gap_count));
1110 
1111         bsp = NCBISubNewBioseq (submission , local_name, NULL,
1112             NULL, 0, mol_type, (Int2)(segseq->mol), length_of_gap,
1113             (Int2)(segseq->topology), (Int2)(segseq->strand));
1114         bsp->repr = Seq_repr_virtual;
1115         sep->choice = 1;
1116         sep->data.ptrvalue = (Pointer)bsp;
1117         SeqMgrSeqEntry(SM_BIOSEQ, (Pointer)bsp, sep);
1118 
1119         SeqMgrConnect(SM_BIOSEQ, (Pointer)bsp, SM_BIOSEQSET, (Pointer)parts);
1120     }
1121                     /* add pointer to segmented seq */
1122     if (segseq->seq_ext != NULL)
1123     {
1124         for (curr = (SeqLocPtr)segseq->seq_ext; curr->next != NULL; curr = curr->next)
1125             continue;
1126     }
1127     else
1128         curr = NULL;
1129 
1130     slp = ValNodeNew(NULL);
1131     if (curr == NULL)
1132         segseq->seq_ext = slp;
1133     else
1134         curr->next = slp;
1135     if (length_of_gap > 0)
1136     {
1137         slp->choice = SEQLOC_INT;
1138         sip = SeqIntNew();
1139         slp->data.ptrvalue = sip;
1140         sip->id = SeqIdDup(bsp->id);
1141         sip->from = 0;
1142         sip->to = length_of_gap - 1;
1143     }
1144     else
1145     {
1146         slp->choice = SEQLOC_NULL;
1147     }
1148 
1149     return TRUE;
1150 }
1151 
AddReferenceToSegmentedEntry(NCBISubPtr submission,SeqEntryPtr segmented_seq_entry,CharPtr genbank_accession,Int4 gi_number,Int4 from,Int4 to,Boolean on_plus_strand)1152 NLM_EXTERN Boolean AddReferenceToSegmentedEntry (
1153     NCBISubPtr submission ,
1154     SeqEntryPtr segmented_seq_entry,
1155     CharPtr genbank_accession ,
1156     Int4 gi_number ,
1157     Int4 from ,
1158     Int4 to ,
1159     Boolean on_plus_strand )
1160 {
1161     BioseqSetPtr segset;
1162     BioseqPtr bsp, segseq= NULL;
1163     SeqEntryPtr tmp, prev;
1164     SeqLocPtr slp, curr;
1165     SeqIntPtr sip;
1166     TextSeqIdPtr tsip;
1167 
1168 
1169     if (segmented_seq_entry == NULL) return FALSE;
1170     if (IS_Bioseq(segmented_seq_entry)) return FALSE;
1171     if (segmented_seq_entry->data.ptrvalue == NULL) return FALSE;
1172 
1173     segset = (BioseqSetPtr)(segmented_seq_entry->data.ptrvalue);
1174     if (segset->_class != 2) return FALSE;
1175 
1176     prev = NULL;
1177     for (tmp = segset->seq_set; tmp != NULL; tmp = tmp->next)
1178     {
1179         if (IS_Bioseq(tmp))
1180         {
1181             bsp = (BioseqPtr)(tmp->data.ptrvalue);
1182             if (bsp->repr == Seq_repr_seg)
1183                 segseq = bsp;
1184         }
1185         prev = tmp;
1186     }
1187 
1188     if (segseq == NULL)
1189     {
1190         Message(MSG_ERROR, "AddRefToSegmentedEntry: no seg seq found");
1191         return FALSE;
1192     }
1193 
1194                 /* add pointer to segmented seq */
1195     if (segseq->seq_ext != NULL)
1196     {
1197         for (curr = (SeqLocPtr)segseq->seq_ext; curr->next != NULL; curr = curr->next)
1198             continue;
1199     }
1200     else
1201         curr = NULL;
1202 
1203     slp = ValNodeNew(NULL);
1204     if (curr == NULL)
1205         segseq->seq_ext = slp;
1206     else
1207         curr->next = slp;
1208 
1209     slp->choice = SEQLOC_INT;
1210     sip = SeqIntNew();
1211     slp->data.ptrvalue = sip;
1212     sip->from = from;
1213     sip->to = to;
1214     if (on_plus_strand)
1215         sip->strand = Seq_strand_plus;
1216     else
1217         sip->strand = Seq_strand_minus;
1218 
1219     curr = ValNodeNew(NULL);
1220     sip->id = curr;
1221     if (gi_number > 0)    /* gis are better */
1222     {
1223         curr->choice = SEQID_GI;
1224         curr->data.intvalue = gi_number;
1225     }
1226     else
1227     {
1228         curr->choice = SEQID_GENBANK;
1229         tsip = TextSeqIdNew();
1230         tsip->accession = StringSaveNoNull(genbank_accession);
1231         curr->data.ptrvalue = tsip;
1232     }
1233 
1234     return TRUE;
1235 }
1236 
1237 /*****************************************************************************
1238 *
1239 *   Build sets of similar sequences
1240 *
1241 *****************************************************************************/
AddPopPhyMutSetToSubmission(NCBISubPtr submission,Uint1 choice)1242 static SeqEntryPtr AddPopPhyMutSetToSubmission (
1243     NCBISubPtr submission, Uint1 choice )
1244 
1245 {
1246     BioseqSetPtr bssp;
1247     SeqEntryPtr tmp, the_set;
1248 
1249     bssp = BioseqSetNew();
1250     bssp->_class = choice;       /* pop-set, phy-set, or mut-set */
1251     the_set = SeqEntryNew();
1252     the_set->choice = 2;    /* set */
1253     the_set->data.ptrvalue = bssp;
1254     SeqMgrSeqEntry(SM_BIOSEQSET, (Pointer)bssp, the_set);
1255 
1256     if (submission->ssp->data == NULL)
1257         submission->ssp->data = (Pointer)the_set;
1258     else
1259     {
1260         for (tmp = (SeqEntryPtr) submission->ssp->data; tmp->next != NULL; tmp = tmp->next)
1261             continue;
1262         tmp->next = the_set;
1263     }
1264 
1265     return the_set;
1266 }
1267 
AddPopSetToSubmission(NCBISubPtr submission)1268 NLM_EXTERN SeqEntryPtr AddPopSetToSubmission (
1269     NCBISubPtr submission )
1270 
1271 {
1272     return AddPopPhyMutSetToSubmission (submission, BioseqseqSet_class_pop_set);
1273 }
1274 
AddPhySetToSubmission(NCBISubPtr submission)1275 NLM_EXTERN SeqEntryPtr AddPhySetToSubmission (
1276     NCBISubPtr submission )
1277 
1278 {
1279     return AddPopPhyMutSetToSubmission (submission, BioseqseqSet_class_phy_set);
1280 }
1281 
AddMutSetToSubmission(NCBISubPtr submission)1282 NLM_EXTERN SeqEntryPtr AddMutSetToSubmission (
1283     NCBISubPtr submission )
1284 
1285 {
1286     return AddPopPhyMutSetToSubmission (submission, BioseqseqSet_class_mut_set);
1287 }
1288 
AddGenBankSetToSubmission(NCBISubPtr submission)1289 NLM_EXTERN SeqEntryPtr AddGenBankSetToSubmission (
1290     NCBISubPtr submission )
1291 
1292 {
1293     return AddPopPhyMutSetToSubmission (submission, BioseqseqSet_class_genbank);
1294 }
1295 
1296 /*****************************************************************************
1297 *
1298 *   Build nuc-prot sets
1299 *
1300 *****************************************************************************/
AddNucProtToSubmission(NCBISubPtr submission)1301 NLM_EXTERN SeqEntryPtr AddNucProtToSubmission (
1302     NCBISubPtr submission )
1303 {
1304     BioseqSetPtr bssp, targetbssp;
1305     SeqEntryPtr tmp, the_set;
1306 
1307     bssp = BioseqSetNew();
1308     bssp->_class = 1;       /* nuc-prot */
1309     the_set = SeqEntryNew();
1310     the_set->choice = 2;    /* set */
1311     the_set->data.ptrvalue = bssp;
1312     SeqMgrSeqEntry(SM_BIOSEQSET, (Pointer)bssp, the_set);
1313 
1314     if (submission->ssp->data == NULL)
1315         submission->ssp->data = (Pointer)the_set;
1316     else
1317     {
1318         tmp = (SeqEntryPtr) submission->ssp->data;
1319         if (tmp != NULL && tmp->choice == 2 && tmp->data.ptrvalue != NULL) {
1320             targetbssp = (BioseqSetPtr) tmp->data.ptrvalue;
1321             if (targetbssp->_class == 7 ||
1322                 (targetbssp->_class >= 13 && targetbssp->_class <= 16) ||
1323                 targetbssp->_class == BioseqseqSet_class_wgs_set ||
1324                 targetbssp->_class == BioseqseqSet_class_small_genome_set) {
1325                 tmp = targetbssp->seq_set;
1326             }
1327         }
1328         for (; tmp->next != NULL; tmp = tmp->next)
1329             continue;
1330         tmp->next = the_set;
1331     }
1332 
1333     return the_set;
1334 }
1335 
AddSeqToNucProtEntry(NCBISubPtr submission,SeqEntryPtr nuc_prot_entry,CharPtr local_name,CharPtr genbank_locus,CharPtr genbank_accession,Int4 gi_number,Int2 molecule_class,Int2 molecule_type,Int4 length,Int2 topology,Int2 strandedness)1336 NLM_EXTERN SeqEntryPtr AddSeqToNucProtEntry (   /** add unsegmented nuc or prot bioseq */
1337     NCBISubPtr submission,
1338     SeqEntryPtr nuc_prot_entry,
1339     CharPtr local_name ,
1340     CharPtr genbank_locus ,
1341     CharPtr genbank_accession ,
1342     Int4 gi_number ,
1343     Int2 molecule_class,
1344     Int2 molecule_type ,
1345     Int4 length ,
1346     Int2 topology ,
1347     Int2 strandedness )
1348 {
1349     BioseqSetPtr nucprot, tp;
1350     BioseqPtr bsp;
1351     SeqEntryPtr sep, tmp, prev, tmp2;
1352     Boolean is_nuc;
1353 
1354     if (nuc_prot_entry == NULL) return NULL;
1355     if (IS_Bioseq(nuc_prot_entry)) return NULL;
1356     if (nuc_prot_entry->data.ptrvalue == NULL) return NULL;
1357 
1358     nucprot = (BioseqSetPtr)(nuc_prot_entry->data.ptrvalue);
1359     if (nucprot->_class != 1) return NULL;
1360 
1361     if (ISA_na(molecule_class))
1362         is_nuc = TRUE;
1363     else
1364         is_nuc = FALSE;
1365 
1366     prev = NULL;
1367     for (tmp = nucprot->seq_set; tmp != NULL; tmp = tmp->next)
1368     {
1369         if (is_nuc)   /* check for multiple nucleotides */
1370         {
1371             if (IS_Bioseq(tmp))
1372             {
1373                 bsp = (BioseqPtr)(tmp->data.ptrvalue);
1374                 if (ISA_na(bsp->mol))
1375                 {
1376                     Message(MSG_ERROR, "AddSeqToNucProt: adding more than one nucleotide seq");
1377                     return NULL;
1378                 }
1379             }
1380             else
1381             {
1382                 tp = (BioseqSetPtr)(tmp->data.ptrvalue);
1383                 if (tp->_class == 2)  /* seg-set */
1384                 {
1385                     for (tmp2 = tp->seq_set; tmp2 != NULL; tmp2 = tmp2->next)
1386                     {
1387                         if (IS_Bioseq(tmp2))
1388                         {
1389                             bsp = (BioseqPtr)(tmp2->data.ptrvalue);
1390                             if (ISA_na(bsp->mol))
1391                             {
1392                                 Message(MSG_ERROR, "AddSeqToNucProt: adding more than one nucleotide seq");
1393                                 return NULL;
1394                             }
1395                         }
1396                     }
1397                 }
1398             }
1399         }
1400         prev = tmp;
1401     }
1402 
1403     sep = SeqEntryNew();
1404     if (prev == NULL)      /* first one */
1405         nucprot->seq_set = sep;
1406     else
1407         prev->next = sep;
1408 
1409     bsp = NCBISubNewBioseq (submission , local_name, genbank_locus,
1410         genbank_accession, gi_number, molecule_class, molecule_type,
1411         length, topology, strandedness);
1412     sep->choice = 1;
1413     sep->data.ptrvalue = (Pointer)bsp;
1414     SeqMgrSeqEntry(SM_BIOSEQ, (Pointer)bsp, sep);
1415     SeqMgrConnect(SM_BIOSEQ, (Pointer)bsp, SM_BIOSEQSET, (Pointer)nucprot);
1416 
1417     return sep;
1418 
1419 }
1420               /** add segmented nuc or prot bioseq set */
1421 
AddSegmentedSeqToNucProtEntry(NCBISubPtr submission,SeqEntryPtr nuc_prot_entry,CharPtr local_name,CharPtr genbank_locus,CharPtr genbank_accession,Int4 gi_number,Int2 molecule_class,Int2 molecule_type,Int4 length,Int2 topology,Int2 strandedness)1422 NLM_EXTERN SeqEntryPtr AddSegmentedSeqToNucProtEntry (
1423     NCBISubPtr submission,
1424     SeqEntryPtr nuc_prot_entry ,
1425     CharPtr local_name ,
1426     CharPtr genbank_locus ,
1427     CharPtr genbank_accession ,
1428     Int4 gi_number ,
1429     Int2 molecule_class,
1430     Int2 molecule_type ,
1431     Int4 length ,
1432     Int2 topology ,
1433     Int2 strandedness )
1434 {
1435     BioseqSetPtr nucprot, tp;
1436     BioseqPtr bsp;
1437     SeqEntryPtr sep, tmp, prev, tmp2, the_set;
1438     Boolean is_nuc;
1439     BioseqSetPtr bssp;
1440 
1441     if (nuc_prot_entry == NULL) return NULL;
1442     if (IS_Bioseq(nuc_prot_entry)) return NULL;
1443     if (nuc_prot_entry->data.ptrvalue == NULL) return NULL;
1444 
1445     nucprot = (BioseqSetPtr)(nuc_prot_entry->data.ptrvalue);
1446     if (nucprot->_class != 1) return NULL;
1447 
1448     if (ISA_na(molecule_class))
1449         is_nuc = TRUE;
1450     else
1451         is_nuc = FALSE;
1452 
1453     prev = NULL;
1454     for (tmp = nucprot->seq_set; tmp != NULL; tmp = tmp->next)
1455     {
1456         if (is_nuc)   /* check for multiple nucleotides */
1457         {
1458             if (IS_Bioseq(tmp))
1459             {
1460                 bsp = (BioseqPtr)(tmp->data.ptrvalue);
1461                 if (ISA_na(bsp->mol))
1462                 {
1463                     Message(MSG_ERROR, "AddSeqToNucProt: adding more than one nucleotide seq");
1464                     return NULL;
1465                 }
1466             }
1467             else
1468             {
1469                 tp = (BioseqSetPtr)(tmp->data.ptrvalue);
1470                 if (tp->_class == 2)  /* seg-set */
1471                 {
1472                     for (tmp2 = tp->seq_set; tmp2 != NULL; tmp2 = tmp2->next)
1473                     {
1474                         if (IS_Bioseq(tmp2))
1475                         {
1476                             bsp = (BioseqPtr)(tmp2->data.ptrvalue);
1477                             if (ISA_na(bsp->mol))
1478                             {
1479                                 Message(MSG_ERROR, "AddSeqToNucProt: adding more than one nucleotide seq");
1480                                 return NULL;
1481                             }
1482                         }
1483                     }
1484                 }
1485             }
1486         }
1487         prev = tmp;
1488     }
1489 
1490     bssp = BioseqSetNew();
1491     bssp->_class = 2;       /* segset */
1492     the_set = SeqEntryNew();
1493     the_set->choice = 2;    /* set */
1494     the_set->data.ptrvalue = bssp;
1495     if (prev == NULL)      /* first one */
1496         nucprot->seq_set = the_set;
1497     else
1498         prev->next = the_set;
1499     SeqMgrSeqEntry(SM_BIOSEQSET, (Pointer)bssp, the_set);
1500     SeqMgrConnect(SM_BIOSEQSET, (Pointer)bssp, SM_BIOSEQSET, (Pointer)nucprot);
1501 
1502     bsp = NCBISubNewBioseq (submission , local_name, genbank_locus,
1503         genbank_accession, gi_number, molecule_class, molecule_type,
1504         length, topology, strandedness);
1505     bsp->repr = Seq_repr_seg;
1506     bsp->seq_ext_type = 1;
1507 
1508     sep = SeqEntryNew();
1509     sep->choice = 1;   /* Bioseq */
1510     sep->data.ptrvalue = bsp;
1511     bssp->seq_set = sep;
1512     SeqMgrSeqEntry(SM_BIOSEQ, (Pointer)bsp, sep);
1513     SeqMgrConnect(SM_BIOSEQ, (Pointer)bsp, SM_BIOSEQSET, (Pointer)bssp);
1514 
1515 
1516     return the_set;
1517 }
1518 
AddDeltaSeqToNucProtEntry(NCBISubPtr submission,SeqEntryPtr nuc_prot_entry,CharPtr local_name,CharPtr genbank_locus,CharPtr genbank_accession,Int4 gi_number,Int2 molecule_class,Int2 molecule_type,Int4 length,Int2 topology,Int2 strandedness)1519 NLM_EXTERN SeqEntryPtr AddDeltaSeqToNucProtEntry (   /** add delta nuc bioseq */
1520     NCBISubPtr submission,
1521     SeqEntryPtr nuc_prot_entry,
1522     CharPtr local_name ,
1523     CharPtr genbank_locus ,
1524     CharPtr genbank_accession ,
1525     Int4 gi_number ,
1526     Int2 molecule_class,
1527     Int2 molecule_type ,
1528     Int4 length ,
1529     Int2 topology ,
1530     Int2 strandedness )
1531 {
1532     BioseqSetPtr nucprot, tp;
1533     BioseqPtr bsp;
1534     SeqEntryPtr sep, tmp, prev, tmp2;
1535     Boolean is_nuc;
1536 
1537     if (nuc_prot_entry == NULL) return NULL;
1538     if (IS_Bioseq(nuc_prot_entry)) return NULL;
1539     if (nuc_prot_entry->data.ptrvalue == NULL) return NULL;
1540 
1541     nucprot = (BioseqSetPtr)(nuc_prot_entry->data.ptrvalue);
1542     if (nucprot->_class != 1) return NULL;
1543 
1544     if (ISA_na(molecule_class))
1545         is_nuc = TRUE;
1546     else
1547         is_nuc = FALSE;
1548 
1549     prev = NULL;
1550     for (tmp = nucprot->seq_set; tmp != NULL; tmp = tmp->next)
1551     {
1552         if (is_nuc)   /* check for multiple nucleotides */
1553         {
1554             if (IS_Bioseq(tmp))
1555             {
1556                 bsp = (BioseqPtr)(tmp->data.ptrvalue);
1557                 if (ISA_na(bsp->mol))
1558                 {
1559                     Message(MSG_ERROR, "AddSeqToNucProt: adding more than one nucleotide seq");
1560                     return NULL;
1561                 }
1562             }
1563             else
1564             {
1565                 tp = (BioseqSetPtr)(tmp->data.ptrvalue);
1566                 if (tp->_class == 2)  /* seg-set */
1567                 {
1568                     for (tmp2 = tp->seq_set; tmp2 != NULL; tmp2 = tmp2->next)
1569                     {
1570                         if (IS_Bioseq(tmp2))
1571                         {
1572                             bsp = (BioseqPtr)(tmp2->data.ptrvalue);
1573                             if (ISA_na(bsp->mol))
1574                             {
1575                                 Message(MSG_ERROR, "AddSeqToNucProt: adding more than one nucleotide seq");
1576                                 return NULL;
1577                             }
1578                         }
1579                     }
1580                 }
1581             }
1582         }
1583         prev = tmp;
1584     }
1585 
1586     sep = SeqEntryNew();
1587     if (prev == NULL)      /* first one */
1588         nucprot->seq_set = sep;
1589     else
1590         prev->next = sep;
1591 
1592     bsp = NCBISubNewBioseq (submission , local_name, genbank_locus,
1593         genbank_accession, gi_number, molecule_class, molecule_type,
1594         length, topology, strandedness);
1595     sep->choice = 1;
1596     sep->data.ptrvalue = (Pointer)bsp;
1597     SeqMgrSeqEntry(SM_BIOSEQ, (Pointer)bsp, sep);
1598     SeqMgrConnect(SM_BIOSEQ, (Pointer)bsp, SM_BIOSEQSET, (Pointer)nucprot);
1599 
1600     bsp->repr = Seq_repr_delta;
1601     bsp->seq_ext_type = 4;    /* delta extension */
1602 
1603     return sep;
1604 
1605 }
1606 
1607 /*************************************************************************
1608 *  GetDNAConv:
1609 *  -- DNA conversion table array
1610 **************************************************************************/
GetDNAConv(void)1611 static Uint1Ptr GetDNAConv(void)
1612 {
1613    SeqCodeTablePtr sctp;
1614    Uint1Ptr        dnaconv;
1615    CharPtr         ptr;
1616    Int2            i;
1617 
1618    dnaconv = MemNew((size_t)255);           /* DNA */
1619    MemSet((CharPtr)dnaconv, (Uint1)1, (size_t)255); /* everything an error */
1620    dnaconv[32] = 0;  /* blank */
1621    sctp = SeqCodeTableFind((Uint1)Seq_code_iupacna);
1622    ptr = sctp->letters;   /* one letter code */
1623    for (i = 0; i < (Int4)(sctp->num); i++, ptr++)
1624        dnaconv[*ptr] = *ptr;
1625 
1626    return (dnaconv);
1627 
1628 }
1629 /*************************************************************************
1630 *  GetProteinConv:
1631 *  -- Protein conversion table array
1632 **************************************************************************/
GetProteinConv(void)1633 static Uint1Ptr GetProteinConv(void)
1634 {
1635    SeqCodeTablePtr sctp;
1636    Uint1Ptr        protconv;
1637    CharPtr         ptr;
1638    Int2            i;
1639 
1640    protconv = MemNew((size_t)255);           /* proteins */
1641    MemSet((CharPtr)protconv, (Uint1)1, (size_t)255); /* everything an error */
1642    protconv[32] = 0;  /* blank */
1643    sctp = SeqCodeTableFind((Uint1)Seq_code_iupacaa);
1644    ptr = sctp->letters;   /* one letter code */
1645    for (i = 0; i < (Int4)(sctp->num); i++, ptr++)
1646        protconv[*ptr] = *ptr;
1647 
1648    return (protconv);
1649 
1650 }
1651 
AddBasesToByteStore(ByteStorePtr bsp,CharPtr the_bases)1652 NLM_EXTERN Boolean AddBasesToByteStore (ByteStorePtr bsp, CharPtr the_bases)
1653 {
1654     Uint1 PNTR buf;
1655     Uint1 PNTR bu;
1656     Uint1    residue;
1657     Uint1Ptr dnaconv;
1658     CharPtr tmp;
1659     Char ch;
1660 
1661     dnaconv = GetDNAConv();
1662     buf = MemNew(StringLen(the_bases) + 1);
1663     bu = buf;
1664     for (tmp = the_bases; *tmp != '\0'; tmp++)
1665     {
1666         ch = TO_UPPER(*tmp);
1667         if (ch == 'U') ch = 'T';
1668         if (ch == 'X') ch = 'N';
1669         residue = dnaconv[ch];
1670         if (residue > 2) {
1671             *bu++ = residue;
1672         } else if (residue == 1 && IS_ALPHA(*tmp)) {
1673             *bu++ = 'N';
1674         } else {
1675             ErrPostEx(SEV_ERROR, 0,0, "Illegal character in Bioseq [%c]", ch);
1676         }
1677     }
1678     BSWrite(bsp, buf, (Int4) (bu - buf));
1679     MemFree(buf);
1680     MemFree(dnaconv);
1681 
1682     return TRUE;
1683 }
1684 
AddAAsToByteStore(ByteStorePtr bsp,CharPtr the_aas)1685 NLM_EXTERN Boolean AddAAsToByteStore (ByteStorePtr bsp, CharPtr the_aas)
1686 {
1687     Uint1 PNTR buf;
1688     Uint1 PNTR bu;
1689     Uint1    residue;
1690     Uint1Ptr aaconv;
1691     CharPtr tmp;
1692     Char ch;
1693 
1694     aaconv = GetProteinConv();
1695     buf = MemNew(StringLen(the_aas) + 1);
1696     bu = buf;
1697     for (tmp = the_aas; *tmp != '\0'; tmp++)
1698     {
1699         ch = TO_UPPER(*tmp);
1700         residue = aaconv[ch];
1701         if (residue > 2) {
1702             *bu++ = residue;
1703         } else if (residue == 1 && IS_ALPHA(ch)) {
1704             *bu++ = 'X';
1705         } else {
1706             ErrPostEx(SEV_ERROR, 0,0, "Illegal character in Bioseq [%c]", ch);
1707         }
1708     }
1709 
1710     BSWrite(bsp, buf, (Int4) (bu - buf));
1711     MemFree(buf);
1712     MemFree(aaconv);
1713 
1714     return TRUE;
1715 }
1716 
1717 /*****************************************************************************
1718 *
1719 *   Add residues to raw Bioseqs
1720 *
1721 *****************************************************************************/
AddBasesToBioseq(NCBISubPtr submission,SeqEntryPtr the_seq,CharPtr the_bases)1722 NLM_EXTERN Boolean AddBasesToBioseq (
1723     NCBISubPtr submission ,
1724     SeqEntryPtr the_seq ,
1725     CharPtr the_bases )
1726 {
1727     BioseqPtr bsp;
1728 
1729     if ((the_seq == NULL) || (the_bases == NULL))
1730         return FALSE;
1731 
1732     if (! IS_Bioseq(the_seq))
1733     {
1734         Message(MSG_ERROR, "Adding bases to a Bioseq-set");
1735         return FALSE;
1736     }
1737 
1738     bsp = (BioseqPtr)(the_seq->data.ptrvalue);
1739 
1740     if (! ISA_na(bsp->mol))
1741     {
1742         Message(MSG_ERROR, "Adding bases to a protein");
1743         return FALSE;
1744     }
1745 
1746     if (bsp->repr != Seq_repr_raw)
1747     {
1748         Message(MSG_ERROR, "Adding residues to non-raw Bioseq");
1749         return FALSE;
1750     }
1751 
1752     if (bsp->seq_data == NULL)
1753     {
1754         bsp->seq_data = (SeqDataPtr) BSNew(bsp->length);
1755         bsp->seq_data_type = Seq_code_iupacna;
1756     }
1757 
1758     return AddBasesToByteStore((ByteStorePtr) bsp->seq_data, the_bases);
1759 }
1760 
AddAminoAcidsToBioseq(NCBISubPtr submission,SeqEntryPtr the_seq,CharPtr the_aas)1761 NLM_EXTERN Boolean AddAminoAcidsToBioseq (
1762     NCBISubPtr submission ,
1763     SeqEntryPtr the_seq ,
1764     CharPtr the_aas )
1765 {
1766     BioseqPtr bsp;
1767 
1768     if ((the_seq == NULL) || (the_aas == NULL))
1769         return FALSE;
1770 
1771     if (! IS_Bioseq(the_seq))
1772     {
1773         Message(MSG_ERROR, "Adding amino acids to a Bioseq-set");
1774         return FALSE;
1775     }
1776 
1777     bsp = (BioseqPtr)(the_seq->data.ptrvalue);
1778 
1779     if (ISA_na(bsp->mol))
1780     {
1781         Message(MSG_ERROR, "Adding amino acids to a nucleotide");
1782         return FALSE;
1783     }
1784 
1785     if (bsp->repr != Seq_repr_raw)
1786     {
1787         Message(MSG_ERROR, "Adding residues to non-raw Bioseq");
1788         return FALSE;
1789     }
1790 
1791     if (bsp->seq_data == NULL)
1792     {
1793         bsp->seq_data = (SeqDataPtr) BSNew(bsp->length);
1794         bsp->seq_data_type = Seq_code_ncbieaa;
1795     }
1796 
1797     return AddAAsToByteStore((ByteStorePtr) bsp->seq_data, the_aas);
1798 }
1799 
1800 
1801 /*****************************************************************************
1802 *
1803 *   Add residues to Literals
1804 *
1805 *****************************************************************************/
AddBasesToLiteral(NCBISubPtr submission,SeqLitPtr the_literal,CharPtr the_bases)1806 NLM_EXTERN Boolean AddBasesToLiteral (
1807     NCBISubPtr submission ,
1808     SeqLitPtr the_literal ,
1809     CharPtr the_bases )
1810 {
1811     if ((the_literal== NULL) || (the_bases == NULL))
1812         return FALSE;
1813 
1814 
1815     if (the_literal->seq_data == NULL)
1816     {
1817         the_literal->seq_data = (SeqDataPtr) BSNew(the_literal->length);
1818         the_literal->seq_data_type = Seq_code_iupacna;
1819     }
1820 
1821     return AddBasesToByteStore((ByteStorePtr) the_literal->seq_data, the_bases);
1822 }
1823 
AddAminoAcidsToLiteral(NCBISubPtr submission,SeqLitPtr the_literal,CharPtr the_aas)1824 NLM_EXTERN Boolean AddAminoAcidsToLiteral (
1825     NCBISubPtr submission ,
1826     SeqLitPtr the_literal ,
1827     CharPtr the_aas )
1828 {
1829 
1830     if ((the_literal == NULL) || (the_aas == NULL))
1831         return FALSE;
1832 
1833 
1834     if (the_literal->seq_data == NULL)
1835     {
1836         the_literal->seq_data = (SeqDataPtr) BSNew(the_literal->length);
1837         the_literal->seq_data_type = Seq_code_ncbieaa;
1838     }
1839 
1840     return AddAAsToByteStore((ByteStorePtr) the_literal->seq_data, the_aas);
1841 }
1842 
1843 /*****************************************************************************
1844 *
1845 *   Add Annotations to Entries
1846 *
1847 *****************************************************************************/
1848 
StripNonAsciiChars(CharPtr str)1849 static Boolean StripNonAsciiChars (CharPtr str)
1850 {
1851     Boolean retval = TRUE;
1852 
1853     while (*str != '\0')
1854     {
1855         if ((*str < ' ') || (*str > '~'))
1856         {
1857             retval = FALSE;
1858             if (*str == '\n' || *str == '\r')
1859                 *str = '~';
1860             else
1861                 *str = '#';
1862         }
1863         str++;
1864     }
1865     return retval;
1866 }
1867 
NewDescrOnSeqEntry(SeqEntryPtr entry,Int2 type)1868 NLM_EXTERN ValNodePtr NewDescrOnSeqEntry (SeqEntryPtr entry, Int2 type)
1869 {
1870     ValNodePtr vnp;
1871     BioseqPtr bsp;
1872     BioseqSetPtr bssp;
1873 
1874     if (entry == NULL)
1875         return NULL;
1876 
1877     if (IS_Bioseq(entry))
1878     {
1879         bsp = (BioseqPtr)(entry->data.ptrvalue);
1880         vnp = SeqDescrAdd(&(bsp->descr));
1881     }
1882     else
1883     {
1884         bssp = (BioseqSetPtr)(entry->data.ptrvalue);
1885         vnp = SeqDescrAdd(&(bssp->descr));
1886     }
1887     if (vnp != NULL)
1888         vnp->choice = (Uint1)type;
1889     return vnp;
1890 }
1891 
GetDescrOnSeqEntry(SeqEntryPtr entry,Int2 type)1892 NLM_EXTERN ValNodePtr GetDescrOnSeqEntry (SeqEntryPtr entry, Int2 type)
1893 {
1894     ValNodePtr vnp;
1895     BioseqPtr bsp;
1896     BioseqSetPtr bssp;
1897 
1898     if (entry == NULL)
1899         return NULL;
1900 
1901     if (IS_Bioseq(entry))
1902     {
1903         bsp = (BioseqPtr)(entry->data.ptrvalue);
1904         for (vnp = bsp->descr; vnp; vnp = vnp->next) {
1905             if (vnp->choice == (Uint1)type) {
1906                 return vnp;
1907             }
1908         }
1909         vnp = SeqDescrAdd(&(bsp->descr));
1910     }
1911     else
1912     {
1913         bssp = (BioseqSetPtr)(entry->data.ptrvalue);
1914         for (vnp = bssp->descr; vnp; vnp = vnp->next) {
1915             if (vnp->choice == (Uint1)type) {
1916                 return vnp;
1917             }
1918         }
1919         vnp = SeqDescrAdd(&(bssp->descr));
1920     }
1921     if (vnp != NULL)
1922         vnp->choice = (Uint1)type;
1923     return vnp;
1924 }
1925 
SubutilMakeAc2GBSeqId(CharPtr accession)1926 static SeqIdPtr SubutilMakeAc2GBSeqId (CharPtr accession)
1927 {
1928    TextSeqIdPtr tsip;
1929    SeqIdPtr sip;
1930 
1931    if (accession == NULL || *accession == '\0')
1932       return NULL;
1933 
1934    sip = ValNodeNew(NULL);
1935    sip->choice = SEQID_GENBANK;
1936    tsip = TextSeqIdNew();
1937    sip->data.ptrvalue = tsip;
1938    tsip->accession = StringSave(accession);
1939 
1940    return sip;
1941 
1942 } /* MakeAc2GBSeqId */
1943 
AddSecondaryAccnToEntry(NCBISubPtr submission,SeqEntryPtr entry,CharPtr accn)1944 NLM_EXTERN Boolean AddSecondaryAccnToEntry (
1945 NCBISubPtr submission,
1946     SeqEntryPtr entry ,
1947     CharPtr accn )
1948 
1949 {
1950     BioseqPtr bsp;
1951     ValNodePtr vnp;
1952     GBBlockPtr gbp;
1953     CharPtr p;
1954     Int4 i, j;
1955     SeqHistPtr shp;
1956     SeqIdPtr sip;
1957 
1958     if ((entry == NULL) || (accn == NULL))
1959         return FALSE;
1960 
1961     if (! IS_Bioseq(entry))
1962         return FALSE;
1963 
1964     bsp = (BioseqPtr)(entry->data.ptrvalue);
1965     if (bsp == NULL)
1966         return FALSE;
1967 
1968     vnp = GetDescrOnSeqEntry (entry, Seq_descr_genbank);
1969     if (vnp == NULL) {
1970         vnp = NewDescrOnSeqEntry (entry, Seq_descr_genbank);
1971         if (vnp != NULL) {
1972             vnp->data.ptrvalue = (Pointer) GBBlockNew ();
1973         }
1974     }
1975     if (vnp == NULL) return FALSE;
1976     gbp = (GBBlockPtr) vnp->data.ptrvalue;
1977     /* jwc added */
1978     if (gbp == NULL) {
1979       vnp->data.ptrvalue = (Pointer) GBBlockNew ();
1980       gbp = vnp->data.ptrvalue;
1981     }
1982     /* end of jwc added */
1983     if (gbp == NULL) return FALSE;
1984 
1985     shp = bsp->hist;
1986 
1987     p = accn;
1988     for (i = 0; isalnum(*p) && *p != '\0'; ++p, ++i) continue;
1989 
1990                /* check one_letter+5digits or two_letter+6digits */
1991        if (i == 6 || i == 8)
1992        {
1993           if (!isalpha(accn[0]) || (!(isdigit(accn[1]) && i == 6) &&
1994               !(isalpha(accn[1]) && i == 8)))
1995           {
1996              ErrPostEx(SEV_ERROR,0,0,
1997  "Invalid accession (one_letter+5digits or two_letter+6digits): %s",
1998                                                            accn);
1999              return FALSE;
2000           }
2001 
2002           for (j = 2; j < i; ++j)
2003           {
2004               if (!(isdigit(accn[j])))
2005               {
2006                  ErrPostEx(SEV_ERROR,0,0,
2007  "Invalid accession (one_letter+5digits or two_letter+6digits): %s",
2008                                                            accn);
2009                  return FALSE;
2010               }
2011           }
2012 
2013           ValNodeCopyStr (&gbp->extra_accessions, 0, accn);
2014           sip = SubutilMakeAc2GBSeqId (accn);
2015           if (shp == NULL)
2016           {
2017              shp = SeqHistNew();
2018              bsp->hist = shp;
2019           }
2020           ValNodeLink (&shp->replace_ids, sip);
2021        }
2022        else
2023        {
2024           ErrPostEx(SEV_ERROR,0,0,
2025  "Invalid accession (one_letter+5digits or two_letter+6digits): %s",
2026                                                            accn);
2027           return FALSE;
2028        }
2029 
2030     return TRUE;
2031 }
2032 
AddTitleToEntry(NCBISubPtr submission,SeqEntryPtr entry,CharPtr title)2033 NLM_EXTERN Boolean AddTitleToEntry (
2034     NCBISubPtr submission,
2035     SeqEntryPtr entry ,
2036     CharPtr title )
2037 {
2038     ValNodePtr vnp;
2039 
2040     if ((submission == NULL) || (entry == NULL) || (title == NULL))
2041         return FALSE;
2042 
2043     vnp = NewDescrOnSeqEntry (entry, Seq_descr_title);
2044 
2045     vnp->data.ptrvalue = (Pointer)(StringSaveNoNull(title));
2046     StripNonAsciiChars((CharPtr)(vnp->data.ptrvalue));
2047     return TRUE;
2048 }
2049 
AddCommentToEntry(NCBISubPtr submission,SeqEntryPtr entry,CharPtr comment)2050 NLM_EXTERN Boolean AddCommentToEntry (
2051     NCBISubPtr submission,
2052     SeqEntryPtr entry ,
2053     CharPtr comment )
2054 {
2055     ValNodePtr vnp;
2056 
2057     if ((submission == NULL) || (entry == NULL) || (comment == NULL))
2058         return FALSE;
2059 
2060     vnp = NewDescrOnSeqEntry (entry, Seq_descr_comment);
2061 
2062     vnp->data.ptrvalue = (Pointer)(StringSaveNoNull(comment));
2063     StripNonAsciiChars((CharPtr)(vnp->data.ptrvalue));
2064     return TRUE;
2065 }
2066 
AddOrganismToEntry(NCBISubPtr submission,SeqEntryPtr entry,CharPtr scientific_name,CharPtr common_name,CharPtr virus_name,CharPtr strain,CharPtr synonym1,CharPtr synonym2,CharPtr synonym3)2067 NLM_EXTERN Boolean AddOrganismToEntry (
2068     NCBISubPtr submission,
2069     SeqEntryPtr entry ,
2070     CharPtr scientific_name ,
2071     CharPtr common_name ,
2072     CharPtr virus_name ,
2073     CharPtr strain ,
2074     CharPtr synonym1,
2075     CharPtr synonym2,
2076     CharPtr synonym3)
2077 {
2078     ValNodePtr vnp;
2079     OrgRefPtr orp;
2080     Char buf[128];
2081 
2082     if ((submission == NULL) || (entry == NULL))
2083         return FALSE;
2084 
2085     vnp = NewDescrOnSeqEntry (entry, Seq_descr_org);
2086 
2087     orp = OrgRefNew();
2088     vnp->data.ptrvalue = (Pointer)orp;
2089 
2090     orp->taxname = StringSaveNoNull(scientific_name);
2091     orp->common = StringSaveNoNull(common_name);
2092     if (virus_name != NULL)    /* kludge for old Org-ref */
2093     {
2094         orp->taxname = StringSaveNoNull(virus_name);
2095         ValNodeCopyStr(&orp->syn, 0, scientific_name);
2096     }
2097 
2098     if (strain != NULL)
2099     {
2100         sprintf(buf, "strain=%.70s", strain);
2101         ValNodeCopyStr(&orp->mod, 0, buf);
2102     }
2103 
2104     ValNodeCopyStr(&orp->syn, 0, synonym1);
2105     ValNodeCopyStr(&orp->syn, 0, synonym2);
2106     ValNodeCopyStr(&orp->syn, 0, synonym3);
2107 
2108      return TRUE;
2109 }
2110 
AddOrganismToEntryEx(NCBISubPtr submission,SeqEntryPtr entry,CharPtr scientific_name,CharPtr common_name,CharPtr virus_name,CharPtr strain,CharPtr synonym1,CharPtr synonym2,CharPtr synonym3,CharPtr taxonomy,Int4 taxid)2111 NLM_EXTERN Boolean AddOrganismToEntryEx (
2112     NCBISubPtr submission,
2113     SeqEntryPtr entry ,
2114     CharPtr scientific_name ,
2115     CharPtr common_name ,
2116     CharPtr virus_name ,
2117     CharPtr strain ,
2118     CharPtr synonym1,
2119     CharPtr synonym2,
2120     CharPtr synonym3,
2121     CharPtr taxonomy,
2122     Int4 taxid)
2123 
2124 {
2125     ValNodePtr vnp;
2126     BioSourcePtr bio;
2127     OrgRefPtr orp;
2128     OrgModPtr orm;
2129     OrgNamePtr onp = NULL;
2130     DbtagPtr dbt;
2131     ObjectIdPtr oip;
2132 
2133     if ((submission == NULL) || (entry == NULL))
2134         return FALSE;
2135 
2136     vnp = GetDescrOnSeqEntry (entry, Seq_descr_source);
2137 
2138     bio = vnp->data.ptrvalue;
2139     if (bio == NULL) {
2140         bio = BioSourceNew();
2141     }
2142     if ((orp = bio->org) == NULL)
2143         orp = OrgRefNew();
2144 
2145     orp->taxname = StringSaveNoNull(scientific_name);
2146     orp->common = StringSaveNoNull(common_name);
2147     if (virus_name != NULL)    /* kludge for old Org-ref */
2148     {
2149         orp->taxname = StringSaveNoNull(virus_name);
2150         ValNodeCopyStr(&orp->syn, 0, scientific_name);
2151     }
2152 
2153     if (taxonomy != NULL) {
2154         onp = OrgNameNew();
2155         onp->lineage = StringSave(taxonomy);
2156     }
2157     if (strain != NULL)
2158     {
2159         orm = OrgModNew();
2160         orm->subtype = 2;  /* strain */
2161         orm->subname = StringSave(strain);
2162         if (onp == NULL) {
2163             onp = OrgNameNew();
2164         }
2165         onp->mod = orm;
2166     }
2167     if (onp != NULL) {
2168         orp->orgname = onp;
2169     }
2170     ValNodeCopyStr(&orp->syn, 0, synonym1);
2171     ValNodeCopyStr(&orp->syn, 0, synonym2);
2172     ValNodeCopyStr(&orp->syn, 0, synonym3);
2173     bio->org = orp;
2174     vnp->data.ptrvalue = (Pointer)bio;
2175 
2176     if (taxid > 0) {
2177         dbt = DbtagNew ();
2178         if (dbt != NULL) {
2179             oip = ObjectIdNew ();
2180             if (oip != NULL) {
2181                 dbt->db = StringSave ("taxon");
2182                 dbt->tag = oip;
2183                 oip->id = taxid;
2184                 ValNodeAddPointer (&orp->db, 0, (Pointer) dbt);
2185             }
2186         }
2187     }
2188 
2189      return TRUE;
2190 }
2191 
AddOrganismToEntryNew(NCBISubPtr submission,SeqEntryPtr entry,CharPtr scientific_name,CharPtr common_name,CharPtr virus_name,CharPtr strain,CharPtr synonym1,CharPtr synonym2,CharPtr synonym3,CharPtr taxonomy)2192 NLM_EXTERN Boolean AddOrganismToEntryNew (
2193     NCBISubPtr submission,
2194     SeqEntryPtr entry ,
2195     CharPtr scientific_name ,
2196     CharPtr common_name ,
2197     CharPtr virus_name ,
2198     CharPtr strain ,
2199     CharPtr synonym1,
2200     CharPtr synonym2,
2201     CharPtr synonym3,
2202     CharPtr taxonomy)
2203 {
2204     return AddOrganismToEntryEx (submission, entry, scientific_name,
2205                                  common_name, virus_name, strain,
2206                                  synonym1, synonym2, synonym3,
2207                                  taxonomy, 0);
2208 }
2209 
SetGeneticCodeForEntry(NCBISubPtr submission,SeqEntryPtr entry,Uint1 genetic_code,Uint1 mito_code)2210 NLM_EXTERN Boolean SetGeneticCodeForEntry (
2211     NCBISubPtr submission,
2212         SeqEntryPtr entry,
2213         Uint1 genetic_code,  /* for cytoplasm */
2214         Uint1 mito_code )   /* for mitochondria */
2215 {
2216     ValNodePtr vnp;
2217     BioSourcePtr bio;
2218     OrgRefPtr orp;
2219     OrgNamePtr onp = NULL;
2220 
2221     if ((submission == NULL) || (entry == NULL))
2222         return FALSE;
2223 
2224     vnp = GetDescrOnSeqEntry (entry, Seq_descr_source);
2225 
2226     bio = vnp->data.ptrvalue;
2227     if (bio == NULL) {
2228         bio = BioSourceNew();
2229         vnp->data.ptrvalue = bio;
2230     }
2231     if ((orp = bio->org) == NULL)
2232     {
2233         orp = OrgRefNew();
2234         bio->org = orp;
2235     }
2236 
2237     if ((onp = orp->orgname) == NULL)
2238     {
2239         onp = OrgNameNew();
2240         orp->orgname = onp;
2241     }
2242 
2243     onp->gcode = genetic_code;
2244     onp->mgcode = mito_code;
2245 
2246     return TRUE;
2247 }
2248 
SubExpandSemicolonedKeyword(ValNodePtr vnp)2249 static void SubExpandSemicolonedKeyword (ValNodePtr vnp)
2250 
2251 {
2252   Char        ch;
2253   ValNodePtr  lastvnp;
2254   ValNodePtr  newvnp;
2255   ValNodePtr  nextvnp;
2256   CharPtr     ptr;
2257   CharPtr     str;
2258   CharPtr     tmp;
2259 
2260   if (vnp == NULL) return;
2261   str = (CharPtr) vnp->data.ptrvalue;
2262   if (StringHasNoText (str)) return;
2263   if (StringChr (str, ';') == NULL && StringChr (str, ',') == NULL) return;
2264 
2265   lastvnp = vnp;
2266   nextvnp = vnp->next;
2267 
2268   tmp = StringSave (str);
2269   str = tmp;
2270   vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
2271   while (StringDoesHaveText (str)) {
2272     ptr = str;
2273     ch = *ptr;
2274     while (ch != '\0' && ch != ',' && ch != ';') {
2275       ptr++;
2276       ch = *ptr;
2277     }
2278     if (ptr != NULL && *ptr != '\0') {
2279       *ptr = '\0';
2280       ptr++;
2281     }
2282     TrimSpacesAroundString (str);
2283     newvnp = ValNodeCopyStr (NULL, 0, str);
2284     if (newvnp != NULL) {
2285       newvnp->next = nextvnp;
2286       lastvnp->next = newvnp;
2287       lastvnp = newvnp;
2288     }
2289     str = ptr;
2290   }
2291   MemFree (tmp);
2292 }
2293 
AddGenBankBlockToEntry(NCBISubPtr submission,SeqEntryPtr entry,CharPtr taxonomy,CharPtr division,CharPtr keyword1,CharPtr keyword2,CharPtr keyword3)2294 NLM_EXTERN Boolean AddGenBankBlockToEntry (
2295     NCBISubPtr submission,
2296     SeqEntryPtr entry ,
2297     CharPtr taxonomy ,
2298     CharPtr division ,
2299     CharPtr keyword1 ,
2300     CharPtr keyword2 ,
2301     CharPtr keyword3 )
2302 {
2303     ValNodePtr vnp, tmp;
2304     GBBlockPtr gbp;
2305 
2306     if ((submission == NULL) || (entry == NULL))
2307         return FALSE;
2308 
2309     vnp = NewDescrOnSeqEntry (entry, Seq_descr_genbank);
2310 
2311     gbp = GBBlockNew();
2312     vnp->data.ptrvalue = (Pointer)gbp;
2313 
2314     gbp->taxonomy = StringSaveNoNull(taxonomy);
2315     gbp->div = StringSaveNoNull(division);
2316 
2317     ValNodeCopyStr(&gbp->keywords, 0, keyword1);
2318     ValNodeCopyStr(&gbp->keywords, 0, keyword2);
2319     ValNodeCopyStr(&gbp->keywords, 0, keyword3);
2320 
2321     for (tmp = gbp->keywords; tmp != NULL; tmp = tmp->next) {
2322         SubExpandSemicolonedKeyword (tmp);
2323     }
2324 
2325     return TRUE;
2326 }
2327 
AddGIBBmethodToEntry(NCBISubPtr submission,SeqEntryPtr entry,Int2 method)2328 NLM_EXTERN Boolean AddGIBBmethodToEntry (
2329     NCBISubPtr submission,
2330     SeqEntryPtr entry ,
2331     Int2     method )
2332 {
2333     ValNodePtr vnp;
2334 
2335     if ((submission == NULL) || (entry == NULL))
2336         return FALSE;
2337 
2338     vnp = NewDescrOnSeqEntry (entry, Seq_descr_method);
2339 
2340     vnp->data.intvalue = method;
2341 
2342     return TRUE;
2343 }
2344 
AddGenomeToEntry(NCBISubPtr submission,SeqEntryPtr entry,Int2 type)2345 NLM_EXTERN Boolean AddGenomeToEntry (
2346     NCBISubPtr submission,
2347     SeqEntryPtr entry ,
2348     Int2     type )
2349 {
2350     ValNodePtr vnp;
2351     BioSourcePtr bio;
2352 
2353     if ((submission == NULL) || (entry == NULL))
2354         return FALSE;
2355 
2356     vnp = GetDescrOnSeqEntry (entry, Seq_descr_source);
2357 
2358     bio = (BioSourcePtr) vnp->data.ptrvalue;
2359     if (bio == NULL) {
2360         bio = BioSourceNew();
2361     }
2362     bio->genome = (Uint1)type;
2363     bio->origin = ORG_DEFAULT;    /* unknown */
2364     vnp->data.ptrvalue = (Pointer) bio;
2365 
2366     return TRUE;
2367 }
2368 
AddSubSourceToEntry(NCBISubPtr submission,SeqEntryPtr entry,Int2 type,CharPtr value)2369 NLM_EXTERN Boolean AddSubSourceToEntry (
2370     NCBISubPtr submission,
2371     SeqEntryPtr entry ,
2372     Int2     type ,
2373     CharPtr value)
2374 {
2375     BioSourcePtr bio;
2376     SubSourcePtr curr, tmp;
2377     ValNodePtr vnp;
2378 
2379     if ((submission == NULL) || (entry == NULL))
2380         return FALSE;
2381 
2382     vnp = GetDescrOnSeqEntry (entry, Seq_descr_source);
2383 
2384     bio = (BioSourcePtr) vnp->data.ptrvalue;
2385     if (bio == NULL) {
2386         return FALSE;
2387     }
2388     tmp = SubSourceNew();
2389         if (bio->subtype == NULL)
2390         bio->subtype = tmp;
2391     else
2392     {
2393         for (curr = bio->subtype; curr->next != NULL; curr = curr->next)
2394             continue;
2395         curr->next = tmp;
2396     }
2397 
2398     tmp->subtype = (Uint1)type;
2399     tmp->name = StringSaveNoNull(value);
2400 
2401     return TRUE;
2402 }
2403 
2404 
AddOrgModToEntry(NCBISubPtr submission,SeqEntryPtr entry,Int2 type,CharPtr value)2405 NLM_EXTERN Boolean AddOrgModToEntry (
2406     NCBISubPtr submission,
2407     SeqEntryPtr entry ,
2408     Int2     type ,
2409     CharPtr value)
2410 {
2411     BioSourcePtr bio;
2412     OrgRefPtr orp;
2413     OrgNamePtr onp;
2414     OrgModPtr curr, tmp;
2415     ValNodePtr vnp;
2416 
2417     if ((submission == NULL) || (entry == NULL))
2418         return FALSE;
2419 
2420     vnp = GetDescrOnSeqEntry (entry, Seq_descr_source);
2421 
2422     bio = (BioSourcePtr) vnp->data.ptrvalue;
2423     if (bio == NULL) {
2424         return FALSE;
2425     }
2426     if (bio->org == NULL)
2427     {
2428         return FALSE;
2429     }
2430     orp = bio->org;
2431     if (orp->orgname == NULL) {
2432         orp->orgname = OrgNameNew ();
2433     }
2434     if (orp->orgname == NULL)
2435         return FALSE;
2436     onp = orp->orgname;
2437     tmp = OrgModNew();
2438         if (onp->mod == NULL)
2439         onp->mod = tmp;
2440     else
2441     {
2442         for (curr = onp->mod; curr->next != NULL; curr = curr->next)
2443             continue;
2444         curr->next = tmp;
2445     }
2446 
2447     tmp->subtype = (Uint1)type;
2448     tmp->subname = StringSaveNoNull(value);
2449 
2450     return TRUE;
2451 }
2452 
AddBiomolToEntry(NCBISubPtr submission,SeqEntryPtr entry,Int2 type)2453 NLM_EXTERN Boolean AddBiomolToEntry (
2454     NCBISubPtr submission,
2455     SeqEntryPtr entry ,
2456     Int2     type )
2457 {
2458     ValNodePtr vnp;
2459     MolInfoPtr mip;
2460 
2461     if ((submission == NULL) || (entry == NULL))
2462         return FALSE;
2463 
2464     vnp = GetDescrOnSeqEntry (entry, Seq_descr_molinfo);
2465 
2466     mip = (MolInfoPtr) vnp->data.ptrvalue;
2467     if (mip == NULL)
2468         mip = MolInfoNew();
2469     mip->biomol = (Uint1)type;
2470     vnp->data.ptrvalue =  (Pointer) mip;
2471 
2472     return TRUE;
2473 }
2474 
AddTechToEntry(NCBISubPtr submission,SeqEntryPtr entry,Int2 tech)2475 NLM_EXTERN Boolean AddTechToEntry (
2476     NCBISubPtr submission,
2477     SeqEntryPtr entry ,
2478     Int2     tech )
2479 {
2480     ValNodePtr vnp;
2481     MolInfoPtr mip;
2482 
2483     if ((submission == NULL) || (entry == NULL))
2484         return FALSE;
2485 
2486     vnp = GetDescrOnSeqEntry (entry, Seq_descr_molinfo);
2487 
2488     mip = (MolInfoPtr) vnp->data.ptrvalue;
2489     if (mip == NULL)
2490         mip = MolInfoNew();
2491     mip->tech = (Uint1)tech;
2492     vnp->data.ptrvalue = (Pointer) mip;
2493 
2494     return TRUE;
2495 }
2496 
AddCompleteToEntry(NCBISubPtr submission,SeqEntryPtr entry,Int2 complete)2497 NLM_EXTERN Boolean AddCompleteToEntry (
2498     NCBISubPtr submission,
2499     SeqEntryPtr entry ,
2500     Int2     complete )
2501 {
2502     ValNodePtr vnp;
2503     MolInfoPtr mip;
2504 
2505     if ((submission == NULL) || (entry == NULL))
2506         return FALSE;
2507 
2508     vnp = GetDescrOnSeqEntry (entry, Seq_descr_molinfo);
2509 
2510     mip = (MolInfoPtr) vnp->data.ptrvalue;
2511     if (mip == NULL)
2512         mip = MolInfoNew();
2513     mip->completeness = (Uint1)complete;
2514     vnp->data.ptrvalue = (Pointer) mip;
2515 
2516     return TRUE;
2517 }
2518 
AddCompleteness(NCBISubPtr submission,SeqEntryPtr sep,SeqFeatPtr sfp)2519 NLM_EXTERN void AddCompleteness(NCBISubPtr submission, SeqEntryPtr sep, SeqFeatPtr sfp)
2520 {
2521     Uint2    retval;
2522     Boolean    partial = FALSE;
2523 
2524     retval = SeqLocPartialCheck(sfp->location);
2525     if ((retval & SLP_START) && (retval & SLP_STOP)) {
2526         AddCompleteToEntry(submission, sep, 5);   /* no_ends */
2527         partial = TRUE;
2528     } else if (retval & SLP_START) {
2529         AddCompleteToEntry(submission, sep, 3);   /* no_left */
2530         partial = TRUE;
2531     } else if (retval & SLP_STOP) {
2532         AddCompleteToEntry(submission, sep, 4);  /* no_right */
2533         partial = TRUE;
2534     } else if (retval & (SLP_OTHER | SLP_INTERNAL)) {
2535         AddCompleteToEntry(submission, sep, 2);  /* partial */
2536         partial = TRUE;
2537     } else if (!partial && sfp->partial) {
2538         AddCompleteToEntry(submission, sep, 2);  /* partial */
2539     }
2540 }
2541 
AddCreateDateToEntry(NCBISubPtr submission,SeqEntryPtr entry,Int2 month,Int2 day,Int2 year)2542 NLM_EXTERN Boolean AddCreateDateToEntry (
2543     NCBISubPtr submission,
2544     SeqEntryPtr entry ,
2545     Int2 month ,
2546     Int2 day ,
2547     Int2 year )
2548 {
2549     ValNodePtr vnp;
2550     DatePtr dp;
2551 
2552     if ((submission == NULL) || (entry == NULL))
2553         return FALSE;
2554 
2555     vnp = NewDescrOnSeqEntry (entry, Seq_descr_create_date);
2556 
2557     dp = DateNew();
2558     DateWrite(dp, year, month, day, NULL);
2559     vnp->data.ptrvalue = (Pointer)dp;
2560 
2561     return TRUE;
2562 }
2563 
AddModifierToEntry(NCBISubPtr submission,SeqEntryPtr entry,Int2 modifier)2564 NLM_EXTERN Boolean AddModifierToEntry (
2565     NCBISubPtr submission,
2566     SeqEntryPtr entry ,
2567     Int2 modifier )
2568 {
2569     ValNodePtr vnp, tmp;
2570     BioseqPtr bsp;
2571     BioseqSetPtr bssp;
2572 
2573     if ((submission == NULL) || (entry == NULL))
2574         return FALSE;
2575 
2576     if (IS_Bioseq(entry))
2577     {
2578         bsp = (BioseqPtr)(entry->data.ptrvalue);
2579         tmp = bsp->descr;
2580     }
2581     else
2582     {
2583         bssp = (BioseqSetPtr)(entry->data.ptrvalue);
2584         tmp = bssp->descr;
2585     }
2586 
2587     vnp = NULL;
2588     while (tmp != NULL)
2589     {
2590         if (tmp->choice == Seq_descr_modif)  /* have one already */
2591         {
2592             vnp = SeqDescrNew((ValNodePtr)(tmp->data.ptrvalue));
2593             break;
2594         }
2595         tmp = tmp->next;
2596     }
2597 
2598     if (vnp == NULL)   /* first one */
2599     {
2600         tmp = NewDescrOnSeqEntry (entry, Seq_descr_modif);
2601         vnp = SeqDescrNew((ValNodePtr)(tmp->data.ptrvalue));
2602         tmp->data.ptrvalue = (Pointer)vnp;
2603     }
2604 
2605     vnp->data.intvalue = (Int4)modifier;
2606 
2607     return TRUE;
2608 }
2609 
AddPubToEntry(NCBISubPtr submission,SeqEntryPtr entry,PubPtr pub)2610 NLM_EXTERN Boolean AddPubToEntry (
2611     NCBISubPtr submission,
2612     SeqEntryPtr entry ,
2613     PubPtr pub )
2614 {
2615     ValNodePtr vnp;
2616     PubdescPtr pdp;
2617 
2618     if ((submission == NULL) || (entry == NULL) || (pub == NULL))
2619         return FALSE;
2620 
2621     vnp = NewDescrOnSeqEntry (entry, Seq_descr_pub);
2622     pdp = PubdescNew();
2623     if (pub->choice == PUB_Equiv)   /* already a Pub-equiv */
2624     {
2625         pdp->pub = (ValNodePtr)(pub->data.ptrvalue);
2626         MemFree(pub);
2627     }
2628     else                     /* make a Pub-equiv of one member */
2629         pdp->pub = pub;
2630     vnp->data.ptrvalue = (Pointer)pdp;
2631 
2632     return TRUE;
2633 }
CitSubBuild(NCBISubPtr submission,Int2 month,Int2 day,Int2 year,Int2 medium)2634 NLM_EXTERN PubPtr CitSubBuild (NCBISubPtr submission, Int2 month,
2635                                Int2 day, Int2 year, Int2 medium)
2636 {
2637     ValNodePtr vnp;
2638     CitSubPtr csp;
2639 
2640     vnp = ValNodeNew(NULL);
2641     vnp->choice = PUB_Sub;   /* Cit-sub */
2642     csp = CitSubNew();
2643     vnp->data.ptrvalue = (Pointer)csp;
2644 
2645     csp->medium = (Uint1)medium;
2646     csp->date = DateNew();
2647     DateWrite(csp->date, year, month, day, NULL);
2648     return (PubPtr) vnp;
2649 }
2650 
CitSubUpdateBuild(NCBISubPtr submission,Int2 month,Int2 day,Int2 year,Int2 medium,CharPtr descr)2651 NLM_EXTERN PubPtr CitSubUpdateBuild (NCBISubPtr submission, Int2 month,
2652                                      Int2 day, Int2 year,Int2 medium ,
2653                                      CharPtr descr )
2654      /* description of update, make it short */
2655 {
2656     ValNodePtr vnp;
2657     CitSubPtr csp;
2658 
2659     vnp = ValNodeNew(NULL);
2660     vnp->choice = PUB_Sub;   /* Cit-sub */
2661     csp = CitSubNew();
2662     vnp->data.ptrvalue = (Pointer)csp;
2663 
2664     csp->medium = (Uint1)medium;
2665     csp->descr = StringSave(descr);
2666     csp->date = DateNew();
2667     DateWrite(csp->date, year, month, day, NULL);
2668     return vnp;
2669 }
2670 
CitArtBuild(NCBISubPtr submission,CharPtr title,CharPtr journal,CharPtr volume,CharPtr issue,CharPtr pages,Int2 month,Int2 day,Int2 year,Int2 status)2671 NLM_EXTERN PubPtr CitArtBuild (
2672                                NCBISubPtr submission,
2673                                CharPtr title ,
2674                                CharPtr journal ,
2675                                CharPtr volume ,
2676                                CharPtr issue ,
2677                                CharPtr pages ,
2678                                Int2 month ,
2679                                Int2 day ,
2680                                Int2 year ,
2681                                Int2 status )
2682 {
2683     ValNodePtr vnp, tmp;
2684     CitArtPtr cap;
2685     CitJourPtr cjp;
2686     CitGenPtr cgp;
2687     ImprintPtr  ip;
2688 
2689     vnp = ValNodeNew(NULL);
2690 
2691     if (status == PUB_STATUS_UNPUBLISHED) {  /* can't do a Cit-art */
2692         vnp->choice = PUB_Gen;   /* Cit-gen */
2693         cgp = CitGenNew();
2694         vnp->data.ptrvalue = cgp;
2695         cgp->cit = StringSaveNoNull("Unpublished");
2696         cgp->title = StringSaveNoNull(title);
2697         tmp = ValNodeCopyStr (&cgp->journal, Cit_title_jta, journal);
2698         cgp->volume = StringSaveNoNull(volume);
2699         cgp->issue = StringSaveNoNull(issue);
2700         cgp->pages = StringSaveNoNull(pages);
2701         if (year > 0) {
2702             cgp->date = DateNew();
2703             DateWrite(cgp->date, year, month, day, NULL);
2704         }
2705     } else {                             /* regular pub */
2706 
2707         vnp->choice = PUB_Article;   /* Cit-art */
2708         cap = CitArtNew();
2709         vnp->data.ptrvalue = cap;
2710         cap->from = 1;     /* from journal only */
2711         tmp = ValNodeCopyStr (&cap->title, Cit_title_name, title);
2712         cjp = CitJourNew();
2713         cap->fromptr = (Pointer)cjp;
2714         tmp = ValNodeCopyStr (&cjp->title, Cit_title_jta, journal);
2715         ip = ImprintNew();
2716         cjp->imp = ip;
2717 
2718         if (year > 0) {
2719             ip->date = DateNew();
2720             DateWrite(ip->date, year, month, day, NULL);
2721         } else
2722             ip->date = DateCurr();
2723 
2724         ip->volume = StringSaveNoNull(volume);
2725         ip->issue = StringSaveNoNull(issue);
2726         ip->pages = StringSaveNoNull(pages);
2727 
2728         if (status == PUB_STATUS_SUBMITTED)
2729             ip->prepub = (Uint1)1;
2730         else if (status == PUB_STATUS_IN_PRESS)
2731             ip->prepub = (Uint1)2;
2732     }
2733     return vnp;
2734 }
2735 
AddAuthorToPub(NCBISubPtr submission,PubPtr the_pub,CharPtr last_name,CharPtr first_name,CharPtr middle_name,CharPtr initials,CharPtr suffix)2736 NLM_EXTERN Boolean AddAuthorToPub (    /* call once for each author, in order */
2737     NCBISubPtr submission,
2738     PubPtr the_pub,
2739     CharPtr last_name,
2740     CharPtr first_name,
2741     CharPtr middle_name,
2742     CharPtr initials,  /* separated by periods, no initial for last name */
2743     CharPtr suffix )   /* Jr. Sr. III */
2744 {
2745     CitGenPtr cgp;
2746     CitSubPtr csp;
2747     CitArtPtr cap;
2748     AuthListPtr alp;
2749     AuthorPtr ap;
2750     PersonIdPtr pip;
2751     NameStdPtr nsp;
2752     ValNodePtr vnp;
2753 
2754     if ((submission == NULL) || (the_pub == NULL) || (last_name == NULL))
2755         return FALSE;
2756 
2757     switch (the_pub->choice)
2758     {
2759         case PUB_Sub:
2760             csp = (CitSubPtr)(the_pub->data.ptrvalue);
2761             if (csp->authors == NULL)
2762             {
2763                 csp->authors = AuthListNew();
2764                 csp->authors->choice = 1;   /* std */
2765             }
2766             alp = csp->authors;
2767             break;
2768         case PUB_Gen:
2769             cgp = (CitGenPtr)(the_pub->data.ptrvalue);
2770             if (cgp->authors == NULL)
2771             {
2772                 cgp->authors = AuthListNew();
2773                 cgp->authors->choice = 1;   /* std */
2774             }
2775             alp = cgp->authors;
2776             break;
2777         case PUB_Article:
2778             cap = (CitArtPtr)(the_pub->data.ptrvalue);
2779             if (cap->authors == NULL)
2780             {
2781                 cap->authors = AuthListNew();
2782                 cap->authors->choice = 1;   /* std */
2783             }
2784             alp = cap->authors;
2785             break;
2786         default:
2787             Message(MSG_ERROR, "AddAuthorToPub: Unsupported Pub type [%d]",
2788                 (int)the_pub->choice);
2789             return FALSE;
2790     }
2791 
2792     nsp = NameStdNew();
2793     nsp->names[0] = StringSaveNoNull(last_name);
2794     nsp->names[1] = StringSaveNoNull(first_name);
2795     nsp->names[2] = StringSaveNoNull(middle_name);
2796     nsp->names[4] = StringSaveNoNull(initials);
2797     nsp->names[5] = StringSaveNoNull(suffix);
2798 
2799     pip = PersonIdNew();
2800     pip->choice = 2;   /* name */
2801     pip->data = (Pointer)nsp;
2802 
2803     ap = AuthorNew();
2804     ap->name = pip;
2805 
2806     vnp = ValNodeAdd(&alp->names);
2807     vnp->data.ptrvalue = (Pointer)ap;
2808 
2809     return TRUE;
2810 }
2811 
AddAffiliationToPub(NCBISubPtr submission,PubPtr the_pub,CharPtr affil,CharPtr div,CharPtr street,CharPtr city,CharPtr sub,CharPtr country,CharPtr postal_code)2812 NLM_EXTERN Boolean AddAffiliationToPub (  /* call once per pub */
2813     NCBISubPtr submission,
2814     PubPtr the_pub,
2815     CharPtr affil,        /* e.g. "Xyz University" */
2816     CharPtr div,          /* e.g. "Dept of Biology" */
2817     CharPtr street,       /* e.g. "123 Academic Road" */
2818     CharPtr city,         /* e.g. "Metropolis" */
2819     CharPtr sub,          /* e.g. "Massachusetts" */
2820     CharPtr country,      /* e.g. "USA" */
2821     CharPtr postal_code ) /* e.g. "01234" */
2822 {
2823     CitGenPtr cgp;
2824     CitSubPtr csp;
2825     CitArtPtr cap;
2826     AuthListPtr alp;
2827     AffilPtr ap;
2828 
2829     if ((submission == NULL) || (the_pub == NULL))
2830         return FALSE;
2831 
2832     switch (the_pub->choice)
2833     {
2834         case PUB_Sub:
2835             csp = (CitSubPtr)(the_pub->data.ptrvalue);
2836             if (csp->authors == NULL)
2837             {
2838                 csp->authors = AuthListNew();
2839                 csp->authors->choice = 1;   /* std */
2840             }
2841             alp = csp->authors;
2842             break;
2843         case PUB_Gen:
2844             cgp = (CitGenPtr)(the_pub->data.ptrvalue);
2845             if (cgp->authors == NULL)
2846             {
2847                 cgp->authors = AuthListNew();
2848                 cgp->authors->choice = 1;   /* std */
2849             }
2850             alp = cgp->authors;
2851             break;
2852         case PUB_Article:
2853             cap = (CitArtPtr)(the_pub->data.ptrvalue);
2854             if (cap->authors == NULL)
2855             {
2856                 cap->authors = AuthListNew();
2857                 cap->authors->choice = 1;   /* std */
2858             }
2859             alp = cap->authors;
2860             break;
2861         default:
2862             Message(MSG_ERROR, "AddAffilToPub: Unsupported Pub type [%d]",
2863                 (int)the_pub->choice);
2864             return FALSE;
2865     }
2866 
2867     if (alp->affil != NULL)
2868     {
2869         Message(MSG_ERROR, "AddAffilToPub: Pub already has affil");
2870         return FALSE;
2871     }
2872 
2873     ap = AffilNew();
2874     alp->affil = ap;
2875     if (affil != NULL && div == NULL && city == NULL && sub == NULL
2876         && country == NULL && street == NULL && postal_code == NULL) {
2877         ap->choice = 1;    /* str affil */
2878         ap->affil = StringSaveNoNull(affil);
2879     } else {
2880         ap->choice = 2;    /* std affil */
2881         ap->affil = StringSaveNoNull(affil);
2882         ap->div = StringSaveNoNull(div);
2883         ap->city = StringSaveNoNull(city);
2884         ap->sub = StringSaveNoNull(sub);
2885         ap->country = StringSaveNoNull(country);
2886         ap->street = StringSaveNoNull(street);
2887         ap->postal_code = StringSaveNoNull(postal_code);
2888     }
2889 
2890     return TRUE;
2891 }
2892 
2893 
2894 /*****************************************************************************
2895 *
2896 *   Add Features to the entry
2897 *
2898 *****************************************************************************/
AddFeatureToEntry(NCBISubPtr submission,SeqEntryPtr entry,SeqFeatPtr feature)2899 static Boolean AddFeatureToEntry (
2900     NCBISubPtr submission,
2901     SeqEntryPtr entry ,
2902     SeqFeatPtr feature )
2903 {
2904     SeqFeatPtr sfp;
2905     SeqAnnotPtr sap;
2906     BioseqPtr bsp;
2907     BioseqSetPtr bssp;
2908 
2909     if ((submission == NULL) || (entry == NULL) || (feature == NULL))
2910         return FALSE;
2911 
2912     if (IS_Bioseq(entry))
2913     {
2914         bsp = (BioseqPtr)(entry->data.ptrvalue);
2915         for (sap = bsp->annot; sap != NULL; sap = sap->next)
2916         {
2917             if (sap->type == 1)   /* feature table */
2918                 break;
2919         }
2920         if (sap == NULL)
2921         {
2922             sap = SeqAnnotNew();
2923             sap->type = 1;
2924             bsp->annot = sap;
2925         }
2926     }
2927     else
2928     {
2929         bssp = (BioseqSetPtr)(entry->data.ptrvalue);
2930         for (sap = bssp->annot; sap != NULL; sap = sap->next)
2931         {
2932             if (sap->type == 1)   /* feature table */
2933                 break;
2934         }
2935         if (sap == NULL)
2936         {
2937             sap = SeqAnnotNew();
2938             sap->type = 1;
2939             bssp->annot = sap;
2940         }
2941     }
2942 
2943     sfp = (SeqFeatPtr)(sap->data);
2944     if (sfp == NULL)
2945         sap->data = (Pointer)feature;
2946     else
2947     {
2948         while (sfp->next != NULL)
2949             sfp = sfp->next;
2950         sfp->next = feature;
2951     }
2952 
2953     return TRUE;
2954 }
2955 
FeatureBuild(NCBISubPtr submission,SeqEntryPtr entry_to_put_feature,Boolean feature_is_partial,Uint1 evidence_is_experimental,Boolean biological_exception,CharPtr comment)2956 NLM_EXTERN SeqFeatPtr FeatureBuild (
2957     NCBISubPtr submission,
2958     SeqEntryPtr entry_to_put_feature,
2959     Boolean feature_is_partial,
2960     Uint1 evidence_is_experimental,
2961     Boolean biological_exception,
2962     CharPtr comment )
2963 {
2964     SeqFeatPtr sfp;
2965 
2966     if (entry_to_put_feature == NULL) return NULL;
2967 
2968     sfp = SeqFeatNew();
2969 
2970     sfp->partial = feature_is_partial;
2971     if ((evidence_is_experimental == EVIDENCE_EXPERIMENTAL)
2972         || (evidence_is_experimental == EVIDENCE_NOT_EXPERIMENTAL))
2973     {
2974         sfp->exp_ev = evidence_is_experimental;
2975     }
2976     sfp->excpt = biological_exception;
2977     if (comment != NULL)
2978     {
2979         if (*comment != '\0')
2980             sfp->comment = StringSaveNoNull(comment);
2981     }
2982 
2983     AddFeatureToEntry(submission, entry_to_put_feature, sfp);
2984 
2985     return sfp;
2986 }
2987 
2988 
AddIntervalToFeature(NCBISubPtr submission,SeqFeatPtr sfp,SeqEntryPtr the_seq,CharPtr local_name,Int4 from,Int4 to,Boolean on_plus_strand,Boolean start_before_from,Boolean stop_after_to)2989 NLM_EXTERN Boolean AddIntervalToFeature (
2990     NCBISubPtr submission,
2991     SeqFeatPtr sfp,
2992     SeqEntryPtr the_seq ,
2993     CharPtr local_name ,
2994     Int4 from ,
2995     Int4 to ,
2996     Boolean on_plus_strand ,
2997     Boolean start_before_from ,
2998     Boolean stop_after_to )
2999 {
3000     BioseqPtr bsp;
3001     Int4 tmp_from, tmp_to;
3002     Int2 tmp_fuzz_from, tmp_fuzz_to, fuzz_from, fuzz_to, strand;
3003 
3004 
3005     if (sfp == NULL) return FALSE;
3006 
3007     bsp = GetBioseqFromChoice(submission, the_seq, local_name, "AddIntervalToFeature");
3008     if (bsp == NULL) return FALSE;
3009 
3010     if (to == -1)
3011         to = BioseqGetLen(bsp);
3012 
3013         /** allow to input numbering from 1 */
3014 
3015     to -= 1;
3016     from -= 1;
3017     fuzz_from = -1;     /* not-set */
3018     fuzz_to = -1;
3019     if (! on_plus_strand)
3020     {
3021         strand = Seq_strand_minus;
3022         tmp_from = from;
3023         from = to;
3024         to = tmp_from;
3025         if (start_before_from)
3026             fuzz_to = 1;    /* gt */
3027         if (stop_after_to)
3028             fuzz_from = 2;  /* lt */
3029     }
3030     else
3031     {
3032         strand = 0;
3033         if (start_before_from)
3034             fuzz_from = 2;    /* lt */
3035         if (stop_after_to)
3036             fuzz_to = 1;  /* gt */
3037 
3038     }
3039 
3040     if (to < from)    /* go around origin on circular sequence */
3041     {
3042         if ((bsp->topology != 2) && (bsp->topology != 3))
3043         {
3044             Message(MSG_ERROR, "Attempt to go around origin of non-circular sequence");
3045             return FALSE;
3046         }
3047         tmp_fuzz_from = -1;
3048         tmp_fuzz_to = -1;
3049 
3050         if (on_plus_strand)
3051         {
3052             tmp_from = from;
3053             tmp_to = (BioseqGetLen(bsp) - 1);
3054             from = 0;
3055             tmp_fuzz_from = fuzz_from;
3056             fuzz_from = -1;
3057         }
3058         else
3059         {
3060             tmp_from = 0;
3061             tmp_to = to;
3062             to = (BioseqGetLen(bsp) - 1);
3063             tmp_fuzz_to = fuzz_to;
3064             fuzz_to = -1;
3065         }
3066 
3067         if (! AddIntToSeqFeat(sfp, tmp_from, tmp_to, bsp, tmp_fuzz_from, tmp_fuzz_to, strand))
3068             return FALSE;
3069     }
3070 
3071     return AddIntToSeqFeat(sfp, from, to, bsp, fuzz_from, fuzz_to, strand);
3072 }
3073 
AddIntToSeqLoc(SeqLocPtr PNTR old_slp,Int4 from,Int4 to,SeqIdPtr sip,Int2 fuzz_from,Int2 fuzz_to,Int2 strand)3074 NLM_EXTERN Boolean AddIntToSeqLoc (SeqLocPtr PNTR old_slp, Int4 from, Int4 to, SeqIdPtr sip,
3075                             Int2 fuzz_from, Int2 fuzz_to, Int2 strand)
3076 {
3077     SeqLocPtr slp, tmp, tmp2;
3078     SeqIntPtr sintp;
3079     IntFuzzPtr ifp;
3080 
3081   if (old_slp == NULL)
3082   {
3083     return FALSE;
3084   }
3085 
3086     sintp = SeqIntNew();
3087     sintp->from = from;
3088     sintp->to = to;
3089     sintp->id = SeqIdDup(sip);
3090     sintp->strand = (Uint1)strand;
3091     if (fuzz_from >= 0)
3092     {
3093         ifp = IntFuzzNew();
3094         ifp->choice = 4;   /* lim */
3095         ifp->a = (Int4)fuzz_from;
3096         sintp->if_from = ifp;
3097     }
3098     if (fuzz_to >= 0)
3099     {
3100         ifp = IntFuzzNew();
3101         ifp->choice = 4;   /* lim */
3102         ifp->a = (Int4)fuzz_to;
3103         sintp->if_to = ifp;
3104     }
3105 
3106     slp = ValNodeNew(NULL);
3107     slp->choice = SEQLOC_INT;
3108     slp->data.ptrvalue = (Pointer)sintp;
3109 
3110     if (*old_slp == NULL)
3111     {
3112         *old_slp = slp;
3113         return TRUE;
3114     }
3115 
3116     tmp = *old_slp;
3117     if (tmp->choice == SEQLOC_MIX)   /* second one already */
3118     {
3119         tmp2 = (ValNodePtr)(tmp->data.ptrvalue);
3120         while (tmp2->next != NULL)
3121             tmp2 = tmp2->next;
3122         tmp2->next = slp;
3123     }
3124     else                             /* create a chain */
3125     {
3126         tmp2 = ValNodeNew(NULL);
3127         tmp2->choice = SEQLOC_MIX;
3128         tmp2->data.ptrvalue = (Pointer)tmp;
3129         tmp->next = slp;
3130         *old_slp = tmp2;
3131     }
3132 
3133     return TRUE;
3134 }
3135 
AddIntToSeqFeat(SeqFeatPtr sfp,Int4 from,Int4 to,BioseqPtr bsp,Int2 fuzz_from,Int2 fuzz_to,Int2 strand)3136 NLM_EXTERN Boolean AddIntToSeqFeat (SeqFeatPtr sfp, Int4 from, Int4 to, BioseqPtr bsp,
3137                             Int2 fuzz_from, Int2 fuzz_to, Int2 strand)
3138 {
3139   return AddIntToSeqLoc (&(sfp->location), from, to, SeqIdFindBest(bsp->id, 0),
3140                             fuzz_from, fuzz_to, strand);
3141 }
3142 
AddPntToSeqLoc(SeqLocPtr PNTR p_slp,Int4 point,BioseqPtr bsp,Int2 fuzz,Int2 strand)3143 NLM_EXTERN Boolean AddPntToSeqLoc (SeqLocPtr PNTR p_slp, Int4 point, BioseqPtr bsp, Int2 fuzz, Int2 strand)
3144 {
3145     SeqLocPtr slp, tmp, tmp2;
3146     SeqPntPtr spp;
3147     IntFuzzPtr ifp;
3148 
3149   if (p_slp == NULL) return FALSE;
3150 
3151     spp = SeqPntNew();
3152     spp->point = point;
3153     spp->id = SeqIdDup(SeqIdFindBest(bsp->id, 0));
3154     spp->strand = (Uint1)strand;
3155     if (fuzz >= 0)
3156     {
3157         ifp = IntFuzzNew();
3158         ifp->choice = 4;   /* lim */
3159         ifp->a = (Int4) fuzz;
3160         spp->fuzz = ifp;
3161     }
3162 
3163     slp = ValNodeNew(NULL);
3164     slp->choice = SEQLOC_PNT;
3165     slp->data.ptrvalue = (Pointer)spp;
3166 
3167     if (*p_slp == NULL)
3168     {
3169         *p_slp = slp;
3170         return TRUE;
3171     }
3172 
3173     tmp = *p_slp;
3174     if (tmp->choice == SEQLOC_MIX)   /* second one already */
3175     {
3176         tmp2 = (ValNodePtr)(tmp->data.ptrvalue);
3177         while (tmp2->next != NULL)
3178             tmp2 = tmp2->next;
3179         tmp2->next = slp;
3180     }
3181     else                             /* create a chain */
3182     {
3183         tmp2 = ValNodeNew(NULL);
3184         tmp2->choice = SEQLOC_MIX;
3185         tmp2->data.ptrvalue = (Pointer)tmp;
3186         tmp->next = slp;
3187         *p_slp = tmp2;
3188     }
3189 
3190     return TRUE;
3191 }
3192 
AddPntToSeqFeat(SeqFeatPtr sfp,Int4 point,BioseqPtr bsp,Int2 fuzz,Int2 strand)3193 NLM_EXTERN Boolean AddPntToSeqFeat (SeqFeatPtr sfp, Int4 point, BioseqPtr bsp, Int2 fuzz, Int2 strand)
3194 {
3195   return AddPntToSeqLoc (&(sfp->location), point, bsp, fuzz, strand);
3196 }
3197 
GetBioseqFromChoice(NCBISubPtr nsp,SeqEntryPtr the_seq,CharPtr local_name,CharPtr the_routine)3198 static BioseqPtr GetBioseqFromChoice (NCBISubPtr nsp, SeqEntryPtr the_seq, CharPtr local_name, CharPtr the_routine)
3199 {
3200     BioseqPtr bsp;
3201     ValNode vn;
3202     ObjectId oid;
3203     Dbtag dbt;
3204 
3205     if (the_seq != NULL)
3206     {
3207         if (! IS_Bioseq(the_seq))
3208         {
3209             Message(MSG_ERROR, "%s: Gave Seq-entry which is not a Bioseq",
3210                 the_routine);
3211             return NULL;
3212         }
3213         bsp = (BioseqPtr)(the_seq->data.ptrvalue);
3214     }
3215     else if (local_name != NULL)
3216     {
3217         vn.next = NULL;
3218         oid.str = local_name;
3219         if (nsp->submittor_key == NULL)
3220         {
3221             vn.choice = SEQID_LOCAL;
3222             vn.data.ptrvalue = (Pointer)(& oid);
3223         }
3224         else
3225         {
3226             vn.choice = SEQID_GENERAL;
3227             vn.data.ptrvalue = (Pointer)(& dbt);
3228             dbt.db = nsp->submittor_key;
3229             dbt.tag = & oid;
3230         }
3231 
3232         bsp = BioseqFind((SeqIdPtr)(& vn));
3233         if (bsp == NULL)
3234         {
3235             Message(MSG_ERROR, "%s: Can't find Bioseq [%s]",
3236                 the_routine, local_name);
3237             return NULL;
3238         }
3239 
3240     }
3241     else
3242     {
3243         Message(MSG_ERROR, "%s: No the_seq or local_name given",
3244             the_routine);
3245         return NULL;
3246     }
3247 
3248     return bsp;
3249 }
3250 
AddPointToFeature(NCBISubPtr submission,SeqFeatPtr sfp,SeqEntryPtr the_seq,CharPtr local_name,Int4 location,Boolean on_plus_strand,Boolean is_after_location,Boolean is_before_location)3251 NLM_EXTERN Boolean AddPointToFeature (
3252     NCBISubPtr submission,
3253     SeqFeatPtr sfp,
3254     SeqEntryPtr the_seq ,
3255     CharPtr local_name ,
3256     Int4 location ,
3257     Boolean on_plus_strand ,
3258     Boolean is_after_location ,
3259     Boolean is_before_location )
3260 {
3261     BioseqPtr bsp;
3262     SeqLocPtr slp, tmp, tmp2;
3263     SeqPntPtr spp;
3264     IntFuzzPtr ifp;
3265 
3266 
3267     if (sfp == NULL) return FALSE;
3268 
3269     bsp = GetBioseqFromChoice(submission, the_seq, local_name, "AddPointToFeature");
3270     if (bsp == NULL) return FALSE;
3271 
3272     spp = SeqPntNew();
3273     if (location == -1)
3274         location = BioseqGetLen(bsp);
3275     spp->point = location - 1;
3276 
3277     spp->id = SeqIdDup(SeqIdFindBest(bsp->id, 0));
3278     if (! on_plus_strand)
3279         spp->strand = Seq_strand_minus;
3280     if (is_before_location)
3281     {
3282         ifp = IntFuzzNew();
3283         ifp->choice = 4;   /* lim */
3284         ifp->a = 2;        /* lt */
3285         spp->fuzz = ifp;
3286     }
3287     else if (is_after_location)
3288     {
3289         ifp = IntFuzzNew();
3290         ifp->choice = 4;   /* lim */
3291         ifp->a = 1;        /* gt */
3292         spp->fuzz = ifp;
3293     }
3294 
3295     slp = ValNodeNew(NULL);
3296     slp->choice = SEQLOC_PNT;
3297     slp->data.ptrvalue = (Pointer)spp;
3298 
3299     if (sfp->location == NULL)
3300     {
3301         sfp->location = slp;
3302         return TRUE;
3303     }
3304 
3305     tmp = sfp->location;
3306     if (tmp->choice == SEQLOC_MIX)   /* second one already */
3307     {
3308         tmp2 = (ValNodePtr)(tmp->data.ptrvalue);
3309         while (tmp2->next != NULL)
3310             tmp2 = tmp2->next;
3311         tmp2->next = slp;
3312     }
3313     else                             /* create a chain */
3314     {
3315         tmp2 = ValNodeNew(NULL);
3316         tmp2->choice = SEQLOC_MIX;
3317         tmp2->data.ptrvalue = (Pointer)tmp;
3318         tmp->next = slp;
3319         sfp->location = tmp2;
3320     }
3321     return TRUE;
3322 }
3323 
MakeCommentFeature(NCBISubPtr submission,SeqFeatPtr feature)3324 NLM_EXTERN Boolean MakeCommentFeature (
3325     NCBISubPtr submission,
3326     SeqFeatPtr feature )
3327 {
3328     if (feature == NULL) return FALSE;
3329 
3330     if (feature->data.choice)
3331     {
3332         Message(MSG_ERROR, "MakeCommentFeature: feature already has data");
3333         return FALSE;
3334     }
3335 
3336     if (feature->comment == NULL)
3337     {
3338         Message(MSG_ERROR, "MakeCommentFeature: no comment provided to FeatureBuild");
3339         return FALSE;
3340     }
3341 
3342      feature->data.choice = SEQFEAT_COMMENT;   /* comment */
3343 
3344     return TRUE;
3345 }
3346 
3347 
MakeCdRegionFeature(NCBISubPtr submission,SeqFeatPtr feature,Int2 frame,Int2 genetic_code,SeqEntryPtr protein_product,CharPtr local_id_for_protein)3348 NLM_EXTERN Boolean MakeCdRegionFeature (
3349     NCBISubPtr submission,
3350     SeqFeatPtr feature,
3351     Int2 frame ,
3352     Int2 genetic_code ,
3353     SeqEntryPtr protein_product ,      /* give id of protein. if NULL, call */
3354     CharPtr local_id_for_protein )  /* function below to create by transl */
3355 {
3356     BioseqPtr bsp;
3357     CdRegionPtr crp;
3358     ValNodePtr vnp;
3359     Char buf[41];
3360 
3361     if (feature == NULL) return FALSE;
3362 
3363     if (feature->data.choice)
3364     {
3365         Message(MSG_ERROR, "MakeCdRegionFeature: feature already has data");
3366         return FALSE;
3367     }
3368 
3369     crp = CdRegionNew();
3370     crp->frame = (Uint1)frame;
3371     if (genetic_code)
3372     {
3373         crp->genetic_code = GeneticCodeNew();
3374         vnp = ValNodeAdd ((ValNodePtr PNTR)&(crp->genetic_code->data.ptrvalue));
3375         vnp->choice = 2;
3376         vnp->data.intvalue = (Int4)genetic_code;
3377     }
3378 
3379     feature->data.choice = 3;   /* cdregion */
3380     feature->data.value.ptrvalue = (Pointer)crp;
3381 
3382     if ((protein_product != NULL) || (local_id_for_protein != NULL))
3383     {
3384         bsp = GetBioseqFromChoice (submission, protein_product, local_id_for_protein,
3385             "MakeCdRegionFeature");
3386         if (bsp != NULL)
3387         {
3388             if (! ISA_aa(bsp->mol))
3389             {
3390                 SeqIdWrite(bsp->id, buf, PRINTID_FASTA_LONG, 40);
3391                 Message(MSG_ERROR, "Using non-protein [%s] for cdregion product",
3392                     buf);
3393             }
3394             else
3395             {
3396                 vnp = ValNodeNew(NULL);
3397                 feature->product = vnp;
3398                 vnp->choice = SEQLOC_WHOLE;
3399                 vnp->data.ptrvalue = SeqIdDup(SeqIdFindBest(bsp->id, 0));
3400             }
3401         }
3402     }
3403 
3404     return TRUE;
3405 }
3406 
3407 
3408 /******************************************************************
3409 *
3410 *   A Code-break allows an exception to be made in the translation
3411 *    of a particular codon. You must give positions of the first
3412 *    and last bases of the codon in the DNA sequence and the amino
3413 *    acid to place there, instead of the normal translation. This
3414 *    should be used sparingly, and a comment on the feature should
3415 *    explain why it was done.
3416 *
3417 ******************************************************************/
3418 
AddCodeBreakToCdRegion(NCBISubPtr submission,SeqFeatPtr sfp,SeqEntryPtr the_seq,CharPtr local_name,Int4 from,Int4 to,Boolean on_plus_strand,CharPtr AA_for_protein)3419 NLM_EXTERN Boolean AddCodeBreakToCdRegion (
3420     NCBISubPtr submission,
3421     SeqFeatPtr sfp,
3422     SeqEntryPtr the_seq ,
3423     CharPtr local_name ,
3424     Int4 from ,
3425     Int4 to ,
3426     Boolean on_plus_strand ,
3427     CharPtr AA_for_protein )
3428 {
3429     SeqFeat sf;
3430     CodeBreakPtr cbp, tmp;
3431     CdRegionPtr crp;
3432 
3433 
3434     if ((submission == NULL) || (sfp == NULL) || (AA_for_protein == NULL))
3435         return FALSE;
3436     if (sfp->data.choice != 3) return FALSE;
3437 
3438     if (on_plus_strand)
3439     {
3440         if ((to - from) != 2) return FALSE;
3441     }
3442     else
3443     {
3444         if ((from - to) != 2) return FALSE;
3445     }
3446 
3447     MemSet(&sf, 0, sizeof(SeqFeat));
3448 
3449     if (! AddIntervalToFeature(submission, &sf, the_seq, local_name, from, to, on_plus_strand, FALSE,FALSE))
3450         return FALSE;
3451 
3452     cbp = CodeBreakNew();
3453 
3454     cbp->loc = sf.location;
3455     cbp->aa.choice = 1;   /* ncbieaa */
3456     cbp->aa.value.intvalue = (Int4)TO_UPPER(*AA_for_protein);
3457 
3458     crp = (CdRegionPtr)(sfp->data.value.ptrvalue);
3459     if (crp->code_break == NULL)
3460         crp->code_break = cbp;
3461     else
3462     {
3463         for (tmp = crp->code_break; tmp->next != NULL; tmp = tmp->next)
3464             continue;
3465         tmp->next = cbp;
3466     }
3467 
3468     return TRUE;
3469 }
3470 
3471 
3472 
3473 /******************************************************************
3474 *
3475 *   Special function to make protein from CdRegion feature
3476 *
3477 ******************************************************************/
3478 
TranslateCdRegion(NCBISubPtr submission,SeqFeatPtr cdregion_feature,SeqEntryPtr nuc_prot_entry_to_put_sequence,CharPtr local_name,CharPtr genbank_locus,CharPtr genbank_accession,Int4 gi_number)3479 NLM_EXTERN SeqEntryPtr TranslateCdRegion (
3480     NCBISubPtr submission ,
3481     SeqFeatPtr cdregion_feature ,
3482     SeqEntryPtr nuc_prot_entry_to_put_sequence ,
3483     CharPtr local_name ,             /* for protein sequence */
3484     CharPtr genbank_locus ,
3485     CharPtr genbank_accession ,
3486     Int4 gi_number )
3487 {
3488     SeqEntryPtr sep;
3489     BioseqPtr bsp;
3490     ByteStorePtr bp;
3491     Int4 protlen;
3492     ValNodePtr vnp;
3493     Uint2    retval;
3494     Boolean    partial = FALSE;
3495 
3496     if ((cdregion_feature == NULL) || (nuc_prot_entry_to_put_sequence == NULL))
3497         return NULL;
3498 
3499     bp = ProteinFromCdRegion (cdregion_feature, FALSE);
3500     if (bp == NULL)
3501     {
3502         Message(MSG_ERROR, "TranslateCdRegion: Couldn't translate CdRegion");
3503         return NULL;
3504     }
3505 
3506     protlen = BSLen(bp);
3507 
3508     sep = AddSeqToNucProtEntry (submission , nuc_prot_entry_to_put_sequence,
3509         local_name, genbank_locus,
3510         genbank_accession, gi_number, MOLECULE_CLASS_PROTEIN,
3511         MOLECULE_TYPE_PEPTIDE ,    protlen, 0, 0);
3512 
3513     AddGIBBmethodToEntry(submission, sep, METHOD_concept_transl);
3514 
3515     retval = SeqLocPartialCheck(cdregion_feature->location);
3516     if (retval & SLP_START) {
3517         AddModifierToEntry(submission, sep, MODIF_no_left);
3518         partial = TRUE;
3519     }
3520     if (retval & SLP_STOP) {
3521         AddModifierToEntry(submission, sep, MODIF_no_right);
3522         partial = TRUE;
3523     }
3524     if (retval & (SLP_OTHER | SLP_INTERNAL)) {
3525         AddModifierToEntry(submission, sep, MODIF_partial);
3526         partial = TRUE;
3527     }
3528     if (!partial && cdregion_feature->partial) {
3529         AddModifierToEntry(submission, sep, MODIF_partial);
3530     }
3531 
3532     bsp = (BioseqPtr)(sep->data.ptrvalue);
3533 
3534     bsp->seq_data = (SeqDataPtr) bp;
3535     bsp->seq_data_type = Seq_code_iupacaa;
3536 
3537     vnp = ValNodeNew(NULL);
3538     cdregion_feature->product = vnp;
3539     vnp->choice = SEQLOC_WHOLE;
3540     vnp->data.ptrvalue = SeqIdDup(SeqIdFindBest(bsp->id, 0));
3541 
3542     return sep;
3543 }
3544 
3545 
TranslateCdRegionNew(NCBISubPtr submission,SeqFeatPtr cdregion_feature,SeqEntryPtr nuc_prot_entry_to_put_sequence,CharPtr local_name,CharPtr genbank_locus,CharPtr genbank_accession,Int4 gi_number)3546 static SeqEntryPtr TranslateCdRegionNew (
3547     NCBISubPtr submission ,
3548     SeqFeatPtr cdregion_feature ,
3549     SeqEntryPtr nuc_prot_entry_to_put_sequence ,
3550     CharPtr local_name ,             /* for protein sequence */
3551     CharPtr genbank_locus ,
3552     CharPtr genbank_accession ,
3553     Int4 gi_number )
3554 {
3555     SeqEntryPtr sep;
3556     BioseqPtr bsp;
3557     ByteStorePtr bp;
3558     Int4 protlen;
3559     ValNodePtr vnp;
3560 
3561     if ((cdregion_feature == NULL) || (nuc_prot_entry_to_put_sequence == NULL))
3562         return NULL;
3563 
3564     bp = ProteinFromCdRegion (cdregion_feature, FALSE);
3565     if (bp == NULL)
3566     {
3567         Message(MSG_ERROR, "TranslateCdRegion: Couldn't translate CdRegion");
3568         return NULL;
3569     }
3570 
3571     protlen = BSLen(bp);
3572 
3573     sep = AddSeqToNucProtEntry (submission , nuc_prot_entry_to_put_sequence,
3574         local_name, genbank_locus,
3575         genbank_accession, gi_number, MOLECULE_CLASS_PROTEIN,
3576         MOLECULE_TYPE_PEPTIDE ,    protlen, 0, 0);
3577 
3578     AddBiomolToEntry(submission, sep, 8);  /* peptide */
3579     AddTechToEntry(submission, sep, 8); /* concept_transl */
3580 
3581     AddCompleteness(submission, sep, cdregion_feature);
3582     bsp = (BioseqPtr)(sep->data.ptrvalue);
3583 
3584     bsp->seq_data = (SeqDataPtr) bp;
3585     bsp->seq_data_type = Seq_code_iupacaa;
3586 
3587     vnp = ValNodeNew(NULL);
3588     cdregion_feature->product = vnp;
3589     vnp->choice = SEQLOC_WHOLE;
3590     vnp->data.ptrvalue = SeqIdDup(SeqIdFindBest(bsp->id, 0));
3591 
3592     return sep;
3593 }
3594 
3595 
MakeRNAFeature(NCBISubPtr submission,SeqFeatPtr feature,Int2 rna_type,Boolean is_pseudo_gene,CharPtr rna_name,CharPtr AA_for_tRNA,CharPtr codon_for_tRNA)3596 NLM_EXTERN Boolean MakeRNAFeature (
3597     NCBISubPtr submission,
3598     SeqFeatPtr feature,
3599     Int2 rna_type ,
3600     Boolean is_pseudo_gene,
3601     CharPtr rna_name ,
3602     CharPtr AA_for_tRNA ,
3603     CharPtr codon_for_tRNA )
3604 {
3605     RnaRefPtr rrp;
3606     tRNAPtr trp;
3607     Int2 i, index, j, wobble;
3608     CharPtr tmp;
3609     Char base;
3610 
3611     if (feature == NULL) return FALSE;
3612 
3613     if (feature->data.choice)
3614     {
3615         Message(MSG_ERROR, "MakeRNAFeature: feature already has data");
3616         return FALSE;
3617     }
3618 
3619     rrp = RnaRefNew();
3620     feature->data.choice = 5;
3621     feature->data.value.ptrvalue = (Pointer)rrp;
3622 
3623     rrp->type = (Uint1) rna_type;
3624     rrp->pseudo = is_pseudo_gene;
3625     if (rna_name != NULL)
3626     {
3627         rrp->ext.choice = 1;
3628         rrp->ext.value.ptrvalue = (Pointer)StringSaveNoNull(rna_name);
3629     }
3630     else if (rna_type == RNA_TYPE_tRNA)
3631     {
3632         if ((AA_for_tRNA != NULL ) || (codon_for_tRNA != NULL))
3633         {
3634             trp = MemNew(sizeof(tRNA));
3635             rrp->ext.choice = 2;
3636             rrp->ext.value.ptrvalue = (Pointer)trp;
3637             for (i = 0; i < 6; i++)
3638                 trp->codon[i] = 255;
3639             if (AA_for_tRNA != '\0')
3640             {
3641                 trp->aatype = 1;    /* iupacaa */
3642                 trp->aa = ValidAminoAcid(AA_for_tRNA);
3643         /*        trp->aa = (Uint1)TO_UPPER(*AA_for_tRNA);*/
3644             }
3645             if (codon_for_tRNA != NULL)
3646             {
3647                 wobble = 1; /* assume no wobble */
3648                 for (j = 0; j < wobble; j++)
3649                 {
3650                     tmp = codon_for_tRNA;
3651                     index = 0;
3652                     for (i = 16; i > 0; i /= 4, tmp++)
3653                     {
3654                         base = TO_UPPER(*tmp);
3655                         switch (base)
3656                         {
3657                             case 'U':
3658                                 base = 'T';
3659                                 break;
3660                             case 'R':
3661                                 if (j==0)
3662                                  base = 'A';
3663                                 else
3664                                  base = 'G';
3665                                 wobble = 2;
3666                                 break;
3667                             case 'Y':
3668                                 if (j==0)
3669                                  base = 'T';
3670                                 else
3671                                  base = 'C';
3672                                 wobble = 2;
3673                                 break;
3674                             default:
3675                                 break;
3676                         }
3677 
3678                         switch (base)
3679                         {
3680                             case 'T':
3681                                 break;    /* 0 */
3682                             case 'C':
3683                                 index += (i * 1);
3684                                 break;
3685                             case 'A':
3686                                 index += (i * 2);
3687                                 break;
3688                             case 'G':
3689                                 index += (i * 3);
3690                                 break;
3691                             default:
3692                                 Message(MSG_ERROR, "Invalid tRNA codon [%s]",
3693                                     codon_for_tRNA);
3694                                 return TRUE;
3695                         }
3696                     }
3697                     trp->codon[j] = (Uint1)index;
3698                 }
3699             }
3700         }
3701     }
3702 
3703     return TRUE;
3704 }
3705 
3706 
3707 
3708 /******************************************************************
3709 *
3710 *  Once you have made a tRNA feature, you may optionally add
3711 *   the location of the anticodon if you know it. This should be
3712 *   within the range of the tRNA feature already created, obviously.
3713 *
3714 *   the location is specified on the DNA the same as for
3715 *     AddIntervalToFeature
3716 *
3717 ******************************************************************/
3718 
AddAntiCodonTotRNA(NCBISubPtr submission,SeqFeatPtr sfp,SeqEntryPtr the_seq,CharPtr local_name,Int4 from,Int4 to,Boolean on_plus_strand)3719 NLM_EXTERN Boolean AddAntiCodonTotRNA (
3720     NCBISubPtr submission,
3721     SeqFeatPtr sfp,
3722     SeqEntryPtr the_seq ,
3723     CharPtr local_name ,
3724     Int4 from ,
3725     Int4 to ,
3726     Boolean on_plus_strand )
3727 {
3728     SeqFeat sf;
3729     RnaRefPtr rrp;
3730     tRNAPtr trp;
3731 
3732     if ((submission == NULL) || (sfp == NULL))
3733         return FALSE;
3734     if (sfp->data.choice != 5) return FALSE;
3735 
3736     rrp = (RnaRefPtr)(sfp->data.value.ptrvalue);
3737     if (rrp->type != RNA_TYPE_tRNA)
3738         return FALSE;
3739 
3740     MemSet(&sf, 0, sizeof(SeqFeat));
3741 
3742     if (! AddIntervalToFeature(submission, &sf, the_seq, local_name, from, to, on_plus_strand, FALSE,FALSE))
3743         return FALSE;
3744 
3745     if (rrp->ext.choice != 2)   /* not extension yet */
3746     {
3747         trp = MemNew(sizeof(tRNA));
3748         rrp->ext.choice = 2;
3749         rrp->ext.value.ptrvalue = (Pointer)trp;
3750     }
3751     else
3752         trp = (tRNAPtr)(rrp->ext.value.ptrvalue);
3753 
3754     trp->anticodon = sf.location;
3755 
3756     return TRUE;
3757 }
3758 
3759 
MakeGeneFeature(NCBISubPtr submission,SeqFeatPtr feature,CharPtr gene_symbol_for_locus,CharPtr allele,CharPtr descriptive_name,CharPtr map_location,Boolean is_pseudo_gene,CharPtr genetic_database,CharPtr gene_id_in_genetic_database,CharPtr synonym1,CharPtr synonym2,CharPtr synonym3)3760 NLM_EXTERN Boolean MakeGeneFeature (
3761     NCBISubPtr submission,
3762     SeqFeatPtr feature,
3763     CharPtr gene_symbol_for_locus ,
3764     CharPtr allele ,
3765     CharPtr descriptive_name ,
3766     CharPtr map_location ,
3767     Boolean is_pseudo_gene ,
3768     CharPtr genetic_database ,
3769     CharPtr gene_id_in_genetic_database ,
3770     CharPtr synonym1 ,
3771     CharPtr synonym2 ,
3772     CharPtr synonym3 )
3773 {
3774     GeneRefPtr grp;
3775     ValNodePtr vnp;
3776     DbtagPtr dbt;
3777     ObjectIdPtr oip;
3778 
3779     if (feature == NULL) return FALSE;
3780 
3781     if (feature->data.choice)
3782     {
3783         Message(MSG_ERROR, "MakeGeneFeature: feature already has data");
3784         return FALSE;
3785     }
3786 
3787     grp = GeneRefNew();
3788     feature->data.choice = 1;
3789     feature->data.value.ptrvalue = grp;
3790 
3791     grp->locus = StringSaveNoNull(gene_symbol_for_locus);
3792     grp->allele = StringSaveNoNull(allele);
3793     grp->desc = StringSaveNoNull(descriptive_name);
3794     grp->maploc = StringSaveNoNull(map_location);
3795     grp->pseudo = is_pseudo_gene;
3796     if ((genetic_database != NULL) && (gene_id_in_genetic_database != NULL))
3797     {
3798         vnp = ValNodeAdd(&grp->db);
3799         dbt = DbtagNew();
3800         vnp->data.ptrvalue = dbt;
3801         dbt->db = StringSaveNoNull(genetic_database);
3802         oip = ObjectIdNew();
3803         dbt->tag = oip;
3804         oip->str = StringSaveNoNull(gene_id_in_genetic_database);
3805     }
3806 
3807     ValNodeCopyStr(&grp->syn, 0, synonym1);
3808     ValNodeCopyStr(&grp->syn, 0, synonym2);
3809     ValNodeCopyStr(&grp->syn, 0, synonym3);
3810 
3811     return TRUE;
3812 }
3813 
MakeProteinFeature(NCBISubPtr submission,SeqFeatPtr feature,CharPtr protein_name1,CharPtr protein_name2,CharPtr protein_name3,CharPtr descriptive_name,CharPtr ECnum1,CharPtr ECnum2,CharPtr activity1,CharPtr activity2,CharPtr protein_database,CharPtr id_in_protein_database)3814 NLM_EXTERN Boolean MakeProteinFeature (
3815     NCBISubPtr submission,
3816     SeqFeatPtr feature ,
3817     CharPtr protein_name1,
3818     CharPtr protein_name2,
3819     CharPtr protein_name3,
3820     CharPtr descriptive_name,
3821     CharPtr ECnum1,
3822     CharPtr ECnum2,
3823     CharPtr activity1,
3824     CharPtr activity2,
3825     CharPtr protein_database,
3826     CharPtr id_in_protein_database)
3827 {
3828     ProtRefPtr prp;
3829     ValNodePtr vnp;
3830     DbtagPtr dbt;
3831     ObjectIdPtr oip;
3832     CharPtr tmp;
3833     Int2 i;
3834 
3835     if (feature == NULL) return FALSE;
3836 
3837     if (feature->data.choice)
3838     {
3839         Message(MSG_ERROR, "MakeProteinFeature: feature already has data");
3840         return FALSE;
3841     }
3842 
3843     prp = ProtRefNew();
3844     feature->data.choice = 4;
3845     feature->data.value.ptrvalue = prp;
3846 
3847     ValNodeCopyStr(&prp->name, 0, protein_name1);
3848     ValNodeCopyStr(&prp->name, 0, protein_name2);
3849     ValNodeCopyStr(&prp->name, 0, protein_name3);
3850 
3851     prp->desc = StringSaveNoNull(descriptive_name);
3852 
3853     tmp = ECnum1;
3854     for (i = 0; i < 2; i++)
3855     {
3856         if (tmp != NULL)
3857         {            /* skip any leading E.C. type stuff */
3858              while ((! IS_DIGIT(*tmp)))
3859             {
3860                 if (*tmp == '\0') break;
3861                 tmp++;
3862             }
3863             if (*tmp != '\0')
3864                 ValNodeCopyStr(&prp->ec, 0, tmp);
3865         }
3866         tmp = ECnum2;
3867     }
3868 
3869     ValNodeCopyStr(&prp->activity, 0, activity1);
3870     ValNodeCopyStr(&prp->activity, 0, activity2);
3871 
3872     if ((protein_database != NULL) && (id_in_protein_database != NULL))
3873     {
3874         vnp = ValNodeAdd(&prp->db);
3875         dbt = DbtagNew();
3876         vnp->data.ptrvalue = dbt;
3877         dbt->db = StringSaveNoNull(protein_database);
3878         oip = ObjectIdNew();
3879         dbt->tag = oip;
3880         oip->str = StringSaveNoNull(id_in_protein_database);
3881     }
3882 
3883     return TRUE;
3884 }
3885 
MakeRegionFeature(NCBISubPtr submission,SeqFeatPtr feature,CharPtr region_name)3886 NLM_EXTERN Boolean MakeRegionFeature (
3887     NCBISubPtr submission,
3888     SeqFeatPtr feature ,
3889     CharPtr region_name )
3890 {
3891     if (feature == NULL) return FALSE;
3892 
3893     if (feature->data.choice)
3894     {
3895         Message(MSG_ERROR, "MakeRegionFeature: feature already has data");
3896         return FALSE;
3897     }
3898 
3899     feature->data.choice = 9;
3900     feature->data.value.ptrvalue = (Pointer)StringSaveNoNull(region_name);
3901     return TRUE;
3902 }
3903 
MakeSiteFeature(NCBISubPtr submission,SeqFeatPtr feature,Int2 site_type)3904 NLM_EXTERN Boolean MakeSiteFeature (
3905     NCBISubPtr submission,
3906     SeqFeatPtr feature ,
3907     Int2 site_type )
3908 {
3909     if (feature == NULL) return FALSE;
3910 
3911     if (feature->data.choice)
3912     {
3913         Message(MSG_ERROR, "MakeSiteFeature: feature already has data");
3914         return FALSE;
3915     }
3916 
3917     feature->data.choice = 12;
3918     feature->data.value.intvalue = (Int4)site_type;
3919     return TRUE;
3920 }
3921 
MakeImpFeature(NCBISubPtr submission,SeqFeatPtr feature,CharPtr key)3922 NLM_EXTERN Boolean MakeImpFeature (
3923     NCBISubPtr submission,
3924     SeqFeatPtr feature ,
3925     CharPtr key )
3926 {
3927     ImpFeatPtr ifp;
3928 
3929     if (feature == NULL) return FALSE;
3930 
3931     if (feature->data.choice)
3932     {
3933         Message(MSG_ERROR, "MakeImpFeature: feature already has data");
3934         return FALSE;
3935     }
3936 
3937     ifp = ImpFeatNew();
3938     ifp->key = StringSaveNoNull(key);
3939 
3940     feature->data.choice = 8;
3941     feature->data.value.ptrvalue = (Pointer)ifp;
3942     return TRUE;
3943 }
3944 
AddQualToImpFeature(NCBISubPtr submission,SeqFeatPtr imp_feature,CharPtr qualifier,CharPtr value)3945 NLM_EXTERN Boolean AddQualToImpFeature (
3946     NCBISubPtr submission,
3947     SeqFeatPtr imp_feature ,
3948     CharPtr qualifier ,
3949     CharPtr value )
3950 {
3951     GBQualPtr gbp, tmp;
3952 
3953     if ((imp_feature == NULL) || (qualifier == NULL))
3954         return FALSE;
3955 
3956     gbp = GBQualNew();
3957     gbp->qual = StringSaveNoNull(qualifier);
3958     gbp->val = StringSaveNoNull(value);
3959 
3960     if (imp_feature->qual == NULL)
3961         imp_feature->qual = gbp;
3962     else
3963     {
3964         for (tmp = imp_feature->qual; tmp->next != NULL; tmp = tmp->next)
3965             continue;
3966         tmp->next = gbp;
3967     }
3968 
3969     return TRUE;
3970 }
3971 
MakePubFeature(NCBISubPtr submission,SeqFeatPtr feature,PubPtr pub)3972 NLM_EXTERN Boolean MakePubFeature (
3973     NCBISubPtr submission,
3974     SeqFeatPtr feature,
3975     PubPtr pub )
3976 {
3977 
3978     PubdescPtr pdp;
3979 
3980     if (feature == NULL) return FALSE;
3981 
3982     if (feature->data.choice)
3983     {
3984         Message(MSG_ERROR, "MakePubFeature: feature already has data");
3985         return FALSE;
3986     }
3987 
3988     feature->data.choice = 6;
3989     pdp = PubdescNew();
3990     if (pub->choice == PUB_Equiv)   /* already a Pub-equiv */
3991     {
3992         pdp->pub = (ValNodePtr)(pub->data.ptrvalue);
3993         MemFree(pub);
3994     }
3995     else                     /* make a Pub-equiv of one member */
3996         pdp->pub = pub;
3997     feature->data.value.ptrvalue = (Pointer)pdp;
3998 
3999     return TRUE;
4000 }
4001 
4002 /*****************************************************************************
4003 *
4004 *   AddPhrapGraphInternal (submission, bsp, phrap_values, offset, num_values)
4005 *       Converts phrap byte array to a SeqGraph, adds to Bioseq.
4006 *
4007 *****************************************************************************/
NewPhrapGraphSeqAnnot(CharPtr name,SeqGraphPtr sgp)4008 static SeqAnnotPtr NewPhrapGraphSeqAnnot (CharPtr name, SeqGraphPtr sgp)
4009 
4010 {
4011     SeqAnnotPtr  sap = NULL;
4012 
4013     if (sgp == NULL) return NULL;
4014     sap = SeqAnnotNew ();
4015     if (sap == NULL) return NULL;
4016 
4017     ValNodeAddPointer (&(sap->desc), Annot_descr_name, StringSave (name));
4018     sap->type = 3;
4019     sap->data = (Pointer) sgp;
4020 
4021   return sap;
4022 }
4023 
AddPhrapGraphInternal(NCBISubPtr submission,BioseqPtr bsp,BytePtr phrap_values,Int4 offset,Int4 num_values)4024 static SeqGraphPtr AddPhrapGraphInternal (
4025     NCBISubPtr submission,
4026     BioseqPtr bsp ,
4027     BytePtr phrap_values ,
4028     Int4 offset ,
4029     Int4 num_values )
4030 {
4031     SeqGraphPtr sgp = NULL;
4032     ByteStorePtr bs = NULL;
4033     Int2 max = INT2_MIN;
4034     Int2 min = INT2_MAX;
4035     BytePtr bp;
4036     Int4 i;
4037     Int2 val;
4038     SeqIntPtr sintp;
4039     SeqAnnotPtr sap;
4040     SeqGraphPtr lastsgp;
4041 
4042     if (bsp == NULL) return NULL;
4043     bs = BSNew (num_values);
4044     if (bs == NULL) return NULL;
4045     BSWrite (bs, (Pointer) phrap_values, num_values);
4046 
4047     sgp = SeqGraphNew ();
4048     if (sgp == NULL) {
4049         BSFree (bs);
4050         return FALSE;
4051     }
4052     sgp->numval = BSLen (bs);
4053     BSPutByte (bs, EOF);
4054     sgp->title = StringSave ("Phrap Quality");
4055 
4056     for (i = 0, bp = phrap_values; i < num_values; i++, bp++) {
4057         val = (Uint1) *bp;
4058         max = MAX (max, (Int2) val);
4059         min = MIN (min, (Int2) val);
4060     }
4061     sgp->flags [0] = 0;
4062     sgp->compr = 1;
4063     sgp->flags [1] = 0;
4064     sgp->flags [2] = 3;
4065     sgp->axis.intvalue = 0;
4066     sgp->min.intvalue = min;
4067     sgp->max.intvalue = max;
4068     sgp->a = 1.0;
4069     sgp->b = 0;
4070     sgp->values = (Pointer) bs;
4071 
4072     sintp = SeqIntNew ();
4073     sintp->from = offset;
4074     sintp->to = num_values - offset - 1;
4075     sintp->id = SeqIdDup (bsp->id);
4076     ValNodeAddPointer (&(sgp->loc), SEQLOC_INT, (Pointer) sintp);
4077 
4078     for (sap = bsp->annot; sap != NULL; sap = sap->next) {
4079         if (sap->type == 3) {
4080             for (lastsgp = sap->data; lastsgp->next != NULL; lastsgp = lastsgp->next) {
4081                 continue;
4082             }
4083             lastsgp->next = sgp;
4084             break;
4085         }
4086     }
4087     if (sap == NULL) {
4088         if (bsp->annot != NULL) {
4089             for (sap = bsp->annot; sap->next != NULL; sap = sap->next) {
4090                 continue;
4091             }
4092             sap->next = NewPhrapGraphSeqAnnot ("Graphs", sgp);
4093         } else {
4094             bsp->annot = NewPhrapGraphSeqAnnot ("Graphs", sgp);
4095         }
4096     }
4097 
4098     return sgp;
4099 }
4100 
AddPhrapGraph(NCBISubPtr submission,SeqEntryPtr the_seq,CharPtr local_name,BytePtr phrap_values)4101 NLM_EXTERN Boolean AddPhrapGraph (
4102     NCBISubPtr submission,
4103     SeqEntryPtr the_seq ,
4104     CharPtr local_name ,
4105     BytePtr phrap_values )
4106 {
4107     BioseqPtr    bsp;
4108     SeqGraphPtr  sgp;
4109 
4110     bsp = GetBioseqFromChoice(submission, the_seq, local_name, "AddPhrapGraph");
4111     sgp =  AddPhrapGraphInternal (submission, bsp, phrap_values, 0, bsp->length);
4112     return (Boolean) (sgp != NULL);
4113 }
4114 
AddPhrapGraphToSeqLit(NCBISubPtr submission,SeqLitPtr slp,BytePtr phrap_values)4115 NLM_EXTERN Boolean AddPhrapGraphToSeqLit (
4116     NCBISubPtr submission,
4117     SeqLitPtr slp ,
4118     BytePtr phrap_values )
4119 {
4120     BioseqPtr     bsp;
4121     SeqGraphPtr   sgp;
4122     ExtSeqLitPtr  xslp;
4123 
4124     if (slp == NULL) return FALSE;
4125     xslp = (ExtSeqLitPtr) slp;
4126     bsp = xslp->parentbsp;
4127     sgp = AddPhrapGraphInternal (submission, bsp, phrap_values, 0, slp->length);
4128     if (sgp != NULL) {
4129         xslp->graph = sgp;
4130         ReadjustSeqLitGraphs (bsp);  /* adjust seqlit graph positions */
4131         return TRUE;
4132     }
4133     return FALSE;
4134 }
4135 
4136 /*****************************************************************************
4137 *
4138 *   NCBISubValidate (nsp, errfile)
4139 *       Validate a submission
4140 *
4141 *****************************************************************************/
NCBISubValidate(NCBISubPtr nsp,FILE * errfile)4142 NLM_EXTERN Int2 NCBISubValidate (NCBISubPtr nsp, FILE * errfile)
4143 {
4144     Int2 numerrors = 0, i;
4145     ValidStructPtr vsp;
4146     SeqEntryPtr sep;
4147 
4148     vsp = ValidStructNew();
4149     vsp->useSeqMgrIndexes = TRUE;
4150     SetAppProperty ("NcbiSubutilValidation", (void *) 1024);
4151 
4152       /**** errfile is no longer supported ****
4153     vsp->errfile = errfile;
4154       ****************************************/
4155 
4156     for (sep = (SeqEntryPtr)(nsp->ssp->data); sep != NULL; sep = sep->next)
4157     {
4158          ValidateSeqEntry(sep, vsp);
4159         for (i = 0; i <=3; i++)
4160         {
4161             numerrors += vsp->errors[i];
4162         }
4163         ValidStructClear(vsp);
4164     }
4165     ValidStructFree(vsp);
4166     return numerrors;
4167 }
4168 
4169 /* reference gene project user object manipulation */
4170 
CreateRefGeneTrackUserObject(void)4171 NLM_EXTERN UserObjectPtr CreateRefGeneTrackUserObject (void)
4172 
4173 {
4174   ObjectIdPtr    oip;
4175   UserObjectPtr  uop;
4176 
4177   uop = UserObjectNew ();
4178   oip = ObjectIdNew ();
4179   oip->str = StringSave ("RefGeneTracking");
4180   uop->type = oip;
4181 
4182   return uop;
4183 }
4184 
AddStatusToRefGeneTrackUserObject(UserObjectPtr uop,CharPtr status)4185 NLM_EXTERN void AddStatusToRefGeneTrackUserObject (UserObjectPtr uop, CharPtr status)
4186 
4187 {
4188   UserFieldPtr  curr;
4189   ObjectIdPtr   oip;
4190 
4191   if (uop == NULL || status == NULL) return;
4192   oip = uop->type;
4193   if (oip == NULL || StringICmp (oip->str, "RefGeneTracking") != 0) return;
4194 
4195   for (curr = uop->data; curr != NULL; curr = curr->next) {
4196     oip = curr->label;
4197     if (oip != NULL && StringICmp (oip->str, "Status") == 0) {
4198       break;
4199     }
4200   }
4201 
4202   if (curr == NULL) {
4203     curr = UserFieldNew ();
4204     oip = ObjectIdNew ();
4205     oip->str = StringSave ("Status");
4206     curr->label = oip;
4207     curr->choice = 1; /* visible string */
4208 
4209     /* link status at beginning of list */
4210 
4211     curr->next = uop->data;
4212     uop->data = curr;
4213   }
4214 
4215   if (curr == NULL || curr->choice != 1) return;
4216 
4217   /* replace any existing status indication */
4218 
4219   curr->data.ptrvalue = MemFree (curr->data.ptrvalue);
4220 
4221   curr->data.ptrvalue = (Pointer) StringSave (status);
4222 }
4223 
AddGeneratedToRefGeneTrackUserObject(UserObjectPtr uop,Boolean generated)4224 NLM_EXTERN void AddGeneratedToRefGeneTrackUserObject (UserObjectPtr uop, Boolean generated)
4225 
4226 {
4227   UserFieldPtr  curr;
4228   ObjectIdPtr   oip;
4229   UserFieldPtr  prev = NULL;
4230 
4231   if (uop == NULL) return;
4232   oip = uop->type;
4233   if (oip == NULL || StringICmp (oip->str, "RefGeneTracking") != 0) return;
4234 
4235   for (curr = uop->data; curr != NULL; curr = curr->next) {
4236     oip = curr->label;
4237     if (oip != NULL && StringICmp (oip->str, "Generated") == 0) {
4238       break;
4239     }
4240     prev = curr;
4241   }
4242 
4243   if (curr == NULL) {
4244     curr = UserFieldNew ();
4245     oip = ObjectIdNew ();
4246     oip->str = StringSave ("Generated");
4247     curr->label = oip;
4248     curr->choice = 4; /* boolean */
4249     curr->data.boolvalue = generated;
4250 
4251     /* link source at end of list */
4252 
4253     if (prev != NULL) {
4254       prev->next = curr;
4255     } else {
4256       uop->data = curr;
4257     }
4258   }
4259 }
4260 
AddCuratorToRefGeneTrackUserObject(UserObjectPtr uop,CharPtr collaborator)4261 NLM_EXTERN void AddCuratorToRefGeneTrackUserObject (UserObjectPtr uop, CharPtr collaborator)
4262 
4263 {
4264   UserFieldPtr  curr;
4265   ObjectIdPtr   oip;
4266   UserFieldPtr  prev = NULL;
4267 
4268   if (uop == NULL || collaborator == NULL) return;
4269   oip = uop->type;
4270   if (oip == NULL || StringICmp (oip->str, "RefGeneTracking") != 0) return;
4271 
4272   for (curr = uop->data; curr != NULL; curr = curr->next) {
4273     oip = curr->label;
4274     if (oip != NULL && StringICmp (oip->str, "Collaborator") == 0) {
4275       break;
4276     }
4277     prev = curr;
4278   }
4279 
4280   if (curr == NULL) {
4281     curr = UserFieldNew ();
4282     oip = ObjectIdNew ();
4283     oip->str = StringSave ("Collaborator");
4284     curr->label = oip;
4285     curr->choice = 1; /* visible string */
4286 
4287     /* link curator at end of list */
4288 
4289     if (prev != NULL) {
4290       prev->next = curr;
4291     } else {
4292       uop->data = curr;
4293     }
4294   }
4295 
4296   if (curr == NULL || curr->choice != 1) return;
4297 
4298   /* replace any existing collaborator indication */
4299 
4300   curr->data.ptrvalue = MemFree (curr->data.ptrvalue);
4301 
4302   curr->data.ptrvalue = (Pointer) StringSave (collaborator);
4303 }
4304 
AddCuratorURLToRefGeneTrackUserObject(UserObjectPtr uop,CharPtr url)4305 NLM_EXTERN void AddCuratorURLToRefGeneTrackUserObject (UserObjectPtr uop, CharPtr url)
4306 
4307 {
4308   UserFieldPtr  curr;
4309   ObjectIdPtr   oip;
4310   UserFieldPtr  prev = NULL;
4311 
4312   if (uop == NULL || url == NULL) return;
4313   oip = uop->type;
4314   if (oip == NULL || StringICmp (oip->str, "RefGeneTracking") != 0) return;
4315 
4316   for (curr = uop->data; curr != NULL; curr = curr->next) {
4317     oip = curr->label;
4318     if (oip != NULL && StringICmp (oip->str, "CollaboratorURL") == 0) {
4319       break;
4320     }
4321     prev = curr;
4322   }
4323 
4324   if (curr == NULL) {
4325     curr = UserFieldNew ();
4326     oip = ObjectIdNew ();
4327     oip->str = StringSave ("CollaboratorURL");
4328     curr->label = oip;
4329     curr->choice = 1; /* visible string */
4330 
4331     /* link curator URL at end of list */
4332 
4333     if (prev != NULL) {
4334       prev->next = curr;
4335     } else {
4336       uop->data = curr;
4337     }
4338   }
4339 
4340   if (curr == NULL || curr->choice != 1) return;
4341 
4342   /* replace any existing collaborator indication */
4343 
4344   curr->data.ptrvalue = MemFree (curr->data.ptrvalue);
4345 
4346   curr->data.ptrvalue = (Pointer) StringSave (url);
4347 }
4348 
AddSourceToRefGeneTrackUserObject(UserObjectPtr uop,CharPtr genomicSource)4349 NLM_EXTERN void AddSourceToRefGeneTrackUserObject (UserObjectPtr uop, CharPtr genomicSource)
4350 
4351 {
4352   UserFieldPtr  curr;
4353   ObjectIdPtr   oip;
4354   UserFieldPtr  prev = NULL;
4355 
4356   if (uop == NULL || genomicSource == NULL) return;
4357   oip = uop->type;
4358   if (oip == NULL || StringICmp (oip->str, "RefGeneTracking") != 0) return;
4359 
4360   for (curr = uop->data; curr != NULL; curr = curr->next) {
4361     oip = curr->label;
4362     if (oip != NULL && StringICmp (oip->str, "GenomicSource") == 0) {
4363       break;
4364     }
4365     prev = curr;
4366   }
4367 
4368   if (curr == NULL) {
4369     curr = UserFieldNew ();
4370     oip = ObjectIdNew ();
4371     oip->str = StringSave ("GenomicSource");
4372     curr->label = oip;
4373     curr->choice = 1; /* visible string */
4374 
4375     /* link source at end of list */
4376 
4377     if (prev != NULL) {
4378       prev->next = curr;
4379     } else {
4380       uop->data = curr;
4381     }
4382   }
4383 
4384   if (curr == NULL || curr->choice != 1) return;
4385 
4386   /* replace any existing source indication */
4387 
4388   curr->data.ptrvalue = MemFree (curr->data.ptrvalue);
4389 
4390   curr->data.ptrvalue = (Pointer) StringSave (genomicSource);
4391 }
4392 
AddAccessionToRefGeneTrackUserObject(UserObjectPtr uop,CharPtr field,CharPtr accn,Int4 gi,Int4 from,Int4 to,CharPtr comment)4393 NLM_EXTERN void AddAccessionToRefGeneTrackUserObject (UserObjectPtr uop, CharPtr field,
4394                                                       CharPtr accn, Int4 gi, Int4 from,
4395                                                       Int4 to, CharPtr comment)
4396 
4397 {
4398   UserFieldPtr  curr;
4399   UserFieldPtr  entry;
4400   UserFieldPtr  last;
4401   UserFieldPtr  prev = NULL;
4402   ObjectIdPtr   oip;
4403   UserFieldPtr  ufp = NULL;
4404 
4405   if (uop == NULL || field == NULL) return;
4406   oip = uop->type;
4407   if (oip == NULL || StringICmp (oip->str, "RefGeneTracking") != 0) return;
4408 
4409   for (curr = uop->data; curr != NULL; curr = curr->next) {
4410     oip = curr->label;
4411     if (oip != NULL && StringICmp (oip->str, field) == 0) {
4412       break;
4413     }
4414     prev = curr;
4415   }
4416 
4417   if (curr == NULL) {
4418     curr = UserFieldNew ();
4419     oip = ObjectIdNew ();
4420     oip->str = StringSave (field);
4421     curr->label = oip;
4422     curr->choice = 11; /* user fields */
4423 
4424     /* link new set at end of list */
4425 
4426     if (prev != NULL) {
4427       prev->next = curr;
4428     } else {
4429       uop->data = curr;
4430     }
4431   }
4432 
4433   if (curr == NULL || curr->choice != 11) return;
4434 
4435   /* curr is now the top level Assembly, Related, etc. */
4436 
4437   entry = UserFieldNew ();
4438   oip = ObjectIdNew ();
4439   oip->id = 0;
4440   entry->label = oip;
4441   entry->choice = 11;
4442 
4443   if (curr->data.ptrvalue == NULL) {
4444     curr->data.ptrvalue = (Pointer) entry;
4445   } else {
4446     for (prev = (UserFieldPtr) curr->data.ptrvalue; prev->next != NULL; prev = prev->next) continue;
4447     prev->next = entry;
4448   }
4449 
4450   /* entry is now in the appropriate list */
4451 
4452   if (! StringHasNoText (accn)) {
4453     ufp = UserFieldNew ();
4454     oip = ObjectIdNew ();
4455     oip->str = StringSave ("accession");
4456     ufp->label = oip;
4457     ufp->choice = 1; /* visible string */
4458     ufp->data.ptrvalue = (Pointer) StringSave (accn);
4459   } else if (comment != NULL && *comment != '\0') {
4460     ufp = UserFieldNew ();
4461     oip = ObjectIdNew ();
4462     oip->str = StringSave ("name");
4463     ufp->label = oip;
4464     ufp->choice = 1; /* visible string */
4465     ufp->data.ptrvalue = (Pointer) StringSave (comment);
4466     comment = NULL;
4467   }
4468 
4469   entry->data.ptrvalue = (Pointer) ufp;
4470   last = ufp;
4471 
4472   if (gi > 0) {
4473     ufp = UserFieldNew ();
4474     oip = ObjectIdNew ();
4475     oip->str = StringSave ("gi");
4476     ufp->label = oip;
4477     ufp->choice = 2; /* integer */
4478     ufp->data.intvalue = gi;
4479     if (last != NULL) {
4480       last->next = ufp;
4481     }
4482     last = ufp;
4483   }
4484 
4485   if (comment != NULL && *comment != '\0') {
4486     ufp = UserFieldNew ();
4487     oip = ObjectIdNew ();
4488     oip->str = StringSave ("comment");
4489     ufp->label = oip;
4490     ufp->choice = 1; /* visible string */
4491     ufp->data.ptrvalue = (Pointer) StringSave (comment);
4492     if (last != NULL) {
4493       last->next = ufp;
4494     }
4495     last = ufp;
4496   }
4497 
4498   if (from == 0 && to == 0) return;
4499   oip = curr->label;
4500   if (oip == NULL || StringICmp (oip->str, "Assembly") != 0) return;
4501 
4502   ufp = UserFieldNew ();
4503   oip = ObjectIdNew ();
4504   oip->str = StringSave ("from");
4505   ufp->label = oip;
4506   ufp->choice = 2; /* integer */
4507   ufp->data.intvalue = from;
4508   if (last != NULL) {
4509     last->next = ufp;
4510   }
4511   last = ufp;
4512 
4513   ufp = UserFieldNew ();
4514   oip = ObjectIdNew ();
4515   oip->str = StringSave ("to");
4516   ufp->label = oip;
4517   ufp->choice = 2; /* integer */
4518   ufp->data.intvalue = to;
4519   last->next = ufp;
4520 }
4521 
CreateMrnaProteinLinkUserObject(BioseqPtr bsp)4522 NLM_EXTERN UserObjectPtr CreateMrnaProteinLinkUserObject (BioseqPtr bsp)
4523 
4524 {
4525   Char           buf [128];
4526   ObjectIdPtr    oip;
4527   SeqIdPtr       sip;
4528   UserFieldPtr   ufp;
4529   UserObjectPtr  uop;
4530 
4531   if (bsp == NULL) return NULL;
4532 
4533   uop = UserObjectNew ();
4534   oip = ObjectIdNew ();
4535   oip->str = StringSave ("MrnaProteinLink");
4536   uop->type = oip;
4537 
4538   sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_OTHER));
4539   SeqIdWrite(sip, buf, PRINTID_FASTA_LONG, 79);
4540   SeqIdFree (sip);
4541 
4542   ufp = UserFieldNew ();
4543   oip = ObjectIdNew ();
4544   oip->str = StringSave ("protein seqID");
4545   ufp->label = oip;
4546   ufp->choice = 1; /* visible string */
4547   ufp->data.ptrvalue = (Pointer) StringSave (buf);
4548 
4549   uop->data = ufp;
4550 
4551   return uop;
4552 }
4553 
CreateSubmissionUserObject(CharPtr univecComment,CharPtr additionalComment,Int4 validatorErrorCount,Int4 validatorHashCode,Boolean isCloningVector)4554 NLM_EXTERN UserObjectPtr CreateSubmissionUserObject (CharPtr univecComment,
4555                                                      CharPtr additionalComment,
4556                                                      Int4 validatorErrorCount,
4557                                                      Int4 validatorHashCode,
4558                                                      Boolean isCloningVector)
4559 
4560 {
4561   UserFieldPtr   last = NULL;
4562   ObjectIdPtr    oip;
4563   UserFieldPtr   ufp;
4564   UserObjectPtr  uop;
4565 
4566   uop = UserObjectNew ();
4567   oip = ObjectIdNew ();
4568   oip->str = StringSave ("Submission");
4569   uop->type = oip;
4570 
4571   ufp = UserFieldNew ();
4572   oip = ObjectIdNew ();
4573   oip->str = StringSave ("ValidatorErrorCount");
4574   ufp->label = oip;
4575   ufp->choice = 2; /* integer */
4576   ufp->data.intvalue = validatorErrorCount;
4577 
4578   uop->data = ufp; /* always making this ufp first */
4579   last = ufp;
4580 
4581   ufp = UserFieldNew ();
4582   oip = ObjectIdNew ();
4583   oip->str = StringSave ("ValidatorHash");
4584   ufp->label = oip;
4585   ufp->choice = 2; /* integer */
4586   ufp->data.intvalue = validatorHashCode;
4587 
4588   last->next = ufp;
4589   last = ufp;
4590 
4591   if (univecComment != NULL && *univecComment != '\0') {
4592     ufp = UserFieldNew ();
4593     oip = ObjectIdNew ();
4594     oip->str = StringSave ("UniVecComment");
4595     ufp->label = oip;
4596     ufp->choice = 1; /* visible string */
4597     ufp->data.ptrvalue = (Pointer) StringSave (univecComment);
4598 
4599     last->next = ufp;
4600     last = ufp;
4601   }
4602 
4603   if (additionalComment != NULL && *additionalComment != '\0') {
4604     ufp = UserFieldNew ();
4605     oip = ObjectIdNew ();
4606     oip->str = StringSave ("AdditionalComment");
4607     ufp->label = oip;
4608     ufp->choice = 1; /* visible string */
4609     ufp->data.ptrvalue = (Pointer) StringSave (additionalComment);
4610 
4611     last->next = ufp;
4612     last = ufp;
4613   }
4614 
4615   if (isCloningVector) {
4616     ufp = UserFieldNew ();
4617     oip = ObjectIdNew ();
4618     oip->str = StringSave ("IsCloningVector");
4619     ufp->label = oip;
4620     ufp->choice = 4; /* boolean */
4621     ufp->data.boolvalue = isCloningVector;
4622 
4623     last->next = ufp;
4624     last = ufp;
4625   }
4626 
4627   return uop;
4628 }
4629 
CreateContigCloneUserObject(CharPtr name,Int4 ID)4630 NLM_EXTERN UserObjectPtr CreateContigCloneUserObject (CharPtr name, Int4 ID)
4631 
4632 {
4633   UserFieldPtr   last = NULL;
4634   ObjectIdPtr    oip;
4635   UserFieldPtr   ufp;
4636   UserObjectPtr  uop;
4637 
4638   uop = UserObjectNew ();
4639   oip = ObjectIdNew ();
4640   oip->str = StringSave ("ContigClone");
4641   uop->type = oip;
4642 
4643   ufp = UserFieldNew ();
4644   oip = ObjectIdNew ();
4645   oip->str = StringSave ("CloneName");
4646   ufp->label = oip;
4647   ufp->choice = 1; /* visible string */
4648   ufp->data.ptrvalue = (Pointer) StringSave (name);
4649 
4650   uop->data = ufp;
4651   last = ufp;
4652 
4653   ufp = UserFieldNew ();
4654   oip = ObjectIdNew ();
4655   oip->str = StringSave ("CloneID");
4656   ufp->label = oip;
4657   ufp->choice = 2; /* integer */
4658   ufp->data.intvalue = ID;
4659 
4660   last->next = ufp;
4661 
4662   return uop;
4663 }
4664 
4665 /* gene ontology user object manipulation */
4666 
CreateGeneOntologyUserObject(void)4667 NLM_EXTERN UserObjectPtr CreateGeneOntologyUserObject (
4668   void
4669 )
4670 
4671 {
4672   ObjectIdPtr    oip;
4673   UserObjectPtr  uop;
4674 
4675   uop = UserObjectNew ();
4676   oip = ObjectIdNew ();
4677   oip->str = StringSave ("GeneOntology");
4678   uop->type = oip;
4679 
4680   return uop;
4681 }
4682 
AddToGeneOntologyUserObject(UserObjectPtr uop,CharPtr type,CharPtr text,CharPtr goid,Int4 pmid,CharPtr goref,CharPtr evidence)4683 NLM_EXTERN void AddToGeneOntologyUserObject (
4684   UserObjectPtr uop,
4685   CharPtr type,
4686   CharPtr text,
4687   CharPtr goid,
4688   Int4 pmid,
4689   CharPtr goref,
4690   CharPtr evidence
4691 )
4692 
4693 {
4694   UserFieldPtr  curr;
4695   UserFieldPtr  entry;
4696   UserFieldPtr  last;
4697   UserFieldPtr  prev = NULL;
4698   ObjectIdPtr   oip;
4699   UserFieldPtr  ufp;
4700 
4701   if (uop == NULL || type == NULL) return;
4702   oip = uop->type;
4703   if (oip == NULL || StringICmp (oip->str, "GeneOntology") != 0) return;
4704 
4705   for (curr = uop->data; curr != NULL; curr = curr->next) {
4706     oip = curr->label;
4707     if (oip != NULL && StringICmp (oip->str, type) == 0) {
4708       break;
4709     }
4710     prev = curr;
4711   }
4712 
4713   if (curr == NULL) {
4714     curr = UserFieldNew ();
4715     oip = ObjectIdNew ();
4716     oip->str = StringSave (type);
4717     curr->label = oip;
4718     curr->choice = 11; /* user fields */
4719 
4720     /* link new set at end of list */
4721 
4722     if (prev != NULL) {
4723       prev->next = curr;
4724     } else {
4725       uop->data = curr;
4726     }
4727   }
4728 
4729   if (curr == NULL || curr->choice != 11) return;
4730 
4731   /* curr is now the top level Process, Component, or Function */
4732 
4733   entry = UserFieldNew ();
4734   oip = ObjectIdNew ();
4735   oip->id = 0;
4736   entry->label = oip;
4737   entry->choice = 11;
4738 
4739   if (curr->data.ptrvalue == NULL) {
4740     curr->data.ptrvalue = (Pointer) entry;
4741   } else {
4742     for (prev = (UserFieldPtr) curr->data.ptrvalue; prev->next != NULL; prev = prev->next) continue;
4743     prev->next = entry;
4744   }
4745 
4746   /* entry is now in the appropriate list */
4747 
4748   ufp = UserFieldNew ();
4749   oip = ObjectIdNew ();
4750   oip->str = StringSave ("text string");
4751   ufp->label = oip;
4752   ufp->choice = 1; /* visible string */
4753   ufp->data.ptrvalue = (Pointer) StringSave (text);
4754 
4755   entry->data.ptrvalue = (Pointer) ufp;
4756   last = ufp;
4757 
4758   if (goid != NULL && *goid != '\0') {
4759     if (StringNICmp (goid, "GO:", 3) == 0) {
4760       goid += 3;
4761     }
4762   }
4763   if (goid != NULL && *goid != '\0') {
4764     ufp = UserFieldNew ();
4765     oip = ObjectIdNew ();
4766     oip->str = StringSave ("go id");
4767     ufp->label = oip;
4768     ufp->choice = 1; /* visible string - need to keep leading zeroes */
4769     ufp->data.ptrvalue = (Pointer) StringSave (goid);
4770     last->next = ufp;
4771     last = ufp;
4772   }
4773 
4774   if (pmid > 0) {
4775     ufp = UserFieldNew ();
4776     oip = ObjectIdNew ();
4777     oip->str = StringSave ("pubmed id");
4778     ufp->label = oip;
4779     ufp->choice = 2; /* integer */
4780     ufp->data.intvalue = pmid;
4781     last->next = ufp;
4782     last = ufp;
4783   }
4784 
4785   if (goref != NULL && *goref != '\0') {
4786     if (StringNICmp (goref, "GO_REF:", 7) == 0) {
4787       goref += 7;
4788     }
4789   }
4790   if (goref != NULL && *goref != '\0') {
4791     ufp = UserFieldNew ();
4792     oip = ObjectIdNew ();
4793     oip->str = StringSave ("go ref");
4794     ufp->label = oip;
4795     ufp->choice = 1; /* visible string - need to keep leading zeroes */
4796     ufp->data.ptrvalue = (Pointer) StringSave (goref);
4797     last->next = ufp;
4798     last = ufp;
4799   }
4800 
4801   if (evidence != NULL && *evidence != '\0') {
4802     ufp = UserFieldNew ();
4803     oip = ObjectIdNew ();
4804     oip->str = StringSave ("evidence");
4805     ufp->label = oip;
4806     ufp->choice = 1; /* visible string */
4807     ufp->data.ptrvalue = (Pointer) StringSave (evidence);
4808     last->next = ufp;
4809     last = ufp;
4810   }
4811 }
4812 
4813 /* model evidence user object */
4814 
CreateModelEvidenceUserObject(CharPtr method,CharPtr contigParent)4815 NLM_EXTERN UserObjectPtr CreateModelEvidenceUserObject (
4816   CharPtr method,
4817   CharPtr contigParent
4818 )
4819 
4820 {
4821   UserFieldPtr   curr;
4822   ObjectIdPtr    oip;
4823   UserFieldPtr   prev = NULL;
4824   UserObjectPtr  uop;
4825 
4826   uop = UserObjectNew ();
4827   oip = ObjectIdNew ();
4828   oip->str = StringSave ("ModelEvidence");
4829   uop->type = oip;
4830 
4831   curr = UserFieldNew ();
4832   oip = ObjectIdNew ();
4833   oip->str = StringSave ("Method");
4834   curr->label = oip;
4835   curr->choice = 1; /* visible string */
4836   curr->data.ptrvalue = (Pointer) StringSave (method);
4837 
4838   uop->data = curr;
4839   prev = curr;
4840 
4841   curr = UserFieldNew ();
4842   oip = ObjectIdNew ();
4843   oip->str = StringSave ("Contig Name");
4844   curr->label = oip;
4845   curr->choice = 1; /* visible string */
4846   curr->data.ptrvalue = (Pointer) StringSave (contigParent);
4847 
4848   prev->next = curr;
4849 
4850   return uop;
4851 }
4852 
FindEvidenceField(UserObjectPtr uop,CharPtr type,Boolean create)4853 static UserFieldPtr FindEvidenceField (
4854   UserObjectPtr uop,
4855   CharPtr type,
4856   Boolean create
4857 )
4858 
4859 {
4860   UserFieldPtr  curr;
4861   ObjectIdPtr   oip;
4862   UserFieldPtr  prev = NULL;
4863 
4864   if (uop == NULL || type == NULL) return NULL;
4865   oip = uop->type;
4866   if (oip == NULL || StringICmp (oip->str, "ModelEvidence") != 0) return NULL;
4867 
4868   /* search for mRNA or EST field */
4869 
4870   for (curr = uop->data; curr != NULL; curr = curr->next) {
4871     oip = curr->label;
4872     if (oip != NULL && StringICmp (oip->str, type) == 0) {
4873       break;
4874     }
4875     prev = curr;
4876   }
4877 
4878   if (curr == NULL && create) {
4879 
4880     /* create new top-level field */
4881 
4882     curr = UserFieldNew ();
4883     oip = ObjectIdNew ();
4884     oip->str = StringSave (type);
4885     curr->label = oip;
4886     curr->choice = 11; /* user fields */
4887 
4888     /* link new set at end of list */
4889 
4890     if (prev != NULL) {
4891       prev->next = curr;
4892     } else {
4893       uop->data = curr;
4894 
4895     }
4896   }
4897 
4898   if (curr == NULL) return NULL;
4899   if (curr->choice == 1 || curr->choice == 11) return curr;
4900 
4901   return NULL;
4902 }
4903 
FindModelEvidenceField(UserObjectPtr uop,CharPtr type)4904 NLM_EXTERN UserFieldPtr FindModelEvidenceField (
4905   UserObjectPtr uop,
4906   CharPtr type
4907 )
4908 
4909 {
4910   return FindEvidenceField (uop, type, FALSE);
4911 }
4912 
FindAccnBlock(UserFieldPtr group,CharPtr accn)4913 static UserFieldPtr FindAccnBlock (
4914   UserFieldPtr group,
4915   CharPtr accn
4916 )
4917 
4918 {
4919   UserFieldPtr  curr;
4920   ObjectIdPtr   oip;
4921   UserFieldPtr  prev = NULL;
4922   UserFieldPtr  ufp;
4923 
4924   if (group == NULL || group->choice != 11 || accn == NULL) return NULL;
4925 
4926   for (curr = (UserFieldPtr) group->data.ptrvalue; curr != NULL; curr = curr->next) {
4927     if (curr->choice == 11) {
4928       for (ufp = (UserFieldPtr) curr->data.ptrvalue; ufp != NULL; ufp = ufp->next) {
4929         oip = ufp->label;
4930         if (oip != NULL && StringICmp (oip->str, "accession") == 0) {
4931           if (StringICmp ((CharPtr) ufp->data.ptrvalue, accn) == 0) {
4932             return curr;
4933           }
4934         }
4935       }
4936     }
4937     prev = curr;
4938   }
4939 
4940   /* create new top-level field */
4941 
4942   curr = UserFieldNew ();
4943   oip = ObjectIdNew ();
4944   oip->id = 0;
4945   curr->label = oip;
4946   curr->choice = 11; /* user fields */
4947 
4948   /* link new set at end of list */
4949 
4950   if (prev != NULL) {
4951     prev->next = curr;
4952   } else {
4953     group->data.ptrvalue = curr;
4954   }
4955 
4956   ufp = UserFieldNew ();
4957   oip = ObjectIdNew ();
4958   oip->str = StringSave ("accession");
4959   ufp->label = oip;
4960   ufp->choice = 1; /* visible string */
4961   ufp->data.ptrvalue = (Pointer) StringSave (accn);
4962 
4963   if (curr->data.ptrvalue == NULL) {
4964     curr->data.ptrvalue = (Pointer) ufp;
4965   } else {
4966     for (prev = (UserFieldPtr) curr->data.ptrvalue; prev->next != NULL; prev = prev->next) continue;
4967     prev->next = ufp;
4968   }
4969 
4970   return curr;
4971 }
4972 
FindIntParamBlock(UserFieldPtr curr,CharPtr type,Boolean create)4973 static UserFieldPtr FindIntParamBlock (
4974   UserFieldPtr curr,
4975   CharPtr type,
4976   Boolean create
4977 )
4978 
4979 {
4980   ObjectIdPtr   oip;
4981   UserFieldPtr  prev = NULL;
4982   UserFieldPtr  ufp;
4983 
4984   if (curr == NULL || type == NULL) return NULL;
4985 
4986   prev = NULL;
4987   for (ufp = (UserFieldPtr) curr->data.ptrvalue; ufp != NULL; ufp = ufp->next) {
4988     oip = ufp->label;
4989     if (oip != NULL && StringICmp (oip->str, type) == 0) {
4990       break;
4991     }
4992     prev = ufp;
4993   }
4994 
4995   if (ufp == NULL && create) {
4996     ufp = UserFieldNew ();
4997     oip = ObjectIdNew ();
4998     oip->str = StringSave (type);
4999     ufp->label = oip;
5000     ufp->choice = 2; /* int */
5001 
5002     /* link new set at end of list */
5003 
5004     if (prev != NULL) {
5005       prev->next = ufp;
5006     } else {
5007       curr->data.ptrvalue = ufp;
5008     }
5009   }
5010 
5011   if (ufp == NULL || ufp->choice != 2) return NULL;
5012 
5013   return ufp;
5014 }
5015 
AddMrnaOrESTtoModelEvidence(UserObjectPtr uop,CharPtr type,CharPtr accn,Int4 length,Int4 gaplen)5016 NLM_EXTERN void AddMrnaOrESTtoModelEvidence (
5017   UserObjectPtr uop,
5018   CharPtr type,
5019   CharPtr accn,
5020   Int4 length,
5021   Int4 gaplen
5022 )
5023 
5024 {
5025   UserFieldPtr  curr;
5026   UserFieldPtr  group;
5027   ObjectIdPtr   oip;
5028   UserFieldPtr  ufp;
5029 
5030   if (uop == NULL || type == NULL || accn == NULL) return;
5031   oip = uop->type;
5032   if (oip == NULL || StringICmp (oip->str, "ModelEvidence") != 0) return;
5033 
5034   group = FindEvidenceField (uop, type, TRUE);
5035   if (group == NULL) return;
5036 
5037   curr = FindAccnBlock (group, accn);
5038   if (curr == NULL) return;
5039 
5040   if (length > 0) {
5041     ufp = FindIntParamBlock (curr, "exon count", TRUE);
5042     if (ufp == NULL) return;
5043     (ufp->data.intvalue)++;
5044 
5045     ufp = FindIntParamBlock (curr, "exon length", TRUE);
5046     if (ufp == NULL) return;
5047     ufp->data.intvalue += length;
5048   }
5049 
5050   if (gaplen > 0) {
5051     ufp = FindIntParamBlock (curr, "gap count", TRUE);
5052     if (ufp == NULL) return;
5053     (ufp->data.intvalue)++;
5054 
5055     ufp = FindIntParamBlock (curr, "gap length", TRUE);
5056     if (ufp == NULL) return;
5057     ufp->data.intvalue += gaplen;
5058   }
5059 }
5060 
5061 /* third party accession list user object manipulation */
5062 
CreateTpaAssemblyUserObject(void)5063 NLM_EXTERN UserObjectPtr CreateTpaAssemblyUserObject (void)
5064 
5065 {
5066   ObjectIdPtr    oip;
5067   UserObjectPtr  uop;
5068 
5069   uop = UserObjectNew ();
5070   oip = ObjectIdNew ();
5071   oip->str = StringSave ("TpaAssembly");
5072   uop->type = oip;
5073 
5074   return uop;
5075 }
5076 
5077 
5078 
CreateTPAAssemblyAccessionField(CharPtr accn)5079 NLM_EXTERN UserFieldPtr CreateTPAAssemblyAccessionField (CharPtr accn)
5080 {
5081   UserFieldPtr ufp;
5082   ObjectIdPtr  oip;
5083 
5084   ufp = UserFieldNew ();
5085   oip = ObjectIdNew ();
5086   oip->str = StringSave ("accession");
5087   ufp->label = oip;
5088   ufp->choice = 1; /* visible string */
5089   ufp->data.ptrvalue = (Pointer) StringSave (accn);
5090 
5091   return ufp;
5092 }
5093 
CreateTPAAssemblyFromField(Int4 from)5094 NLM_EXTERN UserFieldPtr CreateTPAAssemblyFromField (Int4 from)
5095 {
5096   UserFieldPtr ufp;
5097   ObjectIdPtr  oip;
5098 
5099   ufp = UserFieldNew ();
5100   oip = ObjectIdNew ();
5101   oip->str = StringSave ("from");
5102   ufp->label = oip;
5103   ufp->choice = 2; /* int */
5104   ufp->data.intvalue = from;
5105 
5106   return ufp;
5107 }
5108 
5109 
CreateTPAAssemblyToField(Int4 to)5110 NLM_EXTERN UserFieldPtr CreateTPAAssemblyToField (Int4 to)
5111 {
5112   UserFieldPtr ufp;
5113   ObjectIdPtr  oip;
5114 
5115   ufp = UserFieldNew ();
5116   oip = ObjectIdNew ();
5117   oip->str = StringSave ("to");
5118   ufp->label = oip;
5119   ufp->choice = 2; /* int */
5120   ufp->data.intvalue = to;
5121 
5122   return ufp;
5123 }
5124 
5125 
AddAccessionToTpaAssemblyUserObject(UserObjectPtr uop,CharPtr accn,Int4 from,Int4 to)5126 NLM_EXTERN void AddAccessionToTpaAssemblyUserObject (UserObjectPtr uop, CharPtr accn, Int4 from, Int4 to)
5127 
5128 {
5129   UserFieldPtr  curr;
5130   UserFieldPtr  prev = NULL;
5131   ObjectIdPtr   oip;
5132   UserFieldPtr  ufp;
5133 
5134   if (uop == NULL || accn == NULL) return;
5135   oip = uop->type;
5136   if (oip == NULL || StringICmp (oip->str, "TpaAssembly") != 0) return;
5137 
5138   for (curr = uop->data; curr != NULL; curr = curr->next) {
5139     prev = curr;
5140   }
5141 
5142   curr = UserFieldNew ();
5143   oip = ObjectIdNew ();
5144   oip->id = 0;
5145   curr->label = oip;
5146   curr->choice = 11; /* user fields */
5147 
5148   /* link new set at end of list */
5149 
5150   if (prev != NULL) {
5151     prev->next = curr;
5152   } else {
5153     uop->data = curr;
5154   }
5155 
5156   if (curr == NULL || curr->choice != 11) return;
5157 
5158   ufp = CreateTPAAssemblyAccessionField(accn);
5159 
5160   curr->data.ptrvalue = (Pointer) ufp;
5161   prev = ufp;
5162 
5163   if (from == 0 && to == 0) return;
5164 
5165   ufp = CreateTPAAssemblyFromField(from);
5166 
5167   prev->next = ufp;
5168   prev = ufp;
5169 
5170   ufp = CreateTPAAssemblyToField (to);
5171 
5172   prev->next = ufp;
5173 }
5174 
CreateGenomeProjectsDBUserObject(void)5175 NLM_EXTERN UserObjectPtr CreateGenomeProjectsDBUserObject (
5176   void
5177 )
5178 
5179 {
5180   ObjectIdPtr    oip;
5181   UserObjectPtr  uop;
5182 
5183   uop = UserObjectNew ();
5184   oip = ObjectIdNew ();
5185   oip->str = StringSave ("GenomeProjectsDB");
5186   uop->type = oip;
5187 
5188   return uop;
5189 }
5190 
AddIDsToGenomeProjectsDBUserObject(UserObjectPtr uop,Int4 projectID,Int4 parentID)5191 NLM_EXTERN UserObjectPtr AddIDsToGenomeProjectsDBUserObject (
5192   UserObjectPtr uop,
5193   Int4 projectID,
5194   Int4 parentID
5195 )
5196 
5197 {
5198   UserFieldPtr   curr;
5199   UserFieldPtr   prev = NULL;
5200   UserFieldPtr   last = NULL;
5201   ObjectIdPtr    oip;
5202   UserFieldPtr   ufp;
5203 
5204   if (uop == NULL) return NULL;
5205   oip = uop->type;
5206   if (oip == NULL || StringICmp (oip->str, "GenomeProjectsDB") != 0) return uop;
5207 
5208   for (curr = uop->data; curr != NULL; curr = curr->next) {
5209     prev = curr;
5210   }
5211 
5212   ufp = UserFieldNew ();
5213   oip = ObjectIdNew ();
5214   oip->str = StringSave ("ProjectID");
5215   ufp->label = oip;
5216   ufp->choice = 2; /* integer */
5217   ufp->data.intvalue = projectID;
5218 
5219   if (prev != NULL) {
5220     prev->next = ufp;
5221   } else {
5222     uop->data = ufp;
5223   }
5224   last = ufp;
5225 
5226   ufp = UserFieldNew ();
5227   oip = ObjectIdNew ();
5228   oip->str = StringSave ("ParentID");
5229   ufp->label = oip;
5230   ufp->choice = 2; /* integer */
5231   ufp->data.intvalue = parentID;
5232 
5233   last->next = ufp;
5234 
5235   return uop;
5236 }
5237 
5238 /* annot desc comment policy user object */
5239 
CreateAnnotDescCommentPolicyUserObject(Boolean showInCommentBlock)5240 NLM_EXTERN UserObjectPtr CreateAnnotDescCommentPolicyUserObject (
5241   Boolean showInCommentBlock
5242 )
5243 
5244 {
5245   UserFieldPtr   curr;
5246   ObjectIdPtr    oip;
5247   UserObjectPtr  uop;
5248 
5249   uop = UserObjectNew ();
5250   oip = ObjectIdNew ();
5251   oip->str = StringSave ("AnnotDescCommentPolicy");
5252   uop->type = oip;
5253 
5254   curr = UserFieldNew ();
5255   oip = ObjectIdNew ();
5256   oip->str = StringSave ("Policy");
5257   curr->label = oip;
5258   curr->choice = 1; /* visible string */
5259   if (showInCommentBlock) {
5260     curr->data.ptrvalue = (Pointer) StringSave ("ShowInComment");
5261   } else {
5262     curr->data.ptrvalue = (Pointer) StringSave ("ShowInNote");
5263   }
5264 
5265   uop->data = curr;
5266   return uop;
5267 }
5268 
5269 /* feature fetch policy user object */
5270 
CreateFeatureFetchPolicyUserObject(CharPtr policy)5271 NLM_EXTERN UserObjectPtr CreateFeatureFetchPolicyUserObject (
5272   CharPtr policy
5273 )
5274 
5275 {
5276   UserFieldPtr   curr;
5277   ObjectIdPtr    oip;
5278   UserObjectPtr  uop;
5279 
5280   if (StringHasNoText (policy)) return NULL;
5281 
5282   uop = UserObjectNew ();
5283   oip = ObjectIdNew ();
5284   oip->str = StringSave ("FeatureFetchPolicy");
5285   uop->type = oip;
5286 
5287   curr = UserFieldNew ();
5288   oip = ObjectIdNew ();
5289   oip->str = StringSave ("Policy");
5290   curr->label = oip;
5291   curr->choice = 1; /* visible string */
5292   curr->data.ptrvalue = (Pointer) StringSave (policy);
5293 
5294   uop->data = curr;
5295   return uop;
5296 }
5297 
5298 /* structured comment user object for flatfile presentation */
5299 
CreateStructuredCommentUserObject(CharPtr prefix,CharPtr suffix)5300 NLM_EXTERN UserObjectPtr CreateStructuredCommentUserObject (
5301   CharPtr prefix,
5302   CharPtr suffix
5303 )
5304 
5305 {
5306   ObjectIdPtr    oip;
5307   UserObjectPtr  uop;
5308 
5309   uop = UserObjectNew ();
5310   oip = ObjectIdNew ();
5311   oip->str = StringSave ("StructuredComment");
5312   uop->type = oip;
5313 
5314   if (StringDoesHaveText (prefix)) {
5315     AddItemStructuredCommentUserObject (uop, "StructuredCommentPrefix", prefix);
5316   }
5317 
5318   if (StringDoesHaveText (suffix)) {
5319     AddItemStructuredCommentUserObject (uop, "StructuredCommentSuffix", suffix);
5320   }
5321 
5322   return uop;
5323 }
5324 
AddItemStructuredCommentUserObject(UserObjectPtr uop,CharPtr field,CharPtr str)5325 NLM_EXTERN void AddItemStructuredCommentUserObject (
5326   UserObjectPtr uop,
5327   CharPtr field,
5328   CharPtr str
5329 )
5330 
5331 {
5332   UserFieldPtr  curr;
5333   ObjectIdPtr   oip;
5334   UserFieldPtr  prev = NULL;
5335 
5336   if (uop == NULL || StringHasNoText (field) || StringHasNoText (str)) return;
5337   oip = uop->type;
5338   if (oip == NULL || StringICmp (oip->str, "StructuredComment") != 0) return;
5339 
5340   for (curr = uop->data; curr != NULL; curr = curr->next) {
5341     prev = curr;
5342   }
5343 
5344   curr = UserFieldNew ();
5345   oip = ObjectIdNew ();
5346   oip->str = StringSave (field);
5347   curr->label = oip;
5348   curr->choice = 1; /* visible string */
5349   curr->data.ptrvalue = (Pointer) StringSave (str);
5350 
5351   /* link curator at end of list */
5352 
5353   if (prev != NULL) {
5354     prev->next = curr;
5355   } else {
5356     uop->data = curr;
5357   }
5358 }
5359 
5360 
5361 
5362 
CreateDBLinkUserObject(void)5363 NLM_EXTERN UserObjectPtr CreateDBLinkUserObject (
5364   void
5365 )
5366 
5367 {
5368   ObjectIdPtr    oip;
5369   UserObjectPtr  uop;
5370 
5371   uop = UserObjectNew ();
5372   oip = ObjectIdNew ();
5373   oip->str = StringSave ("DBLink");
5374   uop->type = oip;
5375 
5376   return uop;
5377 }
5378 
5379 
AddIntListFieldToDBLinkUserObject(UserObjectPtr uop,Int4 num,Int4Ptr values,CharPtr field_name)5380 NLM_EXTERN void AddIntListFieldToDBLinkUserObject (
5381   UserObjectPtr uop,
5382   Int4 num,
5383   Int4Ptr values,
5384   CharPtr field_name
5385 )
5386 {
5387   UserFieldPtr   curr;
5388   Int4           i;
5389   Int4Ptr        ip;
5390   UserFieldPtr   prev = NULL;
5391   ObjectIdPtr    oip;
5392 
5393   if (uop == NULL || values == NULL) return;
5394   oip = uop->type;
5395   if (oip == NULL || StringICmp (oip->str, "DBLink") != 0) return;
5396 
5397   for (curr = uop->data; curr != NULL; curr = curr->next) {
5398     oip = curr->label;
5399     if (oip != NULL && StringICmp (oip->str, field_name) == 0) {
5400       break;
5401     }
5402     prev = curr;
5403   }
5404 
5405   if (curr == NULL) {
5406     curr = UserFieldNew ();
5407     oip = ObjectIdNew ();
5408     oip->str = StringSave (field_name);
5409     curr->label = oip;
5410     curr->choice = 8; /* sequence of integer */
5411 
5412     /* link new set at end of list */
5413 
5414     if (prev != NULL) {
5415       prev->next = curr;
5416     } else {
5417       uop->data = curr;
5418     }
5419   }
5420 
5421   if (curr == NULL || curr->choice != 8) return;
5422 
5423   ip = (Int4Ptr) MemNew (sizeof (Int4) * (num));
5424   if (ip == NULL) return;
5425 
5426   curr->num = num;
5427   for (i = 0; i < num; i++) {
5428     ip [i] = values [i];
5429   }
5430   curr->data.ptrvalue = (Pointer) ip;
5431 }
5432 
5433 
AddTraceAssemblyIDsToDBLinkUserObject(UserObjectPtr uop,Int4 num,Int4Ptr values)5434 NLM_EXTERN void AddTraceAssemblyIDsToDBLinkUserObject (
5435   UserObjectPtr uop,
5436   Int4 num,
5437   Int4Ptr values
5438 )
5439 
5440 {
5441   AddIntListFieldToDBLinkUserObject (uop, num, values, "Trace Assembly Archive");
5442 }
5443 
5444 
AddStringListFieldToDBLinkUserObject(UserObjectPtr uop,Int4 num,CharPtr PNTR values,CharPtr field_name)5445 NLM_EXTERN void AddStringListFieldToDBLinkUserObject (
5446   UserObjectPtr uop,
5447   Int4 num,
5448   CharPtr PNTR values,
5449   CharPtr field_name
5450 )
5451 
5452 {
5453   CharPtr PNTR   cpp;
5454   UserFieldPtr   curr;
5455   Int4           i;
5456   UserFieldPtr   prev = NULL;
5457   ObjectIdPtr    oip;
5458 
5459   if (uop == NULL || values == NULL) return;
5460   oip = uop->type;
5461   if (oip == NULL || StringICmp (oip->str, "DBLink") != 0) return;
5462 
5463   for (curr = uop->data; curr != NULL; curr = curr->next) {
5464     oip = curr->label;
5465     if (oip != NULL && StringICmp (oip->str, field_name) == 0) {
5466       break;
5467     }
5468     prev = curr;
5469   }
5470 
5471   if (curr == NULL) {
5472     curr = UserFieldNew ();
5473     oip = ObjectIdNew ();
5474     oip->str = StringSave (field_name);
5475     curr->label = oip;
5476     curr->choice = 7; /* sequence of string */
5477 
5478     /* link new set at end of list */
5479 
5480     if (prev != NULL) {
5481       prev->next = curr;
5482     } else {
5483       uop->data = curr;
5484     }
5485   }
5486 
5487   if (curr == NULL || curr->choice != 7) return;
5488 
5489   cpp = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (num));
5490   if (cpp == NULL) return;
5491 
5492   curr->num = num;
5493   for (i = 0; i < num; i++) {
5494     cpp [i] = StringSaveNoNull (values [i]);
5495   }
5496   curr->data.ptrvalue = (Pointer) cpp;
5497 }
5498 
5499 
AddBioSampleIDsToDBLinkUserObject(UserObjectPtr uop,Int4 num,CharPtr PNTR values)5500 NLM_EXTERN void AddBioSampleIDsToDBLinkUserObject (
5501   UserObjectPtr uop,
5502   Int4 num,
5503   CharPtr PNTR values
5504 )
5505 
5506 {
5507   AddStringListFieldToDBLinkUserObject(uop, num, values, "BioSample");
5508 }
5509 
AddSeqReadArchIDsToDBLinkUserObject(UserObjectPtr uop,Int4 num,CharPtr PNTR values)5510 NLM_EXTERN void AddSeqReadArchIDsToDBLinkUserObject (
5511   UserObjectPtr uop,
5512   Int4 num,
5513   CharPtr PNTR values
5514 )
5515 
5516 {
5517   AddStringListFieldToDBLinkUserObject(uop, num, values, "Sequence Read Archive");
5518 }
5519 
5520 
AddProbeDBIDsToDBLinkUserObject(UserObjectPtr uop,Int4 num,CharPtr PNTR values)5521 NLM_EXTERN void AddProbeDBIDsToDBLinkUserObject (
5522   UserObjectPtr uop,
5523   Int4 num,
5524   CharPtr PNTR values
5525 )
5526 
5527 {
5528   AddStringListFieldToDBLinkUserObject(uop, num, values, "ProbeDB");
5529 }
5530 
AddSeqReadArchiveIDsToDBLinkUserObject(UserObjectPtr uop,Int4 num,CharPtr PNTR values)5531 NLM_EXTERN void AddSeqReadArchiveIDsToDBLinkUserObject (
5532   UserObjectPtr uop,
5533   Int4 num,
5534   CharPtr PNTR values
5535 )
5536 
5537 {
5538   AddStringListFieldToDBLinkUserObject(uop, num, values, "Sequence Read Archive");
5539 }
5540 
AddBioProjectIDsToDBLinkUserObject(UserObjectPtr uop,Int4 num,CharPtr PNTR values)5541 NLM_EXTERN void AddBioProjectIDsToDBLinkUserObject (
5542   UserObjectPtr uop,
5543   Int4 num,
5544   CharPtr PNTR values
5545 )
5546 
5547 {
5548   AddStringListFieldToDBLinkUserObject(uop, num, values, "BioProject");
5549 }
5550 
CreateNcbiCleanupUserObject(void)5551 NLM_EXTERN UserObjectPtr CreateNcbiCleanupUserObject (
5552   void
5553 )
5554 
5555 {
5556   ObjectIdPtr    oip;
5557   UserObjectPtr  uop;
5558 
5559   uop = UserObjectNew ();
5560   oip = ObjectIdNew ();
5561   oip->str = StringSave ("NcbiCleanup");
5562   uop->type = oip;
5563 
5564   return uop;
5565 }
5566 
AddStringToNcbiCleanupUserObject(UserObjectPtr uop,CharPtr field,CharPtr str)5567 NLM_EXTERN void AddStringToNcbiCleanupUserObject (
5568   UserObjectPtr uop,
5569   CharPtr field,
5570   CharPtr str
5571 )
5572 
5573 {
5574   UserFieldPtr  curr;
5575   ObjectIdPtr   oip;
5576   UserFieldPtr  prev = NULL;
5577 
5578   if (uop == NULL || StringHasNoText (field) || StringHasNoText (str)) return;
5579   oip = uop->type;
5580   if (oip == NULL || StringICmp (oip->str, "NcbiCleanup") != 0) return;
5581 
5582   for (curr = uop->data; curr != NULL; curr = curr->next) {
5583     prev = curr;
5584   }
5585 
5586   curr = UserFieldNew ();
5587   oip = ObjectIdNew ();
5588   oip->str = StringSave (field);
5589   curr->label = oip;
5590   curr->choice = 1; /* visible string */
5591   curr->data.ptrvalue = (Pointer) StringSave (str);
5592 
5593   /* link item at end of list */
5594 
5595   if (prev != NULL) {
5596     prev->next = curr;
5597   } else {
5598     uop->data = curr;
5599   }
5600 }
5601 
AddIntegerToNcbiCleanupUserObject(UserObjectPtr uop,CharPtr field,Int4 num)5602 NLM_EXTERN void AddIntegerToNcbiCleanupUserObject (
5603   UserObjectPtr uop,
5604   CharPtr field,
5605   Int4 num
5606 )
5607 
5608 {
5609   UserFieldPtr  curr;
5610   ObjectIdPtr   oip;
5611   UserFieldPtr  prev = NULL;
5612 
5613   if (uop == NULL || StringHasNoText (field)) return;
5614   oip = uop->type;
5615   if (oip == NULL || StringICmp (oip->str, "NcbiCleanup") != 0) return;
5616 
5617   for (curr = uop->data; curr != NULL; curr = curr->next) {
5618     prev = curr;
5619   }
5620 
5621   curr = UserFieldNew ();
5622   oip = ObjectIdNew ();
5623   oip->str = StringSave (field);
5624   curr->label = oip;
5625   curr->choice = 2; /* integer */
5626   curr->data.intvalue = num;
5627 
5628   /* link item at end of list */
5629 
5630   if (prev != NULL) {
5631     prev->next = curr;
5632   } else {
5633     uop->data = curr;
5634   }
5635 }
5636 
GetNcbiCleanupDescr(SeqDescrPtr sdp,Pointer userdata)5637 static void GetNcbiCleanupDescr (
5638   SeqDescrPtr sdp,
5639   Pointer userdata
5640 )
5641 
5642 {
5643   ObjectIdPtr        oip;
5644   UserObjectPtr      uop;
5645   UserObjectPtr PNTR uopp;
5646 
5647   if (sdp->choice != Seq_descr_user) return;
5648   uop = (UserObjectPtr) sdp->data.ptrvalue;
5649   if (uop == NULL) return;
5650 
5651   oip = uop->type;
5652   if (oip == NULL || StringICmp (oip->str, "NcbiCleanup") != 0) return;
5653   uopp = (UserObjectPtr PNTR) userdata;
5654   if (uopp == NULL) return;
5655   *uopp = uop;
5656 }
5657 
FindNcbiCleanupUserObject(SeqEntryPtr sep)5658 NLM_EXTERN UserObjectPtr FindNcbiCleanupUserObject (
5659   SeqEntryPtr sep
5660 )
5661 
5662 {
5663   UserObjectPtr  uop = NULL;
5664 
5665   if (sep == NULL) return NULL;
5666 
5667   VisitDescriptorsOnSep (sep, (Pointer) &uop, GetNcbiCleanupDescr);
5668 
5669   return uop;
5670 }
5671 
ClearNcbiCleanupDescr(SeqDescrPtr sdp,Pointer userdata)5672 static void ClearNcbiCleanupDescr (
5673   SeqDescrPtr sdp,
5674   Pointer userdata
5675 )
5676 
5677 {
5678   BoolPtr        bp;
5679   ObjectIdPtr    oip;
5680   ObjValNodePtr  ovp;
5681   UserObjectPtr  uop;
5682 
5683   if (sdp->choice != Seq_descr_user) return;
5684   uop = (UserObjectPtr) sdp->data.ptrvalue;
5685   if (uop == NULL) return;
5686   oip = uop->type;
5687   if (oip == NULL || StringICmp (oip->str, "NcbiCleanup") != 0) return;
5688   if (sdp->extended != 0) {
5689     ovp = (ObjValNodePtr) sdp;
5690     ovp->idx.deleteme = TRUE;
5691     bp = (BoolPtr) userdata;
5692     if (bp != NULL) {
5693       *bp = TRUE;
5694     }
5695   }
5696 }
5697 
ClearSeqAnnotCleanupObj(SeqAnnotPtr sap,Pointer userdata)5698 static void ClearSeqAnnotCleanupObj (
5699   SeqAnnotPtr sap,
5700   Pointer userdata
5701 )
5702 
5703 {
5704   RemoveAllSeqAnnotCleanupUserObjs (sap);
5705 }
5706 
RemoveAllNcbiCleanupUserObjects(SeqEntryPtr sep)5707 NLM_EXTERN void RemoveAllNcbiCleanupUserObjects (
5708   SeqEntryPtr sep
5709 )
5710 
5711 {
5712   Boolean  do_delete = FALSE;
5713   if (sep == NULL) return;
5714 
5715   VisitDescriptorsInSep (sep, (Pointer) &do_delete, ClearNcbiCleanupDescr);
5716   VisitAnnotsInSep (sep, NULL, ClearSeqAnnotCleanupObj);
5717   if (do_delete) {
5718     DeleteMarkedObjects (0, OBJ_SEQENTRY, (Pointer) sep);
5719   }
5720 }
5721 
IsAnnotDescCleanupUserObj(AnnotDescrPtr adp)5722 static Boolean IsAnnotDescCleanupUserObj (
5723   AnnotDescrPtr adp
5724 )
5725 
5726 {
5727   ObjectIdPtr    oip;
5728   UserObjectPtr  uop;
5729 
5730   if (adp->choice != Annot_descr_user) return FALSE;
5731   uop = (UserObjectPtr) adp->data.ptrvalue;
5732   if (uop == NULL) return FALSE;
5733   oip = uop->type;
5734   if (oip == NULL) return FALSE;
5735   if (StringICmp (oip->str, "NcbiCleanup") == 0) return TRUE;
5736 
5737   return FALSE;
5738 }
5739 
FindSeqAnnotCleanupUserObj(SeqAnnotPtr sap)5740 NLM_EXTERN UserObjectPtr FindSeqAnnotCleanupUserObj (
5741   SeqAnnotPtr sap
5742 )
5743 
5744 {
5745   AnnotDescrPtr  adp;
5746   UserObjectPtr  uop;
5747 
5748   if (sap == NULL) return NULL;
5749 
5750   for (adp = sap->desc; adp != NULL; adp = adp->next) {
5751     if (IsAnnotDescCleanupUserObj (adp)) {
5752       uop = (UserObjectPtr) adp->data.ptrvalue;
5753       return uop;
5754     }
5755   }
5756 
5757   return NULL;
5758 }
5759 
RemoveAllSeqAnnotCleanupUserObjs(SeqAnnotPtr sap)5760 NLM_EXTERN void RemoveAllSeqAnnotCleanupUserObjs (
5761   SeqAnnotPtr sap
5762 )
5763 
5764 {
5765   AnnotDescrPtr       adp;
5766   AnnotDescrPtr       next;
5767   AnnotDescrPtr PNTR  prev;
5768 
5769   if (sap == NULL) return;
5770 
5771   prev = &(sap->desc);
5772   adp = sap->desc;
5773   while (adp != NULL) {
5774     next = adp->next;
5775     if (IsAnnotDescCleanupUserObj (adp)) {
5776       *prev = adp->next;
5777       adp->next = NULL;
5778       AnnotDescFree (adp);
5779     } else {
5780       prev = (AnnotDescrPtr PNTR) &(adp->next);
5781     }
5782     adp = next;
5783   }
5784 }
5785 
5786 
GetNcbiAutofixDescr(SeqDescrPtr sdp,Pointer data)5787 static void GetNcbiAutofixDescr(SeqDescrPtr sdp, Pointer data)
5788 {
5789   UserObjectPtr  uop;
5790   UserObjectPtr PNTR p_uop;
5791 
5792   if (sdp != NULL
5793       && sdp->choice == Seq_descr_user
5794       && (uop = (UserObjectPtr)sdp->data.ptrvalue) != NULL
5795       && uop->type != NULL
5796       && StringICmp (uop->type->str, "NcbiAutofix") == 0
5797       && (p_uop = (UserObjectPtr PNTR) data) != NULL) {
5798     *p_uop = uop;
5799   }
5800 }
5801 
5802 
FindNcbiAutofixUserObject(SeqEntryPtr sep)5803 NLM_EXTERN UserObjectPtr FindNcbiAutofixUserObject (
5804   SeqEntryPtr sep
5805 )
5806 
5807 {
5808   UserObjectPtr  uop = NULL;
5809 
5810   if (sep == NULL) return NULL;
5811 
5812   VisitDescriptorsInSep (sep, (Pointer) &uop, GetNcbiAutofixDescr);
5813 
5814   return uop;
5815 }
5816 
5817 
AddNcbiAutofixUserObject(SeqEntryPtr sep)5818 NLM_EXTERN void AddNcbiAutofixUserObject (
5819   SeqEntryPtr sep
5820 )
5821 
5822 {
5823   SeqDescrPtr sdp;
5824   UserObjectPtr uop;
5825 
5826   sdp = CreateNewDescriptor(sep, Seq_descr_user);
5827   uop = UserObjectNew ();
5828   uop->type = ObjectIdNew();
5829   uop->type->str = StringSave ("NcbiAutofix");
5830   sdp->data.ptrvalue = uop;
5831 }
5832 
5833 
RemoveNcbiAutofixDescr(SeqDescrPtr sdp,Pointer data)5834 static void RemoveNcbiAutofixDescr(SeqDescrPtr sdp, Pointer data)
5835 {
5836   UserObjectPtr  uop;
5837   ObjValNodePtr  ovp;
5838 
5839   if (sdp != NULL
5840       && sdp->choice == Seq_descr_user
5841       && (uop = (UserObjectPtr)sdp->data.ptrvalue) != NULL
5842       && uop->type != NULL
5843       && StringICmp (uop->type->str, "NcbiAutofix") == 0
5844       && sdp->extended != 0) {
5845     ovp = (ObjValNodePtr) sdp;
5846     ovp->idx.deleteme = TRUE;
5847   }
5848 }
5849 
5850 
RemoveNcbiAutofixUserObjects(SeqEntryPtr sep)5851 NLM_EXTERN void RemoveNcbiAutofixUserObjects (
5852   SeqEntryPtr sep
5853 )
5854 
5855 {
5856   if (sep == NULL) return;
5857 
5858   VisitDescriptorsInSep (sep, (Pointer) NULL, RemoveNcbiAutofixDescr);
5859   DeleteMarkedObjects (0, OBJ_SEQENTRY, (Pointer) sep);
5860 }
5861 
CreateUnverifiedUserObject(void)5862 NLM_EXTERN UserObjectPtr CreateUnverifiedUserObject (
5863   void
5864 )
5865 
5866 {
5867   ObjectIdPtr    oip;
5868   UserObjectPtr  uop;
5869 
5870   uop = UserObjectNew ();
5871   oip = ObjectIdNew ();
5872   oip->str = StringSave ("Unverified");
5873   uop->type = oip;
5874 
5875   return uop;
5876 }
5877 
GetUnverifiedDescr(SeqDescrPtr sdp,Pointer data)5878 static void GetUnverifiedDescr(SeqDescrPtr sdp, Pointer data)
5879 {
5880   UserObjectPtr  uop;
5881   UserObjectPtr PNTR p_uop;
5882 
5883   if (sdp != NULL
5884       && sdp->choice == Seq_descr_user
5885       && (uop = (UserObjectPtr)sdp->data.ptrvalue) != NULL
5886       && IsUnverifiedUserObject(uop)
5887       && (p_uop = (UserObjectPtr PNTR) data) != NULL) {
5888     *p_uop = uop;
5889   }
5890 }
5891 
5892 
FindUnverifiedUserObject(SeqEntryPtr sep)5893 NLM_EXTERN UserObjectPtr FindUnverifiedUserObject (
5894   SeqEntryPtr sep
5895 )
5896 
5897 {
5898   UserObjectPtr  uop = NULL;
5899 
5900   if (sep == NULL) return NULL;
5901 
5902   VisitDescriptorsInSep (sep, (Pointer) &uop, GetUnverifiedDescr);
5903 
5904   return uop;
5905 }
5906 
5907 
AddUnverifiedUserObject(SeqEntryPtr sep)5908 NLM_EXTERN UserObjectPtr AddUnverifiedUserObject (
5909   SeqEntryPtr sep
5910 )
5911 
5912 {
5913   SeqDescrPtr sdp;
5914   UserObjectPtr uop = NULL;
5915 
5916   if (sep == NULL) return NULL;
5917   sdp = CreateNewDescriptor(sep, Seq_descr_user);
5918   uop = UserObjectNew ();
5919   uop->type = ObjectIdNew();
5920   uop->type->str = StringSave ("Unverified");
5921   sdp->data.ptrvalue = uop;
5922 
5923   return uop;
5924 }
5925 
5926 
AddUnverifiedUserObjectToBioseq(BioseqPtr bsp)5927 NLM_EXTERN UserObjectPtr AddUnverifiedUserObjectToBioseq (
5928   BioseqPtr bsp
5929 )
5930 
5931 {
5932   SeqDescPtr sdp;
5933   SeqMgrDescContext context;
5934   Boolean found = FALSE;
5935   UserObjectPtr uop = NULL;
5936 
5937   if (bsp == NULL || ISA_aa(bsp->mol)) {
5938     return NULL;
5939   }
5940   for (sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_user, &context);
5941        sdp != NULL && !found;
5942        sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_user, &context)) {
5943     if (IsUnverifiedUserObject(sdp->data.ptrvalue)) {
5944       found = TRUE;
5945     }
5946   }
5947   if (!found) {
5948     sdp = CreateNewDescriptorOnBioseq (bsp, Seq_descr_user);
5949     uop = CreateUnverifiedUserObject();
5950     sdp->data.ptrvalue = uop;
5951   }
5952 
5953   return uop;
5954 }
5955 
5956 
AddUnverifiedUserObjectToBioseqParent(BioseqPtr bsp)5957 NLM_EXTERN UserObjectPtr AddUnverifiedUserObjectToBioseqParent (
5958   BioseqPtr bsp
5959 )
5960 
5961 {
5962   SeqDescPtr sdp;
5963   SeqMgrDescContext context;
5964   UserObjectPtr uop = NULL;
5965   BioseqSetPtr bssp;
5966   SeqEntryPtr sep;
5967 
5968   if (bsp == NULL || ISA_aa(bsp->mol)) return NULL;
5969 
5970   for (sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_user, &context);
5971        sdp != NULL;
5972        sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_user, &context)) {
5973     if (IsUnverifiedUserObject(sdp->data.ptrvalue)) return NULL;
5974   }
5975 
5976   bssp = (BioseqSetPtr) bsp->idx.parentptr;
5977   if (bssp == NULL) return NULL;
5978   sep = SeqMgrGetSeqEntryForData (bssp);
5979   if (sep == NULL) return NULL;
5980   sdp = CreateNewDescriptor (sep, Seq_descr_user);
5981   if (sdp == NULL) return NULL;
5982   uop = CreateUnverifiedUserObject();
5983   if (uop == NULL) return NULL;
5984   sdp->data.ptrvalue = uop;
5985 
5986   return uop;
5987 }
AddStringToUnverifiedUserObject(UserObjectPtr uop,CharPtr field,CharPtr str)5988 NLM_EXTERN void AddStringToUnverifiedUserObject (
5989   UserObjectPtr uop,
5990   CharPtr field,
5991   CharPtr str
5992 )
5993 
5994 {
5995   UserFieldPtr  curr;
5996   ObjectIdPtr   oip;
5997   UserFieldPtr  prev = NULL;
5998 
5999   if (uop == NULL || StringHasNoText (field) || StringHasNoText (str)) return;
6000   oip = uop->type;
6001   if (oip == NULL || StringICmp (oip->str, "Unverified") != 0) return;
6002 
6003   for (curr = uop->data; curr != NULL; curr = curr->next) {
6004     prev = curr;
6005   }
6006 
6007   curr = UserFieldNew ();
6008   oip = ObjectIdNew ();
6009   oip->str = StringSave (field);
6010   curr->label = oip;
6011   curr->choice = 1; /* visible string */
6012   curr->data.ptrvalue = (Pointer) StringSave (str);
6013 
6014   /* link item at end of list */
6015 
6016   if (prev != NULL) {
6017     prev->next = curr;
6018   } else {
6019     uop->data = curr;
6020   }
6021 }
6022 
RemoveUnverifiedDescr(SeqDescrPtr sdp,Pointer data)6023 static void RemoveUnverifiedDescr(SeqDescrPtr sdp, Pointer data)
6024 {
6025   UserObjectPtr  uop;
6026   ObjValNodePtr  ovp;
6027 
6028   if (sdp != NULL
6029       && sdp->choice == Seq_descr_user
6030       && (uop = (UserObjectPtr)sdp->data.ptrvalue) != NULL
6031       && uop->type != NULL
6032       && StringICmp (uop->type->str, "Unverified") == 0
6033       && sdp->extended != 0) {
6034     ovp = (ObjValNodePtr) sdp;
6035     ovp->idx.deleteme = TRUE;
6036   }
6037 }
6038 
6039 
RemoveUnverifiedUserObjects(SeqEntryPtr sep)6040 NLM_EXTERN void RemoveUnverifiedUserObjects (
6041   SeqEntryPtr sep
6042 )
6043 
6044 {
6045   if (sep == NULL) return;
6046 
6047   VisitDescriptorsInSep (sep, (Pointer) NULL, RemoveUnverifiedDescr);
6048   DeleteMarkedObjects (0, OBJ_SEQENTRY, (Pointer) sep);
6049 }
6050 
6051 
IsUnverifiedUserObject(UserObjectPtr uop)6052 NLM_EXTERN Boolean IsUnverifiedUserObject (UserObjectPtr uop)
6053 {
6054   if (uop == NULL || uop->type == NULL || StringICmp (uop->type->str, "Unverified") != 0) {
6055     return FALSE;
6056   } else {
6057     return TRUE;
6058   }
6059 }
6060 
6061