NCBI C Toolkit Cross Reference

C/api/asn2ff2.c


  1 /*   asn2ff2.c
  2  * ===========================================================================
  3  *
  4  *                            PUBLIC DOMAIN NOTICE
  5  *            National Center for Biotechnology Information (NCBI)
  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 do not place any restriction on its use or reproduction.
 13  *  We would, however, appreciate having the NCBI and the author cited in
 14  *  any work or product based on this material
 15  *
 16  *  Although all reasonable efforts have been taken to ensure the accuracy
 17  *  and reliability of the software and data, the NLM and the U.S.
 18  *  Government do not and cannot warrant the performance or results that
 19  *  may be obtained by using this software or data. The NLM and the U.S.
 20  *  Government disclaim all warranties, express or implied, including
 21  *  warranties of performance, merchantability or fitness for any particular
 22  *  purpose.
 23  *
 24  * ===========================================================================
 25  *
 26  * File Name:  asn2ff2.c
 27  *
 28  * Author:  Karl Sirotkin, Tom Madden, Tatiana Tatusov
 29  *
 30  * Version Creation Date:   7/15/95
 31  *
 32  * $Revision: 6.37 $
 33  *
 34  * File Description: 
 35  *
 36  * Modifications:  
 37  * --------------------------------------------------------------------------
 38  * Date     Name        Description of modification
 39  * -------  ----------  -----------------------------------------------------
 40  *
 41  * $Log: asn2ff2.c,v $
 42  * Revision 6.37  2004/06/04 18:39:14  bollin
 43  * removed unused variables, fixed compiler warning
 44  *
 45  * Revision 6.36  2001/12/24 16:21:32  kans
 46  * initialize urf in GetStrForUserObject
 47  *
 48  * Revision 6.35  2001/11/09 20:20:41  kans
 49  * new GENOME ANNOTATION REFSEQ text
 50  *
 51  * Revision 6.34  2001/11/09 15:31:47  kans
 52  * bail on evidence user object missing name or method
 53  *
 54  * Revision 6.33  2001/11/09 15:29:19  kans
 55  * display curator for reviewed refseq
 56  *
 57  * Revision 6.32  2001/11/09 14:45:49  kans
 58  * added VALIDATED REFSEQ message
 59  *
 60  * Revision 6.31  2001/11/09 13:38:58  kans
 61  * changed from TranscriptModelGeneration to ModelEvidence user object
 62  *
 63  * Revision 6.30  2001/10/02 19:16:32  yaschenk
 64  * Removing memory leaks
 65  *
 66  * Revision 6.29  2001/08/07 15:51:08  kans
 67  * use NUM_SEQID, added third party annotation seqids
 68  *
 69  * Revision 6.28  2000/12/27 19:43:20  kans
 70  * empty comment could lead to original dsp->vnp being freed twice, corrupting memory on Mac
 71  *
 72  * Revision 6.27  2000/12/04 20:16:25  tatiana
 73  * mrna evidence comments added
 74  *
 75  * Revision 6.26  2000/08/10 13:54:32  tatiana
 76  * predicted refseq comment added
 77  *
 78  * Revision 6.25  2000/08/07 14:02:55  tatiana
 79  * printf format fix
 80  *
 81  * Revision 6.24  2000/07/11 17:01:43  kans
 82  * fixed bug of insufficient allocated memory block
 83  *
 84  * Revision 6.23  2000/07/06 22:42:00  tatiana
 85  * REGSEQ text revised
 86  *
 87  * Revision 6.22  2000/06/19 16:36:27  kans
 88  * NULL out ajp->Spop->ptr before calling StdFormatPrint, since string is freed elsewhere leaving ajp->Spop->ptr dangling
 89  *
 90  * Revision 6.21  2000/06/05 17:52:05  tatiana
 91  * increase size of feature arrays to Int4
 92  *
 93  * Revision 6.20  2000/02/29 16:54:35  bazhin
 94  * Removed memory leaks.
 95  *
 96  * Revision 5.11  1997/06/19 18:36:58  vakatov
 97  * [WIN32,MSVC++]  Adopted for the "NCBIOBJ.LIB" DLL'ization
 98  *
 99  * Revision 5.10  1997/04/23 18:03:28  tatiana
100  * a typo fixed in HTG comments
101  *
102  * Revision 5.9  1997/04/11  21:33:18  tatiana
103  * fixed %d to %ld in PrintComment
104  *
105  * Revision 5.8  1997/03/28  18:44:32  tatiana
106  * type fixed in htg comments
107  *
108  * Revision 5.7  1997/02/10  22:13:22  tatiana
109  * *** empty log message ***
110  *
111  * Revision 5.6  1997/01/13  23:28:50  tatiana
112  * added HTG comments
113  *
114  * Revision 5.5  1996/12/12  21:43:50  tatiana
115  * a bug fixed in GB_GetSeqDescrComms
116  *
117  * Revision 5.4  1996/08/14  21:44:11  tatiana
118  * *** empty log message ***
119  *
120  * Revision 5.4  1996/08/14  21:44:11  tatiana
121  * *** empty log message ***
122  *
123  * Revision 5.3  1996/08/12  16:44:31  tatiana
124  * ErrPostEx changed to ErrpostStr
125  *
126  * Revision 5.2  1996/08/06  20:30:46  kans
127  * SeqIdFindBest called to handle local IDs and genbank IDs coexisting
128  *
129  * Revision 5.1  1996/05/29  21:35:56  tatiana
130  * GetEMBLDate fixed
131  *
132  * Revision 4.26  1996/05/21  14:09:46  tatiana
133  * a bug fixed in GBDescrComFeat
134  *
135  * Revision 4.25  1996/05/03  15:34:23  tatiana
136  * targeting the entry in GenPept format in GatherDescrByChoice
137  *
138  * Revision 4.24  1996/04/30  16:53:13  tatiana
139  * added support for multiple 'region' and 'method' in COMMENT
140  *
141  * Revision 4.23  1996/04/29  18:49:23  tatiana
142  * print multiple comments by number
143  *
144  * Revision 4.22  1996/04/15  16:08:15  tatiana
145  * new line in DBSOURCE
146  *
147  * Revision 4.21  1996/04/15  14:33:03  tatiana
148  * boolet proof added to GetGenDate
149  *
150  * Revision 4.19  1996/04/10  17:53:29  tatiana
151  * init_comment added
152  *
153  * Revision 4.18  1996/04/09  16:17:28  tatiana
154  * hot link to swiss-prot changed
155  *
156  * Revision 4.17  1996/04/09  14:03:32  tatiana
157  * print COMMENT in blocks
158  *
159  * Revision 4.15  1996/03/25  15:54:42  tatiana
160  * use target in GatherDescrByChoice for GenPept and EMBLPept
161  *
162  * Revision 4.14  1996/03/25  15:18:50  tatiana
163  * boolet-proof n StringForSeqTech call
164  *
165  * Revision 4.13  1996/03/13  22:08:25  tatiana
166  * show GI in DBSOURCE line when GetSeqIdForGI returns NULL
167  *
168  * Revision 4.12  1996/02/26  03:45:24  ostell
169  * fixed usage of GatherDescrListByChoice and changed function to allocate
170  * first DescrStruct instead using static storage
171  *
172  * Revision 4.11  1996/02/22  23:28:04  tatiana
173  * typos fixed in PrintDBSourceLine()
174  *
175  * Revision 4.9  1996/02/18  21:16:05  tatiana
176  * memory leaks cleaned up
177  *
178  * Revision 4.8  1996/02/15  15:51:23  tatiana
179  * Gather for temp loaded items added
180  *
181  * Revision 4.7  1996/01/29  22:33:52  tatiana
182  * *** empty log message ***
183  *
184  * Revision 4.6  1995/12/14  19:13:33  kans
185  * fixed EMBL lineage
186  *
187  * Revision 4.5  1995/12/13  16:31:01  tatiana
188  * itemID ... added to descriptors
189  *
190  * Revision 4.4  1995/11/21  17:53:36  tatiana
191  * *** empty log message ***
192  *
193  * Revision 4.3  1995/11/17  21:28:35  kans
194  * asn2ff now uses gather (Tatiana)
195  *
196  * Revision 4.2  1995/08/22  15:37:53  tatiana
197  * GetVersion name changed to GetBiotableVersion
198  *
199  * Revision 4.1  1995/08/01  14:50:30  tatiana
200  * change SeqIdPrint to SeqIdWrite
201  *
202  * Revision 1.38  1995/07/17  19:33:20  kans
203  * parameters combined into Asn2ffJobPtr structure
204  *
205 *
206 **************************************/
207 
208 #include <gather.h>
209 #include <asn2ffg.h>
210 #include <asn2ffp.h>
211 #include <a2ferrdf.h>
212 #include <utilpub.h>
213 #include <ffprint.h>
214 #include <seqmgr.h>
215 
216 
217 NLM_EXTERN Int2 GetGenDate PROTO ((Asn2ffJobPtr ajp, GBEntryPtr gbp, CharPtr buffer));
218 NLM_EXTERN void PrintComment PROTO ((CharPtr string, Boolean identifier, Uint1 format));
219 NLM_EXTERN CharPtr DateToGB PROTO ((CharPtr buf, NCBI_DatePtr ndp));
220 NLM_EXTERN CharPtr mRNAEvidenceComment PROTO ((UserObjectPtr obj, Boolean add));
221 static ValNodePtr AddToUniqueList PROTO ((SeqIdPtr sid, ValNodePtr list));
222 static ValNodePtr GetDBSourceForNuclDB PROTO ((Asn2ffJobPtr ajp, GBEntryPtr gbp));
223 
224 static Boolean has_comment;
225 
226 /*---------- order for other id FASTA_LONG (copied from SeqIdWrite) ------- */
227  
228 static Uint1 fasta_order[NUM_SEQID] = {
229 33, /* 0 = not set */
230 20, /* 1 = local Object-id */
231 15,  /* 2 = gibbsq */
232 16,  /* 3 = gibbmt */
233 30, /* 4 = giim Giimport-id */
234 10, /* 5 = genbank */
235 10, /* 6 = embl */
236 10, /* 7 = pir */
237 10, /* 8 = swissprot */
238 15,  /* 9 = patent */
239 18, /* 10 = other TextSeqId */
240 20, /* 11 = general Dbtag */
241 31,  /* 12 = gi */
242 10, /* 13 = ddbj */
243 10, /* 14 = prf */
244 12, /* 15 = pdb */
245 10,  /* 16 = tpg */
246 10,  /* 17 = tpe */
247 10   /* 18 = tpd */
248 };
249 
250 static ComStructPtr ComStructNew(void)
251 {
252         ComStructPtr csp;
253         
254         csp = (ComStructPtr) MemNew(sizeof(ComStruct));
255         csp->string = NULL;
256         csp->gsdb_id = FALSE;
257         
258         return csp;
259 }
260 
261 static CharPtr SeqIdWriteProc (Asn2ffJobPtr ajp, SeqIdPtr sip)
262 {
263         StdPrintOptionsPtr Spop=ajp->Spop;
264 
265         if (Spop != NULL) {
266                 Spop->ptr = NULL; /* reused ajp->Spop->ptr left dangling by previous call */
267         }
268 
269         if (ajp->show_version) {
270                 if (! StdFormatPrint((Pointer)sip, 
271                         (AsnWriteFunc)SeqIdAsnWrite, "VersionSeqId", Spop)) {
272                         ErrPostStr (SEV_WARNING, 0, 0, "VersionSeqId_StdFormatPrint failed");
273                 }
274         } else {
275                 if (! StdFormatPrint((Pointer)sip, 
276                         (AsnWriteFunc)SeqIdAsnWrite, "StdSeqId", Spop)) {
277                         ErrPostStr (SEV_WARNING, 0, 0, "StdSeqId_StdFormatPrint failed");
278                 }
279         }
280         if (Spop->ptr != NULL && *((CharPtr) (Spop->ptr)) != '\0') 
281                 return Spop->ptr;
282         else
283                 return NULL;
284 }
285 
286 static CharPtr BioseqIdPrintProc (Asn2ffJobPtr ajp, GBEntryPtr gbp)
287 {
288         BioseqPtr bsp=gbp->bsp;
289         StdPrintOptionsPtr Spop=ajp->Spop;
290 
291         if (Spop != NULL) {
292                 Spop->ptr = NULL; /* reused ajp->Spop->ptr left dangling by previous call */
293         }
294 
295         if (gbp == NULL) 
296                 return NULL;
297         if ((bsp=gbp->bsp) == NULL)
298                 return NULL;
299         if (! StdFormatPrint((Pointer)bsp, 
300                 (AsnWriteFunc)BioseqAsnWrite, "StdBioseqId", Spop))
301                     ErrPostStr (SEV_WARNING, 0, 0, "StdBioseqId_StdFormatPrint failed");
302 
303         if (Spop->ptr != NULL && *((CharPtr) (Spop->ptr)) != '\0') 
304                 return Spop->ptr;
305         else
306                 return NULL;
307 }
308 
309 
310 static CharPtr TableIdPrintProc (Asn2ffJobPtr ajp, GBEntryPtr gbp)
311 {
312         BioseqPtr bsp=ajp->asn2ffwep->seg;
313         StdPrintOptionsPtr Spop=ajp->Spop;
314 
315         if (Spop != NULL) {
316                 Spop->ptr = NULL; /* reused ajp->Spop->ptr left dangling by previous call */
317         }
318 
319         if (bsp == NULL)
320                 return NULL;
321 
322         if (! StdFormatPrint((Pointer)bsp, 
323                 (AsnWriteFunc)BioseqAsnWrite, "TableIdPrintProcStdBioseqId", Spop)) {
324                     ErrPostStr (SEV_WARNING, 0, 0, "StdFormatPrint failed");
325         }
326         if (Spop->ptr != NULL && *((CharPtr) (Spop->ptr)) != '\0') 
327                 return Spop->ptr;
328         else
329                 return NULL;
330 }
331 
332 static CharPtr SPBlockPrintProc (Asn2ffJobPtr ajp, ValNodePtr vnp)
333 {
334         StdPrintOptionsPtr Spop=ajp->Spop;
335 
336         if (Spop != NULL) {
337                 Spop->ptr = NULL; /* reused ajp->Spop->ptr left dangling by previous call */
338         }
339 
340         if (! StdFormatPrint((Pointer)vnp->data.ptrvalue, 
341                 (AsnWriteFunc)SPBlockAsnWrite, "StdSPBlock", Spop)) {
342                     ErrPostStr (SEV_WARNING, 0, 0, "StdSPBlockStdFormatPrint failed");
343         }
344         if (Spop->ptr != NULL && *((CharPtr) (Spop->ptr)) != '\0') 
345                 return Spop->ptr;
346         else
347                 return StringSave ("Empty Data\n");
348 }
349 
350 static CharPtr PIRBlockPrintProc (Asn2ffJobPtr ajp, ValNodePtr vnp)
351 {
352         StdPrintOptionsPtr Spop=ajp->Spop;
353 
354         if (Spop != NULL) {
355                 Spop->ptr = NULL; /* reused ajp->Spop->ptr left dangling by previous call */
356         }
357 
358         if (! StdFormatPrint((Pointer)vnp->data.ptrvalue, 
359                 (AsnWriteFunc)PirBlockAsnWrite, "StdPirBlock", Spop)) {
360                     ErrPostStr (SEV_WARNING, 0, 0, "StdFormatPrint failed");
361         }
362         if (Spop->ptr != NULL && *((CharPtr) (Spop->ptr)) != '\0') 
363                 return Spop->ptr;
364         else
365                 return StringSave ("Empty Data\n");
366 }
367 
368 static CharPtr PDBBlockPrintProc (Asn2ffJobPtr ajp, ValNodePtr vnp)
369 {
370         StdPrintOptionsPtr Spop=ajp->Spop;
371 
372         if (Spop != NULL) {
373                 Spop->ptr = NULL; /* reused ajp->Spop->ptr left dangling by previous call */
374         }
375 
376         if (! StdFormatPrint((Pointer)vnp->data.ptrvalue, 
377                 (AsnWriteFunc)PdbBlockAsnWrite, "StdPDBBlock", Spop))
378                     ErrPostStr (SEV_WARNING, 0, 0, "StdFormatPrint failed");
379 
380         if (Spop->ptr != NULL && *((CharPtr) (Spop->ptr)) != '\0') 
381                 return Spop->ptr;
382         else
383                 return StringSave ("Empty Data\n");
384 }
385 
386 static CharPtr PRFBlockPrintProc (Asn2ffJobPtr ajp, ValNodePtr vnp)
387 {
388         StdPrintOptionsPtr Spop=ajp->Spop;
389 
390         if (Spop != NULL) {
391                 Spop->ptr = NULL; /* reused ajp->Spop->ptr left dangling by previous call */
392         }
393 
394         if (! StdFormatPrint((Pointer)vnp->data.ptrvalue, 
395                 (AsnWriteFunc)PrfBlockAsnWrite, "StdPRFBlock", Spop))
396                     ErrPostStr (SEV_WARNING, 0, 0, "StdFormatPrint failed");
397 
398         if (Spop->ptr != NULL && *((CharPtr) (Spop->ptr)) != '\0') 
399                 return Spop->ptr;
400         else
401                 return StringSave ("Empty Data\n");
402 }
403 
404 
405 static DescrStructPtr tie_next_dsp(DescrStructPtr head, DescrStructPtr next)
406 /*  ties next node to the end of the chain */
407 {
408         DescrStructPtr v;
409 
410         if (head == NULL) {
411                 return next;
412         }
413         for (v = head; v->next != NULL; v = v->next) {
414                 v = v;
415         }
416         v->next = next;
417         return head;
418 }
419 
420 
421 /**************************************************************************
422 *GetSfpComment
423 *
424 *       Get the sfp->comments from sfp's that cover the entire bsp, are
425 *       sfp's of type comment, and are not of length zero.  The length
426 *       is checked for in OrganizeSeqFeat.
427 *
428 **************************************************************************/
429 
430 static CharPtr GetSfpComment (Asn2ffJobPtr ajp, GBEntryPtr gbp)
431 {
432         Int4 index;
433         SeqFeatPtr sfp;
434         SortStructPtr p;
435 
436         if (gbp == NULL || gbp->feat == NULL) {
437                 return  NULL;
438         }
439         index = ajp->pap_index;
440         p = gbp->feat->Commlist + index;
441         if ((sfp = p->sfp) == NULL) {
442                 GatherItemWithLock(p->entityID, p->itemID, 
443                         p->itemtype, &sfp, find_item);
444         }
445         if (sfp != NULL) {
446                 return sfp->comment;
447         }
448         return NULL;
449 }
450 
451 NLM_EXTERN void PrintCommentByNumber(Asn2ffJobPtr ajp, GBEntryPtr gbp)
452 {
453         CharPtr newstring;
454         ComStructPtr s;
455         Int4 i, index = ajp->pap_index;
456         
457         if (gbp == NULL) {
458                 return;
459         }
460         for (s = gbp->comm, i=0; s && i < index; s = s->next, i++)
461         {       
462         }
463         newstring = CheckEndPunctuation(s->string, '.');
464         www_PrintComment(newstring, FALSE, (Uint1)ajp->format);
465         newstring = MemFree(newstring);
466         return;
467 }
468 NLM_EXTERN void PrintFirstComment(Asn2ffJobPtr ajp, GBEntryPtr gbp)
469 {
470         CharPtr newstring;
471         ComStructPtr s;
472         
473         if (gbp == NULL) {
474                 return;
475         }
476         if ((s = gbp->comm) != NULL) {
477                 if (s->next == NULL && s->gsdb_id == TRUE) {
478                         newstring = StringSave(s->string);
479                 } else {
480                         newstring = CheckEndPunctuation(s->string, '.');
481                 }
482                 www_PrintComment(newstring, TRUE, (Uint1)ajp->format);
483                 newstring = MemFree(newstring);
484         }
485         return;
486 }
487 /**************************************************************************
488 *  ties next node to the end of the chain 
489 *       returns head
490 **************************************************************************/
491 static ComStructPtr tie_next_comm(ComStructPtr head, ComStructPtr next)
492 {
493         ComStructPtr v;
494 
495         if (head == NULL) {
496                 return next;
497         }
498         for (v = head; v->next != NULL; v = v->next) {
499                 v = v;
500         }
501         v->next = next;
502         return head;
503 }
504 
505 static CharPtr GetStrForBankit(UserObjectPtr uop)
506 {
507     ObjectIdPtr         oip;
508         UserFieldPtr    ufp;
509         CharPtr                 ptr=NULL, ptr1 = NULL;
510         Int2                    i=0, ptrlen = 0;
511         
512         if ((oip = uop->type) == NULL) return NULL;
513         if (StringCmp(oip->str, "Submission") != 0) return NULL;
514         for (ufp=uop->data; ufp; ufp=ufp->next) {
515                 oip = ufp->label;
516                 if (StringCmp(oip->str, "UniVecComment") == 0) {
517                         if (ufp->data.ptrvalue) {
518                                 ptrlen = (StringLen("Vector Explanation: ")
519                                                         + StringLen(ufp->data.ptrvalue) + 1);
520                                 ptr = (CharPtr) MemNew(ptrlen);
521                                 sprintf(ptr, "Vector Explanation: %s", 
522                                                                                 (CharPtr) ufp->data.ptrvalue);
523                         }
524                 }
525         }
526         for (ufp=uop->data; ufp; ufp=ufp->next) {
527                 oip = ufp->label;
528                 if (StringCmp(oip->str, "AdditionalComment") == 0) {
529                         if (ufp->data.ptrvalue) {
530                                 ptr1 = (CharPtr) MemNew(StringLen("Bankit Comment: ")
531                                                         + StringLen(ufp->data.ptrvalue) + 2 + ptrlen);
532                                 if (ptr) {
533                                         sprintf(ptr1, "%s~Bankit Comment: %s", 
534                                                                         ptr, (CharPtr) ufp->data.ptrvalue);
535                                 } else {
536                                         sprintf(ptr1, "Bankit Comment: %s", 
537                                                                                 (CharPtr) ufp->data.ptrvalue);
538                                 }
539                                 return ptr1;
540                         }
541                 }
542         }
543         
544         return ptr;
545 }
546 
547 static CharPtr GetStrForUserObject(UserObjectPtr uop)
548 {
549     ObjectIdPtr         oip;
550         UserFieldPtr    ufp, tmp, u, urf = NULL;
551         CharPtr                 curator = NULL, ptr=NULL, st;
552         Int2                    i=0, acclen;
553         CharPtr                 p = NULL, pp;
554         Int2                    review = 0, len;
555         
556         if ((oip = uop->type) == NULL) return NULL;
557         if (StringCmp(oip->str, "RefGeneTracking") != 0) return NULL;
558         len = StringLen("The reference sequence was derived from ");
559         for (ufp=uop->data; ufp; ufp=ufp->next) {
560                 oip = ufp->label;
561                 if (StringCmp(oip->str, "Assembly") == 0) {
562                         urf = ufp;
563                 }
564                 if (StringCmp(oip->str, "Status") == 0) {
565                         st = (CharPtr) ufp->data.ptrvalue;
566                         if (StringCmp(st, "Provisional") == 0) {
567                                 review = 1;
568                         } else if (StringCmp(st, "Reviewed") == 0) {
569                                 review = 2;
570                         } else if (StringCmp(st, "Predicted") == 0) {
571                                 review = 3;
572                         } else if (StringCmp(st, "Validated") == 0) {
573                                 review = 4;
574                         }
575                 } else if (StringCmp (oip->str, "Collaborator") == 0) {
576                         st = (CharPtr) ufp->data.ptrvalue;
577                         if (! StringHasNoText (st)) {
578                                 curator = st;
579                         }
580                 }
581         }
582         if (urf && urf->choice == 11) {
583                 for (tmp=urf->data.ptrvalue; tmp; tmp=tmp->next, i++) ;
584                 if (review == 2) {
585                         if (curator == NULL) {
586                                 curator = "NCBI staff";
587                         }
588                         ptr = (CharPtr) MemNew(
589                         StringLen("REVIEWED REFSEQ: This record has been curated by . ") + StringLen (curator) + len + 18*i + 1);
590                         sprintf(ptr, "REVIEWED REFSEQ: This record has been curated by %s. ", curator);
591                 } else if (review == 1) {
592                         ptr = (CharPtr) MemNew(
593                         StringLen("PROVISIONAL REFSEQ: This record has not yet been subject to final NCBI review. ") + len + 18*i + 1);
594                         sprintf(ptr, "PROVISIONAL REFSEQ: This record has not yet been subject to final NCBI review. ");
595                 } else if (review == 3) {
596                         ptr = (CharPtr) MemNew(
597                         StringLen("PREDICTED REFSEQ: The mRNA record is supported by experimental evidence; however, the coding sequence is predicted. ") + len + 18*i + 1);
598                         sprintf(ptr, "PREDICTED REFSEQ: The mRNA record is supported by experimental evidence; however, the coding sequence is predicted. ");
599                 } else if (review == 4) {
600                         ptr = (CharPtr) MemNew(
601                         StringLen("VALIDATED REFSEQ: This record has undergone preliminary review of the sequence, but has not yet been subject to final NCBI review. ") + len + 18*i + 1);
602                         sprintf(ptr, "VALIDATED REFSEQ: This record has undergone preliminary review of the sequence, but has not yet been subject to final NCBI review. ");
603                 } else {
604                         ptr = (CharPtr) MemNew( StringLen("REFSEQ: ") + len + 18*i + 1);
605                         sprintf(ptr, "REFSEQ: ");
606                 }
607                 if (i > 0) {
608                         pp = (CharPtr) MemNew(len + 1);
609                         sprintf(pp, "The reference sequence was derived from ");
610                         StringCat(ptr, pp);
611                         MemFree(pp);
612                 }
613                 for (tmp=urf->data.ptrvalue; tmp; tmp=tmp->next) {
614                         for (u = tmp->data.ptrvalue; u; u=u->next) {
615                                 oip = u->label;
616                                 if (StringCmp(oip->str, "accession") == 0) {
617                                         break;
618                                 }
619                         }
620                         if (u) {
621                                 if ((acclen = StringLen(u->data.ptrvalue)) > 15) {
622                                         continue;
623                                 }
624                                 p = (CharPtr) MemNew(acclen + 4);
625                                 if (tmp->next) {
626                                         sprintf(p, "%s, ", (CharPtr) u->data.ptrvalue);
627                                 } else {
628                                         sprintf(p, "%s.~~", (CharPtr) u->data.ptrvalue);
629                                 }
630                         }
631                         StringCat(ptr, p);
632                         MemFree(p);
633                 }
634         }
635         return ptr;
636 }
637 
638 static CharPtr GetStrForMap(DbtagPtr dbtag)
639 {
640         Int2 total;
641         Int4 id = -1;
642         ObjectIdPtr oip;
643         CharPtr db, ptr = NULL, str=NULL;
644         
645         if (dbtag == NULL) {
646                 return NULL;
647         }
648         db=dbtag->db;
649         oip=dbtag->tag;
650         if (oip) {
651                 if (oip->id)
652                         id = oip->id;
653                 if (oip->str)
654                         str = oip->str;
655         }
656         if (db && id != -1) {
657                 total = StringLen("Map location: (Database ; id # )");
658                 total += StringLen(db) + 21;
659                 ptr = MemNew(total);
660                 sprintf(ptr, "Map location: (Database %s; id # %ld)", db, (long) (id));
661         } else if (str) {
662                 total = StringLen("Map location: ") + StringLen(str) + 1;
663                 ptr = MemNew(total);
664                 sprintf(ptr, "Map location: %s", str);
665         }
666         if (ptr) {
667                 return (StringSave(ptr));
668         }
669         return NULL;
670 }
671 
672 static CharPtr GetEvidence(Asn2ffJobPtr ajp, GBEntryPtr gbp)
673 {
674         CharPtr         retval=NULL;
675         UserObjectPtr   uop=NULL;
676         ValNodePtr tvnp, ds_vnp, vnp;
677         DescrStructPtr dsp;
678 
679         if (gbp == NULL || gbp->bsp == NULL) {
680                 return NULL;
681         }
682         tvnp = GatherDescrListByChoice(ajp, gbp, Seq_descr_user); 
683         for (ds_vnp= tvnp; ds_vnp;) {
684                 dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
685                 if((vnp = dsp->vnp) != NULL){
686                         if(!retval){
687                                 uop = (UserObjectPtr) vnp->data.ptrvalue;
688                                 retval=mRNAEvidenceComment(uop, FALSE);
689                         }
690                         MemFree(vnp);
691                 }
692                 MemFree(dsp);
693                 vnp=ds_vnp;
694                 ds_vnp=ds_vnp->next;
695                 MemFree(vnp);
696         }
697         return retval;
698 }
699 
700 static CharPtr genanreftext1 = "GENOME ANNOTATION REFSEQ:  This model reference sequence was predicted from NCBI contig";
701 static CharPtr genanreftext2 = "by automated computational analysis";
702 static CharPtr genanreftext3 = "using gene prediction method:";
703 static CharPtr genanreftext4 = "~Also see:~    Documentation of NCBI's Annotation Process~    Evidence Viewer - alignments supporting this model";
704 
705 static CharPtr GetAnnotationComment(Asn2ffJobPtr ajp, GBEntryPtr gbp)
706 {
707         UserObjectPtr   uop=NULL;
708     ObjectIdPtr         oip;
709         UserFieldPtr    ufp;
710         CharPtr                 retval = NULL, name = NULL, method = NULL;
711         
712         ValNodePtr tvnp, ds_vnp, vnp;
713         DescrStructPtr dsp;
714 
715         if (gbp == NULL || gbp->bsp == NULL) {
716                 return NULL;
717         }
718         tvnp = GatherDescrListByChoice(ajp, gbp, Seq_descr_user); 
719         for (ds_vnp= tvnp;
720                                 ds_vnp; ds_vnp=ds_vnp->next) {
721                 dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
722                 if ((vnp = dsp->vnp) == NULL)
723                         continue;
724                 uop = (UserObjectPtr) vnp->data.ptrvalue;
725         }
726         if (uop == NULL) return retval;
727         if ((oip = uop->type) == NULL) return retval;
728         if (StringCmp(oip->str, "ModelEvidence") != 0) return retval;
729         for (ufp=uop->data; ufp; ufp=ufp->next) {
730                 oip = ufp->label;
731                 if (StringCmp(oip->str, "Contig Name") == 0) {
732                         name = (CharPtr) ufp->data.ptrvalue;
733                 }
734                 if (StringCmp(oip->str, "Method") == 0) {
735                         if (ufp->data.ptrvalue) {
736                                 method = StringSave((CharPtr) ufp->data.ptrvalue);
737                         }
738                 }
739         }
740         if (name == NULL) return NULL;
741         retval = MemNew(StringLen(genanreftext1) + StringLen(genanreftext2) + StringLen(genanreftext3) + StringLen(genanreftext4) + StringLen(name) + StringLen(method) + 15);
742         if (method != NULL) {
743                 sprintf(retval, "%s %s %s %s %s. %s", genanreftext1, name, genanreftext2, genanreftext3, method, genanreftext4);
744         } else {
745                 sprintf(retval, "%s %s %s. %s", genanreftext1, name, genanreftext2, genanreftext4);
746         }
747         return retval;
748         
749 }
750 
751 static void GetCommentByChoice(Asn2ffJobPtr ajp, GBEntryPtr gbp, Uint1 choice)
752 {
753         ValNodePtr ds_vnp, tvnp, vnp = NULL;
754         DescrStructPtr dsp;
755         BioseqPtr bsp = gbp->bsp;
756         DeltaSeqPtr d;
757         static Char buffer[1024];
758         CharPtr sptr = &buffer[0], tmp, tmp3;
759         ComStructPtr csp;
760         MolInfoPtr mfp;
761         CharPtr buf = NULL, ptr = NULL, string=NULL, new_string=NULL, str=NULL;
762         Int4 buflen = 0;
763         Int4 num_s = 0, num_g = 0;
764         Boolean is_other;
765         CharPtr p;
766 
767         if (bsp && bsp->id) {
768                 is_other = (bsp->id->choice == SEQID_OTHER) ? TRUE : FALSE; 
769         }
770         tvnp = GatherDescrListByChoice(ajp, gbp, choice); 
771         for (ds_vnp = tvnp;     ds_vnp; ds_vnp=ds_vnp->next) {
772                 dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
773                 vnp = dsp->vnp;
774                 if (vnp == NULL) {
775                         continue;
776                 }
777                 if (choice == Seq_descr_user) {
778                         if (ajp->bankit && 
779                                 (new_string = GetStrForBankit(vnp->data.ptrvalue))) {
780                                 csp = ComStructNew();
781                                 csp->string = new_string;
782                                 csp->gsdb_id = FALSE;
783                                 csp->entityID = dsp->entityID;
784                                 csp->itemID = dsp->itemID;
785                                 csp->itemtype = dsp->itemtype;
786                                 gbp->comm = tie_next_comm(gbp->comm, csp);
787                                 gbp->comm_num++;
788                         }
789                         if ((new_string = GetStrForUserObject(vnp->data.ptrvalue))) {
790                                 csp = ComStructNew();
791                                 csp->gsdb_id = FALSE;
792                                 csp->string = StringSave(new_string);
793                                 new_string = MemFree(new_string);
794                                 csp->entityID = dsp->entityID;
795                                 csp->itemID = dsp->itemID;
796                                 csp->itemtype = dsp->itemtype;
797                                 gbp->comm = tie_next_comm(gbp->comm, csp);
798                                 gbp->comm_num++;
799                         }
800                 }
801                 csp = ComStructNew();
802                 csp->string = NULL;
803                 csp->gsdb_id = FALSE;
804                 switch (choice) {
805                 case Seq_descr_comment:
806                         csp->string = StringSave(vnp->data.ptrvalue);
807                         break;
808                 case Seq_descr_maploc:
809                         csp->string = GetStrForMap((DbtagPtr) vnp->data.ptrvalue);
810                         break;
811                 case Seq_descr_region:
812                         sprintf(sptr, "Region: ");
813                         new_string = Cat2Strings(sptr , vnp->data.ptrvalue, NULL, 0);
814                         str = CheckEndPunctuation(new_string, '.');
815                         new_string = MemFree(new_string);
816                         csp->string = StringSave(str);
817                         MemFree(str);
818                         break;
819                 case Seq_descr_molinfo:
820                         if ((mfp = vnp->data.ptrvalue) != NULL) {
821                                 if (is_other == TRUE  && mfp->completeness) {
822                                         switch (mfp->completeness) {
823                                                 case 1:
824                                 csp->string = StringSave("COMPLETENESS: full length");
825                                                 break;
826                                                 case 2:
827                                 csp->string = StringSave("COMPLETENESS: not full length");
828                                                 break;
829                                                 case 3:
830                         csp->string = StringSave("COMPLETENESS: incomplete on the 5' end");
831                                                 break;
832                                                 case 4:
833                         csp->string = StringSave("COMPLETENESS: incomplete on the 3' end");
834                                                 break;
835                                                 case 5:
836                         csp->string = StringSave("COMPLETENESS: incomplete on both ends");
837                                                 break;
838                                                 case 6:
839                         csp->string = StringSave("COMPLETENESS: complete on the 5' end");
840                                                 break;
841                                                 case 7:
842                         csp->string = StringSave("COMPLETENESS: complete on the 3' end");
843                                                 break;
844                                                 default:
845                         csp->string = StringSave("COMPLETENESS: unknown");
846                                                 break;
847                                         }
848                                 } else if(mfp->tech > 1) {
849                                         for (d=(DeltaSeqPtr)(bsp->seq_ext); d != NULL; d=d->next) {
850                                                 buflen +=80;
851                                         }
852                                         if (buflen > 0) {
853                                                 buf = MemNew(buflen+1);
854                                                 CountGapsInDeltaSeq(bsp, &num_s, 
855                                                         &num_g, NULL, NULL, buf, buflen);
856                                         }
857                                         if (mfp->tech == MI_TECH_htgs_0) {
858                                                 if (num_s > 0) {
859                                                         sprintf(buffer, 
860                                                         "* NOTE: This record contains %ld individual~* sequencing reads that have not been assembled into~* contigs. Runs of N are used to separate the reads~* and the order in which they appear is completely~* arbitrary. Low-pass sequence sampling is useful for~* identifying clones that may be gene-rich and allows~* overlap relationships among clones to be deduced.~* However, it should not be assumed that this clone~* will be sequenced to completion. In the event that~* the record is updated, the accession number will~* be preserved.", (long) (num_s-num_g));
861                                                 }
862                                                 csp->string = Cat2Strings(buffer, buf, "~", 0);
863                                         } else if (mfp->tech == MI_TECH_htgs_1) {
864                                                 tmp = StringSave(
865                                                 "* NOTE: This is a \"working draft\" sequence.");
866                                                 if (num_s > 0) {
867                                                         sprintf(buffer, 
868                                                         " It currently~* consists of %ld contigs. The true order of the pieces~* is not known and their order in this sequence record is~* arbitrary. Gaps between the contigs are represented as~* runs of N, but the exact sizes of the gaps are unknown.", (long) (num_s-num_g));
869                                                         p = Cat2Strings(tmp, buffer, "", 0);
870                                                         MemFree(tmp);
871                                                         tmp = p;
872                                                 }
873                                                 tmp3 = StringSave("* This record will be updated with the finished sequence~* as soon as it is available and the accession number will~* be preserved.");
874                                                 p = Cat2Strings(tmp, tmp3, "~", 0);
875                                                 MemFree(tmp);
876                                                 MemFree(tmp3);
877                                                 csp->string = Cat2Strings(p, buf, "~", 0);
878                                                 MemFree(p);
879                                         } else if (mfp->tech == MI_TECH_htgs_2) {
880                                                 tmp = StringSave(
881                                                 "* NOTE: This is a \"working draft\" sequence."); 
882                                                 if (num_s > 0) {
883                                                         sprintf(buffer, " It currently~* consists of %ld contigs. Gaps between the contigs~* are represented as runs of N. The order of the pieces~* is believed to be correct as given, however the sizes~* of the gaps between them are based on estimates that have~* provided by the submittor.", (long) (num_s-num_g));
884                                                         p = Cat2Strings(tmp, buffer, "", 0);
885                                                         MemFree(tmp);
886                                                         tmp = p;
887                                                 }
888                                                 tmp3 = StringSave("* This sequence will be replaced~* by the finished sequence as soon as it is available and~* the accession number will be preserved.");
889                                                 p = Cat2Strings(tmp, tmp3, "~", 0);
890                                                 MemFree(tmp);
891                                                 MemFree(tmp3);
892                                                 csp->string = Cat2Strings(p, buf, "~", 0);
893                                                 MemFree(p);
894                                         } else if ((str = StringForSeqTech(mfp->tech)) != NULL) {
895                                                 ptr = MemNew(StringLen(str) + 10);
896                                                 sprintf(ptr, "Method: %s.", str); 
897                                                 csp->string = StringSave(ptr);
898                                                 MemFree(ptr);
899                                         }
900                                         MemFree(buf);
901                                 }
902                         }
903                         break;
904                 case Seq_descr_method:
905                         if (vnp->data.intvalue > 1) {
906                                 str = StringForSeqMethod((Int2) vnp->data.intvalue);
907                                 ptr = MemNew(StringLen(str) + 10);
908                                 sprintf(ptr, "Method: %s.", str); 
909                                 csp->string = StringSave(ptr);
910                                 MemFree(ptr);
911                         }
912                         break;
913                 default:
914                         break;
915                 }
916                 if (choice != Seq_descr_user && csp->string) {
917                         csp->entityID = dsp->entityID;
918                         csp->itemID = dsp->itemID;
919                         csp->itemtype = dsp->itemtype;
920                         gbp->comm = tie_next_comm(gbp->comm, csp);
921                         gbp->comm_num++;
922                 } else {
923                         MemFree(csp);
924                 }
925                 MemFree(vnp);
926                 MemFree(dsp);
927         }
928         ValNodeFree(tvnp);
929         return;
930 }
931 
932 NLM_EXTERN Int2 GB_GetSeqDescrComms(Asn2ffJobPtr ajp, GBEntryPtr gbp)
933 {
934         ComStructPtr csp;
935     DbtagPtr    DBtag = NULL;
936         static Char buf[1001], tmp[28];
937         SeqIdPtr sid = NULL;
938         SeqHistPtr hist;
939         Int2 num_gi;
940         DatePtr dat;
941         CharPtr strd = NULL;
942         TextSeqIdPtr tsip = NULL;
943         Boolean is_contig = FALSE;
944         
945         gbp->comm_num = 0;
946 /*  Get  NT_ contig comment */
947         for (sid = gbp->bsp->id; sid; sid=sid->next) {
948                 if (sid->choice == SEQID_OTHER) {
949                         tsip = (TextSeqIdPtr) sid->data.ptrvalue;
950                         break;
951                 }
952         }
953         if (tsip != NULL) {
954                 if (StringNCmp(tsip->accession, "NT", 2) == 0) {
955                         is_contig = TRUE;                       
956                         csp = ComStructNew();
957                         csp->string = StringSave("GENOME ANNOTATION REFSEQ:  NCBI contigs are derived from assembled genomic sequence data. They may include both draft and finished sequence.");
958                 } else if (StringNCmp(tsip->accession, "XP_", 3) == 0 || StringNCmp(tsip->accession, "XM_", 3) == 0) {
959                         is_contig = TRUE;                       
960                         csp = ComStructNew();
961                         csp->string = GetAnnotationComment(ajp, gbp);
962                 }
963                 if (is_contig) {                        
964                         gbp->comm = tie_next_comm(gbp->comm, csp);
965                         gbp->comm_num++;
966                 }
967                 /*
968                 if ((strd = GetEvidence(ajp, gbp)) != NULL) {
969                         csp = ComStructNew();
970                         csp->string =StringSave( strd);
971                         gbp->comm = tie_next_comm(gbp->comm, csp);
972                         gbp->comm_num++;
973                 }
974                 */
975         }
976 
977         GetCommentByChoice(ajp, gbp, Seq_descr_user);
978 
979 /*  Get GSDB Id */
980         for (sid = gbp->bsp->id; sid; sid=sid->next) {
981                 if (sid->choice != SEQID_GENERAL)
982                         continue;
983                 DBtag = sid->data.ptrvalue;
984                 if (StringCmp(DBtag->db, "GSDB") == 0) {
985                         break;
986                 }
987         }
988         if (sid != NULL) {
989                 if (DBtag && DBtag->tag) {
990                         csp = ComStructNew();
991                         csp->gsdb_id = TRUE;
992                         sprintf(buf, "GSDB:S:%ld", (long) DBtag->tag->id);
993                         csp->string = StringSave(buf);
994                         gbp->comm = tie_next_comm(gbp->comm, csp);
995                         gbp->comm_num++;
996                 }
997         }
998         if ((hist = gbp->bsp->hist) != NULL) {
999                 if (hist->replaced_by_ids != NULL && hist->replaced_by_date != NULL) {
1000                         num_gi = 0;
1001                         for (sid=hist->replaced_by_ids; sid; sid=sid->next) {
1002                                 if (sid->choice == SEQID_GI) {
1003                                         num_gi++;
1004                                 }
1005                         }
1006                         if ((dat = hist->replaced_by_date) != NULL) {
1007                                 strd = PrintDate(dat);
1008                                 if (strd[StringLen(strd)-1] == '\n') {
1009                                         if (strd[StringLen(strd)-2] == '.') {
1010                                                 strd[StringLen(strd)-2] = '\0';
1011                                         } else {
1012                                                 strd[StringLen(strd)-1] = '\0';
1013                                         }
1014                                 }
1015                         }
1016                         csp = ComStructNew();
1017                         csp->string = MemNew((128 + 16*num_gi)*sizeof(Char));
1018                         sprintf(csp->string, "[WARNING] On %s this sequence was replaced by a newer version", strd);
1019                         if(strd != NULL)
1020                                 strd = MemFree(strd);
1021                         for (sid=hist->replaced_by_ids; sid; sid=sid->next) {
1022                                 if (sid->choice == SEQID_GI) {
1023                                         sprintf(tmp, " gi:%ld", (long) sid->data.intvalue);
1024                                         StringCat(csp->string, tmp);
1025                                 }
1026                         }
1027                         gbp->comm = tie_next_comm(gbp->comm, csp);
1028                         gbp->comm_num++;
1029                 }
1030                 if (hist->replace_ids != NULL && hist->replace_date != NULL) {
1031                         num_gi = 0;
1032                         for (sid=hist->replace_ids; sid; sid=sid->next) {
1033                                 if (sid->choice == SEQID_GI) {
1034                                         num_gi++;
1035                                 }
1036                         }
1037                         if ((dat = hist->replace_date) != NULL) {
1038                                 strd = PrintDate(dat);
1039                                 if (strd[StringLen(strd)-1] == '\n') {
1040                                         if (strd[StringLen(strd)-2] == '.') {
1041                                                 strd[StringLen(strd)-2] = '\0';
1042                                         } else {
1043                                                 strd[StringLen(strd)-1] = '\0';
1044                                         }
1045                                 }
1046                         }
1047                         csp = ComStructNew();
1048                         csp->string = MemNew((128 + 16*num_gi)*sizeof(Char));
1049                         sprintf(csp->string, "On %s this sequence version replaced", strd);
1050                         if(strd != NULL)
1051                                 strd = MemFree(strd);
1052                         for (sid=hist->replace_ids; sid; sid=sid->next) {
1053                                 if (sid->choice == SEQID_GI) {
1054                                         sprintf(tmp, " gi:%ld", (long) sid->data.intvalue);
1055                                         StringCat(csp->string, tmp);
1056                                 }
1057                         }
1058                         gbp->comm = tie_next_comm(gbp->comm, csp);
1059                         gbp->comm_num++;
1060                 }
1061         }
1062         GetCommentByChoice(ajp, gbp, Seq_descr_comment);
1063         GetCommentByChoice(ajp, gbp, Seq_descr_maploc);
1064         GetCommentByChoice(ajp, gbp, Seq_descr_region);
1065         GetCommentByChoice(ajp, gbp, Seq_descr_molinfo);
1066         GetCommentByChoice(ajp, gbp, Seq_descr_method);
1067 
1068         return gbp->comm_num;
1069 }
1070 
1071 static CharPtr GetPDBHet (Asn2ffJobPtr ajp, GBEntryPtr gbp, Int2 indent)
1072 {
1073         Boolean first_done=FALSE, line_return, paranthesis=FALSE;
1074         CharPtr het_string="Heterogen Groups:", start, temp, temp1, newstring=NULL, string;
1075         Int2 length;
1076         ValNodePtr vnp=NULL, tvnp, ds_vnp;
1077         DescrStructPtr dsp;
1078 
1079         tvnp = GatherDescrListByChoice(ajp, gbp, Seq_descr_het); 
1080         for (ds_vnp= tvnp;
1081                                 ds_vnp; ds_vnp=ds_vnp->next) {
1082                 dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
1083                 if ((vnp = dsp->vnp) == NULL)
1084                         continue;
1085                 gbp->descr = tie_next_dsp(gbp->descr, dsp);
1086                 string = vnp->data.ptrvalue;
1087                 length = StringLen(string);
1088                 temp = start = MemNew(length*sizeof(Char));
1089                 while (*string != '\0') {
1090                         if (*string == '(') {
1091                                 paranthesis = TRUE;
1092                         } else if (*string == ')') {
1093                                 paranthesis = FALSE;
1094                         }
1095                         if (paranthesis && *string == ' ') {
1096                                 string++;
1097                         } else {
1098                                 *temp = *string;
1099                                 temp++; string++;
1100                         }
1101                 }
1102                 *temp = '\0';
1103 
1104                 if (first_done == FALSE) {
1105                         /* the next two lines initialize DoSpecialLineBreak */
1106                         line_return = DoSpecialLineBreak(NULL, indent);
1107                         line_return = DoSpecialLineBreak(het_string, indent);
1108                         line_return = DoSpecialLineBreak(start, indent);
1109                         if (line_return)
1110                                 newstring = Cat2Strings(het_string, start, "~", 0);
1111                         else
1112                                 newstring = Cat2Strings(het_string, start, " ", 0);
1113                         first_done = TRUE;
1114                 } else {
1115                         line_return = DoSpecialLineBreak(start, indent);
1116                         if (line_return)
1117                                 temp1 = Cat2Strings(newstring, start, ";~", 0);
1118                         else
1119                                 temp1 = Cat2Strings(newstring, start, "; ", 0);
1120                         newstring = MemFree(newstring);
1121                         newstring = temp1;
1122                 }
1123                 start = MemFree(start);
1124                 MemFree(vnp);
1125         }
1126         ValNodeFree(tvnp);
1127         return newstring;
1128 }
1129 
1130 NLM_EXTERN void GBDescrComFeat(Asn2ffJobPtr ajp, GBEntryPtr gbp)
1131 {
1132         CharPtr newstring, string;
1133         Int2 index;
1134         Boolean first = FALSE;
1135         
1136         if (gbp) {
1137                 gbp->descr = NULL;
1138         }
1139         for (index=0; index < gbp->feat->sfpCommsize; index++) {
1140                 ajp->pap_index = (Int4) index;
1141                 if (gbp->comm == NULL && index == 0) {
1142                         first = TRUE;
1143                 }
1144                 string = GetSfpComment(ajp, gbp);
1145                 newstring = CheckEndPunctuation(string, '.');
1146                 PrintComment(newstring, first, (Uint1)ajp->format);
1147                 newstring = MemFree(newstring);
1148         }
1149         return;
1150 }
1151 
1152 NLM_EXTERN Int2 GP_GetSeqDescrComms(Asn2ffJobPtr ajp, GBEntryPtr gbp)
1153 {
1154         ComStructPtr csp;
1155         Boolean got_comment=FALSE;
1156         CharPtr string;
1157 
1158         if (ajp->number_of_cds < 2)
1159         { /* Only print out comments if there's only one CDS */
1160         gbp->comm_num = GB_GetSeqDescrComms(ajp, gbp);
1161         if ((string = GetPDBHet(ajp, gbp, 12)) != NULL) {
1162                 csp = (ComStructPtr) MemNew(sizeof(ComStruct));
1163                 csp->string = StringSave(string);
1164                 if (gbp && gbp->descr) {
1165                         csp->entityID = gbp->descr->entityID;
1166                         csp->itemID = gbp->descr->itemID;
1167                         csp->itemtype = gbp->descr->itemtype;
1168                 }
1169                         gbp->comm = tie_next_comm(gbp->comm, csp);
1170                         gbp->comm_num++;
1171                 }
1172         }
1173 
1174         return gbp->comm_num;
1175 }       /* GP_GetSeqDescrComms */
1176 
1177 /*************************************************************************
1178 *       This function is obsolete. It is replaced by CheckSPBlock() that will
1179 *       check the string in SPBlock and PrintSPBlock() will allocate and print
1180 *       the string (save on allocating memory)
1181 *************************************************************************/
1182 static CharPtr GetSPBlock (Asn2ffJobPtr ajp, GBEntryPtr gbp)
1183 {
1184         ValNodePtr vnp=NULL;
1185         CharPtr temp, temp1, newstring=NULL, string, newline= "~", 
1186                 identifier= "NewSPblock:~";
1187         ValNodePtr tvnp, ds_vnp;
1188         DescrStructPtr dsp;
1189 
1190         tvnp = GatherDescrListByChoice(ajp, gbp, Seq_descr_sp); 
1191         for (ds_vnp= tvnp;
1192                                 ds_vnp; ds_vnp=ds_vnp->next) {
1193                 dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
1194                 if ((vnp = dsp->vnp) == NULL)
1195                         continue;
1196                 gbp->descr = tie_next_dsp(gbp->descr, dsp);
1197                 string = SPBlockPrintProc(ajp, vnp);
1198                 if (newstring == NULL) {
1199                         newstring = StringSave(string);
1200                         string = MemFree(string);
1201                 } else {
1202                         temp = Cat2Strings(newstring, newline, ";", 1); 
1203                         newstring = MemFree(newstring);
1204                         temp1 = Cat2Strings(temp, identifier, NULL, 0); 
1205                         newstring = Cat2Strings(temp1, string, NULL, 0); 
1206                         string = MemFree(string);
1207                         temp = MemFree(temp);
1208                         temp1 = MemFree(temp1);
1209                 }
1210                 MemFree(vnp);
1211         }
1212         ValNodeFree(tvnp);
1213         return newstring;
1214 }
1215 static Boolean CheckSPBlock (Asn2ffJobPtr ajp, GBEntryPtr gbp)
1216 {
1217         ValNodePtr vnp=NULL;
1218         CharPtr string = NULL;
1219         ValNodePtr tvnp, ds_vnp;
1220         DescrStructPtr dsp;
1221         Boolean retval = FALSE;
1222 
1223         tvnp = GatherDescrListByChoice(ajp, gbp, Seq_descr_sp); 
1224         for (ds_vnp= tvnp;
1225                                 ds_vnp; ds_vnp=ds_vnp->next) {
1226                 dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
1227                 if ((vnp = dsp->vnp) == NULL) {
1228                         continue;
1229                 }
1230                 gbp->descr = tie_next_dsp(gbp->descr, dsp);
1231                 if ((string = SPBlockPrintProc(ajp, vnp)) != NULL) {
1232                         MemFree(string);
1233                         retval = TRUE;
1234                 }
1235                 MemFree(vnp);
1236         }
1237         ValNodeFree(tvnp);
1238         return retval;
1239 }
1240 static CharPtr GetPIRBlock (Asn2ffJobPtr ajp, GBEntryPtr gbp)
1241 {
1242         ValNodePtr vnp=NULL;
1243         CharPtr temp, temp1, newstring=NULL, string, string1, newline= "~", 
1244                 identifier= "NewPIRblock:~";
1245         ValNodePtr tvnp, ds_vnp;
1246         DescrStructPtr dsp;
1247 
1248         tvnp = GatherDescrListByChoice(ajp, gbp, Seq_descr_pir); 
1249         for (ds_vnp= tvnp;
1250                                 ds_vnp; ds_vnp=ds_vnp->next) {
1251                 dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
1252                 if ((vnp = dsp->vnp) == NULL)
1253                         continue;
1254                 gbp->descr = tie_next_dsp(gbp->descr, dsp);
1255                 string1 = PIRBlockPrintProc(ajp, vnp);
1256                 if (StringNCmp("host:host", string1, 9) == 0) {
1257                         /* The following takes out the PIR "host". */
1258                         string = Cat2Strings("host", string1+9, ":", 0); 
1259                         string1 = MemFree(string1);
1260                 } else {
1261                         string = string1;
1262                 }
1263                 if (newstring == NULL) {
1264                         newstring = StringSave(string);
1265                         string = MemFree(string);
1266                 } else {
1267                         temp = Cat2Strings(newstring, newline, ";", 1); 
1268                         newstring = MemFree(newstring);
1269                         temp1 = Cat2Strings(temp, identifier, NULL, 0); 
1270                         newstring = Cat2Strings(temp1, string, NULL, 0); 
1271                         string = MemFree(string);
1272                         temp = MemFree(temp);
1273                         temp1 = MemFree(temp1);
1274                 }
1275                 MemFree(vnp);
1276         }
1277         ValNodeFree(tvnp);
1278         return newstring;
1279 }
1280 
1281 static CharPtr GetPDBBlock (Asn2ffJobPtr ajp, GBEntryPtr gbp)
1282 {
1283         ValNodePtr vnp=NULL;
1284         CharPtr temp, temp1, newstring=NULL, string, newline= "~", 
1285                 identifier= "NewPDBblock:~";
1286         ValNodePtr tvnp, ds_vnp;
1287         DescrStructPtr dsp;
1288 
1289         tvnp = GatherDescrListByChoice(ajp, gbp, Seq_descr_pdb); 
1290         for (ds_vnp= tvnp;
1291                                 ds_vnp; ds_vnp=ds_vnp->next) {
1292                 dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
1293                 if ((vnp = dsp->vnp) == NULL)
1294                         continue;
1295                 gbp->descr = tie_next_dsp(gbp->descr, dsp); 
1296                 string = PDBBlockPrintProc(ajp, vnp);
1297                 if (newstring == NULL) {
1298                         newstring = StringSave(string);
1299                         string = MemFree(string);
1300                 } else {
1301                         temp = Cat2Strings(newstring, newline, ";", 1); 
1302                         newstring = MemFree(newstring);
1303                         temp1 = Cat2Strings(temp, identifier, NULL, 0); 
1304                         newstring = Cat2Strings(temp1, string, NULL, 0); 
1305                         string = MemFree(string);
1306                         temp = MemFree(temp);
1307                         temp1 = MemFree(temp1);
1308                 }
1309                 MemFree(vnp);
1310         }
1311         ValNodeFree(tvnp);
1312         return newstring;
1313 }
1314 
1315 
1316 static CharPtr GetPRFBlock (Asn2ffJobPtr ajp, GBEntryPtr gbp)
1317 {
1318         ValNodePtr vnp=NULL;
1319         CharPtr temp, temp1, newstring=NULL, string, newline= "~", 
1320                 identifier= "NewPRFblock:~";
1321         ValNodePtr tvnp, ds_vnp;
1322         DescrStructPtr dsp;
1323 
1324         tvnp = GatherDescrListByChoice(ajp, gbp, Seq_descr_prf); 
1325         for (ds_vnp= tvnp;
1326                                 ds_vnp; ds_vnp=ds_vnp->next) {
1327                 dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
1328                 if ((vnp = dsp->vnp) == NULL)
1329                         continue;
1330                 gbp->descr = tie_next_dsp(gbp->descr, dsp); 
1331                 string = PRFBlockPrintProc(ajp, vnp);
1332                 if (newstring == NULL) {
1333                         newstring = StringSave(string);
1334                         string = MemFree(string);
1335                 } else {
1336                         temp = Cat2Strings(newstring, newline, ";", 1); 
1337                         newstring = MemFree(newstring);
1338                         temp1 = Cat2Strings(temp, identifier, NULL, 0); 
1339                         newstring = Cat2Strings(temp1, string, NULL, 0); 
1340                         string = MemFree(string);
1341                         temp = MemFree(temp);
1342                         temp1 = MemFree(temp1);
1343                 }
1344                 MemFree(vnp);
1345         }
1346         ValNodeFree(tvnp);
1347         return newstring;
1348 }
1349 
1350 static ChoicePID(SeqIdPtr sid) 
1351 {
1352         
1353         DbtagPtr db;
1354 
1355         if (sid->choice != SEQID_GENERAL) {
1356                 return FALSE;
1357         }
1358         db = sid->data.ptrvalue;
1359         if (db == NULL) {
1360                 return FALSE;
1361         }
1362         if ((StringNCmp(db->db, "PIDe", 4) == 0) ||
1363                         (StringNCmp(db->db, "PIDd", 4) == 0) ||
1364                                 (StringNCmp(db->db, "PID", 3) == 0)) {
1365                 return TRUE;
1366         }
1367         return FALSE;
1368 }
1369 
1370 /*************************************************************************
1371 *       Print the DBSource line using the Print Templates.
1372 *       Only used in GenPept mode.
1373 **************************************************************************/
1374 NLM_EXTERN void PrintDBSourceLine(Asn2ffJobPtr ajp, GBEntryPtr gbp)
1375 {
1376         Boolean first=TRUE;
1377         CharPtr newstring, string=NULL;
1378         SeqIdPtr sid;
1379         ValNodePtr vnp, vnp1;
1380 
1381         ff_StartPrint(0, 12, ASN2FF_GB_MAX, NULL);
1382         ff_AddString("DBSOURCE");
1383         TabToColumn(13);
1384         sid = SeqIdSelect(gbp->bsp->id, fasta_order, NUM_SEQID);
1385         if (sid && ((sid->choice == SEQID_PIR) ||
1386                 (sid->choice == SEQID_SWISSPROT) ||
1387                 (sid->choice == SEQID_PDB) ||
1388                 (sid->choice == SEQID_PRF))) {
1389 /* Use TableIdPrintProc as the higher level Bioseq may have more info
1390 than the individual parts of a segmented set, at least in Swiss-prot. */
1391                 string = TableIdPrintProc(ajp, gbp);
1392                 if (string) {
1393                         ff_AddStringWithTildes(string);
1394                         string  = MemFree(string);
1395                 } else if ((string = BioseqIdPrintProc(ajp, gbp)) != NULL) {
1396                         www_dbsource(string, first, sid->choice);
1397                         string  = MemFree(string);
1398                 }
1399         } else if (sid && ((sid->choice == SEQID_EMBL) ||
1400                         (sid->choice == SEQID_GENBANK) || 
1401                         (sid->choice == SEQID_DDBJ) || 
1402                         (sid->choice == SEQID_GIBBSQ) || 
1403                         (sid->choice == SEQID_GIBBMT) || 
1404             (sid->choice == SEQID_OTHER) ||
1405                         (sid->choice == SEQID_TPG) || 
1406                         (sid->choice == SEQID_TPE) || 
1407                         (sid->choice == SEQID_TPD) || 
1408                         (sid->choice == SEQID_GI) || 
1409                         (sid->choice == SEQID_GIIM || (ChoicePID(sid) == TRUE))))  {
1410                 vnp = GetDBSourceForNuclDB(ajp, gbp);
1411                 for (vnp1=vnp; vnp1; vnp1=vnp1->next) {
1412                         sid = (SeqIdPtr) vnp1->data.ptrvalue;
1413                         if ((string = SeqIdWriteProc(ajp, sid)) != NULL) {
1414                                 if (first == FALSE) {
1415                                         NewContLine();
1416                                         TabToColumn(13);
1417                                 }
1418                                 www_dbsource(string, first, sid->choice);
1419                                 string = MemFree(string);
1420                                 first = FALSE;
1421                         }
1422                 }
1423                 vnp = ValNodeFree(vnp);
1424         } else { /* Group all others as unknown */
1425                 ff_AddString("UNKNOWN");
1426         }
1427         if (gbp) {      
1428                 gbp->descr = NULL;
1429         }
1430 /* Only one of the following four should be non-NULL! */
1431         if ((string=GetPRFBlock(ajp, gbp)) != NULL) {
1432                 newstring = CheckEndPunctuation(string, '.');
1433                 NewContLine();
1434                 ff_AddStringWithTildes(newstring);
1435                 MemFree(string);
1436                 MemFree(newstring);
1437         } else if ((string=GetPDBBlock(ajp, gbp)) != NULL) {
1438                 newstring = CheckEndPunctuation(string, '.');
1439                 NewContLine();
1440                 ff_AddStringWithTildes(newstring);
1441                 MemFree(string);
1442                 MemFree(newstring);
1443         } else if (CheckSPBlock(ajp, gbp) == TRUE) {
1444                 NewContLine();
1445                 PrintSPBlock(ajp, gbp); 
1446                 MemFree(string);
1447         } else if ((string=GetPIRBlock(ajp, gbp)) != NULL) {
1448                 newstring = CheckEndPunctuation(string, '.');
1449                 NewContLine();
1450                 ff_AddStringWithTildes(newstring);
1451                 MemFree(string);
1452                 MemFree(newstring);
1453         }
1454 
1455         ff_EndPrint();
1456 
1457 }       /* PrintDBSourceLine */
1458 
1459 
1460 /********************************************************************
1461 *
1462 *       Look for database id's for the DBSource line.  Look first if
1463 *       there's a CDS; if so get the nucleotide id and check if it's
1464 *       unique. 
1465 *
1466 *
1467 *******************************************************************/
1468 
1469 static ValNodePtr GetDBSourceForNuclDB (Asn2ffJobPtr ajp, GBEntryPtr gbp)
1470 {
1471         BioseqPtr bsp;
1472         Int2 index, total_feats;
1473         SeqFeatPtr sfp_in;
1474         SeqIdPtr sid, id = NULL;
1475         SeqLocPtr location, tmp;
1476         ValNodePtr list=NULL, vnp;
1477         SortStructPtr p;
1478  
1479         if (gbp == NULL || gbp->feat == NULL) {
1480                 return NULL;
1481         }
1482         total_feats=gbp->feat->sfpListsize;
1483         p = gbp->feat->List;
1484         for (index=0; index < total_feats; index++, p++) {
1485                 if ((sfp_in = p->sfp) == NULL) {
1486                         GatherItemWithLock(p->entityID, p->itemID, p->itemtype, 
1487                                                                         &sfp_in, find_item);
1488                 }
1489                 if (sfp_in == NULL) {
1490                         continue;
1491                 }
1492                 if (sfp_in->data.choice == SEQFEAT_CDREGION) {
1493                         location = sfp_in->location;
1494                         tmp = NULL;
1495                         while ((tmp = SeqLocFindNext(location, tmp)) != NULL) {
1496                                 sid = SeqLocId(tmp);
1497                                 list = AddToUniqueList(sid, list);
1498                         }
1499                 }
1500         }
1501 
1502 /* If list is still NULL, then there was (probably) no CDS and this is
1503 a "gibbsq" protein (from the backbone).  Use the bsp->id of the protein
1504 itself. */
1505         if (list == NULL) {
1506                 if ((bsp = ajp->asn2ffwep->seg) != NULL)
1507                 {
1508                         sid = SeqIdSelect(bsp->id, fasta_order, NUM_SEQID);
1509                         if (sid->choice == SEQID_GIBBMT) 
1510                                 ValNodeAddPointer(&list, 0, bsp->id);   
1511                 }
1512                 bsp = gbp->bsp;
1513                 ValNodeAddPointer(&list, 0, bsp->id);   
1514         }
1515 
1516 /* Look for a bsp associated with this id and select the best id from
1517 bsp->id.  If no bsp, keep the id that was found above by SeqLocId. */
1518         for (vnp=list; vnp; vnp=vnp->next) {
1519                 id = vnp->data.ptrvalue;
1520                 bsp = BioseqFindCore(id);
1521                 if (bsp) {
1522                         sid = SeqIdSelect(bsp->id, fasta_order, NUM_SEQID);
1523                         vnp->data.ptrvalue = sid;
1524                 } else if (id && id->choice == SEQID_GI) {
1525                         if ((sid = GetSeqIdForGI(id->data.intvalue)) != NULL)
1526                                 vnp->data.ptrvalue = sid;
1527                 }
1528                 
1529         }
1530         return list;
1531 }
1532 
1533 /***********************************************************************
1534 *ValNodePtr AddToUniqueList(SeqIdPtr sid, ValNodePtr list)
1535 *
1536 *
1537 *       Checks that the SeqIdPtr is not already present in the list
1538 *       and adds it if it is not.
1539 ***********************************************************************/
1540 
1541 static ValNodePtr AddToUniqueList(SeqIdPtr sid, ValNodePtr list)
1542 
1543 {
1544         Boolean present=FALSE;
1545         ValNodePtr vnp;
1546 
1547         if (sid == NULL)        /* A sid of NULL doesn't work here */
1548                 return list;
1549 
1550         for (vnp=list; vnp; vnp=vnp->next)
1551         {
1552                 if (SeqIdMatch (sid, (SeqIdPtr) vnp->data.ptrvalue) == TRUE)
1553                 {
1554                         present = TRUE;
1555                         break;
1556                 }
1557         }
1558 
1559         if (present == FALSE)
1560                 vnp = ValNodeAddPointer(&list, 0, sid); 
1561 
1562         if (list == NULL)
1563                 list = vnp;
1564 
1565         return list;
1566 }
1567 
1568 
1569 /*********************************************************************
1570 *       Int4 GetGibbsqNumber (BioseqPtr bsp)
1571 *
1572 *       returns the gibbsq id if a backbone record, otherwise 0.
1573 *
1574 *************************************************************************/
1575 
1576 NLM_EXTERN Int4 GetGibbsqNumber (BioseqPtr bsp)
1577 {
1578         Int4 gibbsq=0;
1579         SeqIdPtr sip;
1580 
1581         for (sip=bsp->id; sip; sip=sip->next)
1582         {
1583                 if (sip->choice == SEQID_GIBBSQ)
1584                         gibbsq = sip->data.intvalue;
1585         }
1586 
1587         return gibbsq;
1588 }
1589 
1590 NLM_EXTERN Int4 GetGibbsqCommentLength(GBEntryPtr gbp)
1591 {
1592         Int4 gibbsq=0, total;
1593         PubdescPtr pdp;
1594         PubStructPtr psp;
1595         ValNodePtr vnp1;
1596 
1597         total = 0;
1598         for (vnp1=gbp->Pub; vnp1; vnp1=vnp1->next) {
1599                 psp = vnp1->data.ptrvalue;
1600                 if ((pdp=psp->descr) != NULL) {
1601                         if (pdp->fig) {
1602                                 total += 30;
1603                                 total += StringLen(pdp->fig);
1604                         }
1605                         if (pdp->poly_a)
1606                                 total += 85;
1607                         if (pdp->maploc) {
1608                                 total += 20;
1609                                 total += StringLen(pdp->maploc);
1610                         }
1611                 }
1612         }
1613         return total;
1614 }
1615 
1616 /**************************************************************************
1617 *       CharPtr GetGibbsqComment (GBEntryPtr gbp)
1618 *
1619 *       This function determines whether the entry was a backbone entry
1620 *       and generates a message if it was.  The CharPtr needs to be
1621 *       deleted by the caller.
1622 **************************************************************************/
1623 
1624 NLM_EXTERN CharPtr GetGibbsqComment(GBEntryPtr gbp)
1625 
1626 {
1627         CharPtr ptr, temp;
1628         Int4 gibbsq=0, length, total;
1629         PubdescPtr pdp;
1630         PubStructPtr psp;
1631         ValNodePtr vnp1;
1632 
1633         gibbsq = GetGibbsqNumber(gbp->bsp);
1634 
1635         if (gibbsq > 0) {
1636                 total = GetGibbsqCommentLength(gbp);
1637 
1638                 ptr = (CharPtr) MemNew((size_t) total*sizeof(Char));
1639                 for (vnp1=gbp->Pub; vnp1; vnp1=vnp1->next) {
1640                         psp = vnp1->data.ptrvalue;
1641                         if ((pdp=psp->descr) != NULL) {
1642                                 if (pdp->fig) {
1643                                         temp = CheckEndPunctuation(pdp->fig, '.');
1644                                         length = StringLen(ptr);
1645                                         sprintf(ptr+length, "~This sequence comes from %s", temp);
1646                                         temp = MemFree(temp);
1647                                 } if (pdp->poly_a) {
1648                                         length = StringLen(ptr);
1649                                         sprintf(ptr+length, "~Polyadenylate residues occurring in the figure were omitted from the sequence.");
1650                                 } if (pdp->maploc) {
1651                                         temp = CheckEndPunctuation(pdp->maploc, '.');
1652                                         length = StringLen(ptr);
1653                                         sprintf(ptr+length, "~Map location: %s", temp);
1654                                         temp = MemFree(temp);
1655                                 }
1656                         }
1657                 }
1658                 return ptr;     /* gibbsq found */
1659         }
1660         return NULL;    /* gibbsq was zero */
1661 
1662 }       /* GetGibbsqComment */
1663 
1664 /**************************************************************************
1665 *       CharPtr GetGibbsqStatement(GBEntryPtr gbp, CharPtr ptr)
1666 *
1667 *       This function determines whether the entry was a backbone entry
1668 *       and generates a message if it was.  The caller needs to 
1669 *       include a Char array of 150 characters.
1670 **************************************************************************/
1671 
1672 NLM_EXTERN Int4 GetGibbsqStatement(GBEntryPtr gbp, CharPtr ptr)
1673 
1674 {
1675         Int4 gibbsq=0;
1676 
1677         gibbsq = GetGibbsqNumber(gbp->bsp);
1678 
1679         if (gibbsq > 0)
1680         {
1681                 sprintf(ptr, "GenBank staff at the National Library of Medicine created this entry [NCBI gibbsq %ld] from the original journal article.", (long) gibbsq);
1682         }
1683         return gibbsq;  
1684 
1685 }       /* GetGibbsqStatement */
1686 
1687 /***************************************************************************
1688 *PrintComment
1689 *
1690 ***************************************************************************/
1691 
1692 NLM_EXTERN void PrintComment (CharPtr string, Boolean identifier, Uint1 format)
1693 
1694 {
1695         if (string != NULL)
1696         {
1697                 if (format == EMBL_FMT || format == PSEUDOEMBL_FMT ||
1698                         format == EMBLPEPT_FMT) {
1699                         if (identifier == TRUE)
1700                                 PrintXX();
1701                         ff_StartPrint(5, 5, ASN2FF_EMBL_MAX, "CC");
1702                 } else {
1703                         ff_StartPrint(0, 12, ASN2FF_GB_MAX, NULL);
1704                         if (identifier == TRUE)
1705                                 ff_AddString("COMMENT");
1706                         TabToColumn(13);
1707                 }
1708 
1709                 ff_AddStringWithTildes(string);
1710         
1711                 ff_EndPrint();
1712         }
1713 
1714         return;
1715 }       /* PrintComment */
1716 
1717 NLM_EXTERN void GetGBDate (Asn2ffJobPtr ajp, GBEntryPtr gbp)
1718 {
1719         Char buffer[12];
1720         Int2 status;
1721 
1722         status = GetGenDate(ajp, gbp, buffer);
1723         if (status != -1)
1724         {
1725                 StringNCpy(gbp->date, buffer, 11);
1726         }
1727         else 
1728         { /* Nothing work, use something */
1729                 StringCpy(gbp->date, "01-JAN-1900");
1730                 if (ASN2FF_SHOW_ERROR_MSG == TRUE && ASN2FF_DATE_ERROR_MSG == TRUE)
1731                 {
1732                         ErrPostStr (SEV_WARNING, ERR_DATE_IllegalDate, 
1733                                 "GetGBDate: No string or std date found");
1734                 }
1735         }
1736         return;
1737 }
1738 
1739 NLM_EXTERN void GetGPDate (Asn2ffJobPtr ajp, GBEntryPtr gbp)
1740 {
1741         Char buffer[12];
1742         Int2 status;
1743 
1744         status = GetGenDate(ajp, gbp, buffer);
1745         if (status != -1)
1746         {
1747                 StringNCpy(gbp->date, buffer, 11);
1748         } else {
1749                 status = GetGenDate(ajp, NULL, buffer);
1750                 if (status != -1)
1751                 {
1752                         StringNCpy(gbp->date, buffer, 11);
1753                 }
1754         }
1755 
1756         if (status == -1)
1757         { 
1758                 StringCpy(gbp->date, "01-JAN-1900");
1759                 if (ASN2FF_SHOW_ERROR_MSG == TRUE && ASN2FF_DATE_ERROR_MSG == TRUE)
1760                 {
1761                         ErrPostStr (SEV_WARNING, ERR_DATE_IllegalDate, 
1762                                 "GetGPDate: No string or std date found");
1763                 }
1764         }
1765 
1766         return;
1767 }
1768 
1769 static Boolean get_descr_vnp (GatherContextPtr gcp)
1770 {
1771 /* find only one (last!) vnp with given choice */
1772         ValNodePtr      tmp, vnp;
1773         DescrStructPtr  PNTR dspp;
1774         DescrStructPtr  dsp;
1775         
1776         dspp = gcp->userdata;
1777         dsp = *dspp;
1778         vnp = dsp->vnp;
1779         switch (gcp->thistype)
1780         {
1781                 case OBJ_SEQDESC:
1782                         tmp = (ValNodePtr) (gcp->thisitem);
1783                         if (tmp->choice == vnp->choice) {
1784                                 if (tmp->data.ptrvalue != NULL) {
1785                                         dsp->vnp = tmp;
1786                                         dsp->entityID = gcp->entityID;
1787                                         dsp->itemID = gcp->itemID;
1788                                         dsp->itemtype = gcp->thistype;
1789                                         *dspp = dsp;
1790                                 }
1791                         } 
1792                         break;
1793                 default:
1794                         break;
1795         }
1796         return TRUE;
1797 }
1798 
1799 static Boolean get_descr_list (GatherContextPtr gcp)
1800 {
1801         ValNodePtr      tmp, vnp, vv, v, v_new;
1802         ValNodePtr      PNTR vnpp;
1803         DescrStructPtr dsp, new_dsp;
1804         
1805         vnpp = gcp->userdata;
1806         vnp = *vnpp;
1807         dsp = vnp->data.ptrvalue;
1808         switch (gcp->thistype)
1809         {
1810                 case OBJ_SEQDESC:
1811                         tmp = (ValNodePtr) (gcp->thisitem);
1812                         if (tmp->choice == dsp->vnp->choice) {
1813                                 v_new = ValNodeNew(NULL);
1814                                 v_new = MemCopy(v_new, tmp, sizeof(ValNode));
1815                                 v_new->next = NULL;
1816                                 if (dsp->vnp->data.ptrvalue == NULL) {
1817                                         ValNodeFree(dsp->vnp);
1818                                         dsp->vnp = v_new;
1819                                         dsp->entityID = gcp->entityID;
1820                                         dsp->itemID = gcp->itemID;
1821                                         dsp->itemtype = gcp->thistype;
1822                                 } else {
1823                                         for (v = *vnpp; v; v=v->next) {
1824                                                 dsp = v->data.ptrvalue;
1825                                                 if (dsp->vnp->data.ptrvalue == v_new->data.ptrvalue) {
1826                                                     ValNodeFree(v_new);
1827                                                     return TRUE;
1828                                                 }
1829                                         }
1830                                         new_dsp = (DescrStructPtr) MemNew(sizeof(DescrStruct));
1831                                         new_dsp->vnp = v_new;
1832                                         new_dsp->entityID = gcp->entityID;
1833                                         new_dsp->itemID = gcp->itemID;
1834                                         new_dsp->itemtype = gcp->thistype;
1835                                         vv = ValNodeNew(NULL);
1836                                         vv->data.ptrvalue = new_dsp;
1837                                         *vnpp = tie_next(*vnpp, vv);
1838                                 }
1839                                 return TRUE;
1840                         } 
1841                         break;
1842                 default:
1843                         break;
1844         }
1845         return TRUE;
1846 }
1847 
1848 
1849 NLM_EXTERN ValNodePtr GatherDescrByChoice(Asn2ffJobPtr ajp, GBEntryPtr gbp, Uint1 choice)
1850 {
1851         ValNodePtr vnp0, vnp;
1852 
1853         GatherScope gsc;
1854         BioseqPtr bsp;
1855         SeqLocPtr slp = NULL;
1856         Uint2 bspID;
1857         DescrStructPtr dsp;
1858 
1859         vnp = ValNodeNew(NULL);
1860         vnp->choice = choice;
1861         vnp0 = vnp;
1862         dsp = MemNew(sizeof(DescrStruct));
1863         dsp->vnp = vnp0;
1864         MemSet ((Pointer) (&gsc), 0, sizeof (GatherScope));
1865         MemSet ((Pointer) (gsc.ignore), (int)(TRUE), (size_t) (OBJ_MAX * sizeof(Boolean)));
1866         gsc.ignore[OBJ_SEQDESC] = FALSE;
1867         if (gbp && gbp->bsp != NULL) {
1868                 bsp = gbp->bsp;
1869                 bspID = ObjMgrGetEntityIDForPointer(bsp);
1870                 slp = ValNodeNew(NULL);
1871                 slp->choice = SEQLOC_WHOLE;
1872                 slp->data.ptrvalue = (SeqIdPtr) SeqIdDup (SeqIdFindBest (bsp->id, 0));
1873                 gsc.target = slp;
1874         } else {
1875                 gsc.target = NULL;
1876         }
1877         if (ajp->sep && ajp->sep->choice == 1) {
1878                 if (ajp->only_one || ajp->genome_view) {
1879                         gsc.target = NULL;
1880                 }
1881         }
1882         GatherEntity(ajp->entityID, &dsp, get_descr_vnp, &gsc); 
1883         if (slp) {
1884                 SeqLocFree(slp);
1885         }
1886         vnp = dsp->vnp;
1887         if (vnp && vnp->data.ptrvalue) {
1888                 ValNodeFree(vnp0);
1889                 if (gbp) {
1890                         gbp->descr = tie_next_dsp(gbp->descr, dsp);
1891                 } else {
1892                         MemFree(dsp);
1893                 }
1894                 return vnp;
1895         }
1896         ValNodeFree(vnp0);
1897         MemFree(dsp);
1898         return NULL;
1899 }
1900 
1901 NLM_EXTERN ValNodePtr GatherDescrListByChoice(Asn2ffJobPtr ajp, GBEntryPtr gbp, Uint1 choice)
1902 {
1903         ValNodePtr vnp0, vnp, ds_vnp;
1904 
1905         GatherScope gsc;
1906         BioseqPtr bsp;
1907         SeqLocPtr slp = NULL;
1908         DescrStructPtr dsp;
1909 
1910         vnp = ValNodeNew(NULL);
1911         vnp->choice = choice;
1912         vnp0 = vnp;
1913         dsp = MemNew(sizeof(DescrStruct));
1914         dsp->vnp = vnp0;
1915         ds_vnp = ValNodeNew(NULL);
1916         ds_vnp->data.ptrvalue = dsp;
1917         MemSet ((Pointer) (&gsc), 0, sizeof (GatherScope));
1918         gsc.get_feats_location = TRUE;
1919         MemSet ((Pointer) (gsc.ignore), (int)(TRUE), (size_t) (OBJ_MAX * sizeof(Boolean)));
1920         gsc.ignore[OBJ_SEQDESC] = FALSE;
1921         if (gbp && gbp->bsp != NULL) {
1922                 bsp = gbp->bsp; 
1923                 slp = ValNodeNew(NULL);
1924                 slp->choice = SEQLOC_WHOLE;
1925                 slp->data.ptrvalue = (SeqIdPtr) SeqIdDup (SeqIdFindBest (bsp->id, 0));
1926                 gsc.target = slp;
1927         } else {
1928                 gsc.target = NULL;
1929         }
1930         GatherEntity(ajp->entityID, &ds_vnp, get_descr_list, &gsc); 
1931         if (slp) {
1932                 SeqLocFree(slp);
1933         }
1934         dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
1935         vnp = dsp->vnp;
1936         if (vnp && vnp->data.ptrvalue) {
1937                 return ds_vnp;
1938         }
1939         ValNodeFree(vnp0);
1940         ValNodeFreeData(ds_vnp);
1941         return NULL;
1942 }
1943 
1944 NLM_EXTERN Int2 GetGenDate(Asn2ffJobPtr ajp, GBEntryPtr gbp, CharPtr buffer)
1945 {
1946 
1947         EMBLBlockPtr ebp=NULL;
1948         GBBlockPtr gblp=NULL;
1949         Int2 date_choice, status;
1950         NCBI_DatePtr date=NULL, best_update_date=NULL, best_create_date=NULL;
1951         SPBlockPtr spp=NULL;
1952         PdbBlockPtr pbp=NULL;
1953         PdbRepPtr prp=NULL;
1954         ValNodePtr vnp;
1955 
1956         date_choice = -1;
1957         if (gbp) {
1958                 gbp->descr = NULL;
1959         }
1960         if ((vnp=GatherDescrByChoice(ajp, gbp, Seq_descr_update_date)) != NULL) {
1961                 if (gbp && gbp->descr) {
1962                         gbp->descr = MemFree(gbp->descr);
1963                 }
1964                 date = (NCBI_DatePtr) vnp->data.ptrvalue;
1965                 if (date->data[0] == 1) {
1966                         if (best_update_date) {
1967                                 status = DateMatch(date, best_update_date, FALSE);
1968                                 if (status == 1) {
1969                                         best_update_date = date; 
1970                                 }
1971                         } else {
1972                                 best_update_date = date;
1973                         }
1974                 }
1975         }
1976 
1977         if ((vnp=GatherDescrByChoice(ajp, gbp, Seq_descr_embl)) != NULL) {
1978         /*      ebp possibly used again below. */
1979                 if (gbp && gbp->descr) {
1980                         gbp->descr = MemFree(gbp->descr);
1981                 }
1982                 ebp = (EMBLBlockPtr) vnp->data.ptrvalue;
1983                 if (ebp->update_date != NULL)
1984                 {
1985                         if (ebp->update_date->data[0] == 1)
1986                         {
1987                                 date = (NCBI_DatePtr) ebp->update_date;
1988                                 if (best_update_date) {
1989                                      status = DateMatch(date, best_update_date, FALSE);
1990                                      if (status == 1) {
1991                                         best_update_date = date; }
1992                                 } else {
1993                                         best_update_date = date; }
1994                         }
1995                 }
1996         }
1997 
1998         if ((vnp=GatherDescrByChoice(ajp, gbp, Seq_descr_sp)) != NULL) {
1999          /*     spp possibly used again below. */
2000                 if (gbp && gbp->descr) {
2001                         gbp->descr = MemFree(gbp->descr);
2002                 }
2003                 spp = (SPBlockPtr) vnp->data.ptrvalue;
2004                 if (spp->sequpd != NULL && spp->sequpd->data[0] == 1)
2005                 {
2006                         date = (NCBI_DatePtr) spp->sequpd;
2007                         if (best_update_date) {
2008                              status = DateMatch(date, best_update_date, FALSE);
2009                              if (status == 1) {
2010                                 best_update_date = date; }
2011                         } else {
2012                                 best_update_date = date; }
2013                 }
2014                 if (spp->annotupd != NULL && spp->annotupd->data[0] == 1)
2015                 {
2016                         date = (NCBI_DatePtr) spp->annotupd;
2017                         if (best_update_date) {
2018                              status = DateMatch(date, best_update_date, FALSE);
2019                              if (status == 1) {
2020                                 best_update_date = date; }
2021                         } else {
2022                                 best_update_date = date; }
2023                 }
2024         }
2025 
2026         if ((vnp=GatherDescrByChoice(ajp, gbp, Seq_descr_pdb)) != NULL) {
2027          /* pbp possibly used again below. */
2028                 if (gbp && gbp->descr) {
2029                         gbp->descr = MemFree(gbp->descr);
2030                 }
2031                 pbp = (PdbBlockPtr) vnp->data.ptrvalue;
2032                 if ((prp = pbp->replace) != NULL && prp->date != NULL && prp->date->data[0] == 1)
2033                 {
2034                         date = (NCBI_DatePtr) prp->date;
2035                         if (best_update_date) {
2036                              status = DateMatch(date, best_update_date, FALSE);
2037                              if (status == 1) {
2038                                 best_update_date = date; }
2039                         } else {
2040                                 best_update_date = date; }
2041                 }
2042         }
2043 
2044         if ((vnp=GatherDescrByChoice(ajp, gbp, Seq_descr_create_date)) != NULL) {
2045                 date = (NCBI_DatePtr) vnp->data.ptrvalue;
2046                 if (gbp && gbp->descr) {
2047                         gbp->descr = MemFree(gbp->descr);
2048                 }
2049                 if (date->data[0] == 1) {
2050                         if (best_create_date) {
2051                                 status = DateMatch(date, best_create_date, FALSE);
2052                                 if (status == 1) {
2053                                         best_create_date = date;
2054                                 }
2055                         } else {
2056                                 best_create_date = date;
2057                         }
2058                 }
2059         }
2060 
2061         if ((vnp=GatherDescrByChoice(ajp, gbp, Seq_descr_genbank)) != NULL) {
2062                 gblp = (GBBlockPtr) vnp->data.ptrvalue;
2063                 if (gbp && gbp->descr) {
2064                         gbp->descr = MemFree(gbp->descr);
2065                 }
2066                 if (gblp->entry_date != NULL ) {
2067                         if (gblp->entry_date->data[0] == 1)
2068                         {
2069                                 date = gblp->entry_date;
2070                                 if (best_create_date) {
2071                                      status = DateMatch(date, best_create_date, FALSE);
2072                                      if (status == 1) {
2073                                         best_create_date = date; }
2074                                 } else {
2075                                         best_create_date = date; }
2076                         }
2077                 }
2078         }
2079 
2080         if (ebp) /* EMBLBlockPtr found above */
2081         {
2082                 if (ebp->creation_date != NULL && ebp->creation_date->data[0] == 1) {
2083                         date = ebp->creation_date;
2084                         if (best_create_date) {
2085                              status = DateMatch(date, best_create_date, FALSE);
2086                              if (status == 1) {
2087                                 best_create_date = date; }
2088                         } else {
2089                                 best_create_date = date; }
2090                 }
2091         }
2092 
2093         if (spp) /* SPBlockPtr found above */
2094         {
2095                 if (spp->created != NULL && spp->created->data[0] == 1) {
2096                         date = spp->created;
2097                         if (best_create_date) {
2098                                 status = DateMatch(date, best_create_date, FALSE);
2099                                 if (status == 1) {
2100                                         best_create_date = date;
2101                                 }
2102                         } else {
2103                                 best_create_date = date;
2104                         }
2105                 }
2106         }
2107 
2108         if (pbp) {
2109                 if (pbp->deposition != NULL && pbp->deposition->data[0] == 1) {
2110                         date = pbp->deposition;
2111                         if (best_create_date) {
2112                                 status = DateMatch(date, best_create_date, FALSE);
2113                                 if (status == 1) {
2114                                         best_create_date = date;
2115                                 }
2116                         } else {
2117                                 best_create_date = date;
2118                         }
2119                 }
2120         }
2121 
2122         if (best_update_date || best_create_date) {
2123                 date_choice = 1;
2124         } else {
2125                 date = NULL;
2126                 if ((vnp=GatherDescrByChoice(ajp, gbp, Seq_descr_update_date)) != NULL) {
2127                 if (gbp && gbp->descr) {
2128                         gbp->descr = MemFree(gbp->descr);
2129                 }
2130                         date = (NCBI_DatePtr) vnp->data.ptrvalue;
2131                         if (date->data[0] == 0)
2132                                 best_update_date = date; 
2133                 }
2134 
2135                 if (!best_update_date && ebp)
2136                         if (ebp->update_date != NULL && ebp->update_date->data[0] == 0)
2137                                 best_update_date = (NCBI_DatePtr) ebp->update_date;
2138 
2139                 if (!best_update_date && spp) {
2140                         if (spp->sequpd != NULL && spp->sequpd->data[0] == 0) {
2141                                 best_update_date = (NCBI_DatePtr) spp->sequpd;
2142                         }
2143                         else if (spp->annotupd != NULL && spp->annotupd->data[0] == 0) {
2144                                 best_update_date = (NCBI_DatePtr) spp->annotupd;
2145                         }
2146                 }
2147 
2148                 if (!best_update_date && prp)
2149                         if (prp->date && prp->date->data[0] == 0)
2150                                 best_update_date = (NCBI_DatePtr) prp->date;
2151 
2152                 if (!best_update_date &&
2153                         (vnp=GatherDescrByChoice(ajp, gbp, Seq_descr_create_date)) != NULL) {
2154                         gbp->descr = MemFree(gbp->descr);
2155                         date = (NCBI_DatePtr) vnp->data.ptrvalue;
2156                         if (date->data[0] == 0) {
2157                                 best_create_date = date;
2158                         }
2159                 }
2160 
2161                 if (!best_update_date && gblp)
2162                         if (gblp->entry_date && gblp->entry_date->data[0] == 0)
2163                                 best_update_date = gblp->entry_date;
2164 
2165                 if (!best_create_date && ebp) /* EMBLBlockPtr found above */ {
2166                         if (ebp->creation_date && ebp->creation_date->data[0] == 0)
2167                                 best_create_date = ebp->creation_date;
2168                 }
2169 
2170                 if (!best_create_date && spp) /* SPBlockPtr found above */ {
2171                         if (spp->created && spp->created->data[0] == 0)
2172                                 best_create_date = spp->created;
2173                 }
2174 
2175                 if (!best_create_date && pbp) /* PDB Block found above */ {
2176                         if (pbp->deposition && pbp->deposition->data[0] == 0)
2177                                 best_create_date = pbp->deposition;
2178                 }
2179                 if (best_update_date || best_create_date)
2180                         date_choice = 0;
2181         }
2182 
2183         if (date_choice == 1) {
2184                 if (best_update_date && best_create_date) {
2185                         status = DateMatch(best_update_date, best_create_date, FALSE);
2186                         if (status == 0 || status == 1) {
2187                                 buffer = DateToGB(buffer, best_update_date);
2188                         } else {
2189                                 buffer = DateToGB(buffer, best_create_date);
2190                                 if (ASN2FF_SHOW_ERROR_MSG == TRUE && 
2191                                                                                 ASN2FF_DATE_ERROR_MSG == TRUE) {
2192                                         ErrPostStr(SEV_WARNING, ERR_DATE_Create_after_update, 
2193                                                         "GetGBDate: std create date after update date");
2194                                 }
2195                         }
2196                 } else if (best_update_date) {
2197                         buffer = DateToGB(buffer, best_update_date);
2198                 } else if (best_create_date) {
2199                         buffer = DateToGB(buffer, best_create_date);
2200                 }
2201         } else if (date_choice == 0)  {
2202                 if (best_update_date) {
2203                         StringNCpy(buffer, best_update_date->str, 11);
2204                         gbp->date[11]='\0';
2205                         if (ASN2FF_SHOW_ERROR_MSG == TRUE && ASN2FF_DATE_ERROR_MSG == TRUE){
2206                                 ErrPostStr(SEV_INFO, ERR_DATE_IllegalDate, 
2207                                         "GetGBDate: Only string update date found");
2208                         }
2209                 }  else if (best_create_date)  {
2210                         StringNCpy(buffer, best_create_date->str, 11);
2211                         buffer[11]='\0';
2212                         if (ASN2FF_SHOW_ERROR_MSG == TRUE && ASN2FF_DATE_ERROR_MSG == TRUE){
2213                                 ErrPostStr(SEV_INFO, ERR_DATE_IllegalDate, 
2214                                         "GetGBDate: Only string create date found");
2215                         }
2216                 }
2217         }
2218         
2219         return date_choice;
2220 }       /* GetGenDate */
2221 
2222 NLM_EXTERN void GetEMBLDate (Asn2ffJobPtr ajp, GBEntryPtr gbep)
2223 
2224 {
2225 
2226         Char buf_update[12], buf_create[12];
2227         EMBLBlockPtr ebp=NULL;
2228         GBBlockPtr gbp=NULL;
2229         Int2 status;
2230         NCBI_DatePtr date=NULL, best_update_date=NULL, best_create_date=NULL;
2231         SPBlockPtr spp=NULL;
2232         PdbBlockPtr pbp=NULL;
2233         PdbRepPtr prp=NULL;
2234         ValNodePtr vnp, ds_vnp, tvnp;
2235         DescrStructPtr dsp;
2236 
2237         buf_create[0] = '\0';
2238         buf_update[0] = '\0';
2239 
2240         if (gbep) {
2241                 gbep->descr = NULL;
2242         }
2243         if ((vnp=GatherDescrByChoice(ajp, gbep, Seq_descr_update_date)) != NULL) {
2244                 date = (NCBI_DatePtr) vnp->data.ptrvalue;
2245                 if (date->data[0] == 1) {
2246                         if (best_update_date) {
2247                              status = DateMatch(date, best_update_date, FALSE);
2248                              if (status == 1) {
2249                                 best_update_date = date; }
2250                         } else {
2251                                 best_update_date = date; }
2252                 }
2253         }
2254 
2255         tvnp = GatherDescrListByChoice(ajp, gbep, Seq_descr_embl); 
2256         for (ds_vnp= tvnp;
2257                                 ds_vnp; ds_vnp=ds_vnp->next) {
2258                 dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
2259                 vnp = dsp->vnp; 
2260                 ebp = (EMBLBlockPtr) vnp->data.ptrvalue;
2261                 if (ebp->update_date != NULL) {
2262                         if (ebp->update_date->data[0] == 1) {
2263                                 date = (NCBI_DatePtr) ebp->update_date;
2264                                 if (best_update_date) {
2265                                      status = DateMatch(date, best_update_date, FALSE);
2266                                      if (status == 1) {
2267                                                 best_update_date = date; 
2268                                         }
2269                                 } else {
2270                                         best_update_date = date;
2271                                 }
2272                         }
2273                         gbep->descr = tie_next_dsp(gbep->descr, dsp);
2274                         break;
2275                 }
2276                 ValNodeFree(vnp);
2277         }
2278 /*      ValNodeFreeData(tvnp); */
2279 
2280         if ((vnp=GatherDescrByChoice(ajp, gbep, Seq_descr_sp)) != NULL) {
2281          /*     spp possibly used again below. */
2282                 spp = (SPBlockPtr) vnp->data.ptrvalue;
2283                 if (spp->sequpd != NULL && spp->sequpd->data[0] == 1) {
2284                         date = (NCBI_DatePtr) spp->sequpd;
2285                         if (best_update_date) {
2286                              status = DateMatch(date, best_update_date, FALSE);
2287                              if (status == 1) {
2288                                 best_update_date = date; }
2289                         } else {
2290                                 best_update_date = date; }
2291                 }
2292                 if (spp->annotupd != NULL && spp->annotupd->data[0] == 1) {
2293                         date = (NCBI_DatePtr) spp->annotupd;
2294                         if (best_update_date) {
2295                              status = DateMatch(date, best_update_date, FALSE);
2296                              if (status == 1) {
2297                                 best_update_date = date; }
2298                         } else {
2299                                 best_update_date = date; }
2300                 }
2301         }
2302 
2303         if ((vnp=GatherDescrByChoice(ajp, gbep, Seq_descr_pdb)) != NULL) {
2304          /* pbp possibly used again below. */
2305                 pbp = (PdbBlockPtr) vnp->data.ptrvalue;
2306                 if ((prp = pbp->replace) != NULL && prp->date != NULL && 
2307                                                                                         prp->date->data[0] == 1) {
2308                         date = (NCBI_DatePtr) prp->date;
2309                         if (best_update_date) {
2310                              status = DateMatch(date, best_update_date, FALSE);
2311                              if (status == 1) {
2312                                 best_update_date = date; }
2313                         } else {
2314                                 best_update_date = date; }
2315                 }
2316         }
2317 
2318         if ((vnp=GatherDescrByChoice(ajp, gbep, Seq_descr_create_date)) != NULL) {
2319                 date = (NCBI_DatePtr) vnp->data.ptrvalue;
2320                 if (date->data[0] == 1) {
2321                         if (best_create_date) {
2322                              status = DateMatch(date, best_create_date, FALSE);
2323                              if (status == 1) {
2324                                 best_create_date = date; }
2325                         } else {
2326                                 best_create_date = date; }
2327                 }
2328         }
2329 
2330         tvnp = GatherDescrListByChoice(ajp, gbep, Seq_descr_genbank); 
2331         for (ds_vnp= tvnp;
2332                                 ds_vnp; ds_vnp=ds_vnp->next) {
2333                 dsp = (DescrStructPtr) ds_vnp->data.ptrvalue;
2334                 if ((vnp = dsp->vnp) == NULL)
2335                         continue; 
2336                 gbp = (GBBlockPtr) vnp->data.ptrvalue;
2337                 if (gbp->entry_date != NULL ) {
2338                         if (gbp->entry_date->data[0] == 1) {
2339                                 date = gbp->entry_date;
2340                                 if (best_create_date) {
2341                                      status = DateMatch(date, best_create_date, FALSE);
2342                                      if (status == 1) {
2343                                         best_create_date = date; }
2344                                 } else {
2345                                         best_create_date = date; }
2346                         }
2347                         gbep->descr = tie_next_dsp(gbep->descr, dsp);
2348                         break;
2349                 }
2350                 MemFree(vnp);
2351         }
2352         ValNodeFreeData(tvnp);
2353 
2354         if (ebp) {/* EMBLBlockPtr found above */
2355                 if (ebp->creation_date != NULL && ebp->creation_date->data[0] == 1) {
2356                         date = ebp->creation_date;
2357                         if (best_create_date) {
2358                              status = DateMatch(date, best_create_date, FALSE);
2359                              if (status == 1) {
2360                                 best_create_date = date; }
2361                         } else {
2362                                 best_create_date = date; }
2363                 }
2364         }
2365 
2366         if (spp) { /* SPBlockPtr found above */
2367                 if (spp->created != NULL && spp->created->data[0] == 1) {
2368                         date = spp->created;
2369                         if (best_create_date) {
2370                                 status = DateMatch(date, best_create_date, FALSE);
2371                                 if (status == 1) {
2372                                         best_create_date = date;
2373                                 }
2374                         } else {
2375                                 best_create_date = date;
2376                         }
2377                 }
2378         }
2379 
2380         if (pbp){  /* PDB Block found above */
2381                 if (pbp->deposition != NULL && pbp->deposition->data[0] == 1) {
2382                         date = pbp->deposition;
2383                         if (best_create_date) {
2384                                 status = DateMatch(date, best_create_date, FALSE);
2385                                 if (status == 1) {
2386                                         best_create_date = date;
2387                                 }
2388                         } else {
2389                                 best_create_date = date;
2390                         }
2391                 }
2392         }
2393 
2394         if (best_update_date)
2395                 DateToGB(buf_update, best_update_date);
2396         if (best_create_date)
2397                 DateToGB(buf_create, best_create_date);
2398 
2399         if (buf_create[0] == '\0') {
2400                 if (!best_create_date && ebp) { /* EMBLBlockPtr found above */
2401                         if (ebp->creation_date && ebp->creation_date->data[0] == 0)
2402                                 best_create_date = ebp->creation_date;
2403                 }
2404 
2405                 if (!best_create_date && spp) { /* SPBlockPtr found above */
2406                         if (spp->created && spp->created->data[0] == 0)
2407                                 best_create_date = spp->created;
2408                 }
2409 
2410                 if (!best_create_date && pbp) { /* PDB Block found above */
2411                         if (pbp->deposition && pbp->deposition->data[0] == 0)
2412                                 best_create_date = pbp->deposition;
2413                 }
2414                 if (best_create_date) {
2415                         StringNCpy(buf_create, best_create_date->str, 11);
2416                         buf_create[11]='\0';
2417                         if (ASN2FF_SHOW_ERROR_MSG == TRUE && ASN2FF_DATE_ERROR_MSG == TRUE) 
2418                         {
2419                                 ErrPostStr(SEV_INFO, ERR_DATE_IllegalDate, 
2420                                         "GetEMBLDate: Only string create date found");
2421                         }
2422                 } else {
2423                         StringCpy(buf_create, "01-JAN-1900");
2424                         if (ASN2FF_SHOW_ERROR_MSG == TRUE && ASN2FF_DATE_ERROR_MSG == TRUE)
2425                         {
2426                                 ErrPostStr(SEV_INFO, ERR_DATE_IllegalDate, 
2427                                         "GetEMBLDate: No string or std create date found");
2428                         }
2429                 }
2430         }
2431 
2432         if (buf_update[0] == '\0') {
2433                 date = NULL;
2434                 if ((vnp=
2435                         GatherDescrByChoice(ajp, gbep, Seq_descr_update_date)) != NULL){
2436                         date = (NCBI_DatePtr) vnp->data.ptrvalue;
2437                         if (date->data[0] == 0) {
2438                                 best_update_date = date;
2439                         } 
2440                 }
2441 
2442                 if (!best_update_date && ebp)
2443                         if (ebp->update_date != NULL && ebp->update_date->data[0] == 0)
2444                                 best_update_date = (NCBI_DatePtr) ebp->update_date;
2445 
2446                 if (!best_update_date && spp) {
2447                         if (spp->sequpd != NULL && spp->sequpd->data[0] == 0) {
2448                                 best_update_date = (NCBI_DatePtr) spp->sequpd;
2449                         } else if (spp->annotupd != NULL && spp->annotupd->data[0] == 0) {
2450                                 best_update_date = (NCBI_DatePtr) spp->annotupd;
2451                         }
2452                 }
2453 
2454                 if (!best_update_date && prp)
2455                         if (prp->date && prp->date->data[0] == 0)
2456                                 best_update_date = (NCBI_DatePtr) prp->date;
2457 
2458                 if (!best_update_date && (vnp=GatherDescrByChoice(ajp, gbep, 
2459                                                                         Seq_descr_create_date)) != NULL) {
2460                         date = (NCBI_DatePtr) vnp->data.ptrvalue;
2461                         if (date->data[0] == 0) {
2462                                 best_create_date = date;
2463                         }
2464                 }
2465 
2466                 if (!best_update_date && gbp) {
2467                         if (gbp->entry_date && gbp->entry_date->data[0] == 0) {
2468                                 best_update_date = gbp->entry_date;
2469                         }
2470                 }
2471 
2472                 if (best_update_date) {
2473                         StringNCpy(buf_update, best_update_date->str, 11);
2474                         buf_update[11]='\0';
2475                         if (ASN2FF_SHOW_ERROR_MSG == TRUE && ASN2FF_DATE_ERROR_MSG == TRUE)
2476                         {
2477                                 ErrPostStr(SEV_INFO, ERR_DATE_IllegalDate, 
2478                                         "GetEMBLDate: Only string update date found");
2479                         }
2480                 }
2481         }
2482 
2483 
2484         gbep->create_date = StringSave(buf_create);
2485         if (buf_update[0] != '\0')
2486                 gbep->update_date = StringSave(buf_update);
2487         
2488         return;
2489 
2490 }       /* GetEMBLDate */
2491 
2492 NLM_EXTERN void GetEntryVersion (GBEntryPtr gbp)
2493 {
2494         BioseqPtr bsp=gbp->bsp;
2495         SeqIdPtr isip, sip;
2496         TextSeqIdPtr tsip;
2497 
2498         isip = bsp->id;
2499 
2500         for (sip=isip; sip; sip=sip->next) {
2501                 if (sip->choice == SEQID_EMBL) {
2502                         tsip = (TextSeqIdPtr) sip->data.ptrvalue;
2503                         if (tsip->release)
2504                                 gbp->embl_rel = tsip->release;
2505                         if (tsip->version)
2506                                 gbp->embl_ver = tsip->version;
2507                 }
2508         }
2509 }       /* GetVersion */
2510 
2511 NLM_EXTERN CharPtr DateToGB (CharPtr buf, NCBI_DatePtr ndp)
2512 {
2513         static CharPtr month_names[] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
2514         "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
2515         };
2516 
2517         int month = 1,
2518                 day = 1,
2519                 year = 1900,
2520                 tens_place = 0; /* in case day is less than ten.        */
2521         
2522         if (ndp->data[0] == 0) {
2523                 StringCpy(buf, ndp->str);
2524         }  else if (ndp->data[0] == 1) {  /* std date */
2525                 year = 1900 + (int)(ndp->data[1]);
2526                 if (ndp->data[2] != 0)
2527                    month = (int)(ndp->data[2]);
2528                 if (ndp->data[3] != 0)
2529                         day = (int)(ndp->data[3]);
2530 
2531                 if (day < 10) {
2532                         sprintf(buf, "%ld%ld-%s-%ld", (long) tens_place, (long) day, 
2533                                                         month_names[month-1], (long) year);
2534                 } else {
2535                         sprintf(buf, "%ld-%s-%ld", 
2536                                 (long) day, month_names[month-1], (long) year);
2537                 }
2538         } else {
2539                 if (ASN2FF_SHOW_ERROR_MSG == TRUE && ASN2FF_DATE_ERROR_MSG == TRUE) {
2540                         ErrPostStr(SEV_WARNING, ERR_DATE_IllegalDate, 
2541                                                                 "Unknown Date type in DateToGB");
2542                 }
2543                 *buf = '\0';
2544         }
2545         return buf;
2546 }
2547 

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

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