1 /* objpub.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * File Name: objpub.c
27 *
28 * Author: James Ostell
29 *
30 * Version Creation Date: 4/1/91
31 *
32 * $Revision: 6.10 $
33 *
34 * File Description: Object manager for module NCBI-Pub
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 * 05-13-93 Schuler All public functions are now declared LIBCALL.
41 *
42 *
43 * $Log: objpub.c,v $
44 * Revision 6.10 2015/10/23 00:04:24 kans
45 * NOIJRA Clear av DataVal variable on AsnWrite, needed for supporting Int8 integers in ASN.1
46 *
47 * Revision 6.9 2010/03/09 16:56:39 bollin
48 * Include Medline/PMID in Medline article formatting.
49 *
50 * Revision 6.8 2009/10/02 19:44:49 kans
51 * address clang static analyzer warnings
52 *
53 * Revision 6.7 2005/12/29 13:46:18 bollin
54 * added PubdescContentMatch function
55 *
56 * Revision 6.6 2004/04/01 13:43:08 lavr
57 * Spell "occurred", "occurrence", and "occurring"
58 *
59 * Revision 6.5 2002/01/08 20:48:22 kans
60 * PubLabelUnique internal call to PubLabelUnique (..., unique), not PubLabel
61 *
62 * Revision 6.4 2001/11/20 14:50:54 kans
63 * PubLabelUnique return immediately if PMID or MUID, already unique
64 *
65 * Revision 6.3 2000/06/15 19:13:28 yaschenk
66 * PubAsnWrite should not fail when pmid is stripped
67 *
68 * Revision 6.2 1998/12/30 20:28:34 ostell
69 * fixed bug in PubLabelUnique() for author list. If alp->names is NULL,
70 * diff was not initialized. So operations using diff moved inside
71 * if (vnp2 != NULL)
72 *
73 * Revision 6.1 1998/08/24 18:28:08 kans
74 * removed solaris -v -fd warnings
75 *
76 * Revision 6.0 1997/08/25 18:50:27 madden
77 * Revision changed to 6.0
78 *
79 * Revision 4.12 1997/06/19 18:41:46 vakatov
80 * [WIN32,MSVC++] Adopted for the "NCBIOBJ.LIB" DLL'ization
81 *
82 * Revision 4.11 1996/09/12 18:42:53 epstein
83 * spec_version fixes as suggested by J. Kans
84 *
85 * Revision 4.10 1996/07/30 15:22:20 epstein
86 * correct logic errors for different spec_versions
87 *
88 * Revision 4.9 1996/07/01 17:46:53 tatiana
89 * month and day added to PubLabelUnique() in submission label
90 *
91 * Revision 4.8 1996/05/30 21:11:24 tatiana
92 * fill in the result buffer if cgp->cit is the only field set (in PubLabelUnique).
93 *
94 * Revision 4.7 1996/03/29 21:09:59 ostell
95 * added support for PubMedId
96 *
97 * Revision 4.6 1996/03/01 18:08:53 tatiana
98 * fix in PubLabelUnique
99 *
100 * Revision 4.5 1995/10/17 18:10:28 tatiana
101 * fix in PubLabelUnique
102 *
103 * Revision 4.4 1995/10/13 14:04:26 tatiana
104 * a bug fixed in PubLabelUnique
105 *
106 * Revision 4.3 1995/09/07 14:16:55 tatiana
107 * fix in PubLabelUnique function
108 *
109 * Revision 4.2 1995/08/30 22:25:21 kans
110 * cap->title uses ->data.ptrvalue
111 *
112 * Revision 4.1 1995/08/30 18:33:53 ostell
113 * added PubLabelUnique function
114 *
115 * Revision 4.0 1995/07/26 13:48:06 ostell
116 * force revision to 4.0
117 *
118 * Revision 3.7 1995/05/15 21:22:00 ostell
119 * added Log line
120 *
121 *
122 *
123 * ==========================================================================
124 */
125 #include <objpub.h> /* the pub interface */
126 #include <asnpub.h> /* the AsnTool header */
127 #include <objmgr.h>
128
129 static Boolean loaded = FALSE;
130
131 /*****************************************************************************
132 *
133 * Pub ObjMgr Routines
134 *
135 *****************************************************************************/
136 static CharPtr pubtypename = "Pub";
137
PubNewFunc(void)138 static Pointer LIBCALLBACK PubNewFunc (void)
139 {
140 return (Pointer) ValNodeNew(NULL);
141 }
142
PubFreeFunc(Pointer data)143 static Pointer LIBCALLBACK PubFreeFunc (Pointer data)
144 {
145 return (Pointer) PubFree ((ValNodePtr) data);
146 }
147
PubAsnWriteFunc(Pointer data,AsnIoPtr aip,AsnTypePtr atp)148 static Boolean LIBCALLBACK PubAsnWriteFunc (Pointer data, AsnIoPtr aip, AsnTypePtr atp)
149 {
150 return PubAsnWrite((ValNodePtr)data, aip, atp);
151 }
152
PubAsnReadFunc(AsnIoPtr aip,AsnTypePtr atp)153 static Pointer LIBCALLBACK PubAsnReadFunc (AsnIoPtr aip, AsnTypePtr atp)
154 {
155 return (Pointer) PubAsnRead (aip, atp);
156 }
157
PubLabelFunc(Pointer data,CharPtr buffer,Int2 buflen,Uint1 content)158 static Int2 LIBCALLBACK PubLabelFunc ( Pointer data, CharPtr buffer, Int2 buflen, Uint1 content)
159 {
160 return PubLabel((ValNodePtr)data, buffer, buflen, content);
161 }
162
PubSubTypeFunc(Pointer ptr)163 static Uint2 LIBCALLBACK PubSubTypeFunc (Pointer ptr)
164 {
165 if (ptr == NULL)
166 return 0;
167 return (Uint2)((ValNodePtr)ptr)->choice;
168 }
169
170 /*****************************************************************************
171 *
172 * CitSub ObjMgr Routines
173 *
174 *****************************************************************************/
175 static CharPtr seqsubcittypename = "Cit";
176
CitSubNewFunc(void)177 static Pointer LIBCALLBACK CitSubNewFunc (void)
178 {
179 return (Pointer) CitSubNew();
180 }
181
CitSubFreeFunc(Pointer data)182 static Pointer LIBCALLBACK CitSubFreeFunc (Pointer data)
183 {
184 return (Pointer) CitSubFree ((CitSubPtr) data);
185 }
186
CitSubAsnWriteFunc(Pointer data,AsnIoPtr aip,AsnTypePtr atp)187 static Boolean LIBCALLBACK CitSubAsnWriteFunc (Pointer data, AsnIoPtr aip, AsnTypePtr atp)
188 {
189 return CitSubAsnWrite((CitSubPtr)data, aip, atp);
190 }
191
CitSubAsnReadFunc(AsnIoPtr aip,AsnTypePtr atp)192 static Pointer LIBCALLBACK CitSubAsnReadFunc (AsnIoPtr aip, AsnTypePtr atp)
193 {
194 return (Pointer) CitSubAsnRead (aip, atp);
195 }
196
CitSubLabelFunc(Pointer data,CharPtr buffer,Int2 buflen,Uint1 content)197 static Int2 LIBCALLBACK CitSubLabelFunc ( Pointer data, CharPtr buffer, Int2 buflen, Uint1 content)
198 {
199 ValNode vn;
200
201 vn.choice = PUB_Sub;
202 vn.data.ptrvalue = data;
203 vn.next = NULL;
204
205 return PubLabel(&vn, buffer, buflen, content);
206 }
207
208
209 /*****************************************************************************
210 *
211 * PubSet ObjMgr Routines
212 *
213 *****************************************************************************/
214 static CharPtr pubsettypename = "PubSet";
215
PubSetNewFunc(void)216 static Pointer LIBCALLBACK PubSetNewFunc (void)
217 {
218 return (Pointer) ValNodeNew(NULL);
219 }
220
PubSetFreeFunc(Pointer data)221 static Pointer LIBCALLBACK PubSetFreeFunc (Pointer data)
222 {
223 return (Pointer) PubSetFree ((ValNodePtr) data);
224 }
225
PubSetAsnWriteFunc(Pointer data,AsnIoPtr aip,AsnTypePtr atp)226 static Boolean LIBCALLBACK PubSetAsnWriteFunc (Pointer data, AsnIoPtr aip, AsnTypePtr atp)
227 {
228 return PubSetAsnWrite((ValNodePtr)data, aip, atp);
229 }
230
PubSetAsnReadFunc(AsnIoPtr aip,AsnTypePtr atp)231 static Pointer LIBCALLBACK PubSetAsnReadFunc (AsnIoPtr aip, AsnTypePtr atp)
232 {
233 return (Pointer) PubSetAsnRead (aip, atp);
234 }
235
PubSetLabelFunc(Pointer data,CharPtr buffer,Int2 buflen,Uint1 content)236 static Int2 LIBCALLBACK PubSetLabelFunc ( Pointer data, CharPtr buffer, Int2 buflen, Uint1 content)
237 {
238 return PubSetLabel ((ValNodePtr)data, buffer, buflen, content);
239 }
240
PubSetLabel(ValNodePtr pubset,CharPtr buffer,Int2 buflen,Uint1 content)241 NLM_EXTERN Int2 LIBCALL PubSetLabel (ValNodePtr pubset, CharPtr buffer, Int2 buflen, Uint1 content)
242 {
243 static CharPtr set_names[8] = {
244 "NotSet",
245 "Pub",
246 "Medline",
247 "Articles",
248 "Journals",
249 "Books",
250 "Procs",
251 "Patents" };
252 Int2 diff, len, i = 0;
253 Char tbuf[40];
254 ValNodePtr vnp;
255
256 if ((pubset == NULL) || (buflen < 1))
257 return 0;
258
259 if ((pubset->choice >=1) && (pubset->choice <= 7))
260 i= (Int2)(pubset->choice);
261
262 len = buflen;
263
264 if (content == OM_LABEL_TYPE)
265 return LabelCopy(buffer, set_names[i], buflen);
266
267 if (content != OM_LABEL_CONTENT)
268 {
269 diff = LabelCopyExtra(buffer, set_names[i], buflen, NULL, ": ");
270 buflen -= diff;
271 buffer += diff;
272 }
273
274 i=0;
275 for (vnp = (ValNodePtr)(pubset->data.ptrvalue); vnp != NULL; vnp = vnp->next)
276 i++;
277
278 if (i == 1)
279 sprintf(tbuf, "1 pub");
280 else
281 sprintf(tbuf, "%d pubs", (int)i);
282
283 diff = LabelCopy(buffer, tbuf, buflen);
284 buflen -= diff;
285 buffer += diff;
286
287 return (len - buflen); /* no special SUMMARY yet */
288 }
289
PubSetSubTypeFunc(Pointer ptr)290 static Uint2 LIBCALLBACK PubSetSubTypeFunc (Pointer ptr)
291 {
292 if (ptr == NULL)
293 return 0;
294 return (Uint2)((ValNodePtr)ptr)->choice;
295 }
296
297 /*****************************************************************************
298 *
299 * PubAsnLoad()
300 *
301 *****************************************************************************/
PubAsnLoad(void)302 NLM_EXTERN Boolean LIBCALL PubAsnLoad (void)
303 {
304 if (loaded)
305 return TRUE;
306 loaded = TRUE;
307
308 if (! GeneralAsnLoad())
309 {
310 loaded = FALSE;
311 return FALSE;
312 }
313 if (! BiblioAsnLoad())
314 {
315 loaded = FALSE;
316 return FALSE;
317 }
318 if (! MedlineAsnLoad())
319 {
320 loaded = FALSE;
321 return FALSE;
322 }
323 if (! AsnLoad())
324 {
325 loaded = FALSE;
326 return FALSE;
327 }
328
329 ObjMgrTypeLoad(OBJ_PUB, "Pub", pubtypename, "Publication",
330 PUB, PubNewFunc, PubAsnReadFunc, PubAsnWriteFunc,
331 PubFreeFunc, PubLabelFunc, PubSubTypeFunc);
332
333 ObjMgrTypeLoad(OBJ_SEQSUB_CIT, "Cit", seqsubcittypename, "Submission Citation",
334 PUB_sub, CitSubNewFunc, CitSubAsnReadFunc, CitSubAsnWriteFunc,
335 CitSubFreeFunc, CitSubLabelFunc, NULL);
336
337 ObjMgrTypeLoad(OBJ_SEQFEAT_CIT, "Seqfeat.cit", "Cit", "Feature Citation",
338 PUB, PubNewFunc, PubAsnReadFunc, PubAsnWriteFunc,
339 PubFreeFunc, PubLabelFunc, PubSubTypeFunc);
340
341 ObjMgrTypeLoad(OBJ_PUB_SET, "Pub-set", pubsettypename, "Set of Publications",
342 PUB_SET, PubSetNewFunc, PubSetAsnReadFunc, PubSetAsnWriteFunc,
343 PubSetFreeFunc, PubSetLabelFunc, PubSetSubTypeFunc);
344
345 return TRUE;
346 }
347
348
349 /*****************************************************************************
350 *
351 * Pub Routines
352 *
353 *****************************************************************************/
354 /*****************************************************************************
355 *
356 * Pub is a choice using an ValNode
357 * choice:
358 * 0 = not set
359 1 = gen Cit-gen , -- general or generic unparsed
360 2 = sub Cit-sub , -- submission
361 3 = medline Medline-entry ,
362 4 = muid INTEGER , -- medline uid
363 5 = article Cit-art ,
364 6 = journal Cit-jour ,
365 7 = book Cit-book ,
366 8 = proc Cit-proc , -- proceedings of a meeting
367 9 = patent Cit-pat ,
368 10 = pat-id Id-pat , -- identify a patent
369 11 = man Cit-let , -- manuscript or letter
370 12 = equiv Pub-equiv -- set of equivalent citation forms for 1 pub
371 13 = pmid INTEGER -- PubMedId
372 *
373 *****************************************************************************/
374 /*****************************************************************************
375 *
376 * PubFree(anp)
377 * Frees one pub and associated data
378 *
379 *****************************************************************************/
PubFree(ValNodePtr anp)380 NLM_EXTERN ValNodePtr LIBCALL PubFree (ValNodePtr anp)
381 {
382 Pointer pnt;
383
384 if (anp == NULL)
385 return anp;
386
387 pnt = anp->data.ptrvalue;
388 switch (anp->choice)
389 {
390 case 1: /* gen */
391 CitGenFree((CitGenPtr)pnt);
392 break;
393 case 2: /* sub */
394 CitSubFree((CitSubPtr)pnt);
395 break;
396 case 3: /* medline */
397 MedlineEntryFree((MedlineEntryPtr)pnt);
398 break;
399 case 4: /* uid in intvalue */
400 break;
401 case 5: /* article */
402 CitArtFree((CitArtPtr)pnt);
403 break;
404 case 6: /* journal */
405 CitJourFree((CitJourPtr)pnt);
406 break;
407 case 7: /* book */
408 case 8: /* proceedings */
409 case 11: /* manuscript */
410 CitBookFree((CitBookPtr)pnt);
411 break;
412 case 9: /* patent */
413 CitPatFree((CitPatPtr)pnt);
414 break;
415 case 10: /* patent id */
416 IdPatFree((IdPatPtr)pnt);
417 break;
418 case 12:
419 PubEquivFree((ValNodePtr)pnt);
420 break;
421 case 13: /* pubmedid */
422 break;
423 }
424
425 ObjMgrDelete(OBJ_PUB, (Pointer)anp);
426
427 return (ValNodePtr)MemFree(anp);
428 }
429
430 /*****************************************************************************
431 *
432 * PubAsnWrite(anp, aip, atp)
433 * atp is the current type (if identifier of a parent struct)
434 * if atp == NULL, then assumes it stands alone (Pub ::=)
435 *
436 *****************************************************************************/
PubAsnWrite(ValNodePtr anp,AsnIoPtr aip,AsnTypePtr orig)437 NLM_EXTERN Boolean LIBCALL PubAsnWrite (ValNodePtr anp, AsnIoPtr aip, AsnTypePtr orig)
438 {
439 DataVal av;
440 AsnTypePtr atp, writetype = NULL;
441 Pointer pnt;
442 AsnWriteFunc func = NULL;
443 Boolean retval = FALSE;
444
445 if (! loaded)
446 {
447 if (! PubAsnLoad())
448 return FALSE;
449 }
450
451 if (aip == NULL)
452 return FALSE;
453
454 atp = AsnLinkType(orig, PUB); /* link local tree */
455 if (atp == NULL) return FALSE;
456
457 if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
458
459 MemSet ((Pointer) (&av), 0, sizeof (DataVal));
460
461 if ((aip->spec_version > 0 && aip->spec_version < 5) && anp->choice >= 13) /* ASN4 strip new value */
462 {
463 ErrPostEx(SEV_ERROR,0,0,"ASN4: PubMedId stripped");
464 retval=TRUE;
465 goto erret;
466 }
467
468 av.ptrvalue = (Pointer)anp;
469 if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) goto erret;
470
471 pnt = anp->data.ptrvalue;
472 switch (anp->choice)
473 {
474 case 1: /* gen */
475 writetype = PUB_gen;
476 func = (AsnWriteFunc) CitGenAsnWrite;
477 break;
478 case 2: /* sub */
479 writetype = PUB_sub;
480 func = (AsnWriteFunc) CitSubAsnWrite;
481 break;
482 case 3: /* medline */
483 writetype = PUB_medline;
484 func = (AsnWriteFunc) MedlineEntryAsnWrite;
485 break;
486 case 4: /* uid in intvalue */
487 av.intvalue = anp->data.intvalue;
488 if (! AsnWrite(aip, PUB_muid, &av)) goto erret;
489 break;
490 case 5: /* article */
491 writetype = PUB_article;
492 func = (AsnWriteFunc) CitArtAsnWrite;
493 break;
494 case 6: /* journal */
495 writetype = PUB_journal;
496 func = (AsnWriteFunc) CitJourAsnWrite;
497 break;
498 case 7: /* book */
499 writetype = PUB_book;
500 func = (AsnWriteFunc) CitBookAsnWrite;
501 break;
502 case 8: /* proceedings */
503 writetype = PUB_proc;
504 func = (AsnWriteFunc) CitProcAsnWrite;
505 break;
506 case 11: /* manuscript */
507 writetype = PUB_man;
508 func = (AsnWriteFunc) CitLetAsnWrite;
509 break;
510 case 9: /* patent */
511 writetype = PUB_patent;
512 func = (AsnWriteFunc) CitPatAsnWrite;
513 break;
514 case 10: /* patent id */
515 writetype = PUB_pat_id;
516 func = (AsnWriteFunc) IdPatAsnWrite;
517 break;
518 case 12: /* equiv */
519 writetype = PUB_equiv;
520 func = (AsnWriteFunc) PubEquivAsnWrite;
521 break;
522 case 13: /* pmid in intvalue */
523 av.intvalue = anp->data.intvalue;
524 if (! AsnWrite(aip, PUB_pmid, &av)) goto erret;
525 break;
526 }
527 if (writetype != NULL)
528 {
529 if (! (*func)(pnt, aip, writetype)) goto erret;
530 }
531 retval = TRUE;
532 erret:
533 AsnUnlinkType(orig); /* unlink local tree */
534 return retval;
535 }
536 /*****************************************************************************
537 *
538 * PubAsnRead(aip, atp)
539 * atp is the current type (if identifier of a parent struct)
540 * assumption is readIdent has occurred
541 * if atp == NULL, then assumes it stands alone and read ident
542 * has not occurred.
543 *
544 *****************************************************************************/
PubAsnRead(AsnIoPtr aip,AsnTypePtr orig)545 NLM_EXTERN ValNodePtr LIBCALL PubAsnRead (AsnIoPtr aip, AsnTypePtr orig)
546 {
547 DataVal av;
548 AsnTypePtr atp;
549 ValNodePtr anp=NULL;
550 Uint1 choice = 0;
551 AsnReadFunc func = NULL;
552
553 if (! loaded)
554 {
555 if (! PubAsnLoad())
556 return anp;
557 }
558
559 if (aip == NULL)
560 return anp;
561
562 if (orig == NULL) /* Pub ::= (self contained) */
563 atp = AsnReadId(aip, amp, PUB);
564 else
565 atp = AsnLinkType(orig, PUB); /* link in local tree */
566 if (atp == NULL) return anp;
567
568 anp = ValNodeNew(NULL);
569 if (anp == NULL) goto erret;
570
571 if (AsnReadVal(aip, atp, &av) <= 0) goto erret; /* read the CHOICE value (nothing) */
572 atp = AsnReadId(aip, amp, atp); /* find the choice */
573 if (atp == NULL) goto erret;
574
575 if (atp == PUB_gen)
576 {
577 choice = 1;
578 func = (AsnReadFunc) CitGenAsnRead;
579 }
580 else if (atp == PUB_sub)
581 {
582 choice = 2;
583 func = (AsnReadFunc) CitSubAsnRead;
584 }
585 else if (atp == PUB_medline)
586 {
587 choice = 3;
588 func = (AsnReadFunc) MedlineEntryAsnRead;
589 }
590 else if (atp == PUB_muid)
591 {
592 choice = 4;
593 if (AsnReadVal(aip, atp, &anp->data) <= 0) goto erret;
594 }
595 else if (atp == PUB_article)
596 {
597 choice = 5;
598 func = (AsnReadFunc) CitArtAsnRead;
599 }
600 else if (atp == PUB_journal)
601 {
602 choice = 6;
603 func = (AsnReadFunc) CitJourAsnRead;
604 }
605 else if (atp == PUB_book)
606 {
607 choice = 7;
608 func = (AsnReadFunc) CitBookAsnRead;
609 }
610 else if (atp == PUB_proc)
611 {
612 choice = 8;
613 func = (AsnReadFunc) CitProcAsnRead;
614 }
615 else if (atp == PUB_patent)
616 {
617 choice = 9;
618 func = (AsnReadFunc) CitPatAsnRead;
619 }
620 else if (atp == PUB_pat_id)
621 {
622 choice = 10;
623 func = (AsnReadFunc) IdPatAsnRead;
624 }
625 else if (atp == PUB_man)
626 {
627 choice = 11;
628 func = (AsnReadFunc) CitLetAsnRead;
629 }
630 else if (atp == PUB_equiv)
631 {
632 choice = 12;
633 func = (AsnReadFunc) PubEquivAsnRead;
634 }
635 else if (atp == PUB_pmid)
636 {
637 choice = 13;
638 if (AsnReadVal(aip, atp, &anp->data) <= 0) goto erret;
639 }
640
641 anp->choice = choice;
642 if ((choice != 4) && (choice != 13) && func != NULL)
643 {
644 anp->data.ptrvalue = (* func)(aip, atp);
645 if (anp->data.ptrvalue == NULL) goto erret;
646 }
647 ret:
648 AsnUnlinkType(orig); /* unlink local tree */
649 return anp;
650 erret:
651 anp = PubFree(anp);
652 goto ret;
653 }
654
655 /*****************************************************************************
656 *
657 * PubSet is a choice using an ValNode
658 * choice:
659 * 0 = not set
660 1 = pub Pub , -- mixed pubs
661 3 = medline Medline-entry , -- use same mapping as Pub for these
662 5 = article Cit-art ,
663 6 = journal Cit-jour ,
664 7 = book Cit-book ,
665 8 = proc Cit-proc , -- proceedings of a meeting
666 9 = patent Cit-pat ,
667 *
668 * PubSet->data.ptrvalue points to chain of Pub (even if not mixed) so
669 * each Pub is self identifying anyway and Pub routines can be used
670 *****************************************************************************/
671 /*****************************************************************************
672 *
673 * PubSetFree(anp)
674 * Frees one Pub-set and associated data
675 *
676 *****************************************************************************/
PubSetFree(ValNodePtr anp)677 NLM_EXTERN ValNodePtr LIBCALL PubSetFree (ValNodePtr anp)
678 {
679 if (anp == NULL)
680 return anp;
681
682 PubEquivFree((ValNodePtr)anp->data.ptrvalue);
683
684 ObjMgrDelete(OBJ_PUB_SET, (Pointer)anp);
685
686 return (ValNodePtr)MemFree(anp);
687 }
688
689 /*****************************************************************************
690 *
691 * PubSetAsnWrite(anp, aip, atp)
692 * atp is the current type (if identifier of a parent struct)
693 * if atp == NULL, then assumes it stands alone (PubSet ::=)
694 *
695 *****************************************************************************/
PubSetAsnWrite(ValNodePtr anp,AsnIoPtr aip,AsnTypePtr orig)696 NLM_EXTERN Boolean LIBCALL PubSetAsnWrite (ValNodePtr anp, AsnIoPtr aip, AsnTypePtr orig)
697 {
698 DataVal av;
699 AsnTypePtr atp, settype = NULL, elementtype;
700 Pointer pnt;
701 Uint1 choice;
702 AsnWriteFunc func = NULL;
703 ValNodePtr oldanp;
704 Boolean retval = FALSE;
705
706 if (! loaded)
707 {
708 if (! PubAsnLoad())
709 return FALSE;
710 }
711
712 if (aip == NULL)
713 return FALSE;
714
715 atp = AsnLinkType(orig, PUB_SET); /* link local tree */
716 if (atp == NULL) return FALSE;
717
718 if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
719
720 MemSet ((Pointer) (&av), 0, sizeof (DataVal));
721
722 av.ptrvalue = (Pointer)anp;
723 if (! AsnWriteChoice(aip, atp, (Int2)anp->choice, &av)) goto erret;
724 choice = anp->choice; /* type of set */
725 switch (choice)
726 {
727 case 1:
728 settype = PUB_SET_pub;
729 elementtype = PUB_SET_pub_E;
730 func = (AsnWriteFunc) PubAsnWrite;
731 break;
732 case 3:
733 settype = PUB_SET_medline;
734 elementtype = PUB_SET_medline_E;
735 func = (AsnWriteFunc) MedlineEntryAsnWrite;
736 break;
737 case 5:
738 settype = PUB_SET_article;
739 elementtype = PUB_SET_article_E;
740 func = (AsnWriteFunc) CitArtAsnWrite;
741 break;
742 case 6:
743 settype = PUB_SET_journal;
744 elementtype = PUB_SET_journal_E;
745 func = (AsnWriteFunc) CitJourAsnWrite;
746 break;
747 case 7:
748 settype = PUB_SET_book;
749 elementtype = PUB_SET_book_E;
750 func = (AsnWriteFunc) CitBookAsnWrite;
751 break;
752 case 8:
753 settype = PUB_SET_proc;
754 elementtype = PUB_SET_proc_E;
755 func = (AsnWriteFunc) CitBookAsnWrite;
756 break;
757 case 9:
758 settype = PUB_SET_patent;
759 elementtype = PUB_SET_patent_E;
760 func = (AsnWriteFunc) CitPatAsnWrite;
761 break;
762 }
763
764 oldanp = anp;
765 if (! AsnOpenStruct(aip, settype, oldanp->data.ptrvalue)) /* start SET OF */
766 goto erret;
767
768 anp = (ValNodePtr)anp->data.ptrvalue;
769
770 while (anp != NULL)
771 {
772 if (choice == 1)
773 pnt = (Pointer)anp;
774 else
775 pnt = anp->data.ptrvalue;
776 if (func != NULL) {
777 if (! (*func)(pnt, aip, elementtype)) goto erret;
778 }
779 anp = anp->next;
780 }
781
782 if (! AsnCloseStruct(aip, settype, oldanp->data.ptrvalue)) /* end SET OF */
783 goto erret;
784 retval = TRUE;
785 erret:
786 AsnUnlinkType(orig); /* unlink local tree */
787 return retval;
788 }
789
790 /*****************************************************************************
791 *
792 * PubSetAsnRead(aip, atp)
793 * atp is the current type (if identifier of a parent struct)
794 * assumption is readIdent has occurred
795 * if atp == NULL, then assumes it stands alone and read ident
796 * has not occurred.
797 *
798 *****************************************************************************/
PubSetAsnRead(AsnIoPtr aip,AsnTypePtr orig)799 NLM_EXTERN ValNodePtr LIBCALL PubSetAsnRead (AsnIoPtr aip, AsnTypePtr orig)
800 {
801 DataVal av;
802 AsnTypePtr atp, settype;
803 Pointer pnt;
804 ValNodePtr anp=NULL, cit, curr;
805 Uint1 choice;
806 AsnReadFunc func;
807 Boolean first;
808
809 if (! loaded)
810 {
811 if (! PubAsnLoad())
812 return anp;
813 }
814
815 if (aip == NULL)
816 return anp;
817
818 if (orig == NULL) /* PubSet ::= (self contained) */
819 atp = AsnReadId(aip, amp, PUB_SET);
820 else
821 atp = AsnLinkType(orig, PUB_SET); /* link in local tree */
822 if (atp == NULL) return anp;
823
824 anp = ValNodeNew(NULL);
825 if (anp == NULL) goto erret;
826
827 if (AsnReadVal(aip, atp, &av) <= 0) /* read the CHOICE value (nothing) */
828 goto erret;
829 settype = AsnReadId(aip, amp, atp); /* find the choice */
830 if (settype == NULL) goto erret;
831 if (AsnReadVal(aip, settype, &av) <= 0) /* read START_STRUCT */
832 goto erret;
833
834 if (settype == PUB_SET_pub)
835 {
836 choice = 1;
837 func = (AsnReadFunc) PubAsnRead;
838 }
839 else if (settype == PUB_SET_medline)
840 {
841 choice = 3;
842 func = (AsnReadFunc) MedlineEntryAsnRead;
843 }
844 else if (settype == PUB_SET_article)
845 {
846 choice = 5;
847 func = (AsnReadFunc) CitArtAsnRead;
848 }
849 else if (settype == PUB_SET_journal)
850 {
851 choice = 6;
852 func = (AsnReadFunc) CitJourAsnRead;
853 }
854 else if (settype == PUB_SET_book)
855 {
856 choice = 7;
857 func = (AsnReadFunc) CitBookAsnRead;
858 }
859 else if (settype == PUB_SET_proc)
860 {
861 choice = 8;
862 func = (AsnReadFunc) CitBookAsnRead;
863 }
864 else if (settype == PUB_SET_patent)
865 {
866 choice = 9;
867 func = (AsnReadFunc) CitPatAsnRead;
868 }
869
870 anp->choice = choice;
871 first = TRUE;
872 curr = NULL;
873 while ((atp = AsnReadId(aip, amp, settype)) != settype)
874 {
875 if (atp == NULL) goto erret;
876 pnt = (* func)(aip, atp);
877 if (pnt == NULL) goto erret;
878 if (settype == PUB_SET_pub) /* already a Pub */
879 {
880 cit = (ValNodePtr)pnt;
881 }
882 else /* make into a Pub */
883 {
884 cit = ValNodeNew(NULL);
885 if (cit == NULL) goto erret;
886 cit->data.ptrvalue = pnt;
887 cit->choice = choice;
888 }
889
890 if (first)
891 {
892 anp->data.ptrvalue = (Pointer)cit;
893 first = FALSE;
894 }
895 else
896 {
897 curr->next = cit;
898 }
899 curr = cit;
900 }
901 if (AsnReadVal(aip, settype, &av) <= 0) /* read END_STRUCT for SET OF */
902 goto erret;
903 if (anp == NULL)
904 ErrPost(CTX_NCBIOBJ, 1, "Empty SET OF Pub. line %ld", aip->linenumber);
905 ret:
906 AsnUnlinkType(orig); /* unlink local tree */
907 return anp;
908 erret:
909 anp = PubSetFree(anp);
910 goto ret;
911 }
912
913 /*****************************************************************************
914 *
915 * PubEquiv is just a chain of Pubs (ValNodes)
916 *
917 *****************************************************************************/
918 /*****************************************************************************
919 *
920 * PubEquivFree(anp)
921 * Frees a chain of Pubs
922 *
923 *****************************************************************************/
PubEquivFree(ValNodePtr anp)924 NLM_EXTERN ValNodePtr LIBCALL PubEquivFree (ValNodePtr anp)
925 {
926 ValNodePtr next;
927
928 while (anp != NULL)
929 {
930 next = anp->next;
931 PubFree(anp); /* each node individually coded as Pub anyway */
932 anp = next;
933 }
934 return anp;
935 }
936
937 /*****************************************************************************
938 *
939 * PubEquivAsnWrite(anp, aip, atp)
940 * atp is the current type (if identifier of a parent struct)
941 * if atp == NULL, then assumes it stands alone (PubEquiv ::=)
942 *
943 *****************************************************************************/
PubEquivAsnWrite(ValNodePtr anp,AsnIoPtr aip,AsnTypePtr orig)944 NLM_EXTERN Boolean LIBCALL PubEquivAsnWrite (ValNodePtr anp, AsnIoPtr aip, AsnTypePtr orig)
945 {
946 AsnTypePtr atp;
947 ValNodePtr oldanp;
948 Boolean retval = FALSE;
949
950 if (! loaded)
951 {
952 if (! PubAsnLoad())
953 return FALSE;
954 }
955
956 if (aip == NULL)
957 return FALSE;
958
959 atp = AsnLinkType(orig, PUB_EQUIV); /* link local tree */
960 if (atp == NULL) return FALSE;
961
962 if (anp == NULL) { AsnNullValueMsg(aip, atp); goto erret; }
963
964 oldanp = anp;
965 if (! AsnOpenStruct(aip, atp, (Pointer)oldanp)) /* start SET OF */
966 goto erret;
967
968 while (anp != NULL)
969 {
970 if (! PubAsnWrite(anp, aip, PUB_EQUIV_E)) goto erret;
971 anp = anp->next;
972 }
973
974 if (! AsnCloseStruct(aip, atp, (Pointer)oldanp)) /* end SET OF */
975 goto erret;
976 retval = TRUE;
977 erret:
978 AsnUnlinkType(orig); /* unlink local tree */
979 return retval;
980 }
981
982 /*****************************************************************************
983 *
984 * PubEquivAsnRead(aip, atp)
985 * atp is the current type (if identifier of a parent struct)
986 * assumption is readIdent has occurred
987 * if atp == NULL, then assumes it stands alone and read ident
988 * has not occurred.
989 *
990 *****************************************************************************/
PubEquivAsnRead(AsnIoPtr aip,AsnTypePtr orig)991 NLM_EXTERN ValNodePtr LIBCALL PubEquivAsnRead (AsnIoPtr aip, AsnTypePtr orig)
992 {
993 DataVal av;
994 AsnTypePtr atp, oldtype;
995 ValNodePtr anp=NULL, cit, curr;
996 Boolean first;
997
998 if (! loaded)
999 {
1000 if (! PubAsnLoad())
1001 return anp;
1002 }
1003
1004 if (aip == NULL)
1005 return anp;
1006
1007 first = TRUE;
1008
1009 if (orig == NULL) /* PubEquiv ::= (self contained) */
1010 oldtype = AsnReadId(aip, amp, PUB_EQUIV);
1011 else
1012 oldtype = AsnLinkType(orig, PUB_EQUIV); /* link in local tree */
1013 if (oldtype == NULL) return anp;
1014
1015 if (AsnReadVal(aip, oldtype, &av) <= 0) /* read START_STRUCT */
1016 goto erret;
1017 atp = oldtype;
1018
1019 curr = NULL;
1020 anp = NULL;
1021 while ((atp = AsnReadId(aip, amp, atp)) != oldtype)
1022 {
1023 if (atp == NULL) goto erret;
1024
1025 cit = PubAsnRead(aip, atp);
1026 if (cit == NULL) goto erret;
1027
1028 if (first)
1029 {
1030 anp = cit;
1031 first = FALSE;
1032 }
1033 else
1034 {
1035 curr->next = cit;
1036 }
1037 curr = cit;
1038 }
1039 if (AsnReadVal(aip, oldtype, &av) <= 0) /* read END_STRUCT for SET OF */
1040 goto erret;
1041 ret:
1042 AsnUnlinkType(orig); /* unlink local tree */
1043 return anp;
1044 erret:
1045 anp = PubEquivFree(anp);
1046 goto ret;
1047 }
1048
1049 /*****************************************************************************
1050 *
1051 * Int2 PubMatch(a, b)
1052 * returns 0 if can determine pubs POINT TO SAME CITATION (not that
1053 * they are identical)
1054 * returns positive or negative number if not the same,
1055 * for arbitrary ordering
1056 * -2, +2 = different types
1057 * -1, +1 = different values, same type
1058 *
1059 *****************************************************************************/
PubMatch(ValNodePtr a,ValNodePtr b)1060 NLM_EXTERN Int2 LIBCALL PubMatch (ValNodePtr a, ValNodePtr b)
1061 {
1062 ValNode vn1;
1063 ValNodePtr ap, bp, tp, vnp[2];
1064 Int2 retval, i;
1065 Int4 muid[2];
1066 Int4 pmid[2];
1067 CitArtPtr cap[2];
1068 CharPtr country[2], /* for patents */
1069 number[2],
1070 app_number[2];
1071
1072 if (a == NULL) return 2;
1073 if (b == NULL) return -2;
1074
1075 /* default return for different pub types */
1076 if (a->choice > b->choice)
1077 retval = 2;
1078 else
1079 retval = -2;
1080
1081 /* if either is a Pub-equiv, treat as both */
1082 if ((a->choice == PUB_Equiv) || (b->choice == PUB_Equiv))
1083 {
1084 ap = (ValNodePtr)(a->data.ptrvalue);
1085 bp = (ValNodePtr)(b->data.ptrvalue);
1086 tp = NULL;
1087 if (a->choice != PUB_Equiv)
1088 {
1089 tp = a;
1090 ap = NULL;
1091 }
1092 else if (b->choice != PUB_Equiv)
1093 {
1094 tp = b;
1095 bp = NULL;
1096 }
1097 if (tp != NULL) /* convert one */
1098 {
1099 MemCopy((Pointer)&vn1, tp, sizeof(ValNode)); /* make a copy of the Pub */
1100 vn1.next = NULL; /* remove from any chain */
1101 tp = (ValNodePtr)&vn1;
1102 if (ap == NULL)
1103 ap = tp;
1104 else
1105 bp = tp;
1106 }
1107 return PubEquivMatch(ap, bp); /* use the PubEquivMatch() */
1108 }
1109 /** here we are just matching two pubs */
1110 /* handle Medline/CitArt combinations */
1111 /* handle CitPat, IdPat combinations */
1112 vnp[0] = a;
1113 vnp[1] = b;
1114 for (i = 0; i < 2; i++)
1115 {
1116 cap[i] = NULL;
1117 muid[i] = 0;
1118 pmid[i] = 0;
1119 country[i] = NULL;
1120 number[i] = NULL;
1121 app_number[i] = NULL;
1122
1123 switch (vnp[i]->choice)
1124 {
1125 case PUB_Medline:
1126 muid[i] = ((MedlineEntryPtr)(vnp[i]->data.ptrvalue))->uid;
1127 cap[i] = ((MedlineEntryPtr)(vnp[i]->data.ptrvalue))->cit;
1128 pmid[i] = ((MedlineEntryPtr)(vnp[i]->data.ptrvalue))->pmid;
1129 break;
1130 case PUB_Muid:
1131 muid[i] = vnp[i]->data.intvalue;
1132 break;
1133 case PUB_Article:
1134 cap[i] = (CitArtPtr)(vnp[i]->data.ptrvalue);
1135 break;
1136 case PUB_Patent:
1137 country[i] = ((CitPatPtr)(vnp[i]->data.ptrvalue))->country;
1138 number[i] = ((CitPatPtr)(vnp[i]->data.ptrvalue))->number;
1139 app_number[i] = ((CitPatPtr)(vnp[i]->data.ptrvalue))->app_number;
1140 break;
1141 case PUB_Pat_id:
1142 country[i] = ((IdPatPtr)(vnp[i]->data.ptrvalue))->country;
1143 number[i] = ((IdPatPtr)(vnp[i]->data.ptrvalue))->number;
1144 app_number[i] = ((IdPatPtr)(vnp[i]->data.ptrvalue))->app_number;
1145 break;
1146 case PUB_PMid:
1147 pmid[i] = vnp[i]->data.intvalue;
1148 break;
1149 }
1150 }
1151
1152 if ((pmid[0] > 0) && (pmid[1] > 0)) /* got 2 muids */
1153 {
1154 if (pmid[0] == pmid[1])
1155 return (Int2)0;
1156 else if (pmid[0] < pmid[1])
1157 return (Int2)-1;
1158 else
1159 return (Int2) 1;
1160 }
1161
1162 if ((muid[0] > 0) && (muid[1] > 0)) /* got 2 muids */
1163 {
1164 if (muid[0] == muid[1])
1165 return (Int2)0;
1166 else if (muid[0] < muid[1])
1167 return (Int2)-1;
1168 else
1169 return (Int2) 1;
1170 }
1171
1172 if ((cap[0] != NULL) && (cap[1] != NULL)) /* 2 articles */
1173 {
1174 return CitArtMatch(cap[0], cap[1]);
1175 }
1176
1177 if ((country[0] != NULL) && (country[1] != NULL)) /* 2 patents */
1178 {
1179 retval = (Int2)StringICmp(country[0], country[1]);
1180 if (retval < 0) /* different countries */
1181 return (Int2) -1;
1182 else if (retval > 0)
1183 return (Int2) 1;
1184
1185 if ((number[0] != NULL) && (number[1] != NULL))
1186 {
1187 retval = (Int2)StringICmp(number[0], number[1]);
1188 if (retval < 0) /* different number */
1189 return (Int2) -1;
1190 else if (retval > 0)
1191 return (Int2) 1;
1192 else
1193 return retval;
1194 }
1195 if ((app_number[0] != NULL) && (app_number[1] != NULL))
1196 {
1197 retval = (Int2)StringICmp(app_number[0], app_number[1]);
1198 if (retval < 0) /* different appl number */
1199 return (Int2) -1;
1200 else if (retval > 0)
1201 return (Int2) 1;
1202 else
1203 return retval;
1204 }
1205 if (number[0] != NULL)
1206 return (Int2) -1;
1207 return (Int2) 1;
1208 }
1209
1210 if (a->choice != b->choice) /* all others must be same type */
1211 {
1212 return retval;
1213 }
1214 /* compare other types */
1215 switch (a->choice)
1216 {
1217 case PUB_Gen: /* generic */
1218 return CitGenMatch((CitGenPtr)a->data.ptrvalue,
1219 (CitGenPtr)b->data.ptrvalue, TRUE);
1220 case PUB_Sub: /* Submission */
1221 return CitSubMatch((CitSubPtr)a->data.ptrvalue,
1222 (CitSubPtr)b->data.ptrvalue);
1223 case PUB_Journal:
1224 return CitJourMatch((CitJourPtr)a->data.ptrvalue,
1225 (CitJourPtr)b->data.ptrvalue);
1226 case PUB_Book:
1227 case PUB_Proc:
1228 case PUB_Man:
1229 return CitBookMatch((CitBookPtr)a->data.ptrvalue,
1230 (CitBookPtr)b->data.ptrvalue);
1231 }
1232
1233 return retval;
1234 }
1235
1236 /*****************************************************************************
1237 *
1238 * Int2 PubEquivMatch(a, b)
1239 * returns 0 if can determine pubs POINT TO SAME CITATION (not that
1240 * they are identical)
1241 * returns +1 or -1 if not the same,
1242 * for arbitrary ordering
1243 *
1244 *****************************************************************************/
PubEquivMatch(ValNodePtr a,ValNodePtr b)1245 NLM_EXTERN Int2 LIBCALL PubEquivMatch (ValNodePtr a, ValNodePtr b)
1246 {
1247 Int2 retval = 0, tmp;
1248 ValNodePtr vnp;
1249
1250 while (a != NULL)
1251 {
1252 vnp = b;
1253 while (vnp != NULL)
1254 {
1255 tmp = PubMatch(a, vnp);
1256 if (! tmp) /* a match */
1257 {
1258 return tmp;
1259 }
1260 if (! retval) /* first one */
1261 retval = tmp;
1262 else if ((retval == 2) || (retval == -2)) /* type diffs only */
1263 retval = tmp;
1264
1265 vnp = vnp->next;
1266 }
1267 a = a->next;
1268 }
1269 if (retval < 0)
1270 retval = -1;
1271 else
1272 retval = 1;
1273 return retval;
1274 }
1275
1276
1277 /*****************************************************************************
1278 *
1279 * PubdescContentMatch(pub1, pub2)
1280 *
1281 * returns TRUE if content of pub1 matches content of pub2, FALSE otherwise
1282 *****************************************************************************/
PubdescContentMatch(PubdescPtr pdp1,PubdescPtr pdp2)1283 NLM_EXTERN Boolean LIBCALL PubdescContentMatch (PubdescPtr pdp1, PubdescPtr pdp2)
1284 {
1285 if (pdp1 == NULL && pdp2 == NULL)
1286 {
1287 return TRUE;
1288 }
1289 else if (pdp1 == NULL || pdp2 == NULL)
1290 {
1291 return FALSE;
1292 }
1293 else if (pdp1->reftype != pdp2->reftype)
1294 {
1295 return FALSE;
1296 }
1297 else if (StringCmp (pdp1->name, pdp2->name) != 0
1298 || StringCmp (pdp1->fig, pdp2->fig) != 0
1299 || StringCmp (pdp1->maploc, pdp2->maploc) != 0
1300 || StringCmp (pdp1->seq_raw, pdp2->seq_raw) != 0
1301 || StringCmp (pdp1->comment, pdp2->comment) != 0)
1302 {
1303 return FALSE;
1304 }
1305 else if (PubMatch (pdp1->pub, pdp2->pub) != 0)
1306 {
1307 return FALSE;
1308 }
1309 else
1310 {
1311 return TRUE;
1312 }
1313 }
1314
1315
1316 /*****************************************************************************
1317 *
1318 * PubLabel(pubptr, buf, buflen, content)
1319 * makes a short label for any Pub in buf, up to buflen size
1320 * content follows objmgr OM_LABEL_
1321 *
1322 *****************************************************************************/
PubLabel(ValNodePtr pub,CharPtr buf,Int2 buflen,Uint1 content)1323 NLM_EXTERN Int2 LIBCALL PubLabel (ValNodePtr pub, CharPtr buf, Int2 buflen, Uint1 content)
1324 {
1325 return PubLabelUnique (pub, buf, buflen, content, FALSE);
1326 }
1327
1328 /*****************************************************************************
1329 *
1330 * PubLabelUnique(pubptr, buf, buflen, content, unique)
1331 * makes a short label for any Pub in buf, up to buflen size
1332 * content follows objmgr OM_LABEL_
1333 * if (unique is TRUE, appends a string based on title words to make
1334 * unique key base on ANSI std Z39.56-1991
1335 *
1336 *****************************************************************************/
PubLabelUnique(ValNodePtr pub,CharPtr buf,Int2 buflen,Uint1 content,Boolean unique)1337 NLM_EXTERN Int2 LIBCALL PubLabelUnique (ValNodePtr pub, CharPtr buf, Int2 buflen, Uint1 content, Boolean unique)
1338 {
1339 CharPtr typelabel = NULL;
1340 static CharPtr pubtypes [14] = {
1341 "Unknown",
1342 "Generic",
1343 "Submit",
1344 "Medline",
1345 "MUID",
1346 "Article",
1347 "Journal",
1348 "Book",
1349 "Proceedings",
1350 "Patent",
1351 "PatID",
1352 "Manuscript",
1353 "Equiv" ,
1354 "PMID" };
1355 ValNodePtr vnp2=NULL, title=NULL;
1356 Int2 len, diff;
1357 Char tbuf[41];
1358 Boolean first = TRUE;
1359
1360 Int4 muid = 0, pmid = 0;
1361 AuthListPtr alp=NULL;
1362 AuthorPtr ap;
1363 ImprintPtr imp = NULL;
1364 CharPtr year = NULL,
1365 volume = NULL,
1366 issue = NULL,
1367 pages = NULL,
1368 title1=NULL,
1369 title2=NULL,
1370 titleunique = NULL,
1371 part_sup = NULL,
1372 part_supi = NULL;
1373 CitArtPtr cap;
1374 CitJourPtr cjp;
1375 CitBookPtr cbp=NULL;
1376 CitSubPtr csp;
1377 CitPatPtr cpp;
1378 IdPatPtr ipp;
1379 CitGenPtr cgp;
1380 MedlineEntryPtr mep;
1381 DatePtr dp = NULL;
1382 Boolean unpublished = FALSE, done;
1383 ValNodePtr eq[5];
1384 Int2 i;
1385 CharPtr s, cit;
1386
1387
1388
1389 if ((buf == NULL) || (buflen < 1)) return 0;
1390
1391 buf[0] = '?';
1392 buf[1] = '\0';
1393
1394 if (pub == NULL) return 0;
1395
1396 if (pub->choice > 13)
1397 typelabel = pubtypes[0];
1398 else
1399 typelabel = pubtypes[pub->choice];
1400
1401 len = buflen;
1402
1403 if (content == OM_LABEL_TYPE)
1404 return LabelCopy(buf, typelabel, buflen);
1405
1406 if (content == OM_LABEL_BOTH)
1407 {
1408 diff = LabelCopyExtra(buf, typelabel, buflen, NULL, ": ");
1409 buflen -= diff; buf += diff;
1410 }
1411
1412 switch (pub->choice)
1413 {
1414 case PUB_Muid:
1415 sprintf(tbuf, "NLM%ld", (long)(pub->data.intvalue));
1416 diff = LabelCopy(buf, tbuf, buflen);
1417 buflen -= diff;
1418 return (len - buflen); /* already unique */
1419 break;
1420 case PUB_PMid:
1421 sprintf(tbuf, "PM%ld", (long)(pub->data.intvalue));
1422 diff = LabelCopy(buf, tbuf, buflen);
1423 buflen -= diff;
1424 return (len - buflen); /* already unique */
1425 break;
1426 case PUB_Equiv:
1427 for (i = 0; i < 5; i++)
1428 eq[i] = NULL;
1429 i = 0;
1430 for (vnp2 = (ValNodePtr)(pub->data.ptrvalue);
1431 ((vnp2 != NULL) && (buflen)); vnp2 = vnp2->next)
1432 {
1433 switch (vnp2->choice)
1434 {
1435 case PUB_Muid:
1436 eq[3] = vnp2;
1437 break;
1438 case PUB_Gen:
1439 cgp = (CitGenPtr)(vnp2->data.ptrvalue);
1440 if (cgp->serial_number > 0)
1441 {
1442 eq[4] = vnp2;
1443 break;
1444 }
1445 default:
1446 if (i < 5)
1447 eq[i] = vnp2;
1448 i++;
1449 break;
1450 }
1451 }
1452 for (i = 0; i < 5; i++)
1453 {
1454 if (eq[i] != NULL)
1455 {
1456 if (! first)
1457 {
1458 diff = LabelCopy(buf, " ", buflen);
1459 buflen -= diff; buf += diff;
1460 }
1461 else
1462 first = FALSE;
1463
1464 diff = PubLabelUnique (eq[i], buf, buflen, OM_LABEL_CONTENT, unique);
1465 buflen -= diff; buf += diff;
1466 }
1467 }
1468 break;
1469 case PUB_Medline:
1470 mep = (MedlineEntryPtr)(pub->data.ptrvalue);
1471 if (mep->pmid > 0)
1472 sprintf(tbuf, "PM%ld", (long)(mep->pmid));
1473 else
1474 sprintf(tbuf, "NLM%ld", (long)(mep->uid));
1475 diff = LabelCopyExtra(buf, tbuf, buflen, NULL, " ");
1476 buflen -= diff; buf += diff;
1477 cap = mep->cit;
1478 goto cit_art;
1479 case PUB_Article:
1480 cap = (CitArtPtr)(pub->data.ptrvalue);
1481 cit_art: alp = cap->authors;
1482 if (cap->title != NULL)
1483 titleunique = (CharPtr)(cap->title->data.ptrvalue);
1484 switch (cap->from)
1485 {
1486 case 1:
1487 cjp = (CitJourPtr)(cap->fromptr);
1488 goto cit_jour;
1489 case 2:
1490 case 3:
1491 cbp = (CitBookPtr)(cap->fromptr);
1492 goto cit_book;
1493 }
1494 break;
1495 case PUB_Journal:
1496 cjp = (CitJourPtr)(pub->data.ptrvalue);
1497 cit_jour: imp = cjp->imp;
1498 title = cjp->title;
1499 break;
1500 case PUB_Book:
1501 case PUB_Proc:
1502 case PUB_Man:
1503 cbp = (CitBookPtr)(pub->data.ptrvalue);
1504 title = cbp->title;
1505 cit_book: imp = cbp->imp;
1506 if (alp == NULL)
1507 alp = cbp->authors;
1508 break;
1509 case PUB_Sub:
1510 csp = (CitSubPtr)(pub->data.ptrvalue);
1511 alp = csp->authors;
1512 imp = csp->imp;
1513 dp = csp->date;
1514 break;
1515 case PUB_Patent:
1516 cpp = (CitPatPtr)(pub->data.ptrvalue);
1517 alp = cpp->authors;
1518 dp = cpp->date_issue;
1519 if (dp == NULL)
1520 dp = cpp->app_date;
1521 title1 = cpp->country;
1522 title2 = cpp->number;
1523 if (title2 == NULL)
1524 title2 = cpp->app_number;
1525 break;
1526 case PUB_Pat_id:
1527 ipp = (IdPatPtr)(pub->data.ptrvalue);
1528 title1 = ipp->country;
1529 title2 = ipp->number;
1530 if (title2 == NULL)
1531 title2 = ipp->app_number;
1532 break;
1533 case PUB_Gen:
1534 cgp = (CitGenPtr)(pub->data.ptrvalue);
1535 if (cgp->serial_number > 0)
1536 {
1537 sprintf(tbuf, "[%d]", (int)(cgp->serial_number));
1538 diff = LabelCopy(buf, tbuf, buflen);
1539 buflen -= diff; buf += diff;
1540 }
1541 if (cgp->muid > 0)
1542 {
1543 sprintf(tbuf, "NLM%ld", (long)(cgp->muid));
1544 diff = LabelCopy(buf, tbuf, buflen);
1545 buflen -= diff; buf += diff;
1546
1547 }
1548 dp = cgp->date;
1549 title = cgp->journal;
1550 alp = cgp->authors;
1551 if (cgp->cit != NULL)
1552 {
1553 if (! StringICmp("Unpublished", cgp->cit))
1554 unpublished = TRUE;
1555 else if (title == NULL)
1556 title2 = cgp->cit;
1557 }
1558 volume = cgp->volume;
1559 issue=cgp->issue;
1560 pages=cgp->pages;
1561 if (cgp->title != NULL)
1562 titleunique = cgp->title;
1563 else if (title2 != NULL)
1564 titleunique = title2;
1565 else if (title == NULL)
1566 titleunique = cgp->cit;
1567 if (title == NULL && alp == NULL && cgp->title == NULL &&
1568 volume == NULL && pages == NULL && issue == NULL) {
1569 titleunique = NULL;
1570 if ((cit = StringSave(cgp->cit)) != NULL) {
1571 if (!unique) {
1572 for (s = cit + StringLen(cit) -1;
1573 s > cit && *s !='|'; s--) continue;
1574 if (*s == '|' ) {
1575 *s = '\0';
1576 }
1577 }
1578 diff = LabelCopy(buf, cit, buflen);
1579 MemFree(cit);
1580 }
1581 return 0;
1582 }
1583 break;
1584 default:
1585 sprintf(tbuf,"Unknown pub[%d]", (int)(pub->choice));
1586 title2 = tbuf;
1587 break;
1588
1589 }
1590
1591 if (imp != NULL)
1592 {
1593 if (dp == NULL)
1594 dp = imp->date;
1595 if (volume == NULL)
1596 volume = imp->volume;
1597 if (issue == NULL)
1598 issue = imp->issue;
1599 if (pages == NULL)
1600 pages = imp->pages;
1601 part_sup = imp->part_sup;
1602 part_supi = imp->part_supi;
1603 }
1604
1605 if (alp != NULL)
1606 {
1607 vnp2 = alp->names;
1608 if (vnp2 != NULL)
1609 {
1610 if (alp->choice == 1) /* std name */
1611 {
1612 ap = (AuthorPtr)(vnp2->data.ptrvalue);
1613 diff = PersonIdLabel(ap->name, buf, buflen, PIDLABEL_GENBANK);
1614 }
1615 else
1616 diff = LabelCopy(buf, (CharPtr)(vnp2->data.ptrvalue), buflen);
1617 buflen -= diff;
1618 buf += diff;
1619 }
1620 }
1621
1622 if (dp != NULL)
1623 {
1624 if (dp->data[0])
1625 {
1626 if (pub->choice == PUB_Sub && dp->data[2] != 0 && dp->data[3] != 0){
1627 sprintf(tbuf, "%d-%d-%d", (int)(dp->data[2]),
1628 (int)(dp->data[3]), (int)(dp->data[1])+1900);
1629 year = tbuf;
1630 } else {
1631 sprintf(tbuf, "%d", (int)(dp->data[1])+1900);
1632 year = tbuf;
1633 }
1634 }
1635 else
1636 year = dp->str;
1637 diff = LabelCopyExtra(buf, year, buflen, " (", ") ");
1638 buflen -= diff; buf += diff;
1639 }
1640
1641 if ((title != NULL) && (titleunique == NULL))
1642 titleunique = (CharPtr)(title->data.ptrvalue);
1643
1644 if (title2 == NULL)
1645 {
1646 if (title != NULL)
1647 title2 = (CharPtr)(title->data.ptrvalue);
1648
1649 }
1650
1651 if (title2 != NULL)
1652 {
1653 if (cbp != NULL)
1654 title1 = "(in) ";
1655
1656 diff = LabelCopyExtra(buf, title2, buflen, title1, " ");
1657 buflen -= diff; buf += diff;
1658 }
1659
1660 if (volume != NULL)
1661 {
1662 if (part_sup != NULL)
1663 title1 = part_sup;
1664 else
1665 title1 = ":";
1666
1667 diff = LabelCopyExtra(buf, volume, buflen, NULL, title1);
1668 buflen -= diff; buf += diff;
1669 if (part_sup != NULL)
1670 {
1671 diff = LabelCopyExtra(buf, ":", buflen, NULL, NULL);
1672 buflen -= diff; buf += diff;
1673 }
1674 }
1675
1676 if (issue != NULL)
1677 {
1678 if (part_supi != NULL)
1679 title1 = part_supi;
1680 else
1681 title1 = ")";
1682
1683 diff = LabelCopyExtra(buf, issue, buflen, "(" , title1);
1684 buflen -= diff; buf += diff;
1685 if (part_supi != NULL)
1686 {
1687 diff = LabelCopyExtra(buf, ")", buflen, NULL, NULL);
1688 buflen -= diff; buf += diff;
1689 }
1690 }
1691
1692 if (pages != NULL)
1693 {
1694 diff = LabelCopy(buf, pages, buflen);
1695 buflen -= diff; buf += diff;
1696 }
1697
1698 if (unpublished)
1699 {
1700 diff = LabelCopy(buf, "Unpublished", buflen);
1701 buflen -= diff; buf += diff;
1702 }
1703
1704 if (unique) /* put on unique tag made from title */
1705 {
1706 done = FALSE;
1707 i=0;
1708 if (titleunique != NULL && *titleunique != '\0')
1709 {
1710 while ((! done) && (i < 40))
1711 {
1712 tbuf[i] = *titleunique;
1713 i++;
1714 while (! IS_WHITESP(*titleunique))
1715 {
1716 titleunique++;
1717 if (*titleunique == '\0')
1718 {
1719 done = TRUE;
1720 break;
1721 }
1722 }
1723 while (IS_WHITESP(*titleunique))
1724 {
1725 titleunique++;
1726 if (*titleunique == '\0')
1727 {
1728 done = TRUE;
1729 break;
1730 }
1731 }
1732 }
1733 }
1734 tbuf[i] = '\0';
1735 diff = LabelCopyExtra(buf, tbuf, buflen, "|" , NULL);
1736 buflen -= diff; buf += diff;
1737 }
1738
1739
1740 return (len - buflen);
1741 }
1742
1743