1 /*   asn2ff5.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:  asn2ff5.c
27 *
28 * Author:  Karl Sirotkin, Tom Madden, Tatiana Tatusov
29 *
30 * Version Creation Date:   7/15/95
31 *
32 * $Revision: 6.13 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date     Name        Description of modification
39 * -------  ----------  -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44 
45 /*************************************
46 *
47  * $Log: asn2ff5.c,v $
48  * Revision 6.13  2002/01/29 12:37:21  kans
49  * restored year for unpublished records to minimize QA diffs
50  *
51  * Revision 6.12  2002/01/10 15:19:16  kans
52  * suppress year in unpublished citgen - this is new policy, and suppresses diffs against asn2gb
53  *
54  * Revision 6.11  2001/06/25 22:39:05  kans
55  * format_patent puts patent seqid in GenPept format
56  *
57  * Revision 6.10  2000/05/15 23:13:35  kans
58  * format_thesis forgot to add space for afp->affil
59  *
60  * Revision 6.9  1998/12/09 18:45:09  tatiana
61  * a bug fixed in GetAuthors()
62  *
63  * Revision 6.8  1998/06/17 21:41:24  tatiana
64  * Null pointer protection added to ValidatePub()
65  *
66  * Revision 6.7  1998/06/15 14:58:53  tatiana
67  * UNIX compiler warnings fixed
68  *
69  * Revision 6.6  1998/04/30 21:49:03  tatiana
70  * *** empty log message ***
71  *
72  * Revision 6.5  1998/03/09 21:45:04  tatiana
73  * changed format_book to skip empty authors
74  *
75  * Revision 6.4  1998/02/06 16:19:25  tatiana
76  * added std affiliation to format_thesis()
77  *
78  * Revision 6.3  1997/12/15 15:53:26  tatiana
79  * features processing has been changed
80  *
81  * Revision 6.1  1997/11/13 19:26:41  tatiana
82  * fixed Array bounds Write error in format_book()
83  *
84  * Revision 6.0  1997/08/25 18:05:02  madden
85  * Revision changed to 6.0
86  *
87  * Revision 5.20  1997/07/22 19:26:35  tatiana
88  * SeqIdFindBest(bsp->id, SEQID_GENBANK) added in CheckAndGetNAFeatLoc
89  *
90  * Revision 5.19  1997/07/16 21:55:43  vakatov
91  * Removed extraneous and DLL-harmful "extern NCBI_months[]" declaration
92  *
93  * Revision 5.18  1997/06/19 18:37:12  vakatov
94  * [WIN32,MSVC++]  Adopted for the "NCBIOBJ.LIB" DLL'ization
95  *
96  * Revision 5.17  1997/06/06 20:27:12  tatiana
97  * doSup changed
98  *
99  * Revision 5.16  1997/04/22  18:07:31  tatiana
100  * added a space between part and suppl in doSup()
101  *
102  * Revision 5.15  1997/02/25  23:45:41  tatiana
103  * line 1121: debugging printf removed
104  *
105  * Revision 5.14  1997/02/10  22:14:24  tatiana
106  * *** empty log message ***
107  *
108  * Revision 5.13  1997/01/27  19:15:10  tatiana
109  * *** empty log message ***
110  *
111  * Revision 5.12  1997/01/06  21:52:53  tatiana
112  * added check for zero patent_seqid in format_patent()
113  *
114  * Revision 5.11  1996/08/27  17:35:01  tatiana
115  * changes in FlatIgnoreThisPatentPub to allow patent pub without SeqId
116  *
117  * Revision 5.10  1996/08/16  20:33:30  tatiana
118  * feat key changed in GetNAFeatKey()
119  *
120  * Revision 5.8  1996/08/12  16:56:40  tatiana
121  * change ErrPostEx to ErrPostStr
122  *
123  * Revision 5.7  1996/07/30  16:33:32  tatiana
124  * add Boolean arg in CheckNAFeat()
125  *
126  * Revision 5.6  1996/07/11  14:58:50  tatiana
127  * title in Thesis
128  *
129  * Revision 5.5  1996/06/14  18:04:30  tatiana
130  * GetNAFeatKey change
131  *
132  * Revision 5.3  1996/06/12  22:34:56  tatiana
133  * turn off aouthor name in format_sub
134  *
135  * Revision 5.2  1996/06/06  14:49:23  tatiana
136  * *** empty log message ***
137  *
138  * Revision 5.1  1996/06/05  18:18:42  tatiana
139  * format_article, format_bookarticle, format_jourarticle are not static any more
140  *
141  * Revision 4.18  1996/04/29  18:51:17  tatiana
142  * whole_book format added
143  *
144  * Revision 4.17  1996/01/29  22:36:57  tatiana
145  * a2ferrdf.h included for error posting MODULE
146  *
147  * Revision 4.16  1995/12/13  16:33:04  tatiana
148  * a bug fixed (check for NULL pointer)
149  *
150  * Revision 4.15  1995/11/17  21:28:35  kans
151  * asn2ff now uses gather (Tatiana)
152  *
153  * Revision 4.4  1995/08/18  21:47:30  tatiana
154  * *** empty log message ***
155  *
156  * Revision 4.3  1995/08/16  15:34:19  tatiana
157  * *** empty log message ***
158  *
159  * Revision 4.2  1995/08/04  15:24:31  tatiana
160  * CheckPubs in debug mode added
161  *
162  * Revision 4.1  1995/08/01  14:52:36  tatiana
163  * change SeqIdPrint to SeqIdWrite
164  *
165  * Revision 1.55  1995/07/17  19:33:20  kans
166  * parameters combined into Asn2ffJobPtr structure
167  *
168 *
169 **************************************/
170 
171 /*************************************************************************
172 *
173 *	"pub.c" which contains files relating to publications.
174 *
175 **************************************************************************/
176 
177 #include <asn2ffp.h>
178 #include <a2ferrdf.h>
179 #include <utilpub.h>
180 #include <parsegb.h>
181 
182 #define CTX_2GB_NOT_IMPLEMENTED 1
183 /***************************************************************************
184 *
185 *	PROTOTYPES, mostly for functions from Karl Sirotkin's code.
186 *
187 *************************************************************************/
188 static CharPtr /*UNUSED*/GetSubmitterName PROTO ((Uint1 format, ValNodePtr pub));
189 NLM_EXTERN CharPtr FlatStringGroupTerm PROTO ((Boolean embl_format, CharPtr start, ValNodePtr head, CharPtr delimit, CharPtr period, CharPtr term));
190 NLM_EXTERN Int2 fix_pages PROTO ((CharPtr out_pages, CharPtr in_pages));
191 NLM_EXTERN CharPtr FlatDateFromCreate PROTO ((CharPtr default_date, NCBI_DatePtr flat_date));
192 NLM_EXTERN ValNodePtr GBGetAuthNames PROTO ((Uint1 format, AuthListPtr ap));
193 NLM_EXTERN CharPtr GetAffiliation PROTO ((AffilPtr afp));
194 NLM_EXTERN Int2 ValidatePub PROTO ((BioseqPtr bsp, ValNodePtr the_pub));
195 static CharPtr format_cit_sub PROTO ((Uint1 format, ValNodePtr the_pub, Boolean PNTR submit, Boolean make_index));
196 static CharPtr format_general PROTO ((Asn2ffJobPtr ajp, BioseqPtr bsp, ValNodePtr the_pub, Boolean make_index));
197 static CharPtr format_patent PROTO ((Uint1 format, ValNodePtr the_pub, Int4 pat_seqid, Boolean make_index));
198 static CharPtr format_thesis PROTO ((Uint1 format, ValNodePtr the_pub, Boolean make_index));
199 void PostARefErrMessage PROTO ((Asn2ffJobPtr ajp, BioseqPtr bsp, PubStructPtr psp, ValNodePtr ext_pub, Int2 status, CharPtr string));
200 static GBQualPtr GBQualCopy PROTO ((GBQualPtr old_qual));
201 static CharPtr StripParanthesis PROTO ((CharPtr ptr_in, Boolean PNTR paranthesis));
202 static CharPtr makeaffil PROTO ((AffilPtr afp, CharPtr temp, Boolean PNTR first_std));
203 static CharPtr doSup PROTO ((CharPtr temp, CharPtr issue, CharPtr part_sup, CharPtr part_supi));
204 NLM_EXTERN CharPtr format_book PROTO ((Uint1 format, ValNodePtr the_pub, Boolean make_index));
205 
206 /*****************************************************************************
207 *GetAuthors
208 *
209 *
210 *****************************************************************************/
211 
212 /*----------- GetAuthors ()------*/
GetAuthors(Asn2ffJobPtr ajp,ValNodePtr the_pub)213 NLM_EXTERN ValNodePtr GetAuthors (Asn2ffJobPtr ajp, ValNodePtr the_pub)
214 {
215 
216 	AuthListPtr ap = NULL;
217 	CharPtr tmp;
218 	CitArtPtr ca;
219 	CitBookPtr cb;
220 	CitGenPtr cg;
221 	CitSubPtr cs;
222 	CitPatPtr cp;
223 	MedlineEntryPtr ml;
224 	ValNodePtr spare, this_name, namehead=NULL;
225 
226 	if (the_pub == NULL)
227 		return NULL;
228 	switch ( the_pub -> choice) {
229 
230 	case PUB_Patent:
231 		cp = (CitPatPtr) the_pub -> data.ptrvalue;
232 		ap = cp  -> authors;
233 		break;
234 	case PUB_Man:
235 	case PUB_Book:
236 		cb = (CitBookPtr) the_pub -> data.ptrvalue;
237 		ap = cb -> authors;
238 		break;
239 	case PUB_Article:
240 	case PUB_Medline:
241 		if ( the_pub -> choice == PUB_Medline){
242 			ml = (MedlineEntryPtr) the_pub -> data.ptrvalue;
243 			ca = (CitArtPtr) ml -> cit;
244 		} else{
245 			ca = (CitArtPtr) the_pub -> data.ptrvalue;
246 		}
247 		ap = ca -> authors;
248 		break;
249 	case PUB_Gen:
250 		cg = (CitGenPtr) the_pub -> data.ptrvalue;
251 		ap = cg -> authors;
252 		break;
253 	case PUB_Sub:
254 		cs = (CitSubPtr)  the_pub -> data.ptrvalue;
255 		ap = cs -> authors;
256 		break;
257 	default:
258 		if (ajp->error_msgs == TRUE)
259 			ErrPostEx(SEV_WARNING, ERR_REFERENCE_Illegalreference,
260 			"FlatAuthor: Unimplemented pub type=%d\n",
261 			(int) the_pub -> choice);
262 		break;
263 	}
264 
265 	if (ap) {
266 		if (ap->choice != 1){   /* just strings */
267 			for (spare = ap->names, namehead = NULL;
268 					spare; spare = spare -> next) {
269 				this_name = ValNodeNew(namehead);
270 				if (namehead == NULL)
271 					namehead = this_name;
272 				this_name -> data.ptrvalue = StringSave(spare -> data.ptrvalue);
273 				if (ajp->format == EMBL_FMT || ajp->format == PSEUDOEMBL_FMT ||
274 					ajp->format == EMBLPEPT_FMT) {
275 					for (tmp=(CharPtr) this_name->data.ptrvalue;
276 						*tmp != '\0'; tmp++) {
277 						if (*tmp == ',') {
278 							*tmp = ' ';
279 							break;
280 						}
281 					}
282 				}
283 			}
284 		}  else {               /* structured names */
285 			namehead = GBGetAuthNames(ajp->format, ap);
286 		}
287 	}
288 
289 	return namehead;
290 
291 }	/* GetAuthors */
292 
293 /*----------- FlatAuthor ()------*/
FlatAuthor(Asn2ffJobPtr ajp,ValNodePtr the_pub)294 NLM_EXTERN CharPtr FlatAuthor (Asn2ffJobPtr ajp, ValNodePtr the_pub)
295 {
296 	CharPtr ret_save, temp, retval=NULL;
297 	int len;
298 	ValNodePtr namehead;
299 
300 	namehead = GetAuthors(ajp, the_pub);
301 
302 	if (ajp->format == EMBL_FMT || ajp->format == PSEUDOEMBL_FMT ||
303 		ajp->format == EMBLPEPT_FMT)
304 		retval = FlatStringGroupTerm(TRUE, NULL, namehead, ", ", NULL, ", ");
305 	else
306 		retval = FlatStringGroupTerm(FALSE, NULL, namehead, ", ", NULL, " and ");
307 
308 	ValNodeFreeData(namehead);     /* remove name list */
309 
310 	if (retval) {
311 		len = StringLen(retval);
312 		if (len > 0){
313 			if ( retval[len-1] != '.') {
314 				ret_save = retval;
315 				temp = retval = MemNew(len+2);
316 				temp = StringMove(temp,ret_save);
317 				temp = StringMove(temp,".");
318 				MemFree (ret_save);
319 			}
320 		}
321 	}
322 
323 	return FlatCleanEquals(retval);
324 
325 }	/* FlatAuthor */
326 
327 
328 /*****************************************************************************
329 *FlatCleanEquals
330 *
331 *	taken (with minor modifications) from Karl Sirotkin's code
332 *	by Tom Madden.
333 *
334 *****************************************************************************/
335 
336 	/*--------FlatCleanEquals()----------*/
337 
FlatCleanEquals(CharPtr retval)338 NLM_EXTERN CharPtr FlatCleanEquals
339 (CharPtr retval)
340 {
341 	CharPtr p=retval;
342 
343 	if (p){
344 		for (;*p; p++){
345 			if (*p == '\"')
346 				*p = '\'';
347 		}
348 	}
349 
350 return retval;
351 }
352 
353 /*****************************************************************************
354 *FlatStringGroupTerm
355 *
356 *	taken (with minor modifications) from Karl Sirotkin's code
357 *	by Tom Madden.
358 *
359 *****************************************************************************/
360 
361 /*----------- FlatStringGroupTerm  ()------*/
FlatStringGroupTerm(Boolean embl_format,CharPtr start,ValNodePtr head,CharPtr delimit,CharPtr period,CharPtr term)362 NLM_EXTERN CharPtr FlatStringGroupTerm
363 (Boolean embl_format, CharPtr start, ValNodePtr head, CharPtr delimit, CharPtr period, CharPtr term)
364 {
365 	CharPtr retval = NULL, p, ptr;
366 	Int4 lenmax, len = 0, lenstart = 0, lende = 0, lente=0, lenper=0;
367 	ValNodePtr an;
368 
369 	if (head == NULL)
370 		return NULL;
371 
372 	if (delimit) {
373 		lende = StringLen(delimit);
374 	}
375 	if (term) {
376 		lente = StringLen(term);
377 	}
378 	lenmax = lende;
379 	if (lente > lende) {
380 		lenmax = lente;
381 	}
382 	if (period) {
383 		lenper=StringLen(period);
384 	}
385 	len =  lenmax + lenper;
386 	if (start) {
387 		len += (lenstart = StringLen(start))  ;
388 	}
389 	for (an = head; an; an = an -> next) {
390 		if (an -> data.ptrvalue) {
391 			len += lenmax + StringLen( (CharPtr) ( an -> data.ptrvalue));
392 		}
393 	}
394 
395 /*--will be lende too long - who cares --- */
396 	p = retval = MemNew ((size_t)(len+1));
397 	if (start) {
398 		StringCpy (p, start);
399 		p += lenstart;
400 		StringCpy(p, delimit);
401 		p += lende;
402 	}
403 	for (an = head; an; an = an -> next) {
404 		if (an -> data.ptrvalue == NULL) {
405 			continue;
406 		}
407 		StringCpy(p, (CharPtr) (an -> data.ptrvalue) );
408 		p += StringLen( (CharPtr) (an->data.ptrvalue));
409 		if (an->next) {
410 			if ( an -> next -> next) {
411 				StringCpy(p, delimit);
412 				p += lende;
413 			} else {
414 				ptr = (CharPtr) an->next->data.ptrvalue;
415 				if ((StringCmp("et al.", ptr)) == 0 ||
416 						(StringCmp("et,al.", ptr)) == 0) {
417 					if (embl_format) {
418 						StringCpy(p, term);
419 						p += lente;
420 					} else {
421 						StringCpy(p, " ");
422 						p++;
423 					}
424 				} else {
425 					StringCpy(p, term);
426 					p += lente;
427 				}
428 			}
429 		}
430 	}
431 	if (period){
432 		StringCpy(p, period);
433 		p += lenper;
434 	}
435 	return retval;
436 }
437 
438 /*****************************************************************************
439 *
440 *   GBGetAuthNames(Uint1 format, AuthListPtr)
441 *   	Allocates a linked list of ValNode
442 *   	Each ->data.ptrvalue will have a string containing a formatted name
443 *   	Processes only AuthList of type "std"
444 *   		Returns NULL on any other type
445 *   	Caller must free returned linked list (call ValNodeFreeData())
446 *
447 *****************************************************************************/
GBGetAuthNames(Uint1 format,AuthListPtr ap)448 NLM_EXTERN ValNodePtr GBGetAuthNames (Uint1 format, AuthListPtr ap)
449 {
450 	ValNodePtr namehead, cur, spare;
451 	CharPtr tmp;
452 	AuthorPtr authptr;
453 	PersonIdPtr pid;
454 	NameStdPtr nsp;
455 	Boolean embl_format = FALSE;
456 
457 	if (ap == NULL)
458 		return NULL;
459 
460 	if (format == EMBL_FMT || format == PSEUDOEMBL_FMT ||
461 					format == EMBLPEPT_FMT) {
462 		embl_format = TRUE;
463 	}
464 	namehead = NULL;   /* convert to strings */
465 	if (ap->choice != 1)
466 		return NULL;
467 
468 	cur = NULL;
469 	for (spare = ap->names; spare; spare = spare->next)
470 	{
471 		cur = ValNodeNew(cur);
472 		if (namehead == NULL)
473 			namehead = cur;
474 		authptr = (AuthorPtr) spare->data.ptrvalue;
475 		pid = authptr->name;
476 		if (pid->choice == 2)  /* structured name */
477 		{
478 			nsp = (NameStdPtr) pid->data;
479 			if (nsp->names[0] != NULL)   /* last name */
480 			{
481 				tmp = MemNew((size_t)(StringLen(nsp->names[0]) + StringLen(nsp->names[4]) + StringLen(nsp->names[5]) + 3));
482 				cur->data.ptrvalue = tmp;
483 				tmp = StringMove(tmp, nsp->names[0]);
484 				if (nsp->names[4] && *nsp->names[4] != '\0')
485 				{
486 				if (embl_format)
487 						tmp = StringMove(tmp, " ");
488 					else
489 						tmp = StringMove(tmp, ",");
490 					tmp = StringMove(tmp, nsp->names[4]);
491 				}
492 				if (nsp->names[5] && *nsp->names[5] != '\0') /* suffix */
493 				{
494 					tmp = StringMove(tmp, " ");
495 					tmp = StringMove(tmp, nsp->names[5]);
496 				}
497 			}
498 			else if (nsp->names[3] && *nsp->names[3] != '\0') /* full name */
499 			{
500 				cur->data.ptrvalue = (Pointer)StringSave(nsp->names[3]);
501 			}
502 		}
503 		else if ((pid->choice == 3) || (pid->choice == 4)){
504 			cur->data.ptrvalue = (Pointer)StringSave((CharPtr)pid->data);
505 				if (embl_format)
506 				for (tmp = (CharPtr) cur->data.ptrvalue;
507 					*tmp != '\0'; tmp ++)
508 				{
509 					if (*tmp == ','){
510 						*tmp = ' ';
511 						break;
512 					}
513 				}
514 		}
515 	}
516 	return namehead;
517 }
518 /*****************************************************************************
519 *
520 *   GetSubmitterName (Uint1 format, ValNodePtr pub)
521 *
522 *	Returns one author name for the submitter line on the flat file.
523 *	The pub should be a cit-sub.
524 *
525 *****************************************************************************/
526 
527 /*______________________________________________________________________
528 **
529 **	This code is not currently used.
530 **	I do not remove this piece of code, just comment it out.
531 **	-- Dmitri Lukyanov
532 */
533 #if 0
534 
535 static CharPtr GetSubmitterName (Uint1 format, ValNodePtr pub)
536 
537 {
538 	AuthListPtr ap;
539 	AuthorPtr authptr;
540 	CharPtr first, initials=NULL, last, middle, start, tmp, submitter_name=NULL;
541 	CitSubPtr cs;
542 	Int2 length;
543 	NameStdPtr nsp;
544 	PersonIdPtr pid;
545 	ValNodePtr spare;
546 
547 	if (pub->choice != 2)
548 		return NULL;
549 
550 	cs = (CitSubPtr) pub->data.ptrvalue;
551 	ap = cs->authors;
552 
553 	if (ap && ap->choice != 1)
554 	{
555 		spare = ap->names;	/* take first name in list */
556 		if (spare)
557 		{
558 			submitter_name = StringSave(spare -> data.ptrvalue);
559 				if (format == EMBL_FMT || format == PSEUDOEMBL_FMT ||
560 					format == EMBLPEPT_FMT)
561 			{
562 				for (tmp=(CharPtr) submitter_name;
563 					*tmp != '\0'; tmp++)
564 				{
565 					if (*tmp == ',')
566 					{
567 						*tmp = ' ';
568 						break;
569 					}
570 				}
571 			}
572 		}
573 	}
574 	else
575 	{
576 		spare = ap->names;
577 		if (spare)
578 		{
579 			authptr = (AuthorPtr) spare->data.ptrvalue;
580 			pid = authptr->name;
581 			if (pid->choice == 2)  /* structured name */
582 			{
583 				nsp = (NameStdPtr) pid->data;
584 				if (nsp->names[3]) /* full name */
585 				{
586 					submitter_name = StringSave(nsp->names[3]);
587 				}
588 				else
589 				{
590 					if (nsp->names[0] != NULL)   /* last name */
591 						last = nsp->names[0];
592 					else
593 						last = NULL;
594 					if (nsp->names[1] != NULL)   /* first name */
595 						first = nsp->names[1];
596 					else
597 						first = NULL;
598 					if (nsp->names[4] != NULL)   /* initials*/
599 					{
600 					    tmp = nsp->names[4];
601 					    while (*tmp == ' ')
602 						tmp++;     /* no white space */
603 					    if (first)
604 					    {
605 					       while (*tmp != '\0')
606 					       {
607 					          if (*tmp == *first)
608 					          {
609 						        tmp++;
610 						        if (*tmp == '.')
611 						   	   tmp++;
612 						        break;
613 						   }
614 						   else
615 							tmp++;
616 					       }
617 					    }
618 					    length = StringLen(tmp);
619 					    if (length > 0)
620 					    {
621 						 if (tmp[length-1] != '.')
622 						 {
623 							start = initials = MemNew((length+2)*sizeof(Char));
624 							initials = StringMove(initials, tmp);
625 							initials = StringMove(initials, ".");
626 							initials = start;
627 						 }
628 						 else
629 					   	 	initials = StringSave(tmp);
630 					    }
631 					    else
632 						 initials = NULL;
633 					}
634 					if (initials == NULL &&
635 						nsp->names[2] != NULL)   /* middle name */
636 					{
637 					     middle = nsp->names[2];
638 					     start = initials = MemNew(3*sizeof(Char));
639 					     *initials = middle[0]; initials++;
640 					     *initials = '.';
641 					     initials = start;
642 					}
643 					length = StringLen(last) +
644 						StringLen(initials) + StringLen(first);
645 					if (last)
646 					{
647 						start = submitter_name =
648 							MemNew((length+3)*sizeof(Char));
649 						if (first)
650 						{
651 					   	   start = StringMove(start, first);
652 						   start = StringMove(start, " ");
653 						}
654 						if (initials)
655 						{
656 						   start = StringMove(start, initials);
657 						   start = StringMove(start, " ");
658 						   initials = MemFree(initials);
659 						}
660 						start = StringMove(start, last);
661 					}
662 				}
663 			}
664 			else if ((pid->choice == 3) || (pid->choice == 4))
665 			{
666 				submitter_name = StringSave((CharPtr)pid->data);
667 				if (format == EMBL_FMT || format == PSEUDOEMBL_FMT ||
668 					format == EMBLPEPT_FMT)
669 					for (tmp = (CharPtr) submitter_name;
670 						*tmp != '\0'; tmp ++)
671 					{
672 						if (*tmp == ','){
673 							*tmp = ' ';
674 							break;
675 						}
676 					}
677 			}
678 		}
679 	}
680 	return submitter_name;
681 }
682 
683 #endif
684 /*______________________________________________________________________
685 */
686 
all_caps(CharPtr p)687 static Boolean all_caps(CharPtr p)
688 {
689 	for ( p++; p != NULL && *p != '\0'; p++){
690 		if (IS_LOWER(*p)) {
691 			return FALSE;
692 		}
693 	}
694 	return TRUE;
695 }
696 
697 /*****************************************************************************
698 *FlatPubTitle
699 *
700 *	taken (with minor modifications) from Karl Sirotkin's code
701 *	creates a title string from ValNode pub
702 *****************************************************************************/
703 
704 /*----------- FlatPubTitle ()------*/
FlatPubTitle(ValNodePtr the_pub)705 NLM_EXTERN CharPtr FlatPubTitle
706 (ValNodePtr the_pub)
707 {
708 	CharPtr retval = NULL;
709 	CitArtPtr ca;
710 	CitBookPtr book;
711 	CitGenPtr cg;
712 	CharPtr str_ret, p;
713 	MedlineEntryPtr ml;
714 	CitPatPtr cp;
715 
716 	switch ( the_pub -> choice){
717 
718 	case PUB_Patent:
719 		cp = (CitPatPtr) the_pub -> data.ptrvalue;
720 		retval = StringSave(cp -> title);
721 		break;
722 	case PUB_Man:
723 	case PUB_Book:
724 		book = (CitBookPtr) the_pub -> data.ptrvalue;
725 		if (book ->  title && book -> title -> data.ptrvalue) {
726 			p = book -> title -> data.ptrvalue;
727 			if (StringLen(p) > 3) {
728 				if (IS_LOWER(*p)) {
729 					*p = TO_UPPER(*p);
730 				}
731 				if (all_caps(p)) {
732 					for ( p++; p != NULL && *p != '\0'; p++){
733 						*p = TO_LOWER(*p);
734 					}
735 				}
736 			}
737 			retval = StringSave(book -> title -> data.ptrvalue);
738 		}
739 		break;
740 
741 	case PUB_Medline:
742 	case PUB_Article:
743 		if ( the_pub -> choice == PUB_Medline){
744 			ml = (MedlineEntryPtr) the_pub -> data.ptrvalue;
745 			ca = (CitArtPtr) ml -> cit;
746 		}else{
747 			ca = (CitArtPtr) the_pub -> data.ptrvalue;
748 		}
749 		if (ca -> title )
750 			if (ca -> title -> data.ptrvalue)
751 				retval = StringSave(ca -> title -> data.ptrvalue);
752 		break;
753 	case PUB_Gen:
754 		cg = (CitGenPtr) the_pub -> data.ptrvalue;
755 		if (cg->title)
756 			retval = StringSave(cg->title);
757 		else
758 		{
759 			str_ret = NULL;
760 			if (cg -> cit)
761 				str_ret = StrStr(cg -> cit ,"Title=\"");
762 			if (str_ret){
763 				retval = StringSave(str_ret + 7);
764 				for (p=retval; *p; p++)
765 					if (*p == '"'){
766 						*p = '\0';
767 						break;
768 					}
769 			}
770 			/* Finish off for unparsed direct subs. */
771 			/* else {
772 				if (StringNICmp("submitted, cg->cit, 8) == 0)
773 					retval = StringSave("Direct Submission");
774 					*/
775 		}
776 		break;
777 	case PUB_Sub:
778 		retval = StringSave("Direct Submission");
779 		break;
780 	default:
781 		break;
782 
783 	}
784 
785 	retval =  FlatCleanEquals(retval);
786 	if(retval) if (*retval)
787 	for (p=retval + StringLen(retval)-1 ; p> retval+2; p--){
788 		if (*p == ' '){
789 			*p = '\0';
790 		}else if (*p == '.'){
791 			Boolean remove_it = FALSE;
792 			if ( p > retval +5){
793 				if ( *(p -1 ) != '.' || * (p-2) != '.')
794 					remove_it = TRUE;
795 			}
796 			if (remove_it)
797 				*p = '\0';
798 			break;
799 		}else{
800 			break;
801 		}
802 	}
803 	return (retval);
804 }
805 
806 /*****************************************************************************
807 *FlatJournal
808 *
809 *	creates 'JOURNAL' line from different ASN.1 pubs
810 *
811 *****************************************************************************/
812 
813 /*----------- FlatJournal ()------*/
FlatJournal(Asn2ffJobPtr ajp,GBEntryPtr gbp,ValNodePtr the_pub,Int4 pat_seqid,Boolean PNTR submit,Boolean make_index)814 NLM_EXTERN CharPtr FlatJournal
815 (Asn2ffJobPtr ajp, GBEntryPtr gbp, ValNodePtr the_pub, Int4 pat_seqid, Boolean PNTR submit, Boolean make_index)
816 {
817 	CharPtr retval=NULL;
818 
819 	if (the_pub)
820 	{
821 		switch ( the_pub -> choice){
822 		case PUB_Sub:
823     			retval = format_cit_sub(ajp->format, the_pub, submit, make_index);
824     			break;
825 
826 		case PUB_Patent:
827     			retval = format_patent(ajp->format, the_pub, pat_seqid, make_index);
828 			break;
829 
830 		case PUB_Man:
831     			retval = format_thesis(ajp->format, the_pub, make_index);
832 			break;
833 
834 		case PUB_Article:
835 		case PUB_Medline:
836     			retval = format_article(ajp, gbp->bsp, the_pub, make_index);
837 			break;
838 
839 		case PUB_Book:
840     			retval = format_book(ajp->format, the_pub, make_index);
841 			break;
842 
843 		case PUB_Gen:
844     			retval = format_general(ajp, gbp->bsp, the_pub, make_index);
845 			break;
846 
847 		default:
848 		if (ASN2FF_SHOW_ERROR_MSG == TRUE)
849 			ErrPostEx(SEV_WARNING, ERR_REFERENCE_Illegalreference,
850 			"FlatJournal: Unimplemented pub type=%d\n",
851 			(int) the_pub -> choice);
852 		}
853 	}
854 
855 	if (retval){
856 		CharPtr hold, p , q;
857 
858 		retval = FlatCleanEquals(retval);
859 		hold = p = MemNew(StringLen(retval)+1);
860 
861 		for (q=retval; *q; q++){
862 			if (*q != '\n' && *q != '\r'){
863 				*p = *q;
864 			}else{
865 				*p = ' ';
866 			}
867 			p ++;
868 		}
869 		*p = '\0';
870 		MemFree(hold);
871 	}
872 
873 	return retval;
874 
875 }	/* FlatJournal */
876 
877 
fmt_cit_sub_1(AffilPtr afp,size_t aflen)878 static size_t fmt_cit_sub_1 (AffilPtr afp, size_t aflen)
879 
880 {
881   if (afp) {
882     if (afp -> choice == 1) {
883       if (afp -> affil) {
884         aflen += StringLen (afp -> affil);
885       }
886     } else if (afp -> choice == 2) {
887       aflen += 15 +
888       StringLen (afp -> affil) +
889       StringLen (afp -> div) +
890       StringLen (afp -> city) +
891       StringLen (afp -> sub) +
892       StringLen (afp -> street) +
893       StringLen (afp -> country);
894     }
895   }
896   return aflen;
897 }
898 
fmt_cit_sub_2(CharPtr start,CharPtr date_std,Uint1 format)899 static CharPtr fmt_cit_sub_2 (CharPtr start, CharPtr date_std, Uint1 format)
900 
901 {
902   CharPtr temp;
903 
904   temp = StringMove (start, "Submitted");
905   temp = StringMove (temp, " (");
906   temp = StringMove (temp, date_std);
907   if (format == EMBL_FMT || format == PSEUDOEMBL_FMT || format == EMBLPEPT_FMT)
908   {
909     temp = StringMove (temp, ")");
910   } else {
911     temp = StringMove (temp, ")");
912   }
913   return temp;
914 }
915 
916 /*************************************************************************
917 *static CharPtr format_cit_sub(Uint1 format, ValNodePtr the_pub, Boolean PNTR submit, Boolean make_index)
918 *
919 *format pubs of type CitSub for GenBank and EMBL flat file.
920 **************************************************************************/
921 
format_cit_sub(Uint1 format,ValNodePtr the_pub,Boolean PNTR submit,Boolean make_index)922 static CharPtr format_cit_sub (Uint1 format, ValNodePtr the_pub, Boolean PNTR submit, Boolean make_index)
923 {
924   AffilPtr afp = NULL;
925   AuthListPtr alp;
926   Boolean need_comma = FALSE, /*UNUSED*/need_space = TRUE;
927   Char ch;
928   CitSubPtr cs;
929   CharPtr affil=NULL, start, retval = NULL, temp, dup_pages = NULL;
930   CharPtr date_std = NULL, ptr;
931   DatePtr dp = NULL;
932   ImprintPtr ip = NULL;
933   size_t aflen = 0;
934   Int2 l_str;
935   Boolean no_to = FALSE;
936 
937   cs = (CitSubPtr) the_pub -> data.ptrvalue;
938   dp = cs->date;
939   if (dp) {
940   	date_std = FlatDateFromCreate (NULL, (NCBI_DatePtr) dp);
941   }
942   if (cs->imp) {
943     ip = cs -> imp;
944     if (dp  == NULL && ip -> date) {
945     	dp = ip -> date;
946     	date_std = FlatDateFromCreate (NULL, (NCBI_DatePtr) dp);
947     }
948     if (ip -> pub) {
949       afp = ip -> pub;
950       aflen = 10;   /* "Submitted " */
951     }
952   }
953 
954   if (afp == NULL) {
955     alp = cs -> authors;
956     if (alp && alp -> affil) {
957       afp = alp -> affil;
958     }
959   }
960 
961   aflen = fmt_cit_sub_1 (afp, aflen);
962 
963 /* stop printing authors  06-12-96 */
964 /*
965   if (afp) {
966   	if (afp->choice == 1) {
967   		authors = NULL;
968   	} else {
969 		authors = GetSubmitterName (format, the_pub);
970 	}
971   } else {
972        	authors = GetSubmitterName (format, the_pub);
973   }
974   retval = MemNew ((size_t) (60 + 2 + StringLen (authors) +
975                    StringLen (date_std) + aflen));
976 */
977   retval = MemNew ((size_t) (60 + 2 + StringLen (date_std) + aflen));
978   temp = fmt_cit_sub_2 (retval, date_std, format);
979 
980   if (afp) {
981     	affil = GetAffiliation (afp);
982   }
983   if (format == EMBL_FMT || format == PSEUDOEMBL_FMT || format == EMBLPEPT_FMT)
984   {
985   	if (affil) {
986 	   l_str = StringLen(" to the EMBL/GenBank/DDBJ databases.");
987 	   if (StringNCmp(affil, " to the EMBL/GenBank/DDBJ databases.",
988 	   		l_str) != 0){
989 	   		no_to = TRUE;
990 	   	}
991 	}
992 	if (no_to) {
993 		temp = StringMove (temp, " to the EMBL/GenBank/DDBJ databases.");
994 	    *temp = NEWLINE;
995 	    need_space = FALSE;
996 	    temp++;
997     } else {
998       	*temp = ' '; temp++;
999     }
1000   }
1001 /* stop printing authors  06-12-96 */
1002 /*
1003   if (authors) {
1004       if (need_space)
1005       {
1006       	*temp = ' '; temp++;
1007       }
1008       temp = StringMove (temp, authors);
1009       authors = MemFree (authors);
1010       need_comma = TRUE;
1011   }
1012 */
1013   *submit = TRUE;
1014 
1015 	if (afp) {
1016   /*  affil = GetAffiliation (afp); */ /*already got it */
1017 		if (need_comma) {
1018 			*temp = ','; temp++;
1019 		}
1020 	if (affil) {
1021 		    start = affil;
1022 		    if (format == EMBL_FMT || format == PSEUDOEMBL_FMT ||
1023 						      format == EMBLPEPT_FMT && afp->choice == 1)
1024 			    affil++;
1025 		    ptr = affil;
1026 		    ch = *affil;
1027 		    while (ch != '\0') {
1028 			    *temp = ch;
1029 		    temp++;
1030 		    affil++;
1031 		    ch = *affil;
1032 		  }
1033 		    affil = ptr;
1034 		    start = MemFree (start);
1035 	    }
1036 	}
1037 
1038   if (date_std) {
1039     MemFree (date_std);
1040   }
1041   if (dup_pages) {
1042     MemFree (dup_pages);
1043   }
1044 
1045   return retval;
1046 }	/* format_cit_sub */
1047 
format_patent(Uint1 format,ValNodePtr the_pub,Int4 pat_seqid,Boolean make_index)1048 static CharPtr format_patent (Uint1 format, ValNodePtr the_pub, Int4 pat_seqid, Boolean make_index)
1049 
1050 {
1051 	AffilPtr afp;
1052 	AuthListPtr ap=NULL;
1053 	CitPatPtr cp;
1054 	CharPtr retval = NULL, temp, pat_date = NULL;
1055 	char buf[10];
1056 	int patlen;
1057 	Boolean embl_format = FALSE;
1058 
1059 	if (format == EMBL_FMT || format == PSEUDOEMBL_FMT ||
1060 					format == EMBLPEPT_FMT) {
1061 		embl_format = TRUE;
1062 	}
1063 	cp = (CitPatPtr) the_pub -> data.ptrvalue;
1064 	if (cp == NULL) {
1065 		return retval;
1066 	}
1067 	patlen = 50;
1068 	patlen += StringLen(cp -> country) ;
1069 	if (cp -> number){
1070 		patlen += StringLen(cp -> number);
1071 	} else if (cp -> app_number){
1072 		patlen += StringLen(cp -> app_number);
1073 	}
1074 	if (cp -> doc_type){
1075 		patlen += StringLen(cp -> doc_type);
1076 	}
1077 	ap = cp -> authors;
1078 	if (ap) {
1079 		afp = ap -> affil;
1080 		if (afp){
1081 			patlen += StringLen(afp -> affil);
1082 			if (afp -> choice == 2){
1083 				patlen += StringLen(afp -> div);
1084 				patlen += StringLen(afp -> city);
1085 				patlen += StringLen(afp -> sub );
1086 				patlen += StringLen(afp -> country);
1087 				patlen += StringLen(afp -> street);
1088 			}
1089 		}
1090 	}
1091 	temp = retval = MemNew(patlen);
1092 	if (embl_format) {
1093 		temp = StringMove(temp,"Patent number ");
1094 	} else {
1095 		temp = StringMove(temp,"Patent: ");
1096 	}
1097 	if (cp -> country) {
1098 		temp = StringMove(temp,cp -> country);
1099 		if (!embl_format)
1100 			temp = StringMove(temp," ");
1101 	}
1102 	if (cp -> number) {
1103 		temp = StringMove(temp, cp -> number);
1104 	} else if (cp -> app_number) {
1105 		temp = StringMove(temp,"(");
1106 		temp = StringMove(temp, cp -> app_number);
1107 		temp = StringMove(temp,")");
1108 	}
1109 	if (cp -> doc_type) if ( *(cp -> doc_type)){
1110 		temp = StringMove(temp,"-");
1111 		temp = StringMove(temp, cp -> doc_type);
1112 	}
1113 	if (pat_seqid > 0) {
1114 		if (embl_format) {
1115 			sprintf(buf,"%s%ld%s", "/", (long) pat_seqid, ", ");
1116 		/*
1117 		} else if (format == GENPEPT_FMT) {
1118 			sprintf(buf,"%s", " ? ");
1119 		*/
1120 		} else {
1121 			sprintf(buf,"%s%ld ", " ", (long) pat_seqid);
1122 		}
1123 		temp = StringMove(temp,buf);
1124 	} else {
1125 		temp = StringMove(temp, " ");
1126 	}
1127 	if (cp -> date_issue){
1128 		pat_date = FlatDateFromCreate(NULL, cp -> date_issue);
1129 	} else if (cp -> app_date) {
1130 		pat_date = FlatDateFromCreate(NULL, cp -> app_date);
1131 	}
1132 	if (pat_date){
1133 		temp = StringMove(temp,pat_date);
1134 	}
1135 	if (embl_format)
1136 		temp = StringMove(temp, ".");
1137 	else
1138 		temp = StringMove(temp, ";");
1139 	ap = cp -> authors;
1140 	if (ap == NULL || afp == NULL) {
1141 		if (pat_date)
1142 			MemFree(pat_date);
1143 		return retval;
1144 	}
1145 	if (make_index != TRUE)
1146 		*temp = NEWLINE;
1147 	else
1148 		*temp = ' ';
1149 	temp++;
1150 	temp = StringMove(temp,afp -> affil);
1151 	if (afp -> choice == 2){
1152 		if (afp -> affil) {
1153 			temp = StringMove(temp,";");
1154 		}
1155 		if (afp -> street){
1156 			if (make_index != TRUE) {
1157 				*temp = NEWLINE;
1158 			} else {
1159 				*temp = ' ';
1160 			}
1161 			temp++;
1162 			temp = StringMove(temp,afp -> street);
1163 			temp = StringMove(temp,";");
1164 		}
1165 		if (afp -> div){
1166 			if (make_index != TRUE)
1167 				*temp = NEWLINE;
1168 			else
1169 				*temp = ' ';
1170 			temp++;
1171 			temp = StringMove(temp,afp -> div);
1172 			temp = StringMove(temp,";");
1173 		}
1174 		if (afp -> city){
1175 			if (make_index != TRUE)
1176 				*temp = NEWLINE;
1177 			else
1178 				*temp = ' ';
1179 			temp++;
1180 			temp = StringMove(temp,afp -> city);
1181 			temp = StringMove(temp,", ");
1182 		}
1183 		if (afp -> sub){
1184 			temp = StringMove(temp, afp -> sub );
1185 		}
1186 		if (afp ->country){
1187 				temp = StringMove(temp,";");
1188 				if (make_index != TRUE)
1189 					*temp = NEWLINE;
1190 				else
1191 					*temp = ' ';
1192 				temp++;
1193 			temp = StringMove(temp,afp -> country);
1194 			temp = StringMove(temp,";");
1195 		}
1196 		MemFree(pat_date);
1197 	}
1198 
1199 	return retval;
1200 
1201 }	/* format_patent */
1202 
format_thesis(Uint1 format,ValNodePtr the_pub,Boolean make_index)1203 static CharPtr format_thesis (Uint1 format, ValNodePtr the_pub, Boolean make_index)
1204 
1205 {
1206 	AffilPtr afp;
1207 	char year[5];
1208 	CitBookPtr cb;
1209 	CharPtr retval = NULL, temp;
1210 	DatePtr dp;
1211 	ImprintPtr ip;
1212 	int aflen=0;
1213 	Boolean /*UNUSED*/embl_format = FALSE;
1214 	Boolean first_std=TRUE;
1215 
1216 	if (format == EMBL_FMT || format == PSEUDOEMBL_FMT ||
1217 					format == EMBLPEPT_FMT) {
1218 		embl_format = TRUE;
1219 	}
1220 	year[0] = '\0';
1221 
1222 	cb = (CitBookPtr) the_pub -> data.ptrvalue;
1223 	if (cb -> othertype == 2 && cb -> let_type == 3){ /* match thesis */
1224 		ip = cb -> imp;
1225 		dp = ip -> date;
1226 		if ( dp -> data[0] == 1){
1227 			sprintf(year,"%ld",(long) ( 1900+dp -> data[1]));
1228 		} else {
1229 			StringNCpy( (CharPtr) year, (CharPtr) dp -> str, (size_t) 4);
1230 			year[4] = '\0';
1231 		}
1232 		if ( ip -> pub){
1233 			afp = ip->pub;
1234 			aflen = 7;
1235 			if (afp->choice == 1) {
1236 				if (afp -> affil){
1237 					aflen += StringLen(afp -> affil) + 6;
1238 				}
1239 
1240 			} else if (afp->choice == 2){
1241 				aflen += 3 + StringLen(afp -> affil);
1242 				aflen += 3 + StringLen(afp -> div);
1243 				aflen += 3 + StringLen(afp -> street);
1244 				aflen += 3 + StringLen(afp -> city);
1245 				aflen += 3 + StringLen(afp -> sub);
1246 				aflen += 3 + StringLen(afp -> country);
1247 			} else {
1248 				aflen = 22;
1249 			}
1250 		}
1251 		if (ip->prepub == 2)   /* In press */
1252 			aflen += 10;
1253 
1254 		temp = retval = MemNew((size_t) (60 + StringLen(year) + aflen));
1255 		temp = StringMove(temp,"Thesis");
1256 		temp = StringMove(temp," (");
1257 		temp = StringMove(temp, year);
1258 		temp = StringMove(temp,")");
1259 
1260 		if ( ip -> pub){
1261 			afp = ip->pub;
1262 			if ( afp->choice == 1){
1263 				if (afp->affil){
1264 					if (StringLen( afp -> affil) > 7){
1265 						temp = StringMove(temp, " ");
1266 						temp = StringMove(temp, afp -> affil);
1267 						if (ip->prepub == 2)   /* In press */
1268 							temp = StringMove(temp, ", In press");
1269 					}
1270 				}
1271 			} else if (afp->choice == 2) {
1272 				*temp = ' ';
1273 				temp++;
1274 				temp = makeaffil(afp, temp, &first_std);
1275 				if (ip->prepub == 2) {
1276 					temp = StringMove(temp, ", In press");
1277 				}
1278 			}
1279 		}
1280 	}
1281 	return retval;
1282 
1283 }	/* format_thesis */
1284 
format_book(Uint1 format,ValNodePtr the_pub,Boolean make_index)1285 NLM_EXTERN CharPtr format_book (Uint1 format, ValNodePtr the_pub, Boolean make_index)
1286 
1287 {
1288 	AffilPtr afp;
1289 	char year[5];
1290 	CharPtr book_tit=NULL;
1291 	CitBookPtr cb;
1292 	CharPtr retval = NULL, temp;
1293 	DatePtr dp;
1294 	ImprintPtr ip;
1295 	int aflen=0;
1296 	Boolean embl_format = FALSE;
1297 	CharPtr p;
1298 	Boolean first_std=TRUE;
1299 
1300 	if (format == EMBL_FMT || format == PSEUDOEMBL_FMT ||
1301 					format == EMBLPEPT_FMT) {
1302 		embl_format = TRUE;
1303 	}
1304 	year[0] = '\0';
1305 	if (the_pub == NULL)
1306 		return NULL;
1307 	cb = (CitBookPtr) the_pub -> data.ptrvalue;
1308 	if (cb == NULL)
1309 		return NULL;
1310 	if ( cb -> othertype != 0){ /* match book */
1311 		return NULL;
1312 	}
1313 	ip = cb -> imp;
1314 	dp = ip -> date;
1315 	if ( dp -> data[0] == 1) {
1316 		sprintf(year,"%ld",(long) ( 1900+dp -> data[1]));
1317 	} else {
1318 		StringNCpy( (CharPtr) year, (CharPtr) dp -> str, (size_t) 4);
1319 		year[4] = '\0';
1320 	}
1321 	if (cb->title)
1322 		book_tit = StringSave(cb -> title -> data.ptrvalue);
1323 	if ( ip -> pub){
1324 		afp = ip -> pub;
1325 		aflen = StringLen(afp -> affil)+ 5;
1326 		if ( afp -> choice == 2){
1327 			aflen += 3 + StringLen(afp -> div);
1328 			aflen += 3 + StringLen(afp -> street);
1329 			aflen += 3 + StringLen(afp -> city);
1330 			aflen += 3 + StringLen(afp -> sub);
1331 			aflen += 3 + StringLen(afp -> country);
1332 		}
1333 	} else{
1334 		aflen = 22;
1335 	}
1336 	if (ip->prepub == 2)   /* In press */
1337 		aflen += 10;
1338 
1339 	temp = retval = MemNew( (size_t) (30+StringLen( book_tit)+StringLen( year) + aflen) );
1340 
1341 /*--make book title all caps */
1342 	for ( p = book_tit; *p; p++){
1343 		*p = TO_UPPER(*p);
1344 	}
1345 	temp = StringMove(temp, "Book: ");
1346 	temp = StringMove(temp, book_tit);
1347 			temp = StringMove(temp, ".");
1348 	if ( ip -> pub){
1349 		afp = ip -> pub;
1350 		*temp = ' ';
1351 		temp++;
1352 		temp = makeaffil(afp, temp, &first_std);
1353 	}
1354 	if (year[0] != '\0') {
1355 		if (! first_std)
1356 			temp = StringMove(temp," (");
1357 		else
1358 			temp = StringMove(temp, "(");
1359 		temp = StringMove(temp, year);
1360 		temp = StringMove(temp, ")");
1361 	}
1362 	if (ip->prepub == 2) { /* In press */
1363 		temp = StringMove(temp, ", In press");
1364 	}
1365 	if (book_tit)
1366 		MemFree(book_tit);
1367 
1368 	return retval;
1369 
1370 }	/* format_book */
1371 
1372 
format_article(Asn2ffJobPtr ajp,BioseqPtr bsp,ValNodePtr the_pub,Boolean make_index)1373 NLM_EXTERN CharPtr format_article (Asn2ffJobPtr ajp, BioseqPtr bsp, ValNodePtr the_pub, Boolean make_index)
1374 {
1375 	CharPtr retval=NULL;
1376 	CitArtPtr ca = NULL;
1377 	MedlineEntryPtr ml;
1378 
1379 	if ( the_pub -> choice == PUB_Medline) {
1380 		ml = (MedlineEntryPtr) the_pub -> data.ptrvalue;
1381 		ca = (CitArtPtr) ml -> cit;
1382 	} else if (the_pub->choice == PUB_Article) {
1383 		ca = (CitArtPtr) the_pub -> data.ptrvalue;
1384 	}
1385 	if (ca == NULL) {
1386 		return NULL;
1387 	}
1388 
1389 	if ( ca -> from != 1) {
1390 		retval = format_bookarticle(ajp, bsp, the_pub, make_index);
1391 	} else {
1392 		retval = format_jourarticle(ajp, bsp, the_pub, make_index);
1393 	}
1394 
1395 	return retval;
1396 
1397 }	/* format_article */
1398 
format_bookarticle(Asn2ffJobPtr ajp,BioseqPtr bsp,ValNodePtr the_pub,Boolean make_index)1399 NLM_EXTERN CharPtr format_bookarticle(Asn2ffJobPtr ajp, BioseqPtr bsp, ValNodePtr the_pub, Boolean make_index)
1400 
1401 {
1402 	AffilPtr afp;
1403 	AuthListPtr ap = NULL;
1404 	Boolean first_std=TRUE, found_paran=FALSE;
1405 	CharPtr temp, dup_pages=NULL, retval=NULL, volume=NULL;
1406 	CharPtr issue=NULL, part_sup=NULL, part_supi=NULL;
1407 	CharPtr p;
1408 	CharPtr book_authors=NULL, book_tit=NULL;
1409 	Char year[5];
1410 	CitArtPtr ca = NULL;
1411 	CitBookPtr book;
1412 	DatePtr dp;
1413 	ImprintPtr ip;
1414 	Int2 aflen=0, length;
1415 	Int2 fix_p_ret;
1416 	MedlineEntryPtr ml;
1417 	ValNodePtr namehead;
1418 	size_t len_page = 0;
1419 	Boolean embl_format = FALSE;
1420 
1421 	if (ajp && (ajp->format == EMBL_FMT || ajp->format == PSEUDOEMBL_FMT ||
1422 					ajp->format == EMBLPEPT_FMT)) {
1423 		embl_format = TRUE;
1424 	}
1425 	if ( the_pub -> choice == PUB_Medline) {
1426 		ml = (MedlineEntryPtr) the_pub -> data.ptrvalue;
1427 		ca = (CitArtPtr) ml -> cit;
1428 	} else if (the_pub->choice == PUB_Article) {
1429 		ca = (CitArtPtr) the_pub -> data.ptrvalue;
1430 	}
1431 	if (ca == NULL) {
1432 		return NULL;
1433 	}
1434 	book = (CitBookPtr) ca->fromptr;
1435 	ap = book -> authors;
1436 	if (ap->choice != 1)   /* just strings */
1437 		namehead = ap->names;
1438 	else                  /* structured names */
1439 			namehead = GBGetAuthNames(ajp->format, ap);
1440 	book_authors = FlatStringGroupTerm(embl_format, NULL, namehead, ", ", NULL, " and ");
1441 
1442 	book_tit = StringSave(book -> title -> data.ptrvalue);
1443 	ip = book -> imp;
1444 	if (ip -> pages){
1445 		len_page = StringLen( ip -> pages);
1446 		dup_pages = MemNew ( 2*len_page );
1447 		fix_p_ret = fix_pages(dup_pages, ip ->pages);
1448 		if (ajp && fix_p_ret == -1 && ajp->error_msgs == TRUE) {
1449 			PostARefErrMessage (ajp, bsp, NULL, the_pub, 1, dup_pages);
1450 		}
1451 	}else if (ajp && !ip->prepub && ajp->error_msgs == TRUE) {
1452 		PostARefErrMessage (ajp, bsp, NULL, the_pub, 2, NULL);
1453 	}
1454 	dp = ip -> date;
1455 	year[0] = '\0';
1456 	if ( dp -> data[0] == 1) {
1457 		sprintf(year,"%ld",(long) ( 1900+dp -> data[1]));
1458 	} else {
1459 		StringNCpy( (CharPtr) year, (CharPtr) dp -> str, (size_t) 4);
1460 		year[4] = '\0';
1461 	}
1462 
1463 	if (ip -> pub){
1464 		afp = ip -> pub;
1465 		aflen = StringLen(afp -> affil)+ 5;
1466 		if ( afp -> choice == 2) {
1467 			aflen += 3 + StringLen(afp -> div);
1468 			aflen += 3 + StringLen(afp -> street);
1469 			aflen += 3 + StringLen(afp -> city);
1470 			aflen += 3 + StringLen(afp -> sub);
1471 			aflen += 3 + StringLen(afp -> country);
1472 		}
1473 	} else {
1474 		aflen = 22;
1475 	}
1476 	if (ip->volume) {
1477 		volume = StringSave(ip->volume);
1478 	}
1479 	if (embl_format) { /* Don't do this for EMBL! */
1480 	   if (ip->part_sup) {
1481 			part_sup = StringSave(ip->part_sup);
1482 	   }
1483 	   if (ip->issue) {
1484 			issue = StripParanthesis(ip->issue, &found_paran);
1485 	        if (ajp && ajp->error_msgs == TRUE && found_paran == TRUE)
1486 		    PostARefErrMessage (ajp, bsp, NULL, the_pub, 5, NULL);
1487 	   }
1488 	   if (ip->part_supi) {
1489 			part_supi = StripParanthesis(ip->part_supi, &found_paran);
1490 	        if (ajp->error_msgs == TRUE && found_paran == TRUE)
1491 		    PostARefErrMessage (ajp, bsp, NULL, the_pub, 5, NULL);
1492 	   }
1493 	}
1494 
1495 	length = 80;
1496 	length += StringLen (book_tit)+ StringLen(book_authors);
1497 	length += StringLen(volume);
1498 	length += StringLen(issue);
1499 	length += StringLen(part_sup);
1500 	length += StringLen(part_supi);
1501 	length += 2*len_page;
1502 	length += StringLen( year) + aflen;
1503 
1504 	temp = retval = MemNew( (size_t) length);
1505 
1506 /*--make book title all caps */
1507 	for ( p = book_tit; *p; p++){
1508 		*p = TO_UPPER(*p);
1509 	}
1510 
1511 	temp = StringMove(temp,"(in) ");
1512 	if (make_index == FALSE && book_authors)
1513 	{
1514 		temp = StringMove(temp,book_authors);
1515 		if (namehead != NULL) {
1516 			temp = StringMove(temp,namehead -> next? " (Eds.);":" (Ed.);");
1517 		}
1518 		*temp = NEWLINE;
1519 		temp++;
1520 	}
1521 
1522 	if (ap->choice == 1)    /* std names */
1523 		ValNodeFreeData(namehead);
1524 
1525 	temp = StringMove(temp,book_tit);
1526 	if (volume && StringCmp(volume, "0") != 0)
1527 	{
1528 		temp = StringMove(temp,", ");
1529 		temp = StringMove(temp, "Vol. ");
1530 		temp = StringMove(temp, volume);
1531 		temp = doSup(temp, issue, part_sup, part_supi);
1532 	}
1533 	if (ip->pages != NULL)
1534 	{
1535 		temp = StringMove(temp,": ");
1536 		temp = StringMove(temp,dup_pages);
1537 	}
1538 	if (book_tit)
1539 	{
1540 		*temp = ';';
1541 		temp++;
1542 	}
1543 	if ( ip -> pub){
1544 		afp = ip -> pub;
1545 		if (make_index != TRUE)
1546 			*temp = NEWLINE;
1547 		else
1548 			*temp = ' ';
1549 		temp++;
1550 		temp = makeaffil(afp, temp, &first_std);
1551 	}
1552 	if (! first_std)
1553 		temp = StringMove(temp," (");
1554 	else
1555 		temp = StringMove(temp,"(");
1556 	temp = StringMove(temp,year);
1557 	temp = StringMove(temp,")");
1558 	if (ip->prepub == 2 && !embl_format)
1559 		temp = StringMove(temp, " In press");
1560 
1561 	if (volume)
1562 		volume = MemFree(volume);
1563 	if (book_authors)
1564 		MemFree(book_authors);
1565 	if (book_tit)
1566 		MemFree(book_tit);
1567 	if (issue)
1568 		issue = MemFree(issue);
1569 	if (part_sup)
1570 		part_sup = MemFree(part_sup);
1571 	if (part_supi)
1572 		part_supi = MemFree(part_supi);
1573 	if (dup_pages)
1574 		MemFree(dup_pages);
1575 
1576 	return retval;
1577 }
1578 
1579 /***********************************************************************
1580 *CharPtr format_jourarticle(Asn2ffJobPtr ajp, BioseqPtr bsp, ValNodePtr the_pub, Boolean make_index)
1581 *
1582 *	format a journal article
1583 *	The caller must deallocate the space allocated.
1584 **********************************************************************/
1585 
format_jourarticle(Asn2ffJobPtr ajp,BioseqPtr bsp,ValNodePtr the_pub,Boolean make_index)1586 NLM_EXTERN CharPtr format_jourarticle(Asn2ffJobPtr ajp, BioseqPtr bsp, ValNodePtr the_pub, Boolean make_index)
1587 
1588 
1589 {
1590 	Boolean found_paran=FALSE;
1591 	char year[5];
1592 	CharPtr temp, dup_pages=NULL, retval=NULL, volume=NULL;
1593 	CharPtr issue=NULL, part_sup=NULL, part_supi=NULL;
1594 	CitArtPtr ca = NULL;
1595 	CitJourPtr jp;
1596 	DatePtr dp;
1597 	ImprintPtr ip;
1598 	Int2 fix_p_ret, length;
1599 	MedlineEntryPtr ml;
1600 	size_t len_page = 0;
1601 	Boolean embl_format = FALSE;
1602 
1603 	if (ajp) {
1604 		if (ajp->format == EMBL_FMT || ajp->format == PSEUDOEMBL_FMT ||
1605 					ajp->format == EMBLPEPT_FMT) {
1606 			embl_format = TRUE;
1607 		}
1608 	}
1609 	if ( the_pub -> choice == PUB_Medline) {
1610 		ml = (MedlineEntryPtr) the_pub -> data.ptrvalue;
1611 		ca = (CitArtPtr) ml -> cit;
1612 	} else if (the_pub->choice == PUB_Article) {
1613 		ca = (CitArtPtr) the_pub -> data.ptrvalue;
1614 	}
1615 	if (ca == NULL) {
1616 		return NULL;
1617 	}
1618 	jp = (CitJourPtr) ca -> fromptr;
1619 	ip = jp -> imp;
1620 	dp = ip -> date;
1621 	year[0] = '\0';
1622 	if ( dp -> data[0] == 1) {
1623 		if (dp->data[1] != '\0') {
1624 			sprintf(year,"%ld",(long) ( 1900+dp -> data[1]));
1625 		}
1626 	} else {
1627 		StringNCpy( (CharPtr) year, (CharPtr) dp -> str, (size_t) 4);
1628 		year[4] = '\0';
1629 	}
1630 	if (ip -> pages){
1631 		len_page = StringLen( ip -> pages);
1632 		dup_pages = MemNew ( 2*len_page );
1633 		fix_p_ret = fix_pages(dup_pages, ip ->pages);
1634 		if (ajp && fix_p_ret == -1 && ajp->error_msgs == TRUE) {
1635 			PostARefErrMessage (ajp, bsp, NULL, the_pub, 1, dup_pages);
1636 		}
1637 	} else if (ajp && !ip->prepub && ajp->error_msgs == TRUE) {
1638 		PostARefErrMessage (ajp, bsp, NULL, the_pub, 2, NULL);
1639 	}
1640 	if (ip->prepub != 1 && ip->prepub != 255) {
1641 		if (ip->volume) {
1642 		    volume = StringSave(ip->volume);
1643 		}
1644 		if (!embl_format) { /* Don't do this for EMBL! */
1645 		   if (ip->part_sup)
1646 			part_sup = StringSave(ip->part_sup);
1647 		   if (ip->issue) {
1648 			issue = StripParanthesis(ip->issue, &found_paran);
1649 		        if (ajp->error_msgs == TRUE && found_paran == TRUE)
1650 			    PostARefErrMessage (ajp, bsp, NULL, the_pub, 5, NULL);
1651 		   }
1652 		   if (ip->part_supi) {
1653 			part_supi = StripParanthesis(ip->part_supi, &found_paran);
1654 		        if (ajp && ajp->error_msgs == TRUE && found_paran == TRUE)
1655 			    PostARefErrMessage (ajp, bsp, NULL, the_pub, 5, NULL);
1656 		   }
1657 		}
1658 
1659 		length = 25;
1660 		length += StringLen ((CharPtr) (jp -> title -> data.ptrvalue));
1661 		length += StringLen(volume);
1662 		length += StringLen(issue);
1663 		length += StringLen(part_sup);
1664 		length += StringLen(part_supi);
1665 		length += 2*len_page + StringLen( year);
1666 
1667 
1668 		/* Does the journal have a title? */
1669 		if (jp -> title -> data.ptrvalue != NULL &&
1670 			StringLen(jp -> title -> data.ptrvalue) > 2)
1671 		{
1672 		   temp = retval = MemNew( (size_t) length);
1673 		   temp = StringMove(temp, (CharPtr) (jp -> title -> data.ptrvalue));
1674 		   if ((volume != NULL) || (ip->pages != NULL))
1675 		   {
1676 			temp = StringMove(temp," ");
1677 			if (volume != NULL)
1678 				temp = StringMove(temp, volume);
1679 			temp = doSup(temp, issue, part_sup, part_supi);
1680 			if (ip->pages != NULL)
1681 				if (embl_format)
1682 					temp = StringMove(temp,":");
1683 				else
1684 					temp = StringMove(temp,", ");
1685 		   }
1686 		   if (ip->pages != NULL)
1687 			temp = StringMove(temp, dup_pages);
1688 		   else if (ip->prepub == 2 && embl_format)
1689 			temp = StringMove(temp, " 0:0-0");
1690 		   else if (embl_format  && ip->pages == NULL
1691 			&& volume == NULL)
1692 			temp = StringMove(temp, " 0:0-0");
1693 		   if (embl_format)
1694 			temp = StringMove(temp," (");
1695 		   else
1696 			temp = StringMove(temp," (");
1697 		   temp = StringMove(temp, year);
1698 		   temp = StringMove(temp,")");
1699 		   if (ip->prepub == 2 && !embl_format)
1700 			temp = StringMove(temp, " In press");
1701 		}
1702 		else
1703 		{
1704 		   length = 2;
1705 		   temp = retval = MemNew( (size_t) length);
1706 		   temp = StringMove(temp,".");
1707 		}
1708 
1709 	}
1710 	else
1711 	{
1712                       temp = retval = MemNew(21*sizeof(Char));
1713                       temp = StringMove(temp, "Unpublished ");
1714                       if (year[0] != NULLB)
1715                       {
1716                               temp = StringMove(temp,"(");
1717                               temp = StringMove(temp, year);
1718                               temp = StringMove(temp,")");
1719                       }
1720 	}
1721 
1722 	if (volume)
1723 		volume = MemFree(volume);
1724 	if (issue)
1725 		issue = MemFree(issue);
1726 	if (part_sup)
1727 		part_sup = MemFree(part_sup);
1728 	if (part_supi)
1729 		part_supi = MemFree(part_supi);
1730 	if (dup_pages)
1731 		MemFree(dup_pages);
1732 
1733 	return retval;
1734 }	/* format_jourarticle */
1735 
1736 
1737 
1738 
1739 
1740 /************************************************************************
1741 *static CharPtr makeaffil(AffilPtr afp, CharPtr temp, Boolean PNTR first_std)
1742 *
1743 *	formats the affiliation into temp, which should already be
1744 *	allocated to hold this stuff.
1745 ***********************************************************************/
1746 
makeaffil(AffilPtr afp,CharPtr temp,Boolean PNTR first_std)1747 static CharPtr makeaffil(AffilPtr afp, CharPtr temp, Boolean PNTR first_std)
1748 
1749 {
1750 	*first_std = TRUE;
1751 
1752 	if (afp -> affil && StringLen(afp->affil) > 0)
1753 	{
1754 		temp = StringMove(temp, afp -> affil);
1755 		*first_std = FALSE;
1756 	}
1757 	if ( afp -> choice == 2){
1758 		if (afp -> div){
1759 			if ( ! *first_std)
1760 				temp = StringMove(temp,", ");
1761 			temp =  StringMove(temp,afp -> div);
1762 			*first_std = FALSE;
1763 		}
1764 		if (afp -> street){
1765 			if ( ! *first_std)
1766 				temp = StringMove(temp,", ");
1767 			temp =  StringMove(temp,afp -> street);
1768 			*first_std = FALSE;
1769 		}
1770 		if (afp -> city){
1771 			if ( ! *first_std)
1772 				temp = StringMove(temp,", ");
1773 			temp =  StringMove(temp,afp -> city);
1774 			*first_std = FALSE;
1775 		}
1776 		if (afp -> sub){
1777 			if ( ! *first_std)
1778 				temp = StringMove(temp,", ");
1779 			temp =  StringMove(temp,afp -> sub);
1780 			*first_std = FALSE;
1781 		}
1782 		if (afp -> country){
1783 			if ( ! *first_std)
1784 				temp = StringMove(temp,", ");
1785 			temp =  StringMove(temp,afp -> country);
1786 			*first_std = FALSE;
1787 		}
1788 	}
1789 	return temp;
1790 }
1791 
IsStringEmpty(CharPtr str)1792 static Boolean IsStringEmpty(CharPtr str)
1793 {
1794  	if (str == NULL)
1795  		return TRUE;
1796  	if (*str == '\0')
1797  		return TRUE;
1798     while (*str)
1799 	if (!isspace(*str))
1800 	    /* The string contains something other then whitespace
1801 	     */
1802 	    return FALSE;
1803 	else
1804 	    str++;
1805 
1806     return TRUE;
1807 }
1808 /************************************************************************
1809 *static CharPtr doSup(CharPtr temp, CharPtr issue, CharPtr part_sup, CharPtr part_supi)
1810 *
1811 *	copies the characters onto temp.
1812 *
1813 **************************************************************************/
doSup(CharPtr temp,CharPtr issue,CharPtr part_sup,CharPtr part_supi)1814 static CharPtr doSup(CharPtr temp, CharPtr issue, CharPtr part_sup, CharPtr part_supi)
1815 
1816 {
1817 	if (!IsStringEmpty(part_sup)) {
1818 		*temp = ' ';
1819 		temp++;
1820 		temp = StringMove(temp, part_sup);
1821 	}
1822 	if (IsStringEmpty(issue) && IsStringEmpty(part_supi)) {
1823 		return temp;
1824 	}
1825 	*temp = ' ';
1826 	temp++;
1827 	*temp = '(';
1828 	temp++;
1829 	if (!IsStringEmpty(issue)) {
1830 		temp = StringMove(temp, issue);
1831 	}
1832 	if (!IsStringEmpty(part_supi)) {
1833 		*temp = ' ';
1834 		temp++;
1835 		temp = StringMove(temp, part_supi);
1836 	}
1837 	*temp = ')';
1838 	temp++;
1839 	return temp;
1840 }
1841 
1842 /*************************************************************************
1843 *static CharPtr format_general(BiotablePtr btp, ValNodePtr the_pub, Boolean make_index)
1844 *
1845 *format pubs of type CitSub for GenBank and EMBL flat file.
1846 **************************************************************************/
1847 
fmt_gen_1(ValNodePtr the_pub,CharPtr unp,CharPtr affil,CitGenPtr cg,Boolean used_cit,Boolean found_journal,CharPtr year,CharPtr unp_long,CharPtr p,size_t len_page)1848 static CharPtr fmt_gen_1 (ValNodePtr the_pub, CharPtr unp, CharPtr affil, CitGenPtr cg, Boolean used_cit, Boolean found_journal,
1849 CharPtr year, CharPtr unp_long, CharPtr p, size_t len_page)
1850 
1851 {
1852   CharPtr  retval;
1853   Int2 volume=0, cit = 0;
1854 
1855   retval = NULL;
1856   /* use cit or journal */
1857   if (cg->cit) {
1858     	cit = StringLen(cg->cit);
1859   }
1860    if (cg->volume) {
1861 	volume = StringLen(cg->volume);
1862   }
1863   if (unp) {
1864     retval = MemNew ((size_t) (9+
1865       StringLen (unp) +
1866       StringLen (affil) +
1867       volume + 2*len_page + StringLen( year)) );
1868   } else if (cg -> cit && ! used_cit && found_journal ) {
1869     retval = MemNew ((size_t) (9 +
1870       11 + volume + 1+ cit + 2*len_page +
1871       StringLen( year) + StringLen (unp_long)) + StringLen(p));
1872   } else { /* tack extra unpub entry to end of year */
1873     retval = MemNew ((size_t) (9+
1874       11 + volume + StringLen(p) +
1875       2*len_page + StringLen( year) + StringLen (unp_long)) );
1876   }
1877 
1878   return retval;
1879 }
1880 
fmt_gen_2(Boolean embl_format,ValNodePtr the_pub,CharPtr start,CharPtr ptr,CharPtr unp,CharPtr unp_long,CitGenPtr cg,Uint1 format,CharPtr dup_pages,CharPtr year)1881 static CharPtr fmt_gen_2 (Boolean embl_format, ValNodePtr the_pub,
1882 		CharPtr start, CharPtr ptr, CharPtr unp, CharPtr unp_long,
1883 		CitGenPtr cg, Uint1 format, CharPtr dup_pages, CharPtr year)
1884 
1885 {
1886   CharPtr  temp, volume=NULL;
1887 
1888 	temp = start;
1889 	if (ptr) {
1890 		temp = StringMove (temp, ptr);
1891 	} else if (unp_long) {
1892 		temp = StringMove (temp, "Unpublished");
1893 	} else if (unp) {
1894 		if (!ASN2FF_SHOW_ALL_PUBS) {
1895 			temp = StringMove (temp, "Unpublished");
1896 		} else {
1897 			temp = StringMove (temp, unp);
1898 		}
1899 	}
1900 	if (cg->volume)
1901 	{
1902 	   volume = StringSave(cg->volume);
1903 	}
1904 
1905   	if (volume)
1906   	{
1907   		temp = StringMove (temp," ");
1908   		temp = StringMove (temp, volume);
1909   	}
1910 
1911   	if (dup_pages != NULL)
1912   	{
1913   		if (embl_format)
1914   			temp = StringMove (temp,":");
1915   		else
1916   			temp = StringMove (temp,", ");
1917   		temp = StringMove (temp, dup_pages);
1918   	}
1919 
1920   	if (year[0] != '\0')
1921   	{
1922   		/* this removes the year from unpublished records
1923   		if (unp == NULL) {
1924   			temp = StringMove (temp," (");
1925   			temp = StringMove (temp, year);
1926   			temp = StringMove (temp,")");
1927   		}
1928   		*/
1929   		temp = StringMove (temp," (");
1930   		temp = StringMove (temp, year);
1931   		temp = StringMove (temp,")");
1932   	}
1933 
1934   if (volume)
1935 	volume = MemFree(volume);
1936   return temp;
1937 }
1938 
format_general(Asn2ffJobPtr ajp,BioseqPtr bsp,ValNodePtr the_pub,Boolean make_index)1939 static CharPtr format_general (Asn2ffJobPtr ajp, BioseqPtr bsp, ValNodePtr the_pub, Boolean make_index)
1940 
1941 {
1942   AuthListPtr ap = NULL;
1943   Char ch;
1944   Boolean used_cit=FALSE, found_journal=FALSE;
1945   Char year[5];
1946   CharPtr affil=NULL, temp, dup_pages=NULL, retval=NULL;
1947   CharPtr str_ret, ptr, unp=NULL, unp_long=NULL, misc_unp=NULL;
1948   CitGenPtr cg;
1949   DatePtr dp;
1950   Int2 fix_p_ret;
1951   size_t len_page = 0;
1952   Uint1 format=ajp->format;
1953   Boolean embl_format = FALSE;
1954 
1955 	if (format == EMBL_FMT || format == PSEUDOEMBL_FMT ||
1956 					format == EMBLPEPT_FMT) {
1957 		embl_format = TRUE;
1958 	}
1959 	cg = (CitGenPtr) the_pub -> data.ptrvalue;
1960 	year[0] = '\0';
1961 	if (cg->date) {
1962 		dp = cg -> date;
1963 		if (dp -> data[0] == 1) {
1964 			sprintf (year,"%ld", (long) (1900 + dp -> data[1]));
1965 		} else {
1966 			StringNCpy ((CharPtr) year, (CharPtr) dp -> str, (size_t) 4);
1967 			year[4] = '\0';
1968 		}
1969 	}
1970 	if (cg->pages) {
1971 		len_page = StringLen (cg -> pages);
1972 		dup_pages = MemNew (2 * len_page);
1973 		fix_p_ret = fix_pages (dup_pages, cg ->pages);
1974 		if (fix_p_ret == -1) {
1975 			if (ajp->error_msgs == TRUE)
1976 				PostARefErrMessage (ajp, bsp, NULL, the_pub, 1, dup_pages);
1977 			}
1978 		} else if (StringNICmp ("unpublished", cg->cit, 11) != 0 &&
1979              StringNICmp ("submitted", cg->cit, 8) != 0 &&
1980              	StringNICmp ("in press", cg->cit, 8) != 0 &&
1981              		StringNICmp ("to be published", cg->cit, 15) != 0) {
1982 			if (ajp->error_msgs == TRUE)
1983 				PostARefErrMessage (ajp, bsp, NULL, the_pub, 2, NULL);
1984 		}
1985 		if (cg->journal) {
1986 			ptr = (CharPtr) (cg->journal->data.ptrvalue);
1987 			found_journal = TRUE;
1988 		} else {
1989 		ptr = NULL;
1990 	}
1991 
1992 	str_ret = NULL;
1993 	if (cg -> cit) {
1994 		ap=cg->authors;
1995 		str_ret = StrStr (cg -> cit ,"Journal=\"");
1996 		if (str_ret) {
1997 			retval = StringSave (str_ret + 9);
1998 			found_journal =used_cit = TRUE;
1999 			for (ptr=retval; *ptr; ptr++) {
2000 				if (*ptr == '=' || *ptr == '\"') {
2001 					*ptr = '\0';
2002 				}
2003 			}
2004 		} else if (ptr == NULL) {   /* no journal field, use cit */
2005 			used_cit = TRUE;
2006 			if (strncmp ("Unpublished ", cg->cit, (unsigned) 12) == 0) {
2007 				if (strlen (cg->cit) > (size_t) 12) { /* rest of Unpub entry */
2008 					unp_long = cg->cit;
2009 					unp_long += 11;
2010 				} else {
2011 					unp = cg->cit;
2012 					if ((ap=cg->authors) != NULL) {
2013 						if (ASN2FF_SHOW_ALL_PUBS)
2014 							affil = GetAffiliation (ap->affil);
2015 					}
2016 				}
2017 			} else if (strncmp ("Unpublished; ", cg->cit, (unsigned) 13) == 0) {
2018         		if (strlen (cg->cit) > (size_t) 13) { /* rest of Unpub entry */
2019 					unp_long = cg->cit;
2020 					unp_long += 12;
2021         		} else {
2022 					unp = cg->cit;
2023         			if ((ap=cg->authors) != NULL) {
2024         				if (ASN2FF_SHOW_ALL_PUBS)
2025           					affil = GetAffiliation (ap->affil);
2026         			}
2027       			}
2028     		} else if (StringNICmp ("unpublished", cg->cit, 11) == 0 ||
2029     		 	StringNICmp ("submitted", cg->cit, 8) == 0 ||
2030              		StringNICmp ("in press", cg->cit, 8) == 0 ||
2031              			StringNICmp ("to be published", cg->cit, 15) == 0) {
2032 				if (ASN2FF_SHOW_ALL_PUBS) {
2033 					misc_unp = StringSave(cg->cit);
2034         			if ((ap=cg->authors) != NULL)
2035          	   			affil = GetAffiliation (ap->affil);
2036 				} else {
2037 					misc_unp = StringSave("Unpublished");
2038 				}
2039 				unp = misc_unp;
2040 			} else if (ASN2FF_SHOW_ALL_PUBS) {
2041 				unp = StringSave(cg->cit);
2042         		if ((ap=cg->authors) != NULL)
2043          	   	affil = GetAffiliation (ap->affil);
2044 			}
2045 		}
2046 	}
2047 
2048   if ((retval == NULL) && ( (ptr != NULL) || unp != NULL || unp_long))   {
2049     /* use cit or journal */
2050     retval = fmt_gen_1 (the_pub, unp, affil, cg, used_cit, found_journal,
2051                         year, unp_long, ptr, len_page);
2052 
2053     temp = fmt_gen_2 (embl_format, the_pub, retval, ptr, unp, unp_long,
2054                       cg, format, dup_pages, year);
2055   }
2056   if (unp_long && ASN2FF_SHOW_ALL_PUBS) {
2057     temp = StringMove (temp, unp_long);
2058   } else if (unp ) {
2059     if (affil) {
2060       ptr = affil;
2061       ch = *affil;
2062       while (ch != '\0') {
2063         *temp = ch;
2064         temp++;
2065         affil++;
2066         ch = *affil;
2067       }
2068       affil = ptr;
2069       affil = MemFree (affil);
2070     }
2071   }
2072   if (cg -> cit && ! used_cit && found_journal) {
2073     temp = StringMove (temp," ");
2074     temp = StringMove (temp, cg -> cit);
2075   }
2076 
2077   if (dup_pages) {
2078     MemFree (dup_pages);
2079   }
2080 
2081   if (misc_unp != NULL)
2082 	misc_unp = MemFree(misc_unp);
2083 
2084   return retval;
2085 
2086 }  /* format_general */
2087 
2088 
2089 /*************************************************************************
2090 *CharPtr StripParanthesis(CharPtr ptr_in, Boolean PNTR paranthesis)
2091 *
2092 *	This function strips spaces and '(' from the front of
2093 *	ptr_in, copies the rest of the string, up to a possible
2094 *	')'.
2095 *
2096 *	The caller is responsible for deallocating "retval".
2097 *	do not strip spaces!   add by Tatiana 06.01.95
2098 ************************************************************************/
2099 
2100 static CharPtr
StripParanthesis(CharPtr ptr_in,Boolean PNTR paranthesis)2101 StripParanthesis(CharPtr ptr_in, Boolean PNTR paranthesis)
2102 {
2103 	CharPtr temp, retval;
2104 	Int2 length;
2105 
2106 	*paranthesis=FALSE;
2107 
2108 	while (*ptr_in == '(' )
2109 	{
2110 		if (*ptr_in == '(')
2111 			*paranthesis = TRUE;
2112 		ptr_in++;
2113 	}
2114 
2115 	if (*ptr_in == NULLB)
2116 		retval = NULL;
2117 	else
2118 	{
2119 		length = StringLen(ptr_in);
2120 		retval = temp = MemNew((length+1)*sizeof(Char));
2121 		while (*ptr_in != ')'  && *ptr_in != NULLB)
2122 		{
2123 			*temp = *ptr_in;
2124 			temp++; *ptr_in++;
2125 		}
2126 		if (*ptr_in == ')')
2127 			*paranthesis = TRUE;
2128 		temp = '\0';
2129 	}
2130 	return retval;
2131 }
2132 
2133 #define MAX_PAGE_DIGITS 12
2134 
2135 /*************************************************************************
2136 *
2137 *	 || (CharPtr out_pages, CharPtr in_pages)
2138 *
2139 *	in_pages: input page numbering.
2140 *	out_pages: output page numbering; "out_pages" should already
2141 *	have allocated space when fix_pages is called (twice as many
2142 *	characters as "in_pages").
2143 *
2144 *	medline type page numbering is expanded (e.g., 125-35 -> 125-135,
2145 *	F124-34 -> F124-F134, 12a-c -> 12a-12c).
2146 *	If only one page is given, this is output without a dash.
2147 *	Expanded numbering is validated to ensure that the
2148 *	first number is smaller than or equal to the second and
2149 *	that the first letter is less than or identical to the second
2150 *	(i.e., a < c).  If the input is all letters (i.e., roman numerals)
2151 *	this is not validated.
2152 *
2153 *	Return values:
2154 *	 0 : valid page numbering.
2155 *	-1 : invalid page numbering.
2156 ************************************************************************/
fix_pages(CharPtr out_pages,CharPtr in_pages)2157 NLM_EXTERN Int2 fix_pages (CharPtr out_pages, CharPtr in_pages)
2158 
2159 {
2160 	Boolean dash=TRUE, first_alpha;
2161 	Char firstbegin[MAX_PAGE_DIGITS];
2162 	Char secondbegin[MAX_PAGE_DIGITS];
2163 	Char firstend[MAX_PAGE_DIGITS];
2164 	Char secondend[MAX_PAGE_DIGITS];
2165 	Char temp[MAX_PAGE_DIGITS];
2166 	CharPtr alphabegin, numbegin, alphaend, numend, ptr, in=in_pages;
2167 	Int2 diff, index, retval=0;
2168 	Int2 length_nb, length_ab, length_ne, length_ae;
2169 	Int4 num1=0, num2=0;
2170 
2171 	while (*in != '\0')
2172 	{			/* Check for digits in input*/
2173 		if (IS_DIGIT(*in))
2174 			break;
2175 		in++;
2176 	}
2177 
2178 	if (*in == '\0' || (in != in_pages && *(in-1) == ' '))
2179 	{		/* if all letters (i.e. roman numerals), put out. */
2180 		out_pages = StringCpy(out_pages, in_pages);
2181 		return retval;
2182 	}
2183 
2184 	in = in_pages;
2185 	if (IS_DIGIT(*in))
2186 	{			/* Do digits come first? */
2187 		first_alpha = FALSE;
2188 		index=0;
2189 		while (IS_DIGIT(*in) || *in == ' ')
2190 		{
2191 			firstbegin[index] = *in;
2192 			if (*in != ' ')
2193 				index++;
2194 			in++;
2195 			if (*in == '-')
2196 				break;
2197 
2198 		}
2199 		firstbegin[index] = '\0';
2200 		index=0;
2201 		if (*in != '-')
2202 		{		/* After digits look for letters. */
2203 			while (IS_ALPHA(*in)  || *in == ' ')
2204 			{
2205 				secondbegin[index] = *in;
2206 				index++;
2207 				in++;
2208 				if (*in == '-')
2209 					break;
2210 			}
2211 		}
2212 		secondbegin[index] = '\0';
2213 		if (*in == '-')		/* if dash is not present, note */
2214 			in++;
2215 		else
2216 			dash=FALSE;
2217 		index=0;
2218 		while (IS_DIGIT(*in) || *in == ' ')
2219 		{			/* Look for digits.	*/
2220 			firstend[index] = *in;
2221 			if (*in != ' ')
2222 				index++;
2223 			in++;
2224 		}
2225 		firstend[index] = '\0';
2226 		index=0;
2227 		if (*in != '\0')
2228 		{			/* Look for letters again. */
2229 			while (IS_ALPHA(*in)  || *in == ' ')
2230 			{
2231 				secondend[index] = *in;
2232 				index++;
2233 				in++;
2234 			}
2235 		}
2236 		secondend[index] = '\0';
2237 	}
2238 	else
2239 	{			/* Do letters come first? */
2240 		first_alpha = TRUE;
2241 		index=0;
2242 		while (IS_ALPHA(*in) || *in == ' ')
2243 		{
2244 			firstbegin[index] = *in;
2245 			index++;
2246 			in++;
2247 			if (*in == '-')
2248 				break;
2249 		}
2250 		firstbegin[index] = '\0';
2251 		index=0;
2252 		if (*in != '-')
2253 		{		/* After letters look for digits. 	*/
2254 			while (IS_DIGIT(*in)  || *in == ' ')
2255 			{
2256 				secondbegin[index] = *in;
2257 				if (*in != ' ')
2258 					index++;
2259 				in++;
2260 				if (*in == '-')
2261 					break;
2262 			}
2263 		}
2264 		secondbegin[index] = '\0';
2265 		if (*in == '-')		/* Note if dash is missing. */
2266 			in++;
2267 		else
2268 			dash=FALSE;
2269 		index=0;
2270 		while (IS_ALPHA(*in) || *in == ' ')
2271 		{		/* Look for letters again. */
2272 			firstend[index] = *in;
2273 			index++;
2274 			in++;
2275 		}
2276 		firstend[index] = '\0';
2277 		index=0;
2278 		if (*in != '\0')
2279 		{		/* Any digits here? */
2280 			while (IS_DIGIT(*in)  || *in == ' ')
2281 			{
2282 				secondend[index] = *in;
2283 				if (*in != ' ')
2284 					index++;
2285 				in++;
2286 			}
2287 		}
2288 		secondend[index] = '\0';
2289 	}
2290 
2291 	if (first_alpha)
2292 	{
2293 		alphabegin = firstbegin;
2294 		numbegin = secondbegin;
2295 		alphaend = firstend;
2296 		numend = secondend;
2297 	}
2298 	else
2299 	{
2300 		numbegin = firstbegin;
2301 		alphabegin = secondbegin;
2302 		numend = firstend;
2303 		alphaend = secondend;
2304 	}
2305 
2306 	length_nb = StringLen(numbegin);
2307 	length_ab = StringLen(alphabegin);
2308 	length_ne = StringLen(numend);
2309 	length_ae = StringLen(alphaend);
2310 
2311 	/* If no dash, but second letters or numbers present, reject. */
2312 	if (dash == FALSE)
2313 	{
2314 		if (length_ne != 0 || length_ae != 0)
2315 			retval = -1;
2316 	}
2317 	/* Check for situations like "AAA-123" or "222-ABC". */
2318 	if (dash == TRUE)
2319 	{
2320 		if (length_ne == 0 && length_ab == 0)
2321 			retval = -1;
2322 		else if (length_ae == 0 && length_nb == 0)
2323 			retval = -1;
2324 	}
2325 
2326 	/* The following expands "F502-512" into "F502-F512" and
2327 	checks, for entries like "12a-12c" that a > c.  "12aa-12ab",
2328 	"125G-137A", "125-G137" would be rejected. */
2329 	if (retval == 0)
2330 	{
2331 		if (length_ab > 0)
2332 		{
2333 			if (length_ae > 0)
2334 			{
2335 				if (StringCmp(alphabegin, alphaend) != 0)
2336 				{
2337 					if (length_ab != 1 || length_ae != 1)
2338 						retval = -1;
2339 					else if (*alphabegin > *alphaend)
2340 						retval = -1;
2341 				}
2342 			}
2343 			else
2344 			{
2345 				alphaend = alphabegin;
2346 				length_ae = length_ab;
2347 			}
2348 		}
2349 		else if (length_ae > 0)
2350 			retval = -1;
2351 	}
2352 
2353 /* The following expands "125-37" into "125-137".	*/
2354 	if (retval == 0)
2355 	{
2356 		if (length_nb > 0)
2357 		{
2358 			if (length_ne > 0)
2359 			{
2360 				diff = length_nb - length_ne;
2361 				if (diff > 0)
2362 				{
2363 					index=0;
2364 					while (numend[index] != '\0')
2365 					{
2366 						temp[index+diff] = numend[index];
2367 						index++;
2368 					}
2369 					temp[index+diff] = numend[index];
2370 					for (index=0; index<diff; index++)
2371 						temp[index] = numbegin[index];
2372 					index=0;
2373 					while (temp[index] != '\0')
2374 					{
2375 						numend[index] = temp[index];
2376 						index++;
2377 					}
2378 					numend[index] = temp[index];
2379 				}
2380 			}
2381 			else
2382 			{
2383 				numend = numbegin;
2384 				length_ne = length_nb;
2385 			}
2386 
2387 		}
2388 		else if (length_ne > 0)
2389 			retval = -1;
2390 	/* Check that the first number is <= the second (expanded) number. */
2391 		if (retval == 0)
2392 		{
2393 	/*		sscanf(numbegin, "%ld", &num_type);
2394 			num1 = (Int4) num_type;
2395 			sscanf(	numend, "%ld", &num_type);
2396 			num2 = (Int4) num_type;
2397 	*/
2398 			num1 = (Int4) atol(numbegin);
2399 			num2 = (Int4) atol(numend);
2400 			if (num2 < num1)
2401 				retval = -1;
2402 		}
2403 	}
2404 
2405 	if (retval == -1)
2406 	{
2407 		out_pages = StringCpy(out_pages, in_pages);
2408 	}
2409 	else
2410 	{
2411 		ptr = out_pages;
2412 	/* Place expanded and validated page numbers into "out_pages". */
2413 		if (first_alpha)
2414 		{
2415 			while (*alphabegin != '\0')
2416 			{
2417 				*ptr = *alphabegin;
2418 				alphabegin++;
2419 				ptr++;
2420 			}
2421 			while (*numbegin != '\0')
2422 			{
2423 				*ptr = *numbegin;
2424 				numbegin++;
2425 				ptr++;
2426 			}
2427 			if (dash == TRUE)
2428 			{
2429 				*ptr = '-';
2430 				ptr++;
2431 				while (*alphaend != '\0')
2432 				{
2433 					*ptr = *alphaend;
2434 					alphaend++;
2435 					ptr++;
2436 				}
2437 				while (*numend != '\0')
2438 				{
2439 					*ptr = *numend;
2440 					numend++;
2441 					ptr++;
2442 				}
2443 			}
2444 			*ptr = '\0';
2445 		}
2446 		else
2447 		{
2448 			while (*numbegin != '\0')
2449 			{
2450 				*ptr = *numbegin;
2451 				numbegin++;
2452 				ptr++;
2453 			}
2454 			while (*alphabegin != '\0')
2455 			{
2456 				*ptr = *alphabegin;
2457 				alphabegin++;
2458 				ptr++;
2459 			}
2460 			if (dash == TRUE)
2461 			{
2462 				*ptr = '-';
2463 				ptr++;
2464 				while (*numend != '\0')
2465 				{
2466 					*ptr = *numend;
2467 					numend++;
2468 					ptr++;
2469 				}
2470 				while (*alphaend != '\0')
2471 				{
2472 					*ptr = *alphaend;
2473 					alphaend++;
2474 					ptr++;
2475 				}
2476 			}
2477 			*ptr = '\0';
2478 		}
2479 	}
2480 	return retval;
2481 }
2482 
2483 /*****************************************************************************
2484 *FlatDateFromCreate
2485 *
2486 *	taken (with minor modifications) from Karl Sirotkin's code
2487 *	by Tom Madden.
2488 *
2489 *****************************************************************************/
2490 
2491 NLM_EXTERN CharPtr
FlatDateFromCreate(CharPtr default_date,NCBI_DatePtr flat_date)2492 FlatDateFromCreate (CharPtr default_date, NCBI_DatePtr flat_date)
2493 {
2494 	CharPtr retval = NULL;
2495 	char month[4], year[5]  , day[3];
2496 	CharPtr daypt = & day[0];
2497 	char result[14];
2498 	char localbuf[14];
2499 
2500 	if ( flat_date -> data[0] == 0){
2501 /*---string---*/
2502 		if (StringICmp(flat_date -> str,"Not given") != 0){
2503 			retval = StringSave(flat_date -> str);
2504 		}
2505 	}else{
2506 /*---standard---*/
2507 		if (! default_date  ||
2508 				(flat_date -> data[1] &&flat_date -> data[2]
2509 					&& flat_date -> data[3])){
2510 			if (flat_date -> data[1]){
2511 				sprintf(year, "%4ld", (long) (flat_date -> data[1] + 1900));
2512 			}else{
2513 				sprintf(year, "????");
2514 			}
2515 			if (flat_date -> data[3]){
2516 				if (flat_date -> data[3] <= 9){
2517 					*daypt = '0';
2518 					daypt ++;
2519 				}
2520 				sprintf(localbuf, "%ld", (long) (flat_date -> data[3] ));
2521 			}else{
2522 				sprintf(localbuf, "??");
2523 			}
2524 			StringCpy (daypt, localbuf);
2525 			if ( flat_date -> data[2] ){
2526 				StringCpy(month, NCBI_months[flat_date -> data[2] -1 ]);
2527 				month[1] = TO_UPPER(month[1]);
2528 				month[2] = TO_UPPER(month[2]);
2529 			}else{
2530 				sprintf(month, "??");
2531 			}
2532 			sprintf(result,"%s-%s-%s",day,month, year);
2533 			retval = StringSave(result);
2534 		}
2535 	}
2536 	return retval;
2537 }
2538 
2539 /*****************************************************************************
2540 *FlatIgnoreThisPatentPub
2541 *	Compares patent pub with patent seq_id
2542 *	returns TRUE if they don't match
2543 *****************************************************************************/
FlatIgnoreThisPatentPub(BioseqPtr bsp,ValNodePtr best,Int4Ptr seqidPt)2544 NLM_EXTERN Boolean FlatIgnoreThisPatentPub (BioseqPtr bsp, ValNodePtr best, Int4Ptr seqidPt)
2545 {
2546 	Boolean retval = FALSE;
2547 	CitPatPtr cp;
2548 	SeqIdPtr sip;
2549 	PatentSeqIdPtr psip;
2550 	IdPatPtr ip;
2551 
2552 	if (best == NULL)
2553 		return FALSE;
2554 	if (seqidPt){
2555 		* seqidPt = 0;
2556 	}
2557 	if (best -> choice != 9){
2558 		return retval;
2559 	}
2560 	cp = (CitPatPtr) best -> data.ptrvalue;
2561 	for ( sip = bsp -> id; sip; sip = sip -> next){
2562 		if (sip -> choice != SEQID_PATENT) {
2563 			continue;
2564 		}
2565 		psip = (PatentSeqIdPtr) sip -> data.ptrvalue;
2566 		ip = psip -> cit;
2567 		if (ip == NULL) {
2568 			continue;
2569 		}
2570 		retval = TRUE;
2571 		if (ip -> number){
2572 			if (StringCmp(ip -> number, cp -> number) == 0){
2573 				retval = FALSE;
2574 				if (seqidPt){
2575 					*seqidPt = psip -> seqid;
2576 				}
2577 				break;
2578 			}
2579 		} else if (ip -> app_number){
2580 			if (StringCmp(ip -> app_number, cp -> app_number) == 0){
2581 				retval = FALSE;
2582 				if (seqidPt){
2583 					*seqidPt = (psip -> seqid);
2584 				}
2585 				break;
2586 			}
2587 		}
2588 	}
2589 
2590 	return retval;
2591 }
2592 
GetAffiliation(AffilPtr afp)2593 NLM_EXTERN CharPtr GetAffiliation (AffilPtr afp)
2594 
2595 {
2596 	Boolean need_comma=FALSE;
2597 	CharPtr string=NULL, temp, ptr;
2598 	Int2 aflen=15;
2599 
2600 	if (afp) {
2601 		if (afp -> choice == 1){
2602 			if (afp -> affil){
2603 				aflen += StringLen(afp -> affil);
2604 			}
2605 		}else if (afp -> choice == 2){
2606 			aflen += StringLen (afp -> affil) +
2607 			StringLen (afp -> div) +
2608 			StringLen (afp -> city) +
2609 			StringLen (afp -> sub) +
2610 			StringLen (afp -> street) +
2611 			StringLen (afp -> country) + StringLen(afp->postal_code);
2612 		}
2613 
2614 		temp = string = MemNew(aflen);
2615 
2616 		if ( afp -> choice == 1){
2617 			 if (afp -> affil){
2618 				*temp = ' '; temp++;
2619 				ptr = afp->affil;
2620 				while ((*temp = *ptr) != '\0')
2621 				{
2622 					temp++; ptr++;
2623 				}
2624 			 }
2625 		}else if (afp -> choice == 2){
2626 
2627 			*temp = ' ';
2628 			temp++;
2629 			if( afp -> div) {
2630 				if (need_comma)
2631 				{
2632 					*temp = ','; temp++;
2633 					*temp = ' '; temp++;
2634 				}
2635 				ptr = afp->div;
2636 				while ((*temp = *ptr) != '\0')
2637 				{
2638 					temp++; ptr++;
2639 				}
2640 				need_comma = TRUE;
2641 			}
2642 
2643 			if(afp -> affil) {
2644 				if (need_comma)
2645 				{
2646 					*temp = ','; temp++;
2647 					*temp = ' '; temp++;
2648 				}
2649 				ptr = afp->affil;
2650 				while ((*temp = *ptr) != '\0')
2651 				{
2652 					temp++; ptr++;
2653 				}
2654 				need_comma = TRUE;
2655 			}
2656 
2657 			if(afp -> street) {
2658 				if (need_comma)
2659 				{
2660 					*temp = ','; temp++;
2661 					*temp = ' '; temp++;
2662 				}
2663 				ptr = afp->street;
2664 				while ((*temp = *ptr) != '\0')
2665 				{
2666 					temp++; ptr++;
2667 				}
2668 				need_comma = TRUE;
2669 			}
2670 
2671 			if( afp -> city) {
2672 				if (need_comma)
2673 				{
2674 					*temp = ','; temp++;
2675 					*temp = ' '; temp++;
2676 				}
2677 				ptr = afp->city;
2678 				while ((*temp = *ptr) != '\0')
2679 				{
2680 					temp++; ptr++;
2681 				}
2682 				need_comma = TRUE;
2683 			}
2684 
2685 			if( afp -> sub) {
2686 				if (need_comma)
2687 				{
2688 					*temp = ','; temp++;
2689 					*temp = ' '; temp++;
2690 				}
2691 				ptr = afp->sub;
2692 				while ((*temp = *ptr) != '\0')
2693 				{
2694 					temp++; ptr++;
2695 				}
2696 				need_comma = TRUE;
2697 			}
2698 
2699 			if( afp -> postal_code){
2700 				*temp = ' ';
2701 				temp++;
2702 				ptr = afp->postal_code;
2703 				while ((*temp = *ptr) != '\0')
2704 				{
2705 					temp++; ptr++;
2706 				}
2707 			}
2708 
2709 			if( afp -> country){
2710 				if (need_comma)
2711 				{
2712 					*temp = ','; temp++;
2713 					*temp = ' '; temp++;
2714 				}
2715 				ptr = afp->country;
2716 				while ((*temp = *ptr) != '\0')
2717 				{
2718 					temp++; ptr++;
2719 				}
2720 				need_comma = TRUE;
2721 			}
2722 		}
2723 		temp++;
2724 		*temp = '\0';
2725 	}
2726 	return string;
2727 }	/* GetAffiliation */
2728 
2729 
2730 /*****************************************************************************
2731 *CheckPubs
2732 *
2733 *	Code to check that the pub contains enough info to warrant
2734 *	printing out.  This is checked out in ValidatePub.
2735 *	If the pub is not valid, it is deleted from the list.
2736 *
2737 *	do not delete in debug mode  (tatiana)
2738 *	Returns the number of valid pubs found.
2739 *
2740 *****************************************************************************/
2741 
CheckPubs(Asn2ffJobPtr ajp,BioseqPtr bsp,ValNodePtr PNTR vnpp)2742 NLM_EXTERN Int2 CheckPubs (Asn2ffJobPtr ajp, BioseqPtr bsp, ValNodePtr PNTR vnpp)
2743 
2744 {
2745 	Boolean good_one = FALSE;
2746 	Int2 retval=0, status;
2747 	PubStructPtr psp;
2748 	ValNodePtr last, newpub, vnp2, vnp = *vnpp, pub;
2749 
2750 	UniquePubs(vnpp);
2751 	last=NULL;
2752 	vnp = *vnpp;
2753 	while (vnp)
2754 	{
2755 		psp = vnp->data.ptrvalue;
2756 		if ((psp->pub)->choice == PUB_Equiv)
2757 			newpub = psp->pub->data.ptrvalue;
2758 		else
2759 			newpub = psp->pub;
2760 
2761 		for (vnp2=newpub; vnp2; vnp2=vnp2->next)
2762 			if ((status=ValidatePub(bsp, vnp2)) > 0)
2763 			{
2764 				retval++;
2765 				break;
2766 			}
2767 
2768 		if (status < 0)
2769 		{
2770 			vnp->choice = (Uint1) 1;
2771 			if (ajp->error_msgs)
2772 				PostARefErrMessage (ajp, bsp, psp, NULL, status, NULL);
2773 		}
2774 		else
2775 		{
2776 			good_one = TRUE;
2777 		}
2778 		vnp = vnp->next;
2779 	}
2780 
2781 /* If not one good pub was found, look for something printable and take that. */
2782 	vnp = *vnpp;
2783 	if (good_one == FALSE)
2784 	{
2785 		retval = -1;
2786 		while (vnp)
2787 		{
2788 			psp = vnp->data.ptrvalue;
2789 			pub = FlatRefBest(psp->pub, FALSE, FALSE);
2790 /* If a pub is a patent it probably failed FlatIgnoreThisPatentPub; don't
2791 take it and keep looking. */
2792 			if (pub != NULL && pub->choice != PUB_Patent)
2793 			{
2794 				vnp->choice = (Uint1) 0;
2795 				retval = 0;
2796 				break;
2797 			}
2798 			vnp = vnp->next;
2799 		}
2800 	}
2801 	if (ASN2FF_SHOW_ALL_PUBS) {
2802 		return retval;
2803 	}
2804 /* Drop the bad ones. */
2805 	vnp = *vnpp;
2806 	last = NULL;
2807 	while (vnp)
2808 	{
2809 		if (vnp->choice != 0)
2810 		{
2811 		    if (last == NULL)
2812 		    {	/* If the first pub is bad. */
2813 			*vnpp = vnp->next;
2814 			vnp->next = NULL;
2815 			FreePubStruct(vnp->data.ptrvalue);
2816 			ValNodeFree(vnp);
2817 			vnp = *vnpp;
2818 		    }
2819 		    else
2820 		    {	/* If any but the first pub is bad. */
2821 			last->next = vnp->next;
2822 			vnp->next = NULL;
2823 			FreePubStruct(vnp->data.ptrvalue);
2824 			ValNodeFree(vnp);
2825 			vnp = last->next;
2826 		    }
2827 		}
2828 		else
2829 		{
2830 			last = vnp;
2831 			vnp = vnp->next;
2832 		}
2833 	}
2834 
2835 	return retval;
2836 }
2837 
2838 /*****************************************************************************
2839 *ValidatePub
2840 *
2841 *	Checks whether pubs include authors, journal names etc.
2842 *
2843 * At present (2/10/94) this function passes most pubs w/o checks (i.e.,
2844 * status is 0.  This should be tightened up to include more checks
2845 *(vol. # etc.)???????????
2846 *
2847 *	(8/17/94): adding more specific information on error return:
2848 *	status:
2849 *		-1	not specific, reference is just bad.
2850 *		-2	no valid author names.
2851 *		-3	no valid journal title.
2852 *
2853 *****************************************************************************/
2854 
ValidatePub(BioseqPtr bsp,ValNodePtr the_pub)2855 NLM_EXTERN Int2 ValidatePub (BioseqPtr bsp, ValNodePtr the_pub)
2856 {
2857 	AuthListPtr		ap;
2858 	AuthorPtr		authptr;
2859 	Boolean			ignore_this=FALSE;
2860 	CitBookPtr		cb;
2861 	CitSubPtr		cs;
2862 	CitGenPtr		cg;
2863 	CitArtPtr		ca;
2864 	CitPatPtr		cp;
2865 	Int2 			length, status = -1;
2866 	Int4			pat;
2867 	MedlineEntryPtr ml;
2868 	CitJourPtr		jp;
2869 	ImprintPtr		ip;
2870 	NameStdPtr		nsp;
2871 	PersonIdPtr		pid;
2872 
2873 	switch ( the_pub -> choice) {
2874 
2875      	case PUB_Sub:
2876 			status = 1;
2877 			cs = (CitSubPtr) the_pub -> data.ptrvalue;
2878 			ap = cs->authors;
2879 		break;
2880 		case PUB_Man:
2881 		case PUB_Book:
2882 			cb = (CitBookPtr) the_pub -> data.ptrvalue;
2883 			if ( cb -> imp) {
2884 				ip = cb -> imp;
2885 				if (ip)
2886 					status = 1;
2887 			}
2888 			ap = cb->authors;
2889 		break;
2890 		case PUB_Patent:
2891 			ignore_this = FlatIgnoreThisPatentPub(bsp, the_pub, &pat);
2892 			if (ignore_this == FALSE || ISA_aa(bsp->mol))
2893 				status = 1;
2894 			cp = (CitPatPtr) the_pub -> data.ptrvalue;
2895 			ap = cp->authors;
2896 			break;
2897 
2898 		case PUB_Medline:
2899 		case PUB_Article:
2900 			if ( the_pub -> choice == PUB_Medline) {
2901 				ml = (MedlineEntryPtr) the_pub -> data.ptrvalue;
2902 				ca = (CitArtPtr) ml -> cit;
2903 			} else {
2904 				ca = (CitArtPtr) the_pub -> data.ptrvalue;
2905 			}
2906 		if ( ca -> fromptr) {
2907 			if ( ca -> from ==1) {
2908 				jp = (CitJourPtr) ca -> fromptr;
2909 				if (StringLen((CharPtr)jp->title->data.ptrvalue) == 0) {
2910 					ip = jp->imp;
2911 					if (ip && ip->prepub == 0) {
2912 						status = -3;
2913 						break;
2914 					}
2915 				}
2916 				if ( jp -> imp)
2917 						status = 1;
2918 			} else {
2919 				CitBookPtr book = (CitBookPtr) ca -> fromptr;
2920 					if ( book -> imp)
2921 							status = 1;
2922 			}
2923 		}
2924 		ap = ca -> authors;
2925 		break;
2926 		case PUB_Gen:
2927 			cg = (CitGenPtr) the_pub -> data.ptrvalue;
2928 			if (cg -> cit) {
2929 				if (StringNICmp("unpublished", cg->cit, 11) == 0)
2930 					status = 1;
2931 				if (StringNICmp("submitted", cg->cit, 8) == 0)
2932 					status = 1;
2933 				if (StringNICmp("to be published", cg->cit, 15) == 0)
2934 					status = 1;
2935 				if (StringNICmp("in press", cg->cit, 8) == 0)
2936 					status = 1;
2937 				else if (StrStr(cg->cit, "Journal") != NULL)
2938 					status = 1;
2939 			} else {
2940 				if ((cg->journal) && (cg->date))
2941 					status = 1;
2942 				else if (cg->journal == NULL)
2943 					status = -4;
2944 				else if (cg->date == NULL)
2945 					status = -5;
2946 			}
2947 
2948 			ap = cg -> authors;
2949 			break;
2950 		default:
2951 			status = -1;
2952 			break;
2953 	}
2954 
2955 	if (status < 0)
2956 		return status;
2957 	else if (ap == NULL)
2958 		return -2;
2959 
2960 	if (ap && the_pub -> choice != PUB_Patent) {
2961 		if (ap->choice == 1) {
2962 			if (ap->names == NULL) {
2963 				return -2;
2964 			}
2965 			authptr = (AuthorPtr) (ap->names)->data.ptrvalue;
2966 			pid = authptr->name;
2967 			if (pid->choice == 2) {
2968 				nsp = (NameStdPtr) pid->data;
2969 				length = StringLen(nsp->names[0]);
2970 				length += StringLen(nsp->names[3]);
2971 				if (length == 0)
2972 					status = -2;
2973 			} else if (pid->choice == 3 || pid->choice == 4) {
2974 				length = StringLen((CharPtr)pid->data);
2975 				if (length == 0)
2976 					status = -2;
2977 			}
2978 		} else if (ap->choice == 2 || ap->choice == 3) {
2979 			if (ap->names == NULL)
2980 				status = -2;
2981 			else if (StringLen((CharPtr)ap->names->data.ptrvalue) == 0)
2982 				status = -2;
2983 		}
2984 	}
2985 
2986 	return status;
2987 }
2988 
2989 /*************************************************************************
2990 *void PostARefErrMessage(Asn2ffJobPtr ajp, BioseqPtr bsp, PubStructPtr psp, ValNodePtr pub, Int2 status, CharPtr string)
2991 *
2992 *	Given a pub, by "checkPubs", this function posts an error
2993 *	message about the invalid reference.
2994 *
2995 *	status has the following meanings:
2996 *
2997 *		-1	not specific, reference is just bad.
2998 *		-2	no valid author names.
2999 *		-3	no valid journal title.
3000 *************************************************************************/
3001 
PostARefErrMessage(Asn2ffJobPtr ajp,BioseqPtr bsp,PubStructPtr psp,ValNodePtr ext_pub,Int2 status,CharPtr ext_string)3002 NLM_EXTERN void PostARefErrMessage (Asn2ffJobPtr ajp, BioseqPtr bsp, PubStructPtr psp, ValNodePtr ext_pub, Int2 status, CharPtr ext_string)
3003 
3004 {
3005 	Boolean /*UNUSED*/ignore_this, submit=FALSE, error;
3006 	CharPtr authors=NULL, string=NULL, newstring=NULL, title=NULL, journal=NULL, ptr;
3007 	Char buffer[30];
3008 	Int2 length;
3009 	Int4 pat_seqid=0;
3010 	ValNodePtr equiv, pub;
3011 
3012 /*	ajp->format = GENBANK_FMT; */
3013 /*	ajp->newline = ' '; */
3014 	error = ajp->error_msgs;
3015 	ajp->error_msgs = FALSE;
3016 
3017 	if (bsp == NULL) {
3018 		flat2asn_delete_locus_user_string();
3019 		flat2asn_install_locus_user_string("SET_UP");
3020 		flat2asn_delete_accession_user_string();
3021 		flat2asn_install_accession_user_string("SET_UP");
3022 	} else {
3023 		MakeAnAccession(buffer, bsp->id, 30);
3024 		flat2asn_delete_locus_user_string();
3025 		flat2asn_install_locus_user_string(buffer);
3026 		flat2asn_delete_accession_user_string();
3027 		flat2asn_install_accession_user_string(buffer);
3028 	}
3029 	if (ext_pub)
3030 		pub = ext_pub;
3031 	else if (psp)
3032 		pub = FlatRefBest(psp->pub, TRUE, FALSE);
3033 	else	/* Nothing done here, as neither pub nor psp is given! */
3034 		return;
3035 
3036 	if (pub == NULL && ext_string == NULL)
3037 	{	/* Look for pubs that only have muid of zero! */
3038 		equiv = psp->pub;
3039 		if (equiv->choice == PUB_Equiv)
3040 			pub = equiv->data.ptrvalue;
3041 		else
3042 			pub = equiv;
3043 		if (pub)
3044 		{
3045 			if (pub->choice == 4 && pub->next == NULL)
3046 			   if (pub->data.intvalue == 0)
3047 				status = -9;
3048 		}
3049 		pub = NULL;	/* To avoid problems down below */
3050 	}
3051 
3052 
3053 
3054 	if (pub != NULL)
3055 	{
3056 		ignore_this = FlatIgnoreThisPatentPub(bsp, pub, &pat_seqid);
3057 /* if ext_pub is not NULL, then the call is from FlatJournal, due to
3058 bad pagination, and calling FlatJournal, with error_msgs set to TRUE, risks
3059 a loop! */
3060 		if (ext_pub != NULL)
3061 			ajp->error_msgs = FALSE;
3062 		journal = FlatJournal(ajp, ajp->asn2ffwep->gbp, pub, pat_seqid, &submit, FALSE);
3063 		title = FlatPubTitle(pub);
3064 		authors = FlatAuthor(ajp, pub);
3065 	}
3066 
3067 	length = StringLen(ext_string) + StringLen(authors) + StringLen(journal) + StringLen(title) + 5;
3068 
3069 	string = newstring = MemNew(length*sizeof(Char));
3070 
3071 	if (authors)
3072 	{
3073 		ptr = authors;
3074 		while (*ptr != '\0')
3075 		{
3076 			*string = *ptr;
3077 			ptr++; string++;
3078 		}
3079 		authors = MemFree(authors);
3080 	}
3081 	*string = '|';
3082 	string++;
3083 
3084 	if (journal)
3085 	{
3086 		ptr = journal;
3087 		while (*ptr != '\0')
3088 		{
3089 			*string = *ptr;
3090 			ptr++; string++;
3091 		}
3092 	}
3093 	*string = '|';
3094 	string++;
3095 
3096 	if (title)
3097 	{	/* Also may be needed below. */
3098 		ptr = title;
3099 		while (*ptr != '\0')
3100 		{
3101 			*string = *ptr;
3102 			ptr++; string++;
3103 		}
3104 	}
3105 	*string = '|';
3106 	string++;
3107 
3108 	if (ext_string)
3109 	{
3110 		ptr = ext_string;
3111 		while (*ptr != '\0')
3112 		{
3113 			*string = *ptr;
3114 			ptr++; string++;
3115 		}
3116 	}
3117 
3118 /* Sometimes an error is caused by a Direct Sub in a cit-gen */
3119 	if (status > 0 &&
3120 		pub->choice == 1 &&
3121 		    title != NULL &&
3122 			StringNCmp(title, "Direct Submission", 17) == 0)
3123 		status = 3;
3124 	else if (status > 0 &&
3125 		pub->choice == 1 &&
3126 		    journal != NULL &&
3127 			StringNCmp(journal, "Submitted", 9) == 0)
3128 		status = 3;
3129 
3130 	if (title)
3131 		title = MemFree(title);
3132 	if (journal)
3133 		journal = MemFree(journal);
3134 
3135 	if (status == 5)
3136 	    ErrPostStr(SEV_INFO, ERR_REFERENCE_ParanInSupp, newstring);
3137 	if (status == 4)
3138 	    ErrPostStr(SEV_INFO, ERR_REFERENCE_VolHasSuppl, newstring);
3139 	else if (status == 3)
3140 	    ErrPostStr(SEV_INFO, ERR_REFERENCE_DirSubInCitGen, newstring);
3141 	else if (status == 2)
3142 	    ErrPostStr(SEV_WARNING, ERR_REFERENCE_NoPageNumbering, newstring);
3143 	else if (status == 1)
3144 	    ErrPostStr(SEV_WARNING, ERR_REFERENCE_IllegalPageRange, newstring);
3145 	else if (status == -1)
3146 	    ErrPostStr(SEV_ERROR, ERR_REFERENCE_Illegalreference, newstring);
3147 	if (status == -2)
3148 	    ErrPostStr(SEV_ERROR, ERR_REFERENCE_NoAuthorName, newstring);
3149 	else if (status == -3 || status == -4)
3150 	    ErrPostStr(SEV_ERROR, ERR_REFERENCE_NoJournalName, newstring);
3151 	else if (status == -5)
3152 	    ErrPostStr(SEV_ERROR, ERR_REFERENCE_NoDateOnRef, newstring);
3153 	else if (status == -9)
3154 	    ErrPostStr(SEV_WARNING, ERR_REFERENCE_MuidZeroOnly, newstring);
3155 
3156 	newstring = MemFree(newstring);
3157 	ajp->error_msgs = error;
3158 	return;
3159 }
3160 
3161 /*************************************************************************
3162 *	This function does a check that the NAFeat will be valid at all,
3163 *	i.e., that it has a valid key and all the mandatory qualifiers
3164 *	are present.  ValidateNAImpFeat does a more thorough validation
3165 *	later on.
3166 *	New condition (7/21/94): if the feature is a misc_feature and
3167 *	has no valid qualifiers, it is dropped.
3168 ************************************************************************/
CheckNAFeat(Boolean is_new,BioseqPtr bsp,SeqFeatPtr sfp)3169 NLM_EXTERN Boolean CheckNAFeat(Boolean is_new, BioseqPtr bsp, SeqFeatPtr sfp)
3170 
3171 {
3172 	Boolean allocated=FALSE, found_key, location=FALSE, valid=FALSE;
3173 	CharPtr key=NULL;
3174 	CharPtr ptr=NULL;
3175 	GBQualPtr gbqual;
3176 	Int2 index, status;
3177 
3178 	found_key = GetNAFeatKey(is_new, &key, sfp, NULL);
3179 
3180 	if (found_key)
3181 	{
3182 		flat2asn_install_feature_user_string(key, NULL);
3183 		index = GBFeatKeyNameValid(&key, FALSE);
3184 		if (index != -1)
3185 		{
3186 			location = CheckAndGetNAFeatLoc(bsp, &ptr, sfp, TRUE);
3187 			flat2asn_delete_feature_user_string();
3188 			flat2asn_install_feature_user_string(key, ptr);
3189 			gbqual=sfp->qual;
3190 			if (StringCmp(key, "source") == 0) {  /*fake check for Biosource */
3191 				status = GB_FEAT_ERR_NONE;
3192 				valid = TRUE;
3193 			} else {
3194 				status = GBFeatKeyQualValid(sfp->cit, index, &gbqual,
3195 											ASN2FF_SHOW_ERROR_MSG, FALSE);
3196 				if (status == GB_FEAT_ERR_NONE)
3197 					valid = TRUE;
3198 				else if (status == GB_FEAT_ERR_REPAIRABLE)
3199 				{ /* Check if bad qual is required!! */
3200 					gbqual = GBQualCopy(sfp->qual);
3201 					allocated = TRUE;
3202 					status = GBFeatKeyQualValid(sfp->cit, index, &gbqual,
3203 																 FALSE, TRUE);
3204 					if (status != GB_FEAT_ERR_DROP)
3205 						valid = TRUE;
3206 				}
3207 			}
3208 			ptr = MemFree(ptr);
3209 
3210 			if (valid == TRUE &&
3211 				StringCmp(key, "misc_feature") == 0)
3212 			{ /* Check for at least one valid qual on misc_feature*/
3213 				if (gbqual == NULL)
3214 					if (sfp->data.choice != 1 &&
3215 						sfp->comment == NULL)
3216 					{
3217 						valid = FALSE;
3218 					ErrPostStr(SEV_WARNING, ERR_FEATURE_NoQualOnMiscFeat, " ");
3219 					}
3220 			} /* was gbqual allocated, or a copy of sfp->qual?*/
3221 			if (allocated == TRUE && gbqual != NULL)
3222 					gbqual = GBQualFree(gbqual);
3223 		}
3224 		else if (ASN2FF_SHOW_ERROR_MSG == TRUE)
3225 		{
3226 			ErrPostStr(SEV_WARNING, ERR_FEATURE_UnknownFeatureKey, " ");
3227 		}
3228 		flat2asn_delete_feature_user_string();
3229 	}
3230 
3231 	if (location && valid)
3232 		return TRUE;
3233 	else
3234 		return FALSE;
3235 }	/* CheckNAFeat */
3236 
3237 /*************************************************************************
3238 *Boolean CheckAndGetNAFeatLoc(BiotablePtr btp, Int2 count, CharPtr PNTR buffer, SeqFeatPtr sfp, Boolean loc_return)
3239 *
3240 *	This function does a check that the feature location is valid.
3241 *	It makes use of parser validation functions.
3242 *	The Boolean "loc_return" specifies whether or not a location should
3243 *	be returned.
3244 ************************************************************************/
3245 
CheckAndGetNAFeatLoc(BioseqPtr bsp,CharPtr PNTR buffer,SeqFeatPtr sfp,Boolean loc_return)3246 NLM_EXTERN Boolean CheckAndGetNAFeatLoc(BioseqPtr bsp, CharPtr PNTR buffer, SeqFeatPtr sfp, Boolean loc_return)
3247 
3248 {
3249 	Boolean location=FALSE;
3250 	CharPtr flatloc_ptr=NULL;
3251 	ImpFeatPtr ifp=NULL;
3252 	int num_errs;
3253 	Boolean keep_rawPt, sitesPt;
3254 	SeqIdPtr seq_id;
3255 	SeqLocPtr slp;
3256 
3257 	if (bsp == NULL)
3258 		return FALSE;
3259 	seq_id = SeqIdFindBest(bsp->id, SEQID_GENBANK);
3260 	install_gbparse_range_func(NULL, check_range);
3261 	if (ASN2FF_SHOW_ERROR_MSG == TRUE) {
3262 		install_gbparse_error_handler(do_loc_errors);
3263 	} else {
3264 		install_gbparse_error_handler(do_no_loc_errors);
3265 	}
3266 	if (sfp->data.choice == SEQFEAT_IMP) {	/* Use ifp->loc if OK */
3267 		ifp = sfp->data.value.ptrvalue;
3268 		if (ifp && ifp->loc) {
3269 			slp = gbparseint(ifp->loc, &keep_rawPt,
3270 							&sitesPt, &num_errs, seq_id);
3271 			if (num_errs == 0) {
3272 				SeqLocFree(slp);
3273 				location=TRUE;
3274 			} else if ( ASN2FF_VALIDATE_FEATURES == FALSE && loc_return) {
3275 				flat2asn_install_feature_user_string(ifp->key, ifp->loc);
3276 				flat2asn_delete_feature_user_string();
3277 			}
3278 			if (loc_return) {
3279 				if (*buffer)
3280 					*buffer = MemFree(*buffer);
3281 				*buffer = StringSave (ifp->loc);
3282 			}
3283 		}
3284 	}
3285 
3286 	if (location == FALSE)
3287 	{	/* only called if not an ImpFeatPtr and/or ifp->loc bad */
3288 		flatloc_ptr =  FlatLoc(bsp, sfp->location);
3289 		slp = gbparseint(flatloc_ptr, &keep_rawPt, &sitesPt, &num_errs, seq_id);
3290 
3291 		if (num_errs == 0 || ASN2FF_VALIDATE_FEATURES == FALSE)
3292 		{
3293 			SeqLocFree(slp);
3294 			location=TRUE;
3295 		}
3296 		if (loc_return)
3297 		{
3298 			if (*buffer)
3299 				*buffer = MemFree(*buffer);
3300 			*buffer = flatloc_ptr;
3301 		}
3302 		else
3303 			flatloc_ptr = MemFree(flatloc_ptr);
3304 	}
3305 
3306 	if (location)
3307 		return TRUE;
3308 	else
3309 		return FALSE;
3310 }	/* CheckAndGetNAFeatLoc */
3311 
3312 /*****************************************************************************
3313 *void GetAAFeatLoc(BioseqPtr bsp, CharPtr PNTR buffer, SeqFeatPtr sfp, Boolean use_product)
3314 *
3315 *	"twin" to CheckAndGetNAFeatLoc, except that no checking is done
3316 *	yet for genpept.
3317 ****************************************************************************/
3318 
GetAAFeatLoc(BioseqPtr bsp,CharPtr PNTR buffer,SeqFeatPtr sfp,Boolean use_product)3319 NLM_EXTERN void GetAAFeatLoc(BioseqPtr bsp, CharPtr PNTR buffer, SeqFeatPtr sfp, Boolean use_product)
3320 {
3321 	Boolean location=FALSE;
3322 	CharPtr flatloc_ptr=NULL;
3323 	ImpFeatPtr ifp=NULL;
3324 
3325 	if (sfp->data.choice == SEQFEAT_IMP) {
3326 		ifp = sfp->data.value.ptrvalue;
3327 		if (ifp && ifp->loc) {
3328 			if (*buffer) {
3329 				*buffer = MemFree(*buffer);
3330 			}
3331 			*buffer = StringSave (ifp->loc);
3332 			location = TRUE;
3333 		}
3334 	}
3335 
3336 	if (location == FALSE) {
3337 		if (use_product)  /* Used for CDS in genpept. */
3338 			flatloc_ptr =  FlatLoc(bsp, sfp->product);
3339 		else
3340 			flatloc_ptr =  FlatLoc(bsp, sfp->location);
3341 
3342 		if (*buffer)
3343 			*buffer = MemFree(*buffer);
3344 		*buffer = flatloc_ptr;
3345 	}
3346 
3347 }	/* GetAAFeatLoc */
3348 
GBQualCopy(GBQualPtr old_qual)3349 static GBQualPtr GBQualCopy (GBQualPtr old_qual)
3350 {
3351         GBQualPtr curq, new_qual, new_qual_start=NULL;
3352 
3353         if (old_qual)
3354         {
3355                 new_qual_start = new_qual = GBQualNew();
3356                 for (curq=old_qual; curq; curq=curq->next)
3357                 {
3358                         if (curq->val)
3359                                 new_qual->val = StringSave(curq->val);
3360                         if (curq->qual)
3361                                 new_qual->qual = StringSave(curq->qual);
3362                         if (curq->next)
3363                         {
3364                                 new_qual->next = GBQualNew();
3365                                 new_qual = new_qual->next;
3366                         }
3367                         else
3368                                 new_qual->next = NULL;
3369                 }
3370         }
3371         return new_qual_start;
3372 }
3373 
3374