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