1 /* tomedlin.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: tomedlin.c
27 *
28 * Author: Jonathan Kans
29 *
30 * Version Creation Date: 10/15/91
31 *
32 * $Revision: 6.12 $
33 *
34 * File Description: conversion to medlars format
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 *
41 *
42 * $Log: tomedlin.c,v $
43 * Revision 6.12 2012/08/21 19:18:45 kans
44 * fixed several potential null dereferences found by clang
45 *
46 * Revision 6.11 2004/03/10 15:19:47 kans
47 * ParseMedline loops on journal, only saves one of iso-jta or ml-jta to avoid memory leak
48 *
49 * Revision 6.10 2003/09/28 20:22:47 kans
50 * added PubmedEntryToXXXFile functions
51 *
52 * Revision 6.9 2003/09/26 18:57:51 kans
53 * MedlineEntryToDataFile calls MakeMLAuthString for structured author
54 *
55 * Revision 6.8 2001/10/29 20:37:06 kans
56 * MakeAuthorString for structured authors
57 *
58 * Revision 6.7 2001/10/22 13:37:12 kans
59 * break up huge author list
60 *
61 * Revision 6.6 2001/10/15 12:24:05 kans
62 * MedlineEntryToDataFile breaks up long mesh, substance, and xref lists
63 *
64 * Revision 6.5 1999/10/26 20:17:04 kans
65 * allocate separate string for abstract since some may be very long
66 *
67 * Revision 6.4 1999/10/01 17:20:08 kans
68 * fixed stack overflow found by DV
69 *
70 * Revision 6.3 1999/03/11 23:32:08 kans
71 * sprintf casts
72 *
73 * Revision 6.2 1998/06/12 20:05:50 kans
74 * fixed unix compiler warnings
75 *
76 * Revision 6.1 1997/12/02 17:42:29 kans
77 * added cast in sprintf
78 *
79 * Revision 6.0 1997/08/25 18:07:55 madden
80 * Revision changed to 6.0
81 *
82 * Revision 5.16 1997/06/19 18:39:27 vakatov
83 * [WIN32,MSVC++] Adopted for the "NCBIOBJ.LIB" DLL'ization
84 *
85 * Revision 5.15 1997/04/14 18:02:31 grisha
86 * set MedlarsEntryToDataFile() to be external
87 *
88 * Revision 5.14 1997/04/11 16:24:13 levitsky
89 * *** empty log message ***
90 *
91 * Revision 5.13 1997/04/11 15:58:58 levitsky
92 * New functions for support tomedlars added
93 *
94 * Revision 5.12 1997/04/10 18:16:06 levitsky
95 * New version of MEDLARS output
96 *
97 * Revision 5.11 1997/04/08 19:35:43 levitsky
98 * *** empty log message ***
99 *
100 * Revision 5.10 1997/04/08 17:30:46 levitsky
101 * fixed break error
102 *
103 * Revision 5.9 1997/04/07 21:34:40 levitsky
104 * Added SO field for medlars report
105 *
106 * Revision 5.8 1997/03/19 18:06:23 kans
107 * fixed use of mep->pub_type
108 *
109 * Revision 5.7 1997/03/19 16:53:08 levitsky
110 * publication type added to output
111 *
112 * Revision 5.6 1997/02/20 21:25:17 kans
113 * added MedlineEntryToAbsFile and MedlarsEntryToAbsFile
114 *
115 * Revision 5.5 1997/02/19 15:09:22 levitsky
116 * pmid added to output
117 *
118 * Revision 5.4 1997/02/12 21:30:02 grisha
119 * add code to support MEDLARS report generation
120 * for MedlarsEntry
121 *
122 * Revision 5.3 1997/01/27 16:15:39 grisha
123 * Fix bugs with SO field generation
124 *
125 * Revision 5.2 1996/08/27 23:10:43 kans
126 * protect prefixes (e.g., van, el, den) with initials that can be
127 * mistaken for suffixes (e.g., I). this won't protect against
128 * names with the Van incorrectly entered at the end.
129 *
130 * Revision 5.1 1996/05/31 21:04:12 kans
131 * check for individual suffixes before stripping
132 *
133 * Revision 5.0 1996/05/28 13:23:23 ostell
134 * Set to revision 5.0
135 *
136 * Revision 4.2 1996/01/23 20:59:15 kans
137 * now allows iso-jta as well as ml-jta
138 *
139 * Revision 4.1 1995/12/27 17:50:11 kans
140 * changed StringAppend to StrngAppend to avoid conflict with future ncbistr.h
141 *
142 * Revision 4.0 1995/07/26 13:49:01 ostell
143 * force revision to 4.0
144 *
145 * Revision 2.5 1995/05/15 21:46:05 ostell
146 * added Log line
147 *
148 *
149 *
150 * ==========================================================================
151 */
152
153 #include <objmedli.h>
154 #include <tofile.h>
155 #include <tomedlin.h>
156
157 #ifdef VAR_ARGS
158 #include <varargs.h>
159 #else
160 #include <stdarg.h>
161 #endif
162
163 #ifdef COMP_MPW
164 #pragma segment CdrSegD
165 #endif
166
167 #define BUFSIZE 8192
168
169 static CharPtr buffer;
170 static CharPtr pos;
171
172 /* ----- Function Prototypes ----- */
173
174 static void ClearString PROTO((void));
175 static void AddString PROTO((CharPtr string));
176 static CharPtr CleanAuthorString PROTO((CharPtr auth));
177 static CharPtr CDECL StrngAppend VPROTO((CharPtr first, ...));
178
179 /* ----- Function Bodies ----- */
180
ClearString(void)181 static void ClearString (void)
182
183 {
184 pos = buffer;
185 *pos = '\0';
186 }
187
AddString(CharPtr string)188 static void AddString (CharPtr string)
189
190 {
191 pos = StringMove (pos, string);
192 *pos = '\0';
193 }
194
195 static ColData table [2] = {{0, 6, 0, 'l', TRUE, TRUE, FALSE},
196 {0, 72, 0, 'l', TRUE, TRUE, TRUE}};
197
198
199 static Char *months[13] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
200 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
201
MakeMLAuthString(CharPtr name,CharPtr initials,CharPtr suffix)202 static CharPtr MakeMLAuthString (
203 CharPtr name,
204 CharPtr initials,
205 CharPtr suffix
206 )
207
208 {
209 Char ch;
210 size_t len;
211 CharPtr ptr;
212 CharPtr str;
213 CharPtr tmp;
214
215 if (name == NULL) return NULL;
216
217 len = StringLen (name) + StringLen (initials) * 3 + StringLen (suffix);
218 str = MemNew (sizeof (Char) * (len + 4));
219 if (str == NULL) return NULL;
220
221 tmp = str;
222
223 tmp = StringMove (tmp, name);
224
225 ptr = initials;
226 if (! StringHasNoText (initials)) {
227 tmp = StringMove (tmp, " ");
228 ch = *ptr;
229 while (ch != '\0') {
230 if (ch == '-') {
231 *tmp = '-';
232 tmp++;
233 } else if (ch != '.') {
234 *tmp = ch;
235 tmp++;
236 }
237 ptr++;
238 ch = *ptr;
239 }
240 *tmp = '\0';
241 }
242
243 if (! StringHasNoText (suffix)) {
244 tmp = StringMove (tmp, " ");
245 tmp = StringMove (tmp, suffix);
246 }
247
248 return str;
249 }
250
MedlineEntryToDataFileEx(MedlineEntryPtr mep,Int4 pmid,FILE * fp)251 static Boolean MedlineEntryToDataFileEx (MedlineEntryPtr mep, Int4 pmid, FILE *fp)
252
253 {
254 CharPtr abstract;
255 AffilPtr affil;
256 AuthorPtr ap;
257 AuthListPtr authors = NULL;
258 CitArtPtr cit = NULL;
259 CitJourPtr citjour = NULL;
260 Int2 count;
261 CharPtr curr;
262 DatePtr date = NULL;
263 ValNodePtr gene;
264 Int2 i;
265 ImprintPtr imp = NULL;
266 CharPtr issue = NULL;
267 size_t len;
268 MedlineMeshPtr mesh;
269 ValNodePtr names;
270 NameStdPtr nsp;
271 CharPtr p;
272 CharPtr pages = NULL;
273 ParData para;
274 PersonIdPtr pid;
275 CharPtr ptr;
276 ValNodePtr qual;
277 Boolean rsult;
278 Char str [32];
279 MedlineRnPtr substance;
280 ValNodePtr title;
281 CharPtr tmp;
282 CharPtr volume = NULL;
283 ValNodePtr xref;
284 CharPtr lpTemp;
285 CharPtr lpMedAbbr = NULL;
286 CharPtr lpMedCode = NULL;
287 CharPtr lpIssn = NULL;
288
289 rsult = TRUE;
290 buffer = MemNew (BUFSIZE);
291 if (buffer != NULL) {
292 para.openSpace = FALSE;
293 ClearString ();
294 AddString ("UI -\t");
295 sprintf (str, "%ld", (long) mep->uid);
296 AddString (str);
297 AddString ("\n");
298 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
299 ClearString ();
300
301 if ( mep->pmid > 0 ) {
302 ClearString ();
303 AddString ("PM -\t");
304 sprintf (str, "%ld", (long) mep->pmid);
305 AddString (str);
306 AddString ("\n");
307 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
308 ClearString ();
309 }
310
311 if ( mep->pub_type != NULL ) {
312 ClearString ();
313 AddString ("PT -\t");
314 AddString ((CharPtr) mep->pub_type->data.ptrvalue);
315 AddString ("\n");
316 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
317 ClearString ();
318 }
319
320 cit = mep->cit;
321 if (cit != NULL) {
322 authors = cit->authors;
323 if (authors != NULL) {
324 if (authors->choice == 1) {
325 names = authors->names;
326 count = 0;
327 while (names != NULL) {
328 if (count >= 20) {
329 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
330 ClearString ();
331 count = 0;
332 }
333 curr = NULL;
334 ap = (AuthorPtr) names->data.ptrvalue;
335 if (ap != NULL) {
336 pid = ap->name;
337 if (pid != NULL) {
338 if (pid->choice == 2) {
339 nsp = (NameStdPtr) pid->data;
340 if (nsp != NULL) {
341 if (! StringHasNoText (nsp->names [0])) {
342 curr = MakeMLAuthString (nsp->names [0], nsp->names [4], nsp->names [5]);
343 } else if (! StringHasNoText (nsp->names [3])) {
344 curr = MakeMLAuthString (nsp->names [3], NULL, NULL);
345 }
346 }
347 } else if (pid->choice == 3 || pid->choice == 4) {
348 curr = MakeMLAuthString ((CharPtr) pid->data, NULL, NULL);
349 }
350 }
351 }
352 if (curr != NULL) {
353 AddString ("AU -\t");
354 AddString (curr);
355 AddString ("\n");
356 curr = MemFree (curr);
357 }
358 names = names->next;
359 count++;
360 }
361 } else if (authors->choice == 2 || authors->choice == 3) {
362 names = authors->names;
363 count = 0;
364 while (names != NULL) {
365 if (count >= 20) {
366 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
367 ClearString ();
368 count = 0;
369 }
370 AddString ("AU -\t");
371 AddString (names->data.ptrvalue);
372 AddString ("\n");
373 names = names->next;
374 count++;
375 }
376 }
377 }
378 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
379 ClearString ();
380 title = cit->title;
381 count = 0;
382 while (title != NULL) {
383 if (count >= 20) {
384 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
385 ClearString ();
386 count = 0;
387 }
388 if (title->choice == 1) {
389 AddString ("TI -\t");
390 AddString (title->data.ptrvalue);
391 AddString ("\n");
392 }
393 title = title->next;
394 count++;
395 }
396 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
397 ClearString ();
398 }
399
400 mesh = mep->mesh;
401 count = 0;
402 while (mesh != NULL) {
403 if (count >= 20) {
404 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
405 ClearString ();
406 count = 0;
407 }
408 AddString ("MH -\t");
409 if (mesh->mp) {
410 AddString ("*");
411 }
412 AddString (mesh->term);
413 qual = mesh->qual;
414 while (qual != NULL) {
415 AddString ("/");
416 if (qual->choice != 0) {
417 AddString ("*");
418 }
419 p = (CharPtr) qual->data.ptrvalue;
420 while (*p != '\0') {
421 *p = TO_UPPER (*p);
422 p++;
423 }
424 AddString (qual->data.ptrvalue);
425 qual = qual->next;
426 }
427 AddString ("\n");
428 mesh = mesh->next;
429 count++;
430 }
431 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
432 ClearString ();
433 substance = mep->substance;
434 count = 0;
435 while (substance != NULL) {
436 if (count >= 20) {
437 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
438 ClearString ();
439 count = 0;
440 }
441 AddString ("RN -\t");
442 switch (substance->type) {
443 case 0:
444 AddString ("0 (");
445 AddString (substance->name);
446 AddString (")");
447 break;
448 case 1:
449 AddString (substance->cit);
450 AddString (" (");
451 AddString (substance->name);
452 AddString (")");
453 break;
454 case 2:
455 AddString ("EC ");
456 AddString (substance->cit);
457 AddString (" (");
458 AddString (substance->name);
459 AddString (")");
460 break;
461 default:
462 break;
463 }
464 AddString ("\n");
465 substance = substance->next;
466 count++;
467 }
468 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
469 ClearString ();
470 gene = mep->gene;
471 while (gene != NULL) {
472 AddString ("GS -\t");
473 AddString (gene->data.ptrvalue);
474 AddString ("\n");
475 gene = gene->next;
476 }
477 xref = mep->xref;
478 count = 0;
479 while (xref != NULL) {
480 if (count >= 20) {
481 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
482 ClearString ();
483 count = 0;
484 }
485 AddString ("SI -\t");
486 switch (xref->choice) {
487 case 1:
488 AddString ("DDBJ/");
489 break;
490 case 2:
491 AddString ("CARBBANK/");
492 break;
493 case 3:
494 AddString ("EMBL/");
495 break;
496 case 4:
497 AddString ("HDB/");
498 break;
499 case 5:
500 AddString ("GENBANK/");
501 break;
502 case 6:
503 AddString ("HGML/");
504 break;
505 case 7:
506 AddString ("MIM/");
507 break;
508 case 8:
509 AddString ("MSD/");
510 break;
511 case 9:
512 AddString ("PDB/");
513 break;
514 case 10:
515 AddString ("PIR/");
516 break;
517 case 11:
518 AddString ("PRFSEQDB/");
519 break;
520 case 12:
521 AddString ("PSD/");
522 break;
523 case 13:
524 AddString ("SWISSPROT/");
525 break;
526 default:
527 AddString ("?/");
528 break;
529 }
530 AddString (xref->data.ptrvalue);
531 AddString ("\n");
532 xref = xref->next;
533 count++;
534 }
535 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
536 ClearString ();
537 if (cit != NULL) {
538 citjour = cit->fromptr;
539 }
540 if (citjour != NULL) {
541 imp = citjour->imp;
542 if (imp != NULL) {
543 date = imp->date;
544 if (date != NULL) {
545 switch (date->data [0]) {
546 case 0:
547 AddString ("DP -\t");
548 StringNCpy (str, date->str, sizeof (str) - 1);
549 AddString (str);
550 AddString ("\n");
551 break;
552 case 1:
553 AddString ("DP -\t");
554 sprintf (str, "%d", date->data [1] + 1900);
555 AddString (str);
556 AddString (" ");
557 i = date->data [2];
558 if (i >= 0 && i <= 11) {
559 AddString (months [i]);
560 }
561 if (date->data [3] > 0) {
562 AddString (" ");
563 sprintf (str, "%d", date->data [3]);
564 AddString (str);
565 }
566 AddString ("\n");
567 default:
568 break;
569 }
570 }
571 }
572 title = citjour->title;
573 while (title != NULL) {
574 if ( title->choice == Cit_title_jta ) {
575 lpTemp = "JC -\t";
576 lpMedCode = title->data.ptrvalue;
577 } else if ( title->choice == Cit_title_ml_jta ) {
578 lpTemp = "TA -\t";
579 lpMedAbbr = title->data.ptrvalue;
580 } else if ( title->choice == Cit_title_issn ) {
581 lpTemp = "IS -\t";
582 lpIssn = title->data.ptrvalue;
583 } else {
584 title = title->next;
585 continue;
586 }
587 AddString (lpTemp);
588 AddString (title->data.ptrvalue);
589 AddString ("\n");
590 title = title->next;
591 }
592 if (imp != NULL) {
593 pages = imp->pages;
594 if (pages != NULL) {
595 AddString ("PG -\t");
596 AddString (pages);
597 AddString ("\n");
598 }
599 issue = imp->issue;
600 if (issue != NULL) {
601 AddString ("IP -\t");
602 AddString (issue);
603 AddString ("\n");
604 }
605 volume = imp->volume;
606 if (volume != NULL) {
607 AddString ("VI -\t");
608 AddString (volume);
609 AddString ("\n");
610 }
611 }
612 }
613 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
614 ClearString ();
615 abstract = mep->abstract;
616 if (abstract != NULL) {
617 len = StringLen (abstract);
618 tmp = (CharPtr) MemNew (sizeof (Char) * (len + 10));
619 ptr = StringMove (tmp, "AB -\t");
620 ptr = StringMove (ptr, abstract);
621 ptr = StringMove (ptr, "\n");
622 rsult = (Boolean) (SendTextToFile (fp, tmp, ¶, table) && rsult);
623 MemFree (tmp);
624 }
625 ClearString ();
626 if (cit != NULL && authors != NULL) {
627 affil = authors->affil;
628 if (affil != NULL && affil->choice == 1) {
629 AddString ("AD -\t");
630 AddString (affil->affil);
631 AddString ("\n");
632 }
633 }
634 if (citjour != NULL && imp != NULL) {
635 AddString ("SO -\t");
636 if ( lpMedAbbr != NULL ) {
637 AddString(lpMedAbbr);
638 } else if ( lpIssn != NULL ) {
639 AddString(lpIssn);
640 } else if ( lpMedCode != NULL ) {
641 AddString(lpMedCode);
642 }
643 AddString (" ");
644 if (date != NULL) {
645 switch (date->data [0]) {
646 case 0:
647 StringNCpy (str, date->str, sizeof (str) - 1);
648 AddString (str);
649 AddString (";");
650 break;
651 case 1:
652 sprintf (str, "%d", date->data [1] + 1900);
653 AddString (str);
654 AddString (" ");
655 i = date->data [2];
656 if (i >= 0 && i <= 11) {
657 AddString (months [i]);
658 }
659 if (date->data [3] > 0) {
660 AddString (" ");
661 sprintf (str, "%d", date->data [3]);
662 AddString (str);
663 }
664 AddString (";");
665 default:
666 break;
667 }
668 }
669 if (volume != NULL) {
670 AddString (volume);
671 }
672 if (issue != NULL) {
673 AddString ("(");
674 AddString (issue);
675 AddString (")");
676 }
677 if (pages != NULL) {
678 AddString (":");
679 AddString (pages);
680 }
681 AddString ("\n");
682 }
683 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, table) && rsult);
684 ClearString ();
685 buffer = MemFree (buffer);
686 }
687 return rsult;
688 }
689
MedlineEntryToDataFile(MedlineEntryPtr mep,FILE * fp)690 NLM_EXTERN Boolean MedlineEntryToDataFile (MedlineEntryPtr mep, FILE *fp)
691
692 {
693 return MedlineEntryToDataFileEx (mep, 0, fp);
694 }
695
PubmedEntryToDataFile(PubmedEntryPtr pep,FILE * fp)696 NLM_EXTERN Boolean PubmedEntryToDataFile (PubmedEntryPtr pep, FILE *fp)
697
698 {
699 MedlineEntryPtr mep;
700
701 if (pep == NULL || fp == NULL) return FALSE;
702 mep = (MedlineEntryPtr) pep->medent;
703 if (mep == NULL) return FALSE;
704 return MedlineEntryToDataFileEx (mep, pep->pmid, fp);
705 }
706
707 #ifdef VAR_ARGS
StrngAppend(first,va_alist)708 static CharPtr CDECL StrngAppend (first, va_alist)
709 CharPtr first;
710 va_dcl
711 #else
712 static CharPtr CDECL StrngAppend (CharPtr first, ...)
713 #endif
714
715 {
716 va_list args;
717 Uint2 len;
718 CharPtr rsult;
719 CharPtr str;
720
721 #ifdef VAR_ARGS
722 va_start (args);
723 #else
724 va_start (args, first);
725 #endif
726 len = (Uint2) StringLen (first);
727 str = va_arg (args, CharPtr);
728 while (str != NULL) {
729 len += StringLen (str);
730 str = va_arg (args, CharPtr);
731 }
732 va_end(args);
733
734 #ifdef VAR_ARGS
735 va_start (args);
736 #else
737 va_start (args, first);
738 #endif
739 rsult = MemNew (len + 1);
740 StringCpy (rsult, first);
741 str = va_arg (args, CharPtr);
742 while (str != NULL) {
743 StringCat (rsult, str);
744 str = va_arg (args, CharPtr);
745 }
746 va_end(args);
747 return rsult;
748 }
749
750 static CharPtr suffixes [] =
751 {"Jr", "Sr", "I", "II", "III", "IV", "V", "VI",
752 "1st", "2nd", "3rd", "4th", "5th", "6th",
753 "1d", "2d", "3d", NULL};
754
755 static CharPtr prefixes [] =
756 {"van ", "ten ", "ter ", "Mac ", "Mc ", "el ", "al ",
757 "Ben ", "ben ", "Bar ", "den ", NULL};
758
CleanAuthorString(CharPtr auth)759 static CharPtr CleanAuthorString (CharPtr auth)
760
761 {
762 Char ch;
763 CharPtr first;
764 Int2 i;
765 CharPtr last;
766 Uint4 len;
767 CharPtr p;
768 CharPtr per;
769 CharPtr ps;
770 CharPtr str;
771
772 if (StringLen (auth) > 0) {
773 if (StringCmp (auth, "et al") == 0) {
774 str = StringSave ("...");
775 } else {
776 p = NULL;
777 first = NULL;
778 last = StringSave (auth);
779 ps = StringRChr (last, ' ');
780 if (ps != NULL && ps != StringChr (last, ' ')) {
781 i = 0;
782 while (prefixes [i] != NULL) {
783 len = StringLen (prefixes [i]);
784 if (len > 0 && StringNCmp (last, prefixes [i], len) == 0) {
785 last [len - 1] = '_';
786 }
787 i++;
788 }
789 ps = StringRChr (last, ' ');
790 }
791 if (ps != NULL && ps != StringChr (last, ' ')) {
792 per = StringChr (ps, '.');
793 if (per != NULL) {
794 *per = '\0';
795 }
796 i = 0;
797 while (suffixes [i] != NULL) {
798 if (StringCmp (ps + 1, suffixes [i]) == 0) {
799 *ps = '\0';
800 }
801 i++;
802 }
803 /*
804 p = ps + 1;
805 while (*p != '\0') {
806 if (! IS_UPPER(*p)) {
807 *ps = '\0';
808 p = ps;
809 } else {
810 p++;
811 }
812 }
813 */
814 }
815 ps = StringRChr (last, ' ');
816 if (ps != NULL) {
817 p = ps + 1;
818 *ps = '\0';
819 }
820 if (p != NULL) {
821 len = StringLen (p);
822 first = MemNew (3 * (size_t) len + 1);
823 i = 0;
824 while (*p != '\0') {
825 first [i] = *p;
826 i++;
827 first [i] = '.';
828 i++;
829 first [i] = ' ';
830 i++;
831 p++;
832 }
833 }
834 ps = last;
835 ch = *ps;
836 while (ch != '\0') {
837 if (ch == '_') {
838 *ps = ' ';
839 }
840 ps++;
841 ch = *ps;
842 }
843 if (first != NULL) {
844 str = StrngAppend (first, (CharPtr) last, (CharPtr) NULL);
845 last = MemFree (last);
846 first = MemFree (first);
847 } else {
848 str = last;
849 }
850 }
851 } else {
852 str = StringSave ("");
853 }
854 return str;
855 }
856
MakeAuthorString(CharPtr name,CharPtr initials,CharPtr suffix)857 static CharPtr MakeAuthorString (
858 CharPtr name,
859 CharPtr initials,
860 CharPtr suffix
861 )
862
863 {
864 Char ch;
865 size_t len;
866 CharPtr ptr;
867 CharPtr str;
868 CharPtr tmp;
869
870 if (name == NULL) return NULL;
871
872 len = StringLen (name) + StringLen (initials) * 3 + StringLen (suffix);
873 str = MemNew (sizeof (Char) * (len + 4));
874 if (str == NULL) return NULL;
875
876 tmp = str;
877
878 ptr = initials;
879 if (! StringHasNoText (initials)) {
880 ch = *ptr;
881 while (ch != '\0') {
882 if (ch == '-') {
883 *tmp = '-';
884 tmp++;
885 } else if (ch != '.') {
886 *tmp = ch;
887 tmp++;
888 *tmp = '.';
889 tmp++;
890 *tmp = ' ';
891 tmp++;
892 }
893 ptr++;
894 ch = *ptr;
895 }
896 *tmp = '\0';
897 }
898
899 tmp = StringMove (tmp, name);
900 if (! StringHasNoText (suffix)) {
901 tmp = StringMove (tmp, " ");
902 tmp = StringMove (tmp, suffix);
903 }
904
905 return str;
906 }
907
ParseMedline(MedlineEntryPtr mep)908 NLM_EXTERN MedlinePtr ParseMedline (MedlineEntryPtr mep)
909
910 {
911 AffilPtr affil;
912 AuthorPtr ap;
913 AuthListPtr authors;
914 CharPtr chptr;
915 CitArtPtr cit;
916 CitJourPtr citjour;
917 CharPtr curr;
918 DatePtr date;
919 ValNodePtr gene;
920 ImprintPtr imp;
921 CharPtr iso_jta;
922 CharPtr last;
923 MedlineMeshPtr mesh;
924 CharPtr ml_jta;
925 MedlinePtr mPtr = NULL;
926 ValNodePtr names;
927 NameStdPtr nsp;
928 PersonIdPtr pid;
929 ValNodePtr qual;
930 Char str [32];
931 MedlineRnPtr substance;
932 ValNodePtr title;
933
934 buffer = MemNew (BUFSIZE);
935 if (buffer != NULL) {
936 ClearString ();
937 mPtr = MemNew (sizeof (MedlineData));
938 if (mPtr != NULL && mep != NULL) {
939 sprintf (str, "%1ld", (long) mep->uid);
940 mPtr->uid = StringSave (str);
941 cit = mep->cit;
942 if (cit != NULL) {
943 if (cit->from == 1) {
944 citjour = (CitJourPtr) cit->fromptr;
945 if (citjour != NULL) {
946 iso_jta = NULL;
947 ml_jta = NULL;
948 title = citjour->title;
949 while (title != NULL) {
950 if (title->choice == 5) {
951 iso_jta = title->data.ptrvalue;
952 } else if (title->choice == 6) {
953 ml_jta = title->data.ptrvalue;
954 }
955 title = title->next;
956 }
957 if (iso_jta != NULL) {
958 AddString (iso_jta);
959 AddString (" ");
960 mPtr->journal = StringSave (buffer);
961 ClearString ();
962 } else if (ml_jta != NULL) {
963 AddString (ml_jta);
964 AddString (" ");
965 mPtr->journal = StringSave (buffer);
966 ClearString ();
967 }
968 imp = citjour->imp;
969 if (imp != NULL) {
970 date = imp->date;
971 if (date != NULL) {
972 switch (date->data [0]) {
973 case 0:
974 StringNCpy (str, date->str, sizeof (str) - 1);
975 chptr = StringChr (str, ' ');
976 if (chptr != NULL) {
977 *chptr = '\0';
978 }
979 mPtr->year = StringSave (str);
980 break;
981 case 1:
982 sprintf (str, "%0d", (Int2) (date->data [1] + 1900));
983 mPtr->year = StringSave (str);
984 default:
985 break;
986 }
987 }
988 mPtr->volume = StringSave (imp->volume);
989 mPtr->pages = StringSave (imp->pages);
990 }
991 }
992 }
993 title = cit->title;
994 while (title != NULL) {
995 switch (title->choice) {
996 case 1:
997 mPtr->title = StringSave ((CharPtr) title->data.ptrvalue);
998 break;
999 case 2:
1000 break;
1001 case 3:
1002 mPtr->transl = StringSave ((CharPtr) title->data.ptrvalue);
1003 break;
1004 default:
1005 break;
1006 }
1007 title = title->next;
1008 }
1009 authors = cit->authors;
1010 if (authors != NULL) {
1011 if (authors->choice == 1 || authors->choice == 2 || authors->choice == 3) {
1012 names = authors->names;
1013 while (names != NULL) {
1014 last = mPtr->authors;
1015 curr = NULL;
1016 if (authors->choice == 1) {
1017 ap = (AuthorPtr) names->data.ptrvalue;
1018 if (ap != NULL) {
1019 pid = ap->name;
1020 if (pid != NULL) {
1021 if (pid->choice == 2) {
1022 nsp = (NameStdPtr) pid->data;
1023 if (nsp != NULL) {
1024 if (! StringHasNoText (nsp->names [0])) {
1025 curr = MakeAuthorString (nsp->names [0], nsp->names [4], nsp->names [5]);
1026 } else if (! StringHasNoText (nsp->names [3])) {
1027 curr = MakeAuthorString (nsp->names [3], NULL, NULL);
1028 }
1029 }
1030 } else if (pid->choice == 3 || pid->choice == 4) {
1031 curr = MakeAuthorString ((CharPtr) pid->data, NULL, NULL);
1032 }
1033 }
1034 }
1035 } else if (authors->choice == 2 || authors->choice == 3) {
1036 curr = CleanAuthorString ((CharPtr) names->data.ptrvalue);
1037 }
1038 if (last != NULL) {
1039 if (names->next != NULL) {
1040 mPtr->authors = StrngAppend (last, (CharPtr) ", ",
1041 (CharPtr) curr, (CharPtr) NULL);
1042 } else {
1043 mPtr->authors = StrngAppend (last, (CharPtr) " & ",
1044 (CharPtr) curr, (CharPtr) NULL);
1045 }
1046 last = MemFree (last);
1047 curr = MemFree (curr);
1048 } else {
1049 mPtr->authors = curr;
1050 }
1051 names = names->next;
1052 }
1053 }
1054 affil = authors->affil;
1055 if (affil != NULL) {
1056 if (affil->choice == 1) {
1057 mPtr->affil = StringSave (affil->affil);
1058 }
1059 }
1060 }
1061 }
1062 mPtr->abstract = StringSave (mep->abstract);
1063 mesh = mep->mesh;
1064 while (mesh != NULL) {
1065 if (mesh->mp) {
1066 StringNCpy (str, "*", sizeof (str));
1067 } else {
1068 StringNCpy (str, "", sizeof (str));
1069 }
1070 last = mPtr->mesh;
1071 if (last != NULL) {
1072 mPtr->mesh = StrngAppend (last, (CharPtr) "\n ", (CharPtr) str,
1073 (CharPtr) mesh->term, (CharPtr) NULL);
1074 last = MemFree (last);
1075 } else {
1076 mPtr->mesh = StrngAppend ((CharPtr) " ", (CharPtr) str,
1077 (CharPtr) mesh->term, (CharPtr) NULL);
1078 }
1079 qual = mesh->qual;
1080 while (qual != NULL) {
1081 if (qual->choice != 0) {
1082 StringNCpy (str, "*", sizeof (str));
1083 } else {
1084 StringNCpy (str, "", sizeof (str));
1085 }
1086 last = mPtr->mesh;
1087 mPtr->mesh = StrngAppend (last, (CharPtr) "/", (CharPtr) str,
1088 (CharPtr) qual->data.ptrvalue, (CharPtr) NULL);
1089 last = MemFree (last);
1090 qual = qual->next;
1091 }
1092 mesh = mesh->next;
1093 }
1094 if (mPtr->mesh != NULL) {
1095 last = mPtr->mesh;
1096 mPtr->mesh = StrngAppend (last, (CharPtr) "\n", (CharPtr) NULL);
1097 last = MemFree (last);
1098 }
1099 gene = mep->gene;
1100 if (gene != NULL) {
1101 ClearString ();
1102 while (gene != NULL) {
1103 AddString (" ");
1104 AddString (gene->data.ptrvalue);
1105 AddString ("\n");
1106 gene = gene->next;
1107 }
1108 mPtr->gene = StringSave (buffer);
1109 }
1110 substance = mep->substance;
1111 if (substance != NULL) {
1112 ClearString ();
1113 while (substance != NULL) {
1114 AddString (" ");
1115 switch (substance->type) {
1116 case 0:
1117 AddString (substance->name);
1118 break;
1119 case 1:
1120 AddString (substance->name);
1121 AddString (" (");
1122 AddString ("CAS ");
1123 AddString (substance->cit);
1124 AddString (")");
1125 break;
1126 case 2:
1127 AddString (substance->name);
1128 AddString (" (");
1129 AddString ("EC ");
1130 AddString (substance->cit);
1131 AddString (")");
1132 break;
1133 default:
1134 break;
1135 }
1136 AddString ("\n");
1137 substance = substance->next;
1138 }
1139 mPtr->substance = StringSave (buffer);
1140 }
1141 }
1142 ClearString ();
1143 buffer = MemFree (buffer);
1144 }
1145 return mPtr;
1146 }
1147
FreeMedline(MedlinePtr mPtr)1148 NLM_EXTERN MedlinePtr FreeMedline (MedlinePtr mPtr)
1149
1150 {
1151 if (mPtr != NULL) {
1152 mPtr->journal = MemFree (mPtr->journal);
1153 mPtr->volume = MemFree (mPtr->volume);
1154 mPtr->pages = MemFree (mPtr->pages);
1155 mPtr->year = MemFree (mPtr->year);
1156 mPtr->title = MemFree (mPtr->title);
1157 mPtr->transl = MemFree (mPtr->transl);
1158 mPtr->authors = MemFree (mPtr->authors);
1159 mPtr->affil = MemFree (mPtr->affil);
1160 mPtr->abstract = MemFree (mPtr->abstract);
1161 mPtr->mesh = MemFree (mPtr->mesh);
1162 mPtr->gene = MemFree (mPtr->gene);
1163 mPtr->substance = MemFree (mPtr->substance);
1164 mPtr->uid = MemFree (mPtr->uid);
1165 mPtr = MemFree (mPtr);
1166 }
1167 return NULL;
1168 }
1169
1170 static ColData colFmt [3] = {{0, 0, 0, 'l', TRUE, TRUE, FALSE},
1171 {0, 0, 0, 'l', TRUE, TRUE, FALSE},
1172 {0, 0, 0, 'l', TRUE, TRUE, TRUE}};
1173
1174 static ColData mshFmt [1] = {{0, 80, 0, 'l', FALSE, FALSE, TRUE}};
1175
MedlineEntryToDocOrAbsFile(MedlineEntryPtr mep,Int4 pmid,FILE * fp,Boolean showMesh)1176 static Boolean MedlineEntryToDocOrAbsFile (MedlineEntryPtr mep, Int4 pmid, FILE *fp, Boolean showMesh)
1177
1178 {
1179 size_t len;
1180 MedlinePtr mPtr;
1181 ParData para;
1182 CharPtr ptr;
1183 Boolean rsult;
1184 CharPtr tmp;
1185
1186 rsult = TRUE;
1187 if (fp != NULL && mep != NULL) {
1188 mPtr = ParseMedline (mep);
1189 if (mPtr != NULL) {
1190 buffer = MemNew (BUFSIZE);
1191 if (buffer != NULL) {
1192 para.openSpace = FALSE;
1193 ClearString ();
1194 AddString (mPtr->journal);
1195 AddString ("\t");
1196 AddString (mPtr->volume);
1197 AddString (":\t");
1198 AddString (mPtr->pages);
1199 AddString (" (");
1200 AddString (mPtr->year);
1201 AddString (")");
1202 AddString (" [");
1203 AddString (mPtr->uid);
1204 AddString ("]");
1205 AddString ("\n");
1206 rsult = (Boolean) (SendTextToFile (fp, buffer, ¶, colFmt) && rsult);
1207 ClearString ();
1208 AddString (mPtr->title);
1209 AddString ("\n");
1210 rsult = (Boolean) (SendTextToFile (fp, buffer, NULL, NULL) && rsult);
1211 ClearString ();
1212 if (mPtr->transl != NULL) {
1213 AddString ("[");
1214 AddString (mPtr->transl);
1215 AddString ("]\n");
1216 rsult = (Boolean) (SendTextToFile (fp, buffer, NULL, NULL) && rsult);
1217 ClearString ();
1218 }
1219 AddString (mPtr->authors);
1220 AddString ("\n");
1221 rsult = (Boolean) (SendTextToFile (fp, buffer, NULL, NULL) && rsult);
1222 ClearString ();
1223 if (mPtr->affil != NULL) {
1224 AddString (mPtr->affil);
1225 AddString ("\n");
1226 rsult = (Boolean) (SendTextToFile (fp, buffer, NULL, NULL) && rsult);
1227 ClearString ();
1228 }
1229 if (mPtr->abstract != NULL) {
1230 len = StringLen (mPtr->abstract);
1231 tmp = (CharPtr) MemNew (sizeof (Char) * (len + 10));
1232 ptr = StringMove (tmp, mPtr->abstract);
1233 ptr = StringMove (ptr, "\n");
1234 rsult = (Boolean) (SendTextToFile (fp, tmp, NULL, NULL) && rsult);
1235 MemFree (tmp);
1236 }
1237 if (showMesh) {
1238 if (mPtr->mesh != NULL) {
1239 rsult = (Boolean) (SendTextToFile (fp, "MeSH Terms:\n", NULL, NULL) && rsult);
1240 rsult = (Boolean) (SendTextToFile (fp, mPtr->mesh, ¶, mshFmt) && rsult);
1241 }
1242 if (mPtr->gene != NULL) {
1243 rsult = (Boolean) (SendTextToFile (fp, "Gene Symbols:\n", NULL, NULL) && rsult);
1244 rsult = (Boolean) (SendTextToFile (fp, mPtr->gene, ¶, mshFmt) && rsult);
1245 }
1246 if (mPtr->substance != NULL) {
1247 rsult = (Boolean) (SendTextToFile (fp, "Substances:\n", NULL, NULL) && rsult);
1248 rsult = (Boolean) (SendTextToFile (fp, mPtr->substance, ¶, mshFmt) && rsult);
1249 }
1250 }
1251 buffer = MemFree (buffer);
1252 }
1253 mPtr = FreeMedline (mPtr);
1254 }
1255 }
1256 return rsult;
1257 }
1258
MedlineEntryToDocFile(MedlineEntryPtr mep,FILE * fp)1259 NLM_EXTERN Boolean MedlineEntryToDocFile (MedlineEntryPtr mep, FILE *fp)
1260
1261 {
1262 return MedlineEntryToDocOrAbsFile (mep, 0, fp, TRUE);
1263 }
1264
MedlineEntryToAbsFile(MedlineEntryPtr mep,FILE * fp)1265 NLM_EXTERN Boolean MedlineEntryToAbsFile (MedlineEntryPtr mep, FILE *fp)
1266
1267 {
1268 return MedlineEntryToDocOrAbsFile (mep, 0, fp, FALSE);
1269 }
1270
PubmedEntryToDocFile(PubmedEntryPtr pep,FILE * fp)1271 NLM_EXTERN Boolean PubmedEntryToDocFile (PubmedEntryPtr pep, FILE *fp)
1272
1273 {
1274 MedlineEntryPtr mep;
1275
1276 if (pep == NULL || fp == NULL) return FALSE;
1277 mep = (MedlineEntryPtr) pep->medent;
1278 if (mep == NULL) return FALSE;
1279 return MedlineEntryToDocOrAbsFile (mep, pep->pmid, fp, TRUE);
1280 }
1281
PubmedEntryToAbsFile(PubmedEntryPtr pep,FILE * fp)1282 NLM_EXTERN Boolean PubmedEntryToAbsFile (PubmedEntryPtr pep, FILE *fp)
1283
1284 {
1285 MedlineEntryPtr mep;
1286
1287 if (pep == NULL || fp == NULL) return FALSE;
1288 mep = (MedlineEntryPtr) pep->medent;
1289 if (mep == NULL) return FALSE;
1290 return MedlineEntryToDocOrAbsFile (mep, pep->pmid, fp, FALSE);
1291 }
1292
1293 #define IBM_MEDLINE_DIVSS '$'
1294 #define IBM_MEDLINE_DIVSV '&'
1295 #define IBM_MEDLINE_DIVEV '#'
1296 #define SIZE_OF_ARRAY(x) (sizeof(x)/sizeof(x[0]))
1297
1298 typedef struct {
1299 char cSubHead[4];
1300 char* pFullName;
1301 } SSubheadAbbr;
1302
1303 static SSubheadAbbr theSubHead [] = {
1304 { "VE", "veterinary" },
1305 { "UR", "urine" },
1306 { "UT", "utilization" },
1307 { "UY", "Uruguay" },
1308 { "UL", "ultrastructure" },
1309 { "US", "ultrasonography" },
1310 { "TD", "trends" },
1311 { "TR", "transplantation" },
1312 { "TM", "transmission" },
1313 { "TO", "toxicity" },
1314 { "TH", "therapy" },
1315 { "TU", "therapeutic use" },
1316 { "SU", "surgery" },
1317 { "SD", "supply & distribution" },
1318 { "SN", "statistics & numerical data" },
1319 { "ST", "standards" },
1320 { "SE", "secretion" },
1321 { "SC", "secondary" },
1322 { "RH", "rehabilitation" },
1323 { "RT", "radiotherapy" },
1324 { "RI", "radionuclide imaging" },
1325 { "RA", "radiography" },
1326 { "RE", "radiation effects" },
1327 { "PX", "psychology" },
1328 { "PC", "prevention & control" },
1329 { "PO", "poisoning" },
1330 { "PP", "physiopathology" },
1331 { "PH", "physiology" },
1332 { "PD", "pharmacology" },
1333 { "PK", "pharmacokinetics" },
1334 { "PA", "pathology" },
1335 { "PY", "pathogenicity" },
1336 { "PS", "parasitology" },
1337 { "OG", "organization & administration" },
1338 { "NU", "nursing" },
1339 { "NP", "Nepal" },
1340 { "MO", "mortality" },
1341 { "MI", "microbiology" },
1342 { "MT", "methods" },
1343 { "ME", "metabolism" },
1344 { "MA", "manpower" },
1345 { "LJ", "legislation & jurisprudence" },
1346 { "IP", "isolation & purification" },
1347 { "IS", "instrumentation" },
1348 { "IR", "innervation" },
1349 { "IN", "injuries" },
1350 { "PR", "in pregnancy" },
1351 { "OA", "in old age" },
1352 { "MY", "in middle age" },
1353 { "IC", "in infancy & childhood" },
1354 { "AU", "in adulthood" },
1355 { "AO", "in adolescence" },
1356 { "IM", "immunology" },
1357 { "IL", "Illinois" },
1358 { "HI", "history" },
1359 { "GD", "growth & development" },
1360 { "GE", "genetics" },
1361 { "ET", "etiology" },
1362 { "EH", "ethnology" },
1363 { "EP", "epidemiolgy" },
1364 { "EN", "enzymology" },
1365 { "EM", "embryology" },
1366 { "ED", "education" },
1367 { "EC", "economics" },
1368 { "DT", "drug therapy" },
1369 { "DE", "drug effects" },
1370 { "DH", "diet therapy" },
1371 { "DU", "diagnostic use" },
1372 { "DI", "diagnosis" },
1373 { "DF", "deficiency" },
1374 { "CI", "chemically induced" },
1375 { "CY", "cytology" },
1376 { "CT", "contraindications" },
1377 { "CN", "congenital" },
1378 { "CO", "complications" },
1379 { "CL", "classification" },
1380 { "CH", "chemistry" },
1381 { "CL", "chemistry induced" },
1382 { "CS", "chemical synthesis" },
1383 { "CD", "Chad" },
1384 { "CF", "cerebrospinal fluid" },
1385 { "BS", "blood supply" },
1386 { "BL", "blood" },
1387 { "BI", "biosynthesis" },
1388 { "BT", "Bhutan" },
1389 { "AI", "antagonists & inhibitors" },
1390 { "AH", "anatomy & histology" },
1391 { "AN", "analysis" },
1392 { "AA", "analogs & derivatives" },
1393 { "AE", "adverse effects" },
1394 { "AD", "administration & dosage" },
1395 { "AB", "abnormalities" },
1396 { "AG", "AG" },
1397 { "VI", "VI" }
1398 };
1399
1400 /****************************************************************************/
1401 /*.doc GetTopicSubHead (internal) */
1402 /*+
1403 This function search subhead using subhead abbreviation. Return
1404 pointer to founded subhead or original subhead abbreviation if
1405 subhead not found.
1406 -*/
1407 /****************************************************************************/
1408 static char*
GetTopicSubHead(char * lpSubHead)1409 /*FCN*/GetTopicSubHead (
1410 char* lpSubHead
1411 ){
1412 register int i; /* fast index */
1413
1414 for ( i = 0; i < SIZE_OF_ARRAY(theSubHead); i++ ) {
1415 if ( StringICmp (lpSubHead, theSubHead[i].cSubHead)
1416 == 0 ) {
1417 return theSubHead[i].pFullName; /* return full name */
1418 }
1419 }
1420
1421 return lpSubHead; /* return original subhead */
1422 } /* GetTopicSubHead() */
1423
1424 /****************************************************************************/
1425 /*.doc TranslateMesh (internal) */
1426 /*+
1427 This function translate MeSH string to standart printable form
1428 -*/
1429 /****************************************************************************/
1430 static void
TranslateMesh(char * lpOut,char * lpRecord)1431 /*FCN*/TranslateMesh (
1432 char* lpOut,
1433 char* lpRecord
1434 ){
1435 register char* lpTemp; /* Temporary pointer */
1436 char* lpMainTerm; /* Main termin */
1437 int iDescClass; /* Descriptor Class */
1438 char cInputType; /* Input type */
1439
1440 /* extract Mesh Term from Mesh record */
1441 if ( (lpTemp = strchr (lpRecord, IBM_MEDLINE_DIVSS)) != NULL ) {
1442 *lpTemp = '\0'; /* set EOS for Mesh Term */
1443 lpTemp++; /* lpTemp set to next character after $ */
1444 } else {
1445 strcpy(lpOut,lpRecord);
1446 return;
1447 }
1448
1449 lpMainTerm = lpRecord;
1450 strcpy(lpOut,lpMainTerm);
1451
1452 /* Skip descriptor class. A number that designates to
1453 what class the MeSH heading belongs as follows:
1454 1 - an INDEX MEDICUS major descriptor
1455 2 - a citation type major descriptor, e.g., ENGLISH ABSTRACT
1456 3 - a check tag major descriptor, e.g., HUMAN
1457 4 - a geographic major descriptor, e.g., FRANCE
1458 5 - a non-MeSH major descriptor, e.g., PATIENT CARE
1459 MANAGEMENT (NON MESH)
1460 6 - a withdrawn major descriptor
1461 */
1462 if ( isdigit((int)(*lpTemp)) ) {
1463 lpRecord = lpTemp;
1464 lpTemp++;
1465 iDescClass = atoi (lpRecord);
1466 iDescClass = iDescClass; /* Do not use descriptor class */
1467 }
1468
1469 /* Skip next subelement. Value is I or M. 'I' means an indexer
1470 input the Heading. 'M' means it was attached throwgh
1471 computer mapping
1472 */
1473 if ( *lpTemp == IBM_MEDLINE_DIVSS
1474 && (*(lpTemp+1) == 'I' || *(lpTemp+1) == 'M') ) {
1475 lpTemp++; /* skip IBM_MEDLINE_DIVSS */
1476 cInputType = *lpTemp++;
1477 cInputType = cInputType;
1478 }
1479
1480 /* Qualifier List. A list of two-letter subheading (qualifier)
1481 abbreviations, separated by slashes if there is more than
1482 one value. Each subheading abbreviation may have an *
1483 (central concept indicator) preceding it. This subelement
1484 may consist of a single *, which indicates the MeSH
1485 heading alone is a central concept of the article.
1486 */
1487 if ( *lpTemp == IBM_MEDLINE_DIVSS ) {
1488 int bIsCentralConcept;
1489 char cSubHead[3];
1490
1491 lpTemp++; /* skip IBM_MEDLINE_DIVSS */
1492 cSubHead[2] = '\0'; /* set EOL */
1493
1494 /* read tokens from qualifier list */
1495 while ( (cSubHead[0]=*lpTemp++) != '\0' ) {
1496 bIsCentralConcept = 0;
1497 if ( cSubHead[0] == '*' ) { /* is central concept mark? */
1498 cSubHead[0] = *lpTemp++;
1499 if ( cSubHead[0] == '/' ) {
1500 strcpy(lpOut,"*");
1501 strcat(lpOut,lpMainTerm);
1502 continue;
1503 }
1504 if ( cSubHead[0] == '\0'
1505 || cSubHead[0] == IBM_MEDLINE_DIVEV
1506 || cSubHead[0] == IBM_MEDLINE_DIVSV ) {
1507 strcpy(lpOut,"*");
1508 strcat(lpOut,lpMainTerm);
1509 break;
1510 }
1511 bIsCentralConcept = 1;
1512 }
1513 if ( (cSubHead[1] = *lpTemp++) == '\0' ) {
1514 /* Special case for mii.d80.back66.rf, it has a bad data
1515 in MeSH heading for entry 68324942
1516 */
1517 break;
1518 }
1519 strcat(lpOut,"/");
1520 if ( bIsCentralConcept == 1 ) {
1521 strcat(lpOut,"*");
1522 }
1523 strcat(lpOut,GetTopicSubHead(cSubHead));
1524 if ( *lpTemp == '/' ) {
1525 lpTemp++;
1526 } else if ( *lpTemp == IBM_MEDLINE_DIVEV
1527 || *lpTemp == IBM_MEDLINE_DIVSV ) {
1528 /* ignore Sort version and Entry version */
1529 break;
1530 }
1531 }
1532 }
1533
1534 return;
1535 } /* TranslateMesh() */
1536
1537
1538 /***********************************************************************/
1539 /*.doc MedlarsEntryToDataFile (external) */
1540 /*+
1541 Function send MEDLARS entry to I/O stream
1542 -*/
1543 /***********************************************************************/
1544 NLM_EXTERN Boolean
MedlarsEntryToDataFile(MedlarsEntryPtr mep,FILE * fp)1545 /*FCN*/MedlarsEntryToDataFile (
1546 MedlarsEntryPtr mep,
1547 FILE *fp
1548 ){
1549 ParData thePara;
1550 CharPtr lpBuffer;
1551 MedlarsRecordPtr pRecord;
1552 Boolean bResult = TRUE;
1553 char buf[BUFSIZE];
1554 int i, exist;
1555 char* ptr;
1556 #define MAX_ELHILL 24
1557 int ElhillOrder[MAX_ELHILL] = {
1558 /* UI */ MEDLINE_UI,
1559 /* AU */ MEDLINE_AU,
1560 /* TI */ MEDLINE_TI,
1561 /* LA */ MEDLINE_LA,
1562 /* MH */ MEDLINE_MH,
1563 /* RN */ MEDLINE_RN,
1564 /* PT */ MEDLINE_PT,
1565 /* ID */ MEDLINE_ID,
1566 /* DA */ MEDLINE_DA,
1567 /* DP */ MEDLINE_DP,
1568 /* IS */ MEDLINE_IS,
1569 /* TA */ MEDLINE_TA,
1570 /* PG */ MEDLINE_PG,
1571 /* SB */ MEDLINE_SB,
1572 /* CY */ MEDLINE_CY,
1573 /* IP */ MEDLINE_IP,
1574 /* VI */ MEDLINE_VI,
1575 /* JC */ MEDLINE_JC,
1576 /* AA */ MEDLINE_AA,
1577 /* EM */ MEDLINE_EM,
1578 /* AB */ MEDLINE_AB,
1579 /* AD */ MEDLINE_AD,
1580 /* RF */ MEDLINE_RF,
1581 /* RO */ MEDLINE_RO
1582 };
1583
1584 char* TA="";
1585 char* DP="";
1586 char* VI="";
1587 char* IP="";
1588 char* PG="";
1589
1590 if ( mep == NULL || fp == NULL ) {
1591 return FALSE;
1592 }
1593
1594 MemSet (&thePara, 0, sizeof(thePara));
1595
1596 if ( (lpBuffer=MemNew(BUFSIZE)) == NULL ) return FALSE;
1597
1598 /* First run to print known Elhill codes */
1599 for( i = 0; i < MAX_ELHILL; i++ ) {
1600
1601 for ( pRecord = mep->recs;
1602 pRecord != NULL;
1603 pRecord = pRecord->next ) {
1604
1605 if( pRecord->code != ElhillOrder[i] ) continue;
1606
1607 if ( pRecord->abbr != NULL ) {
1608 /* This record has record type abbreviation */
1609 sprintf( lpBuffer, "%-4s-\t", pRecord->abbr );
1610 } else {
1611 /* This record has no record type abbreviation, use number */
1612 sprintf ( lpBuffer, "%-4d-\t", pRecord->code );
1613 }
1614
1615 if ( MEDLINE_TA == pRecord->code )
1616 TA = pRecord->data; /* TA - name of journal */
1617 if ( MEDLINE_DP == pRecord->code )
1618 DP = pRecord->data; /* DP - date of publication */
1619 if ( MEDLINE_VI == pRecord->code )
1620 VI = pRecord->data; /* VI - volume number */
1621 if ( MEDLINE_IP == pRecord->code )
1622 IP = pRecord->data; /* IP - issue number */
1623 if ( MEDLINE_PG == pRecord->code )
1624 PG = pRecord->data; /* PG - page numbers */
1625
1626
1627 switch( pRecord->code ) {
1628
1629 case MEDLINE_MH:
1630 TranslateMesh( buf, pRecord->data);
1631 StringCat(lpBuffer,buf);
1632 break;
1633
1634 case MEDLINE_RO:
1635 strncpy( buf, pRecord->data, BUFSIZE-1 );
1636 for ( ptr = buf; *ptr; ptr++ )
1637 if( '$' == *ptr ) *ptr = ':';
1638 StringCat( lpBuffer, buf );
1639 break;
1640
1641 case MEDLINE_ID:
1642 strncpy( buf, pRecord->data, BUFSIZE-1 );
1643 for ( ptr = buf; *ptr; ptr++ )
1644 if( '$' == *ptr ) *ptr = '/';
1645 StringCat( lpBuffer, buf );
1646 break;
1647
1648 default:
1649 StringCat(lpBuffer,pRecord->data);
1650 break;
1651
1652 }
1653
1654 StringCat(lpBuffer,"\n");
1655
1656 if ( SendTextToFile (fp, lpBuffer, &thePara, table) != TRUE ) {
1657 MemFree(lpBuffer);
1658 return FALSE;
1659 }
1660 }
1661 }
1662
1663 /* Second run to print unknown Elhill codes */
1664 for ( pRecord = mep->recs;
1665 pRecord != NULL;
1666 pRecord = pRecord->next ) {
1667
1668 exist = 0;
1669 for( i = 0; i < MAX_ELHILL; i++ ) {
1670 if( pRecord->code == ElhillOrder[i] ) {
1671 exist = 1;
1672 break;
1673 }
1674 }
1675 if( exist ) continue;
1676 if ( pRecord->abbr != NULL ) {
1677 /* This record has record type abbreviation */
1678 sprintf (
1679 lpBuffer,
1680 "%-4s-\t",
1681 pRecord->abbr
1682 );
1683 } else {
1684 /* This record has no record type abbreviation, use number */
1685 sprintf (
1686 lpBuffer,
1687 "%-4d-\t",
1688 pRecord->code
1689 );
1690 }
1691
1692 StringCat(lpBuffer,pRecord->data);
1693 StringCat(lpBuffer,"\n");
1694
1695 if ( SendTextToFile (fp, lpBuffer, &thePara, table) != TRUE ) {
1696 MemFree(lpBuffer);
1697 return FALSE;
1698 }
1699 }
1700
1701 /* Generate SO field */
1702 strcpy( lpBuffer,"SO -\t");
1703 strcat( lpBuffer, TA );
1704 strcat( lpBuffer," " );
1705 strcat( lpBuffer, DP );
1706 strcat( lpBuffer,";" );
1707 strcat( lpBuffer, VI );
1708 if ( *IP != '\0' ) {
1709 strcat( lpBuffer,"(");
1710 strcat( lpBuffer, IP );
1711 strcat( lpBuffer,")" );
1712 }
1713 strcat( lpBuffer, ":" );
1714 strcat( lpBuffer, PG );
1715 strcat(lpBuffer,"\n");
1716
1717 if ( SendTextToFile (fp, lpBuffer, &thePara, table) != TRUE )
1718 bResult = FALSE;
1719
1720 MemFree(lpBuffer);
1721 return bResult;
1722 } /* MedlarsEntryToDataFile() */
1723
1724 /***********************************************************************/
1725 /*.doc MedlarsEntryToDocFile (external) */
1726 /*+
1727 Function send MEDLARS entry to I/O stream
1728 -*/
1729 /***********************************************************************/
1730 NLM_EXTERN Boolean
MedlarsEntryToDocFile(MedlarsEntryPtr mep,FILE * fp)1731 /*FCN*/MedlarsEntryToDocFile (
1732 MedlarsEntryPtr mep,
1733 FILE *fp
1734 ){
1735 if ( mep == NULL || fp == NULL ) {
1736 return FALSE;
1737 }
1738 return TRUE;
1739 } /* MedlarsEntryToDocFile() */
1740
1741 /***********************************************************************/
1742 /*.doc MedlarsEntryToAbsFile (external) */
1743 /*+
1744 Function send MEDLARS entry to I/O stream
1745 -*/
1746 /***********************************************************************/
1747 NLM_EXTERN Boolean
MedlarsEntryToAbsFile(MedlarsEntryPtr mep,FILE * fp)1748 /*FCN*/MedlarsEntryToAbsFile (
1749 MedlarsEntryPtr mep,
1750 FILE *fp
1751 ){
1752 if ( mep == NULL || fp == NULL ) {
1753 return FALSE;
1754 }
1755 return TRUE;
1756 } /* MedlarsEntryToAbsFile() */
1757
1758