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