1 /*
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: findrepl.c
27 *
28 * Author:  Jonathan Kans, Tim Ford
29 *
30 * Version Creation Date:   10/17/00
31 *
32 * File Description:
33 *   Complete redesign of find/replace from original of Yuri Sadykov
34 *
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date     Name        Description of modification
39 * -------  ----------  -----------------------------------------------------
40 *
41 * ==========================================================================
42 *
43 */
44 
45 #include <ncbi.h>
46 #include <objall.h>
47 #include <objfdef.h>
48 #include <objsub.h>
49 #include <gather.h>
50 #include <sqnutils.h>
51 #include <subutil.h>
52 #include <findrepl.h>
53 
54 /* callback type for search/replace functions */
55 typedef void (*FindReplFunc) (CharPtr PNTR strp, Pointer fspdata);
56 
57 /* internal data structure */
58 
59 typedef struct findstruct {
60   Uint2         entityID;
61   FindReplFunc  func;
62   FindReplProc  callback;
63   Pointer       userdata;
64   StringActionFunc string_action;
65 
66   CharPtr       find_string;
67   CharPtr       replace_string;
68   Boolean       case_counts;
69   Boolean       whole_word;
70   Int4          findLen;
71   Int4          replaceLen;
72 
73   Boolean       select_item;
74   Int2          send_update;
75   Boolean       did_find;
76   Boolean       did_replace;
77   Boolean       dirty;
78 
79   Boolean       descFilter [SEQDESCR_MAX];
80   Boolean       featFilter [FEATDEF_MAX];
81   Boolean       seqidFilter [NUM_SEQID];
82 
83   int           d [256];
84   TextFsaPtr    fsa;
85 } FindStruct, PNTR FindStructPtr;
86 
87 #define FINDREPL_BUFFER_MAX  1000000
88 
89 /* BOYER-MOORE SEARCH FUNCTIONS */
90 
91 /* StringSearch and StringISearch use the Boyer-Moore algorithm, as described
92    in Niklaus Wirth, Algorithms and Data Structures, Prentice- Hall, Inc.,
93    Englewood Cliffs, NJ., 1986, p. 69.  The original had an error, where
94    UNTIL (j < 0) OR (p[j] # s[i]) should be UNTIL (j < 0) OR (p[j] # s[k]). */
95 
FindSubString(CharPtr str,CharPtr sub,Boolean case_counts,size_t strLen,size_t subLen,int * d)96 static CharPtr FindSubString (
97   CharPtr str,
98   CharPtr sub,
99   Boolean case_counts,
100   size_t strLen,
101   size_t subLen,
102   int *d
103 )
104 
105 {
106   int  ch;
107   int  i;
108   int  j;
109   int  k;
110 
111   i = subLen;
112   do {
113     j = subLen;
114     k = i;
115     do {
116       k--;
117       j--;
118     } while (j >= 0 &&
119              (case_counts ? sub [j] : TO_UPPER (sub [j])) ==
120              (case_counts ? str [k] : TO_UPPER (str [k])));
121     if (j >= 0) {
122       ch = (int) (case_counts ? str [i - 1] : TO_UPPER (str [i - 1]));
123       if (ch >= 0 && ch <= 255) {
124         i += d [ch];
125       } else {
126         i++;
127       }
128     }
129   } while (j >= 0 && i <= (int) strLen);
130 
131   if (j < 0) {
132     i -= subLen;
133     return (CharPtr) (str + i);
134   }
135 
136   return NULL;
137 }
138 
139 /* passed subLen and d array to avoid repeated initialization
140    of the Boyer-Moore displacement table */
141 
SearchForString(CharPtr str,CharPtr sub,Boolean case_counts,Boolean whole_word,size_t subLen,int * d)142 static CharPtr SearchForString (
143   CharPtr str,
144   CharPtr sub,
145   Boolean case_counts,
146   Boolean whole_word,
147   size_t subLen,
148   int * d
149 )
150 
151 {
152   Char     ch;
153   size_t   diff;
154   CharPtr  ptr = NULL;
155   size_t   strLen;
156   CharPtr  tmp;
157   Boolean  keep_looking = TRUE;
158 
159   if (str == NULL || *str == '\0') return NULL;
160   strLen = StringLen (str);
161   if (subLen > strLen) return NULL;
162 
163   ptr = FindSubString (str, sub, case_counts, strLen, subLen, d);
164   if (ptr == NULL) return NULL;
165 
166   if (! whole_word) return ptr;
167 
168   while (keep_looking && ptr != NULL) {
169     keep_looking = FALSE;
170     if (ptr > str) {
171       tmp = ptr - 1;
172       ch = *tmp;
173       if ((! IS_WHITESP (ch)) && (! ispunct (ch))) {
174         keep_looking = TRUE;
175       }
176     }
177     if (! keep_looking) {
178       tmp = ptr + subLen;
179       ch = *tmp;
180       if (ch != '\0' && (! IS_WHITESP (ch)) && (! ispunct (ch))) {
181         keep_looking = TRUE;
182       }
183     }
184     if (keep_looking) {
185       diff = ptr - str;
186       ptr = FindSubString (ptr + subLen, sub, case_counts, strLen - diff, subLen, d);
187     }
188   }
189 
190   return ptr;
191 }
192 
BoyerMooreFindString(CharPtr PNTR strp,Pointer userdata)193 static void BoyerMooreFindString (
194   CharPtr PNTR strp,
195   Pointer userdata
196 )
197 
198 {
199   FindStructPtr  fsp;
200   CharPtr        searchString;
201 
202   if (strp == NULL || userdata == NULL) return;
203   fsp = (FindStructPtr) userdata;
204 
205   searchString = *strp;
206   if (SearchForString (searchString, fsp->find_string, fsp->case_counts,
207                        fsp->whole_word, fsp->findLen, fsp->d) != NULL) {
208     fsp->did_find = TRUE;
209   }
210 }
211 
BoyerMooreReplaceString(CharPtr PNTR strp,Pointer userdata)212 static void BoyerMooreReplaceString (
213   CharPtr PNTR strp,
214   Pointer userdata
215 )
216 
217 {
218   Uint4          buffSize;
219   FindStructPtr  fsp;
220   Uint4          searchLen;
221   CharPtr        searchString;
222   CharPtr        substringPtr;
223   Boolean        wasChanged;
224   CharPtr        workingBuffer;
225 
226   if (strp == NULL || userdata == NULL) return;
227   fsp = (FindStructPtr) userdata;
228 
229   searchString = *strp;
230   searchLen  = StringLen (searchString);
231 
232   wasChanged = FALSE;
233 
234   /*------------------------------------------------*/
235   /* Make a guess of how big a working buffer we'll */
236   /* need based on a worst case scenario.           */
237   /*                                                */
238   /*   A = Max occurrences of find string =         */
239   /*               searchLen / findLen              */
240   /*                                                */
241   /*   B = Size increase for each replacement =     */
242   /*               replaceLen - findLen             */
243   /*                                                */
244   /*   Maximum resultant string size =              */
245   /*               searchLen + (A * B)              */
246   /*                                                */
247   /*------------------------------------------------*/
248 
249   if (fsp->replaceLen > fsp->findLen) {
250       buffSize = searchLen + ((searchLen/fsp->findLen) * (fsp->replaceLen - fsp->findLen));
251       if (buffSize > FINDREPL_BUFFER_MAX) {
252         buffSize = FINDREPL_BUFFER_MAX;
253       }
254   } else {
255     buffSize = searchLen;
256   }
257 
258   workingBuffer = (CharPtr) MemNew (buffSize + 2);
259   if (workingBuffer == NULL) return;
260 
261   workingBuffer[0] = '\0';
262 
263   /*----------------------------------------*/
264   /* Create a new string with all instances */
265   /* of the find string replaced by the     */
266   /* replace string.                        */
267   /*----------------------------------------*/
268 
269   while ((substringPtr = SearchForString (searchString, fsp->find_string,
270           fsp->case_counts, fsp->whole_word, fsp->findLen, fsp->d)) != NULL) {
271     wasChanged = TRUE;
272     substringPtr [0] = '\0';
273 
274     if (StringLen (workingBuffer) + StringLen (searchString) > buffSize) return;
275 
276     StringCat (workingBuffer, searchString);
277     StringCat (workingBuffer, fsp->replace_string);
278     substringPtr [0] = 'x';
279     searchString = substringPtr + fsp->findLen;
280   }
281 
282   if (searchString != NULL) {
283     StringCat (workingBuffer, searchString);
284   }
285 
286   /*-------------------------------------*/
287   /* If any replacements were made, then */
288   /* swap in the new string for the old. */
289   /*-------------------------------------*/
290 
291   if (wasChanged) {
292     MemFree (*strp);
293     (*strp) = workingBuffer;
294 
295     fsp->did_replace = TRUE;
296     fsp->dirty = TRUE;
297   } else {
298     MemFree (workingBuffer);
299   }
300 }
301 
302 /* FINITE-STATE AUTOMATON SEARCH FUNCTION */
303 
FSAFindStrings(CharPtr PNTR strp,Pointer userdata)304 static void FSAFindStrings (
305   CharPtr PNTR strp,
306   Pointer userdata
307 )
308 
309 {
310   Char           ch;
311   FindStructPtr  fsp;
312   CharPtr        ptr;
313   CharPtr        searchString;
314   Int4           state;
315   ValNodePtr     matches;
316 
317   if (strp == NULL || userdata == NULL) return;
318   fsp = (FindStructPtr) userdata;
319 
320   searchString = *strp;
321   if (searchString == NULL) return;
322 
323   state = 0;
324   ptr = searchString;
325   ch = *ptr;
326 
327   while (ch != '\0') {
328     matches = NULL;
329     state = TextFsaNext (fsp->fsa, state, ch, &matches);
330     if (matches != NULL) {
331       fsp->did_find = TRUE;
332       return;
333     }
334     ptr++;
335     ch = *ptr;
336   }
337 }
338 
339 /* MASTER SEARCH FUNCTION CALLS DESIGNATED FUNC CALLBACK */
340 
341 /*=======================================================================*/
342 /*                                                                       */
343 /* FindReplString () - Does a search and replace in a given string.      */
344 /*                                                                       */
345 /*    Main Parameters:                                                   */
346 /*                                                                       */
347 /*         strp : The string to operate on. Passed as a pointer to       */
348 /*                a string so that it can be replaced by the             */
349 /*                resulting string.                                      */
350 /*                                                                       */
351 /*         fsp->find_string : The substring that is being replaced       */
352 /*                            in strp.                                   */
353 /*                                                                       */
354 /*         fsp->replace_string : The substring that is replacing         */
355 /*                               find_string in strp.                    */
356 /*                                                                       */
357 /*=======================================================================*/
358 
FindReplString(CharPtr PNTR strp,FindStructPtr fsp)359 static void FindReplString (
360   CharPtr PNTR strp,
361   FindStructPtr fsp
362 )
363 
364 {
365   if (strp == NULL || fsp == NULL || fsp->func == NULL) return;
366 
367   fsp->func (strp, (Pointer) fsp);
368 }
369 
370 /*=======================================================================*/
371 /*                                                                       */
372 /*  FindReplStringList()                                                 */
373 /*                                                                       */
374 /*=======================================================================*/
375 
FindReplStringList(ValNodePtr vnp,FindStructPtr fsp)376 static void FindReplStringList (
377   ValNodePtr vnp,
378   FindStructPtr fsp
379 )
380 
381 {
382   while (vnp != NULL) {
383     FindReplString ((CharPtr PNTR) &(vnp->data.ptrvalue), fsp);
384     vnp = vnp->next;
385   }
386 }
387 
388 /*=======================================================================*/
389 /*                                                                       */
390 /*  FindReplDbxrefs() -                                                  */
391 /*                                                                       */
392 /*=======================================================================*/
393 
FindReplDbxrefs(ValNodePtr vnp,FindStructPtr fsp)394 static void FindReplDbxrefs (
395   ValNodePtr vnp,
396   FindStructPtr fsp
397 )
398 
399 {
400   DbtagPtr     dbt;
401   ObjectIdPtr  oip;
402 
403   while (vnp != NULL) {
404     dbt = (DbtagPtr) vnp->data.ptrvalue;
405     if (dbt != NULL) {
406       FindReplString (&(dbt->db), fsp);
407       oip = dbt->tag;
408       if (oip != NULL && oip->str != NULL) {
409         FindReplString (&(oip->str), fsp);
410       }
411     }
412     vnp = vnp->next;
413   }
414 }
415 
416 /*=======================================================================*/
417 /*                                                                       */
418 /*  FindReplAffil() -                                                    */
419 /*                                                                       */
420 /*=======================================================================*/
421 
FindReplAffil(AffilPtr pAffil,FindStructPtr fsp)422 static void FindReplAffil (
423   AffilPtr pAffil,
424   FindStructPtr fsp
425 )
426 
427 {
428   if (pAffil == NULL) return;
429 
430   if (pAffil->choice == 1) {
431     FindReplString (&(pAffil->affil)      , fsp);
432   } else {
433     FindReplString (&(pAffil->affil)      , fsp);
434     FindReplString (&(pAffil->div)        , fsp);
435     FindReplString (&(pAffil->city)       , fsp);
436     FindReplString (&(pAffil->sub)        , fsp);
437     FindReplString (&(pAffil->country)    , fsp);
438     FindReplString (&(pAffil->street)     , fsp);
439     FindReplString (&(pAffil->email)      , fsp);
440     FindReplString (&(pAffil->fax)        , fsp);
441     FindReplString (&(pAffil->phone)      , fsp);
442     FindReplString (&(pAffil->postal_code), fsp);
443   }
444 }
445 
446 /*=======================================================================*/
447 /*                                                                       */
448 /*  FindReplAuthor() -                                                   */
449 /*                                                                       */
450 /*=======================================================================*/
451 
452 #define NAMESTD_LAST     0
453 #define NAMESTD_FIRST    1
454 #define NAMESTD_MIDDLE   2
455 #define NAMESTD_FULL     3
456 #define NAMESTD_INITIALS 4
457 #define NAMESTD_SUFFIX   5
458 #define NAMESTD_TITLE    6
459 
460 #define PID_NOTSET 0
461 #define PID_DBTAG  1
462 #define PID_NAME   2
463 #define PID_ML     3
464 #define PID_STR    4
465 #define PID_CONSRT 5
466 
FindReplAuthor(AuthorPtr pAuthor,FindStructPtr fsp)467 static void FindReplAuthor (
468   AuthorPtr pAuthor,
469   FindStructPtr fsp
470 )
471 
472 {
473   NameStdPtr   pNameStandard;
474   ValNodePtr   pDbxref;
475   PersonIdPtr  pid;
476 
477   if (pAuthor == NULL) return;
478 
479   FindReplAffil (pAuthor->affil, fsp);
480 
481   pid = pAuthor->name;
482   if (pid == NULL) return;
483 
484   switch (pid->choice) {
485     case PID_NOTSET :
486       break;
487     case PID_DBTAG :
488       pDbxref = pid->data;
489       FindReplDbxrefs (pDbxref, fsp);
490       break;
491     case PID_NAME :
492       pNameStandard = pid->data;
493       if (pNameStandard != NULL) {
494         FindReplString (&(pNameStandard->names [NAMESTD_LAST])    , fsp);
495         FindReplString (&(pNameStandard->names [NAMESTD_FIRST])   , fsp);
496         FindReplString (&(pNameStandard->names [NAMESTD_MIDDLE])  , fsp);
497         FindReplString (&(pNameStandard->names [NAMESTD_FULL])    , fsp);
498         FindReplString (&(pNameStandard->names [NAMESTD_INITIALS]), fsp);
499         FindReplString (&(pNameStandard->names [NAMESTD_SUFFIX])  , fsp);
500         FindReplString (&(pNameStandard->names [NAMESTD_TITLE])   , fsp);
501       }
502       break;
503     case PID_ML :
504     case PID_STR :
505       FindReplString ((CharPtr PNTR) &(pid->data), fsp);
506       break;
507     case PID_CONSRT :
508       FindReplString ((CharPtr PNTR) &(pid->data), fsp);
509       break;
510     default:
511       break;
512     }
513 }
514 
515 /*=======================================================================*/
516 /*                                                                       */
517 /*  FindReplAuthList() -                                                 */
518 /*                                                                       */
519 /*=======================================================================*/
520 
521 #define AUTHLIST_STRUCTURED 1
522 #define AUTHLIST_ML         2
523 #define AUTHLIST_STRING     3
524 
FindReplAuthlist(AuthListPtr alp,FindStructPtr fsp)525 static void FindReplAuthlist (
526   AuthListPtr alp,
527   FindStructPtr fsp
528 )
529 
530 {
531   ValNodePtr vnpNames;
532   CharPtr    szAuthor;
533   AuthorPtr  pAuthor;
534 
535   if (alp == NULL) return;
536 
537   FindReplAffil (alp->affil, fsp);
538   vnpNames = alp->names;
539   while (vnpNames != NULL) {
540     if (alp->choice == AUTHLIST_STRUCTURED) {
541       pAuthor = (AuthorPtr) vnpNames->data.ptrvalue;
542       if (pAuthor != NULL) {
543         FindReplAuthor (pAuthor, fsp);
544       }
545     } else {
546       szAuthor = (CharPtr) vnpNames->data.ptrvalue;
547       if (szAuthor != NULL) {
548         FindReplString (&szAuthor, fsp);
549         vnpNames->data.ptrvalue = szAuthor;
550       }
551     }
552     vnpNames = vnpNames->next;
553   }
554 }
555 
556 /*=======================================================================*/
557 /*                                                                       */
558 /*  FindReplCitRetract() -                                               */
559 /*                                                                       */
560 /*=======================================================================*/
561 
FindReplCitRetract(CitRetractPtr pCitRetract,FindStructPtr fsp)562 static void FindReplCitRetract (
563   CitRetractPtr pCitRetract,
564   FindStructPtr fsp
565 )
566 
567 {
568   if (pCitRetract == NULL) return;
569 
570   FindReplString (&(pCitRetract->exp), fsp);
571 }
572 
573 /*=======================================================================*/
574 /*                                                                       */
575 /*  FindReplImprint() -                                                  */
576 /*                                                                       */
577 /*=======================================================================*/
578 
FindReplImprint(ImprintPtr pImprint,FindStructPtr fsp)579 static void FindReplImprint (
580   ImprintPtr pImprint,
581   FindStructPtr fsp
582 )
583 
584 {
585   if (pImprint == NULL) return;
586 
587   FindReplString (&(pImprint->volume)   , fsp);
588   FindReplString (&(pImprint->issue)    , fsp);
589   FindReplString (&(pImprint->pages)    , fsp);
590   FindReplString (&(pImprint->section)  , fsp);
591   FindReplString (&(pImprint->part_sup) , fsp);
592   FindReplString (&(pImprint->language) , fsp);
593   FindReplString (&(pImprint->part_supi), fsp);
594 
595   FindReplAffil (pImprint->pub, fsp);
596   FindReplCitRetract (pImprint->retract, fsp);
597 }
598 
599 /*=======================================================================*/
600 /*                                                                       */
601 /*  FindReplCitBook() -                                                  */
602 /*                                                                       */
603 /*=======================================================================*/
604 
FindReplCitBook(CitBookPtr pCitBook,FindStructPtr fsp)605 static void FindReplCitBook (
606   CitBookPtr pCitBook,
607   FindStructPtr fsp
608 )
609 
610 {
611   AffilPtr    afp;
612   CharPtr     tmpStr;
613   ValNodePtr  vnp;
614 
615   if (pCitBook == NULL) return;
616 
617   FindReplStringList (pCitBook->title, fsp);
618   FindReplImprint (pCitBook->imp, fsp);
619   FindReplAuthlist (pCitBook->authors, fsp);
620   FindReplStringList (pCitBook->title, fsp);
621   FindReplStringList (pCitBook->coll, fsp);
622 
623   if (pCitBook->othertype == 1) {
624     for (vnp = (ValNodePtr) pCitBook->otherdata; vnp != NULL; vnp = vnp->next) {
625       switch (vnp->choice) {
626         case 1 :
627           FindReplString ((CharPtr PNTR) &(vnp->data.ptrvalue), fsp);
628           break;
629         case 3 :
630           afp = (AffilPtr) vnp->data.ptrvalue;
631           FindReplAffil (afp, fsp);
632           break;
633         default :
634           break;
635       }
636     }
637   } else if (pCitBook->othertype == 2) {
638     tmpStr = (CharPtr) pCitBook->otherdata;
639     FindReplString (&tmpStr, fsp);
640     pCitBook->otherdata = tmpStr;
641   }
642 }
643 
FindReplCitArt(CitArtPtr pCitArt,FindStructPtr fsp)644 static void FindReplCitArt (
645   CitArtPtr pCitArt,
646   FindStructPtr fsp
647 )
648 
649 {
650   CitBookPtr  pCitBook;
651   CitJourPtr  pCitJournal;
652 
653   if (pCitArt == NULL) return;
654 
655   FindReplAuthlist (pCitArt->authors, fsp);
656   if (pCitArt->fromptr != NULL) {
657     switch (pCitArt->from) {
658     case 1 :
659       pCitJournal = (CitJourPtr) pCitArt->fromptr;
660       FindReplStringList (pCitArt->title, fsp);
661       FindReplImprint (pCitJournal->imp, fsp);
662       break;
663     case 2 :
664     case 3 :
665       pCitBook = (CitBookPtr) pCitArt->fromptr;
666       FindReplCitBook (pCitBook, fsp);
667       break;
668     default :
669       break;
670     }
671   }
672 }
673 
674 /*=======================================================================*/
675 /*                                                                       */
676 /*  FindReplMedlineEntry() -                                             */
677 /*                                                                       */
678 /*=======================================================================*/
679 
FindReplMedlineEntry(MedlineEntryPtr pMedlineEntry,FindStructPtr fsp)680 static void FindReplMedlineEntry (
681   MedlineEntryPtr pMedlineEntry,
682   FindStructPtr fsp
683 )
684 
685 {
686   MedlineFieldPtr pField;
687   MedlineMeshPtr  pMesh;
688   MedlineRnPtr    pRn;
689   CharPtr         tmpStr;
690 
691   if (pMedlineEntry == NULL) return;
692 
693   FindReplCitArt(pMedlineEntry->cit, fsp);
694   FindReplString (&(pMedlineEntry->abstract), fsp);
695 
696   pRn = pMedlineEntry->substance;
697   while (pRn != NULL) {
698     FindReplString (&(pRn->cit), fsp);
699     FindReplString (&(pRn->name), fsp);
700     pRn = pRn->next;
701   }
702 
703   pMesh = pMedlineEntry->mesh;
704   while (pMesh != NULL) {
705     FindReplString (&(pMesh->term), fsp);
706     pMesh = pMesh->next;
707   }
708 
709   if (pMedlineEntry->xref != NULL) {
710     tmpStr = (CharPtr) pMedlineEntry->xref->data.ptrvalue;
711     FindReplString (&tmpStr, fsp);
712     pMedlineEntry->xref->data.ptrvalue = tmpStr;
713   }
714 
715   if (pMedlineEntry->idnum != NULL) {
716     tmpStr = (CharPtr) pMedlineEntry->idnum->data.ptrvalue;
717     FindReplString (&tmpStr, fsp);
718     pMedlineEntry->idnum->data.ptrvalue = tmpStr;
719   }
720 
721   if (pMedlineEntry->pub_type != NULL) {
722     tmpStr = (CharPtr) pMedlineEntry->pub_type->data.ptrvalue;
723     FindReplString (&tmpStr, fsp);
724     pMedlineEntry->pub_type->data.ptrvalue = tmpStr;
725   }
726 
727   if (pMedlineEntry->gene != NULL) {
728     tmpStr = (CharPtr) pMedlineEntry->gene->data.ptrvalue;
729     FindReplString (&tmpStr, fsp);
730     pMedlineEntry->gene->data.ptrvalue = tmpStr;
731   }
732 
733   pField = pMedlineEntry->mlfield;
734   while (pField != NULL) {
735     FindReplString (&(pField->str), fsp);
736     pField = pField->next;
737   }
738 }
739 
740 /*=======================================================================*/
741 /*                                                                       */
742 /*  FindReplPub() -                                                      */
743 /*                                                                       */
744 /*=======================================================================*/
745 
FindReplPub(ValNodePtr vnp,FindStructPtr fsp)746 static void FindReplPub (
747   ValNodePtr vnp,
748   FindStructPtr fsp
749 )
750 
751 {
752   CitArtPtr       cap;
753   CitBookPtr      cbp;
754   CitGenPtr       cgp;
755   CitJourPtr      cjp;
756   CitPatPtr       cpp;
757   ValNodePtr      cpvnp;
758   CitSubPtr       csp;
759   IdPatPtr        ipp;
760   MedlineEntryPtr mep;
761   CharPtr         tmpStr;
762   ValNodePtr      pub;
763 
764   if (vnp == NULL) return;
765 
766   /* check for numerical pub types, NULL ptrvalue */
767 
768   switch (vnp->choice) {
769     case PUB_PMid :
770     case PUB_Muid :
771       return;
772     default :
773       break;
774   }
775   if (vnp->data.ptrvalue == NULL) return;
776 
777   switch (vnp->choice) {
778     case PUB_Gen :
779       cgp = (CitGenPtr) vnp->data.ptrvalue;
780       FindReplAuthlist (cgp->authors, fsp);
781       FindReplString (&(cgp->cit), fsp);
782       FindReplString (&(cgp->volume), fsp);
783       FindReplString (&(cgp->issue), fsp);
784       FindReplString (&(cgp->pages), fsp);
785       FindReplString (&(cgp->title), fsp);
786       if (cgp->journal != NULL) {
787         tmpStr = (CharPtr) cgp->journal->data.ptrvalue;
788         FindReplString (&tmpStr, fsp);
789         cgp->journal->data.ptrvalue = tmpStr;
790       }
791       break;
792     case PUB_Sub :
793       csp = (CitSubPtr) vnp->data.ptrvalue;
794       FindReplAuthlist (csp->authors, fsp);
795       FindReplString (&(csp->descr), fsp);
796       break;
797     case PUB_Medline :
798       mep = (MedlineEntryPtr) vnp->data.ptrvalue;
799       FindReplMedlineEntry(mep, fsp);
800       break;
801     case PUB_Article :
802       cap = (CitArtPtr) vnp->data.ptrvalue;
803       FindReplCitArt(cap,fsp);
804       break;
805     case PUB_Journal :
806       cjp = (CitJourPtr) vnp->data.ptrvalue;
807       if (cjp->title != NULL) {
808         tmpStr = (CharPtr) cjp->title->data.ptrvalue;
809         FindReplString (&tmpStr, fsp);
810         cjp->title->data.ptrvalue = tmpStr;
811       }
812       FindReplImprint (cjp->imp, fsp);
813       break;
814     case PUB_Book :
815       cbp = (CitBookPtr) vnp->data.ptrvalue;
816       FindReplCitBook (cbp, fsp);
817       break;
818     case PUB_Proc :
819       cbp = (CitBookPtr) vnp->data.ptrvalue;
820       cpvnp = cbp->otherdata;
821       while (cpvnp != NULL) {
822         if (cpvnp->choice == 1) {
823           tmpStr = (CharPtr) cpvnp->data.ptrvalue;
824           FindReplString (&tmpStr, fsp);
825           cpvnp->data.ptrvalue = tmpStr;
826         } else if (cpvnp->choice == 3) {
827           FindReplAffil((AffilPtr) cpvnp->data.ptrvalue, fsp);
828         }
829         cpvnp = cpvnp->next;
830       }
831       break;
832     case PUB_Patent :
833       cpp = (CitPatPtr) vnp->data.ptrvalue;
834       FindReplAuthlist (cpp->authors, fsp);
835       FindReplAuthlist (cpp->applicants, fsp);
836       FindReplAuthlist (cpp->assignees, fsp);
837       FindReplString (&(cpp->country), fsp);
838       FindReplString (&(cpp->doc_type), fsp);
839       FindReplString (&(cpp->title), fsp);
840       FindReplString (&(cpp->number), fsp);
841       FindReplString (&(cpp->app_number), fsp);
842       FindReplString (&(cpp->abstract), fsp);
843       break;
844     case PUB_Pat_id :
845       ipp = (IdPatPtr) vnp->data.ptrvalue;
846       FindReplString (&(ipp->country), fsp);
847       FindReplString (&(ipp->number), fsp);
848       FindReplString (&(ipp->app_number), fsp);
849       FindReplString (&(ipp->doc_type), fsp);
850       break;
851     case PUB_Man :
852       cbp = (CitBookPtr) vnp->data.ptrvalue;
853       FindReplCitBook (cbp, fsp);
854       break;
855     case PUB_Equiv :
856       /* recursive */
857       for (pub = vnp->data.ptrvalue; pub != NULL; pub = pub->next) {
858         FindReplPub (pub, fsp);
859       }
860     default:
861       break;
862     }
863 }
864 
865 /*=======================================================================*/
866 /*                                                                       */
867 /*  FindReplPubDesc() -                                                  */
868 /*                                                                       */
869 /*=======================================================================*/
870 
FindReplPubdesc(PubdescPtr pdp,FindStructPtr fsp)871 static void FindReplPubdesc (
872   PubdescPtr pdp,
873   FindStructPtr fsp
874 )
875 
876 {
877   ValNodePtr  vnp;
878 
879   if (pdp == NULL) return;
880 
881   FindReplString (&(pdp->comment), fsp);
882 
883   for (vnp = pdp->pub; vnp != NULL; vnp = vnp->next) {
884     FindReplPub (vnp, fsp);
885   }
886 }
887 
RemoveTaxRef(OrgRefPtr orp)888 extern void RemoveTaxRef (OrgRefPtr orp)
889 {
890   ValNodePtr      vnp, next;
891   ValNodePtr PNTR prev;
892   DbtagPtr        dbt;
893 
894   vnp = orp->db;
895   if (vnp == NULL) return;
896   prev = (ValNodePtr PNTR) &(orp->db);
897   while (vnp != NULL) {
898     next = vnp->next;
899     dbt = (DbtagPtr) vnp->data.ptrvalue;
900     if (dbt != NULL && StringICmp ((CharPtr) dbt->db, "taxon") == 0) {
901       *prev = vnp->next;
902       vnp->next = NULL;
903       DbtagFree (dbt);
904       ValNodeFree (vnp);
905     } else {
906       prev = (ValNodePtr PNTR) &(vnp->next);
907     }
908     vnp = next;
909   }
910 }
911 
FindReplBioSource(BioSourcePtr biop,OrgRefPtr orp,FindStructPtr fsp)912 static void FindReplBioSource (
913   BioSourcePtr biop,
914   OrgRefPtr orp,
915   FindStructPtr fsp
916 )
917 
918 {
919   OrgModPtr      omp;
920   OrgNamePtr     onp;
921   SubSourcePtr   ssp;
922   CharPtr        old_taxname;
923 
924   if (biop != NULL) {
925     orp = biop->org;
926     for (ssp = biop->subtype; ssp != NULL; ssp = ssp->next) {
927       if (ssp->subtype != SUBSRC_germline &&
928           ssp->subtype != SUBSRC_rearranged &&
929           ssp->subtype != SUBSRC_transgenic &&
930           ssp->subtype != SUBSRC_environmental_sample &&
931           ssp->subtype != SUBSRC_metagenomic) {
932         FindReplString (&(ssp->name), fsp);
933       }
934       FindReplString (&(ssp->attrib), fsp);
935     }
936   }
937   if (orp != NULL) {
938     old_taxname = StringSave (orp->taxname);
939     FindReplString (&(orp->taxname), fsp);
940     if (StringCmp (old_taxname, orp->taxname) != 0)
941     {
942       RemoveTaxRef (orp);
943       orp->common = MemFree (orp->common);
944     }
945     MemFree (old_taxname);
946     FindReplString (&(orp->common), fsp);
947     FindReplStringList (orp->mod, fsp);
948     FindReplStringList (orp->syn, fsp);
949     FindReplDbxrefs (orp->db, fsp);
950     onp = orp->orgname;
951     while (onp != NULL) {
952       FindReplString (&(onp->attrib), fsp);
953       FindReplString (&(onp->lineage), fsp);
954       FindReplString (&(onp->div), fsp);
955       for (omp = onp->mod; omp != NULL; omp = omp->next) {
956         FindReplString (&(omp->subname), fsp);
957         FindReplString (&(omp->attrib), fsp);
958       }
959       onp = onp->next;
960     }
961   }
962 }
963 
964 /*=======================================================================*/
965 /*                                                                       */
966 /*  FindReplPatentSeqId() -                                              */
967 /*                                                                       */
968 /*=======================================================================*/
969 
FindReplPatentSeqId(PatentSeqIdPtr pPatentSeqId,FindStructPtr fsp)970 static void FindReplPatentSeqId (
971   PatentSeqIdPtr pPatentSeqId,
972   FindStructPtr fsp
973 )
974 
975 {
976   if (pPatentSeqId == NULL) return;
977   if (pPatentSeqId->cit == NULL) return;
978 
979   FindReplString (&(pPatentSeqId->cit->country), fsp);
980   FindReplString (&(pPatentSeqId->cit->number), fsp);
981   FindReplString (&(pPatentSeqId->cit->app_number), fsp);
982   FindReplString (&(pPatentSeqId->cit->doc_type), fsp);
983 }
984 
985 /*=======================================================================*/
986 /*                                                                       */
987 /*  FindReplTextSeqId() -                                                */
988 /*                                                                       */
989 /*=======================================================================*/
990 
FindReplTextSeqId(TextSeqIdPtr pTextSeqId,FindStructPtr fsp)991 static void FindReplTextSeqId (
992   TextSeqIdPtr pTextSeqId,
993   FindStructPtr fsp
994 )
995 
996 {
997   if (pTextSeqId == NULL) return;
998 
999   FindReplString (&(pTextSeqId->name), fsp);
1000   FindReplString (&(pTextSeqId->accession), fsp);
1001   FindReplString (&(pTextSeqId->release), fsp);
1002 }
1003 
1004 /*=======================================================================*/
1005 /*                                                                       */
1006 /*  FindReplGiim() -                                                     */
1007 /*                                                                       */
1008 /*=======================================================================*/
1009 
FindReplGiim(GiimPtr pGiim,FindStructPtr fsp)1010 static void FindReplGiim (
1011   GiimPtr pGiim,
1012   FindStructPtr fsp
1013 )
1014 
1015 {
1016   if (pGiim == NULL) return;
1017 
1018   FindReplString (&(pGiim->db), fsp);
1019   FindReplString (&(pGiim->release), fsp);
1020 }
1021 
1022 /*=======================================================================*/
1023 /*                                                                       */
1024 /*  FindReplPDBSeqId() -                                                 */
1025 /*                                                                       */
1026 /*=======================================================================*/
1027 
FindReplPDBSeqId(PDBSeqIdPtr pPDBSeqId,FindStructPtr fsp)1028 static void FindReplPDBSeqId (
1029   PDBSeqIdPtr pPDBSeqId,
1030   FindStructPtr fsp
1031 )
1032 
1033 {
1034   if (pPDBSeqId == NULL) return;
1035 
1036   FindReplString (&(pPDBSeqId->mol), fsp);
1037 }
1038 
1039 /*=======================================================================*/
1040 /*                                                                       */
1041 /*  FindReplObjectId() -                                                 */
1042 /*                                                                       */
1043 /*=======================================================================*/
1044 
FindReplObjectId(ObjectIdPtr pObjectId,FindStructPtr fsp)1045 static void FindReplObjectId (
1046   ObjectIdPtr pObjectId,
1047   FindStructPtr fsp
1048 )
1049 
1050 {
1051   if (pObjectId == NULL) return;
1052 
1053   FindReplString (&(pObjectId->str), fsp);
1054 }
1055 
1056 /*=======================================================================*/
1057 /*                                                                       */
1058 /*  FindReplSeqId() -                                                    */
1059 /*                                                                       */
1060 /*=======================================================================*/
1061 
FindReplSeqId(SeqIdPtr sip,Pointer userdata)1062 static void FindReplSeqId (
1063   SeqIdPtr sip,
1064   Pointer userdata
1065 )
1066 
1067 {
1068   FindStructPtr  fsp;
1069   Uint1          subtype;
1070 
1071   if (sip == NULL) return;
1072   fsp = (FindStructPtr) userdata;
1073 
1074   /* check subtype against filter */
1075 
1076   subtype = sip->choice;
1077   if (subtype >= NUM_SEQID) return;
1078   if (! fsp->seqidFilter [subtype]) return;
1079 
1080   switch (subtype) {
1081     case SEQID_NOT_SET :
1082       break;
1083     case SEQID_LOCAL :
1084       FindReplObjectId((ObjectIdPtr) sip->data.ptrvalue, fsp);
1085       break;
1086     case SEQID_GIBBSQ :
1087     case SEQID_GIBBMT :
1088       break;
1089     case SEQID_GIIM :
1090       FindReplGiim((GiimPtr) sip->data.ptrvalue, fsp);
1091       break;
1092     case SEQID_GENBANK :
1093     case SEQID_EMBL :
1094     case SEQID_PIR :
1095     case SEQID_SWISSPROT :
1096     case SEQID_OTHER :
1097     case SEQID_DDBJ :
1098     case SEQID_PRF :
1099     case SEQID_TPG :
1100     case SEQID_TPE :
1101     case SEQID_TPD :
1102     case SEQID_GPIPE :
1103     case SEQID_NAMED_ANNOT_TRACK :
1104       FindReplTextSeqId((TextSeqIdPtr) sip->data.ptrvalue, fsp);
1105       break;
1106     case SEQID_PATENT :
1107       FindReplPatentSeqId((PatentSeqIdPtr) sip->data.ptrvalue, fsp);
1108       break;
1109     case SEQID_GENERAL :
1110       FindReplDbxrefs((ValNodePtr) sip->data.ptrvalue, fsp);
1111       break;
1112     case SEQID_GI :
1113       break;
1114     case SEQID_PDB :
1115       FindReplPDBSeqId((PDBSeqIdPtr) sip->data.ptrvalue, fsp);
1116       break;
1117     default:
1118       break;
1119     }
1120 }
1121 
1122 /*=======================================================================*/
1123 /*                                                                       */
1124 /*  FindReplSendMessages() -                                             */
1125 /*                                                                       */
1126 /*=======================================================================*/
1127 
FindReplSendMessages(FindStructPtr fsp,Uint4 itemID,Uint2 itemtype)1128 static void FindReplSendMessages (
1129   FindStructPtr fsp,
1130   Uint4 itemID,
1131   Uint2 itemtype
1132 )
1133 
1134 {
1135   if (fsp->send_update == UPDATE_EACH && fsp->did_replace) {
1136     ObjMgrSetDirtyFlag (fsp->entityID, TRUE);
1137     ObjMgrSendMsg (OM_MSG_UPDATE, fsp->entityID, 0, 0);
1138   }
1139   if (fsp->select_item && (fsp->did_find || fsp->did_replace)) {
1140     ObjMgrAlsoSelect (fsp->entityID, itemID, itemtype, 0, NULL);
1141   }
1142   if (fsp->callback != NULL && (fsp->did_find || fsp->did_replace)) {
1143     fsp->callback (fsp->entityID, itemID, itemtype, fsp->userdata);
1144   }
1145 }
1146 
1147 /*=======================================================================*/
1148 /*                                                                       */
1149 /*  FindReplBioseqs() -                                                  */
1150 /*                                                                       */
1151 /*=======================================================================*/
1152 
FindReplBioseqs(BioseqPtr bsp,Pointer userdata)1153 static void FindReplBioseqs (
1154   BioseqPtr bsp,
1155   Pointer userdata
1156 )
1157 
1158 {
1159   FindStructPtr  fsp;
1160   SeqIdPtr       sip;
1161 
1162   if (bsp == NULL) return;
1163 
1164   fsp = (FindStructPtr) userdata;
1165   fsp->did_find = FALSE;
1166   fsp->did_replace = FALSE;
1167 
1168   for (sip = bsp->id; sip != NULL; sip = sip->next) {
1169     FindReplSeqId (sip, userdata);
1170   }
1171 
1172   if (fsp->did_replace) {
1173     SeqMgrReplaceInBioseqIndex (bsp);
1174   }
1175 
1176   FindReplSendMessages (fsp, bsp->idx.itemID, bsp->idx.itemtype);
1177 }
1178 
1179 /*=======================================================================*/
1180 /*                                                                       */
1181 /*  FindReplAligns() -                                                   */
1182 /*                                                                       */
1183 /*=======================================================================*/
1184 
FindReplAligns(SeqAlignPtr sap,Pointer userdata)1185 static void FindReplAligns (
1186   SeqAlignPtr sap,
1187   Pointer userdata
1188 )
1189 
1190 {
1191   DenseDiagPtr   ddp;
1192   DenseSegPtr    dsp;
1193   FindStructPtr  fsp;
1194   SeqIdPtr       sip;
1195   SeqLocPtr      slp;
1196   StdSegPtr      ssp;
1197 
1198   if (sap == NULL) return;
1199 
1200   fsp = (FindStructPtr) userdata;
1201   fsp->did_find = FALSE;
1202   fsp->did_replace = FALSE;
1203 
1204   VisitSeqIdsInSeqLoc (sap->bounds, userdata, FindReplSeqId);
1205   FindReplSeqId (sap->master, userdata);
1206 
1207   if (sap->segs == NULL) return;
1208 
1209   /* SAS_DISC recursively presented by visit function, so removed here */
1210 
1211   switch (sap->segtype) {
1212     case SAS_DENDIAG :
1213       ddp = (DenseDiagPtr) sap->segs;
1214       for (sip = ddp->id; sip != NULL; sip = sip->next) {
1215         FindReplSeqId (sip, userdata);
1216       }
1217       break;
1218     case SAS_DENSEG :
1219       dsp = (DenseSegPtr) sap->segs;
1220       for (sip = dsp->ids; sip != NULL; sip = sip->next) {
1221         FindReplSeqId (sip, userdata);
1222       }
1223       break;
1224     case SAS_STD :
1225       for (ssp = (StdSegPtr) sap->segs; ssp != NULL; ssp = ssp->next) {
1226         for (sip = ssp->ids; sip != NULL; sip = sip->next) {
1227           FindReplSeqId (sip, userdata);
1228         }
1229         for (slp = ssp->loc; slp != NULL; slp = slp->next) {
1230           VisitSeqIdsInSeqLoc (slp, userdata, FindReplSeqId);
1231         }
1232       }
1233       break;
1234     default :
1235       break;
1236   }
1237 
1238   FindReplSendMessages (fsp, sap->idx.itemID, sap->idx.itemtype);
1239 }
1240 
1241 /*=======================================================================*/
1242 /*                                                                       */
1243 /*  FindReplGraphs() -                                                   */
1244 /*                                                                       */
1245 /*=======================================================================*/
1246 
FindReplGraphs(SeqGraphPtr sgp,Pointer userdata)1247 static void FindReplGraphs (
1248   SeqGraphPtr sgp,
1249   Pointer userdata
1250 )
1251 
1252 {
1253   FindStructPtr  fsp;
1254 
1255   if (sgp == NULL) return;
1256 
1257   fsp = (FindStructPtr) userdata;
1258   fsp->did_find = FALSE;
1259   fsp->did_replace = FALSE;
1260 
1261   VisitSeqIdsInSeqLoc (sgp->loc, userdata, FindReplSeqId);
1262 
1263   FindReplSendMessages (fsp, sgp->idx.itemID, sgp->idx.itemtype);
1264 }
1265 
1266 /*=======================================================================*/
1267 /*                                                                       */
1268 /*  FindReplFeats() -                                                    */
1269 /*                                                                       */
1270 /*=======================================================================*/
1271 
FindReplFeats(SeqFeatPtr sfp,Pointer userdata)1272 static void FindReplFeats (
1273   SeqFeatPtr sfp,
1274   Pointer userdata
1275 )
1276 
1277 {
1278   BioSourcePtr   biop;
1279   CodeBreakPtr   cbp;
1280   CdRegionPtr    crp;
1281   FindStructPtr  fsp;
1282   GBQualPtr      gbq;
1283   GeneRefPtr     grp;
1284   ImpFeatPtr     ifp;
1285   OrgRefPtr      orp = NULL;
1286   PubdescPtr     pdp;
1287   ProtRefPtr     prp;
1288   RnaRefPtr      rrp;
1289   Uint1          subtype;
1290   tRNAPtr        trp;
1291   RNAGenPtr      rgp;
1292   RNAQualPtr     rq;
1293 
1294   if (sfp == NULL) return;
1295 
1296   fsp = (FindStructPtr) userdata;
1297   fsp->did_find = FALSE;
1298   fsp->did_replace = FALSE;
1299 
1300   /* change seqids on location and product */
1301 
1302   VisitSeqIdsInSeqLoc (sfp->location, userdata, FindReplSeqId);
1303   VisitSeqIdsInSeqLoc (sfp->product, userdata, FindReplSeqId);
1304 
1305   /* check subtype against filter */
1306 
1307   subtype = sfp->idx.subtype;
1308   if (subtype >= FEATDEF_MAX) return;
1309   if (! fsp->featFilter [subtype]) return;
1310 
1311   /* common fields */
1312 
1313   FindReplString (&(sfp->comment), fsp);
1314   FindReplString (&(sfp->title), fsp);
1315   FindReplString (&(sfp->except_text), fsp);
1316 
1317   for (gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
1318     FindReplString (&(gbq->qual), fsp);
1319     FindReplString (&(gbq->val), fsp);
1320   }
1321 
1322   FindReplDbxrefs (sfp->dbxref, fsp);
1323 
1324   /* check for numerical features, NULL ptrvalue */
1325 
1326   switch (sfp->data.choice) {
1327     case SEQFEAT_BOND :
1328     case SEQFEAT_SITE :
1329     case SEQFEAT_PSEC_STR :
1330     case SEQFEAT_COMMENT:
1331       return;
1332     default :
1333       break;
1334   }
1335   if (sfp->data.value.ptrvalue == NULL) return;
1336 
1337   /* feature-specific fields */
1338 
1339   switch (sfp->data.choice) {
1340     case SEQFEAT_GENE :
1341       grp = (GeneRefPtr) sfp->data.value.ptrvalue;
1342       FindReplString (&(grp->locus), fsp);
1343       FindReplString (&(grp->allele), fsp);
1344       FindReplString (&(grp->desc), fsp);
1345       FindReplString (&(grp->maploc), fsp);
1346       FindReplString (&(grp->locus_tag), fsp);
1347       FindReplStringList (grp->syn, fsp);
1348       FindReplDbxrefs (grp->db, fsp);
1349       break;
1350     case SEQFEAT_ORG :
1351       orp = (OrgRefPtr) sfp->data.value.ptrvalue;
1352       FindReplBioSource (NULL, orp, fsp);
1353       break;
1354     case SEQFEAT_CDREGION :
1355       crp = (CdRegionPtr) sfp->data.value.ptrvalue;
1356       for (cbp = crp->code_break; cbp != NULL; cbp = cbp->next) {
1357         VisitSeqIdsInSeqLoc (cbp->loc, userdata, FindReplSeqId);
1358       }
1359       break;
1360     case SEQFEAT_PROT :
1361       prp = (ProtRefPtr) sfp->data.value.ptrvalue;
1362       FindReplString (&(prp->desc), fsp);
1363       FindReplStringList (prp->name, fsp);
1364       FindReplStringList (prp->ec, fsp);
1365       FindReplStringList (prp->activity, fsp);
1366       FindReplDbxrefs (prp->db, fsp);
1367       break;
1368     case SEQFEAT_RNA :
1369       rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
1370       if (rrp->ext.choice == 1) {
1371         FindReplString ((CharPtr PNTR) &(rrp->ext.value.ptrvalue), fsp);
1372       } else if (rrp->ext.choice == 2) {
1373         trp = (tRNAPtr) rrp->ext.value.ptrvalue;
1374         VisitSeqIdsInSeqLoc (trp->anticodon, userdata, FindReplSeqId);
1375       } else if (rrp->ext.choice == 3) {
1376         rgp = (RNAGenPtr) rrp->ext.value.ptrvalue;
1377         FindReplString(&(rgp->_class), fsp);
1378         FindReplString(&(rgp->product), fsp);
1379         for (rq = rgp->quals; rq != NULL; rq = rq->next) {
1380           FindReplString(&(rq->val), fsp);
1381         }
1382       }
1383       break;
1384     case SEQFEAT_PUB :
1385       pdp = (PubdescPtr) sfp->data.value.ptrvalue;
1386       FindReplPubdesc (pdp, fsp);
1387       break;
1388     case SEQFEAT_SEQ :
1389       break;
1390     case SEQFEAT_IMP :
1391       ifp = (ImpFeatPtr) sfp->data.value.ptrvalue;
1392       /* FindReplString (&(ifp->key), fsp); */
1393       FindReplString (&(ifp->loc), fsp);
1394       FindReplString (&(ifp->descr), fsp);
1395       break;
1396     case SEQFEAT_REGION :
1397       FindReplString ((CharPtr PNTR) &(sfp->data.value.ptrvalue), fsp);
1398       break;
1399     case SEQFEAT_RSITE :
1400       break;
1401     case SEQFEAT_USER :
1402       break;
1403     case SEQFEAT_TXINIT :
1404       break;
1405     case SEQFEAT_NUM :
1406       break;
1407     case SEQFEAT_NON_STD_RESIDUE :
1408       break;
1409     case SEQFEAT_HET :
1410       break;
1411     case SEQFEAT_BIOSRC :
1412       biop = (BioSourcePtr) sfp->data.value.ptrvalue;
1413       FindReplBioSource (biop, NULL, fsp);
1414       break;
1415     default :
1416       break;
1417   }
1418 
1419   FindReplSendMessages (fsp, sfp->idx.itemID, sfp->idx.itemtype);
1420 }
1421 
1422 /*=======================================================================*/
1423 /*                                                                       */
1424 /*  FindReplDescs() -                                                    */
1425 /*                                                                       */
1426 /*=======================================================================*/
1427 
FindReplDescs(SeqDescrPtr sdp,Pointer userdata)1428 static void FindReplDescs (
1429   SeqDescrPtr sdp,
1430   Pointer userdata
1431 )
1432 
1433 {
1434   BioSourcePtr   biop;
1435   FindStructPtr  fsp;
1436   GBBlockPtr     gbp;
1437   OrgRefPtr      orp = NULL;
1438   ObjValNodePtr  ovp;
1439   PubdescPtr     pdp;
1440   Uint1          subtype;
1441 
1442   if (sdp == NULL) return;
1443 
1444   fsp = (FindStructPtr) userdata;
1445   fsp->did_find = FALSE;
1446   fsp->did_replace = FALSE;
1447 
1448   /* check subtype against filter */
1449 
1450   subtype = sdp->choice;
1451   if (subtype >= SEQDESCR_MAX) return;
1452   if (! fsp->descFilter [subtype]) return;
1453 
1454   /* check for numerical descriptors, NULL ptrvalue */
1455 
1456   switch (sdp->choice) {
1457     case Seq_descr_mol_type :
1458     case Seq_descr_method :
1459       return;
1460     default :
1461       break;
1462   }
1463   if (sdp->data.ptrvalue == NULL) return;
1464 
1465   /* descriptor-specific fields */
1466 
1467   switch (sdp->choice) {
1468     case Seq_descr_modif :
1469       break;
1470     case Seq_descr_name :
1471       FindReplString ((CharPtr PNTR) &(sdp->data.ptrvalue), fsp);
1472       break;
1473     case Seq_descr_title :
1474       FindReplString ((CharPtr PNTR) &(sdp->data.ptrvalue), fsp);
1475       break;
1476     case Seq_descr_org :
1477       orp = (OrgRefPtr) sdp->data.ptrvalue;
1478       FindReplBioSource (NULL, orp, fsp);
1479       break;
1480     case Seq_descr_comment :
1481       FindReplString ((CharPtr PNTR) &(sdp->data.ptrvalue), fsp);
1482       break;
1483     case Seq_descr_num :
1484       break;
1485     case Seq_descr_maploc :
1486       break;
1487     case Seq_descr_pir :
1488       break;
1489     case Seq_descr_genbank :
1490       gbp = (GBBlockPtr) sdp->data.ptrvalue;
1491       FindReplStringList (gbp->extra_accessions, fsp);
1492       FindReplStringList (gbp->keywords, fsp);
1493       FindReplString (&(gbp->source), fsp);
1494       FindReplString (&(gbp->origin), fsp);
1495       FindReplString (&(gbp->date), fsp);
1496       FindReplString (&(gbp->div), fsp);
1497       FindReplString (&(gbp->taxonomy), fsp);
1498       break;
1499     case Seq_descr_pub :
1500       pdp = (PubdescPtr) sdp->data.ptrvalue;
1501       FindReplPubdesc (pdp, fsp);
1502       break;
1503     case Seq_descr_region :
1504       FindReplString ((CharPtr PNTR) &(sdp->data.ptrvalue), fsp);
1505       break;
1506     case Seq_descr_user :
1507       break;
1508     case Seq_descr_sp :
1509       break;
1510     case Seq_descr_dbxref :
1511       break;
1512     case Seq_descr_embl :
1513       break;
1514     case Seq_descr_create_date :
1515       break;
1516     case Seq_descr_update_date :
1517       break;
1518     case Seq_descr_prf :
1519       break;
1520     case Seq_descr_pdb :
1521       break;
1522     case Seq_descr_het :
1523       break;
1524     case Seq_descr_source :
1525       biop = (BioSourcePtr) sdp->data.ptrvalue;
1526       FindReplBioSource (biop, NULL, fsp);
1527       break;
1528     case Seq_descr_molinfo :
1529       break;
1530     default :
1531       break;
1532   }
1533 
1534   if (sdp->extended != 0) {
1535     ovp = (ObjValNodePtr) sdp;
1536     FindReplSendMessages (fsp, ovp->idx.itemID, ovp->idx.itemtype);
1537   }
1538 }
1539 
1540 /*=======================================================================*/
1541 /*                                                                       */
1542 /*  FindReplSubmitBlock() -                                              */
1543 /*                                                                       */
1544 /*=======================================================================*/
1545 
FindReplSubmitBlock(SeqSubmitPtr ssp,FindStructPtr fsp)1546 static void FindReplSubmitBlock (
1547   SeqSubmitPtr ssp,
1548   FindStructPtr fsp
1549 )
1550 
1551 {
1552   ContactInfoPtr  cip;
1553   CitSubPtr       csp;
1554   SubmitBlockPtr  sub;
1555 
1556   if (ssp == NULL) return;
1557   sub = ssp->sub;
1558   if (sub == NULL) return;
1559 
1560   fsp->did_find = FALSE;
1561   fsp->did_replace = FALSE;
1562 
1563   FindReplString (&(sub->tool), fsp);
1564   FindReplString (&(sub->user_tag), fsp);
1565   FindReplString (&(sub->comment), fsp);
1566 
1567   cip = sub->contact;
1568   if (cip != NULL) {
1569     FindReplString (&(cip->name), fsp);
1570     FindReplStringList (cip->address, fsp);
1571     FindReplString (&(cip->phone), fsp);
1572     FindReplString (&(cip->fax), fsp);
1573     FindReplString (&(cip->email), fsp);
1574     FindReplString (&(cip->telex), fsp);
1575     FindReplObjectId (cip->owner_id, fsp);
1576     FindReplString (&(cip->last_name), fsp);
1577     FindReplString (&(cip->first_name), fsp);
1578     FindReplString (&(cip->middle_initial), fsp);
1579     FindReplAuthor (cip->contact, fsp);
1580   }
1581 
1582   csp = sub->cit;
1583   if (csp != NULL) {
1584     FindReplAuthlist (csp->authors, fsp);
1585     FindReplString (&(csp->descr), fsp);
1586   }
1587 
1588   FindReplSendMessages (fsp, ssp->idx.itemID, ssp->idx.itemtype);
1589 }
1590 
1591 
GetSpecialWinCharacterReplacement(unsigned char ch)1592 NLM_EXTERN CharPtr GetSpecialWinCharacterReplacement (unsigned char ch)
1593 {
1594   CharPtr r = "#";
1595 
1596   if (ch == 198 || ch == 196)
1597   {
1598     r = "Ae";
1599   }
1600   else if (ch == 230 || ch == 228)
1601   {
1602     r = "ae";
1603   }
1604   else if (ch == 197)
1605   {
1606     r = "Aa";
1607   }
1608   else if (ch == 229)
1609   {
1610     r = "aa";
1611   }
1612   else if (ch == 220)
1613   {
1614     r = "Ue";
1615   }
1616   else if (ch == 252)
1617   {
1618     r = "ue";
1619   }
1620   else if (ch == 214)
1621   {
1622     r = "Oe";
1623   }
1624   else if (ch == 246)
1625   {
1626     r = "oe";
1627   }
1628   else if (ch == 223)
1629   {
1630     r = "ss";
1631   }
1632   else if (ch == 199)
1633   {
1634     r = "C";
1635   }
1636   else if (ch >= 200 && ch <= 203)
1637   {
1638     r = "E";
1639   }
1640   else if (ch >= 204 && ch <= 207)
1641   {
1642     r = "I";
1643   }
1644   else if (ch == 209)
1645   {
1646     r = "N";
1647   }
1648   else if ((ch >= 210 && ch <= 214) || ch == 216)
1649   {
1650     r = "O";
1651   }
1652   else if (ch >= 217 && ch <= 220)
1653   {
1654     r = "U";
1655   }
1656   else if (ch == 221)
1657   {
1658     r = "Y";
1659   }
1660   else if (ch >= 224 && ch <= 229)
1661   {
1662     r = "a";
1663   }
1664   else if (ch == 231)
1665   {
1666     r = "c";
1667   }
1668   else if (ch >= 232 && ch <= 235)
1669   {
1670     r = "e";
1671   }
1672   else if (ch >= 236 && ch <= 239)
1673   {
1674     r = "i";
1675   }
1676   else if (ch == 241)
1677   {
1678     r = "n";
1679   }
1680   else if ((ch >= 242 && ch <= 246) || ch == 248)
1681   {
1682     r = "o";
1683   }
1684   else if (ch >= 249 && ch <= 252)
1685   {
1686     r = "u";
1687   }
1688   else if (ch == 253 || ch == 255)
1689   {
1690     r = "y";
1691   }
1692   return r;
1693 }
1694 
1695 
GetSpecialMacCharacterReplacement(unsigned char ch)1696 NLM_EXTERN CharPtr GetSpecialMacCharacterReplacement (unsigned char ch)
1697 {
1698   CharPtr r = "#";
1699 
1700   if (ch == 174 || ch == 128)
1701   {
1702     r = "Ae";
1703   }
1704   else if (ch == 190 || ch == 138)
1705   {
1706     r = "ae";
1707   }
1708   else if (ch == 129)
1709   {
1710     r = "Aa";
1711   }
1712   else if (ch == 140)
1713   {
1714     r = "aa";
1715   }
1716   else if (ch == 134)
1717   {
1718     r = "Ue";
1719   }
1720   else if (ch == 159)
1721   {
1722     r = "ue";
1723   }
1724   else if (ch == 133)
1725   {
1726     r = "Oe";
1727   }
1728   else if (ch == 154)
1729   {
1730     r = "oe";
1731   }
1732   else if (ch == 167)
1733   {
1734     r = "ss";
1735   }
1736   else if (ch == 130)
1737   {
1738     r = "C";
1739   }
1740   else if (ch == 233 || ch == 131 || ch == 230 || ch == 232)
1741   {
1742     r = "E";
1743   }
1744   else if (ch == 237 || ch == 234 || ch == 235 || ch == 236)
1745   {
1746     r = "I";
1747   }
1748   else if (ch == 132)
1749   {
1750     r = "N";
1751   }
1752   else if (ch == 241 || ch == 238 || ch == 239 || ch == 205 || ch == 133 || ch == 175)
1753   {
1754     r = "O";
1755   }
1756   else if (ch == 244 || ch == 242 || ch == 243 || ch == 134)
1757   {
1758     r = "U";
1759   }
1760   else if (ch == 136 || ch == 135 || ch == 137 || ch == 139 || ch == 138)
1761   {
1762     r = "a";
1763   }
1764   else if (ch == 141)
1765   {
1766     r = "c";
1767   }
1768   else if (ch == 143 || ch == 142 || ch == 144 || ch == 145)
1769   {
1770     r = "e";
1771   }
1772   else if (ch == 147 || ch == 146 || ch == 148 || ch == 149)
1773   {
1774     r = "i";
1775   }
1776   else if (ch == 150)
1777   {
1778     r = "n";
1779   }
1780   else if (ch == 152 || ch == 151 || ch == 153 || ch == 155 || ch == 154 || ch == 190)
1781   {
1782     r = "o";
1783   }
1784   else if (ch == 157 || ch == 156 || ch == 158 || ch == 159)
1785   {
1786     r = "u";
1787   }
1788   else if (ch == 216)
1789   {
1790     r = "y";
1791   }
1792   return r;
1793 }
1794 
1795 
GetSpecialCharacterReplacement(unsigned char ch)1796 NLM_EXTERN CharPtr GetSpecialCharacterReplacement (unsigned char ch)
1797 
1798 {
1799 #ifdef WIN_MAC
1800   return GetSpecialMacCharacterReplacement (ch);
1801 #endif
1802 #ifdef WIN_MSWIN
1803   return GetSpecialWinCharacterReplacement (ch);
1804 #endif
1805   return NULL;
1806 }
1807 
1808 
SpecialCharFind(CharPtr PNTR strp,Pointer userdata,BoolPtr did_find,BoolPtr did_change)1809 NLM_EXTERN void SpecialCharFind (CharPtr PNTR strp, Pointer userdata, BoolPtr did_find, BoolPtr did_change)
1810 {
1811   CharPtr cp;
1812   Boolean found_any = FALSE;
1813 
1814   if (strp == NULL || *strp == NULL) return;
1815 
1816   cp = *strp;
1817   while (*cp != 0 && !found_any)
1818   {
1819     if (*cp < ' ' || *cp > '~')
1820     {
1821       found_any = TRUE;
1822     }
1823     cp++;
1824   }
1825   if (found_any && did_find != NULL)
1826   {
1827     *did_find = TRUE;
1828   }
1829 }
1830 
1831 
SpecialCharReplace(CharPtr PNTR strp,Pointer userdata,BoolPtr did_find,BoolPtr did_change)1832 NLM_EXTERN void SpecialCharReplace (CharPtr PNTR strp, Pointer userdata, BoolPtr did_find, BoolPtr did_change)
1833 {
1834   Int4 orig_len, new_len, repl_len;
1835   CharPtr cp, cpy, dst, repl;
1836   Boolean found_any = FALSE;
1837 
1838   if (strp == NULL || *strp == NULL) return;
1839 
1840   /* count all characters that need two replacement characters */
1841   cp = *strp;
1842   orig_len = StringLen (cp);
1843   new_len = orig_len;
1844   while (*cp != 0)
1845   {
1846     new_len += abs (StringLen (GetSpecialCharacterReplacement ((unsigned char)*cp)) - 1);
1847     if (*cp < ' ' || *cp > '~')
1848     {
1849       found_any = TRUE;
1850     }
1851     cp++;
1852   }
1853   if (!found_any)
1854   {
1855     return;
1856   }
1857 
1858   /* allocate memory for new string if necessary */
1859   if (new_len > orig_len)
1860   {
1861     cpy = (CharPtr) MemNew (sizeof (Char) * (new_len + 1));
1862   }
1863   else
1864   {
1865     cpy = *strp;
1866   }
1867 
1868   /* copy in with replacements */
1869   cp = *strp;
1870   dst = cpy;
1871   while (*cp != 0)
1872   {
1873     if ((unsigned char)*cp < ' ')
1874     {
1875       /* will replace with pound sign */
1876       *dst = '#';
1877       dst++;
1878     }
1879     else if ((unsigned char)*cp > '~')
1880     {
1881 #if 0
1882       repl = GetSpecialCharacterReplacement ((unsigned char)*cp);
1883 #else
1884       repl = "#";
1885 #endif
1886       repl_len = StringLen (repl);
1887       StringNCpy (dst, repl, repl_len);
1888       dst += repl_len;
1889     }
1890     else
1891     {
1892       *dst = *cp;
1893       dst++;
1894     }
1895     cp++;
1896   }
1897   *dst = 0;
1898 
1899   /* put new string in place of old string */
1900   if (cpy != *strp)
1901   {
1902     *strp = MemFree (*strp);
1903     *strp = cpy;
1904   }
1905   if (did_find != NULL)
1906   {
1907     *did_find = TRUE;
1908   }
1909   if (did_change != NULL)
1910   {
1911     *did_change = TRUE;
1912   }
1913 }
1914 
1915 
StringActionCallback(CharPtr PNTR strp,Pointer fspdata)1916 static void StringActionCallback (CharPtr PNTR strp, Pointer fspdata)
1917 {
1918   FindStructPtr fsp;
1919 
1920   if (strp == NULL || fspdata == NULL) return;
1921 
1922   fsp = (FindStructPtr) fspdata;
1923 
1924   if (fsp->string_action == NULL) return;
1925   (fsp->string_action)(strp, fsp->userdata, &(fsp->did_find), &(fsp->dirty));
1926 }
1927 
1928 
1929 /* EXTERNAL FIND-REPLACE FUNCTIONS */
StringActionInEntity(Uint2 entityID,Boolean select_item,Int2 send_update,BoolPtr descFilter,BoolPtr featFilter,BoolPtr seqidFilter,Boolean do_seqid_local,StringActionFunc action_func,FindReplProc callback,Pointer userdata)1930 NLM_EXTERN void StringActionInEntity (
1931   Uint2 entityID,
1932   Boolean select_item,
1933   Int2 send_update,
1934   BoolPtr descFilter,
1935   BoolPtr featFilter,
1936   BoolPtr seqidFilter,
1937   Boolean do_seqid_local,
1938   StringActionFunc action_func,
1939   FindReplProc callback,
1940   Pointer userdata
1941 )
1942 
1943 {
1944   FindStruct     fs;
1945   ObjMgrDataPtr  omdp;
1946   SeqEntryPtr    sep = NULL;
1947   SeqSubmitPtr   ssp = NULL;
1948 
1949   if (entityID == 0 || action_func == NULL) return;
1950 
1951   omdp = ObjMgrGetData (entityID);
1952   if (omdp != NULL) {
1953     switch (omdp->datatype) {
1954       case OBJ_SEQSUB :
1955         ssp = (SeqSubmitPtr) omdp->dataptr;
1956         if (ssp != NULL && ssp->datatype == 1) {
1957           sep = (SeqEntryPtr) ssp->data;
1958         }
1959         break;
1960       case OBJ_BIOSEQ :
1961         sep = (SeqEntryPtr) omdp->choice;
1962         break;
1963       case OBJ_BIOSEQSET :
1964         sep = (SeqEntryPtr) omdp->choice;
1965         break;
1966       default :
1967         break;
1968     }
1969   }
1970   /* sep = GetTopSeqEntryForEntityID (entityID); */
1971   if (sep == NULL) return;
1972 
1973   MemSet ((Pointer) &fs, 0, sizeof (FindStruct));
1974 
1975   fs.entityID = entityID;
1976   fs.func = StringActionCallback;
1977   fs.callback = callback;
1978   fs.userdata = userdata;
1979   fs.string_action = action_func;
1980 
1981   fs.select_item = select_item;
1982   fs.send_update = send_update;
1983   fs.dirty = FALSE;
1984 
1985   /* if desc or feat filter arrays not supplied, default to all TRUE */
1986 
1987   if (descFilter != NULL) {
1988     MemCopy ((Pointer) &fs.descFilter, (Pointer) descFilter, sizeof (fs.descFilter));
1989   } else {
1990     MemSet ((Pointer) &fs.descFilter, (int) TRUE, sizeof (fs.descFilter));
1991   }
1992 
1993   if (featFilter != NULL) {
1994     MemCopy ((Pointer) &fs.featFilter, (Pointer) featFilter, sizeof (fs.featFilter));
1995   } else {
1996     MemSet ((Pointer) &fs.featFilter, (int) TRUE, sizeof (fs.featFilter));
1997   }
1998 
1999   /* if seqid filter array not supplied, default to all FALSE */
2000 
2001   if (seqidFilter != NULL) {
2002     MemCopy ((Pointer) &fs.seqidFilter, (Pointer) seqidFilter, sizeof (fs.seqidFilter));
2003   } else if (do_seqid_local) {
2004     MemSet ((Pointer) &fs.seqidFilter, (int) FALSE, sizeof (fs.seqidFilter));
2005     fs.seqidFilter [SEQID_LOCAL] = TRUE;
2006   } else {
2007     MemSet ((Pointer) &fs.seqidFilter, (int) FALSE, sizeof (fs.seqidFilter));
2008   }
2009 
2010   /* ensure feature subtype is set in sfp->idx block */
2011 
2012   AssignIDsInEntity (entityID, 0, NULL);
2013 
2014   /* visit callbacks that find/replace specific fields */
2015 
2016   VisitBioseqsInSep (sep, (Pointer) &fs, FindReplBioseqs);
2017 
2018   VisitFeaturesInSep (sep, (Pointer) &fs, FindReplFeats);
2019 
2020   VisitAlignmentsInSep (sep, (Pointer) &fs, FindReplAligns);
2021 
2022   VisitGraphsInSep (sep, (Pointer) &fs, FindReplGraphs);
2023 
2024   VisitDescriptorsInSep (sep, (Pointer) &fs, FindReplDescs);
2025 
2026   if (ssp != NULL) {
2027     FindReplSubmitBlock (ssp, &fs);
2028   }
2029 
2030   /* send select message, if applicable */
2031 
2032   if (fs.send_update == UPDATE_ONCE && fs.dirty) {
2033     ObjMgrSetDirtyFlag (entityID, TRUE);
2034     ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
2035   }
2036 }
2037 
StringActionForObject(Uint2 datatype,Pointer objdata,Uint2 entityID,Boolean select_item,Int2 send_update,StringActionFunc action_func,FindReplProc callback,Pointer userdata)2038 NLM_EXTERN void StringActionForObject (
2039   Uint2   datatype,
2040   Pointer objdata,
2041   Uint2 entityID,
2042   Boolean select_item,
2043   Int2 send_update,
2044   StringActionFunc action_func,
2045   FindReplProc callback,
2046   Pointer userdata
2047 )
2048 
2049 {
2050   FindStruct     fs;
2051 
2052   if (objdata == NULL || action_func == NULL) return;
2053 
2054   MemSet ((Pointer) &fs, 0, sizeof (FindStruct));
2055 
2056   fs.entityID = entityID;
2057   fs.func = StringActionCallback;
2058   fs.callback = callback;
2059   fs.userdata = userdata;
2060   fs.string_action = action_func;
2061 
2062   fs.select_item = select_item;
2063   fs.send_update = send_update;
2064   fs.dirty = FALSE;
2065 
2066   MemSet ((Pointer) &fs.descFilter, (int) TRUE, sizeof (fs.descFilter));
2067 
2068   MemSet ((Pointer) &fs.featFilter, (int) TRUE, sizeof (fs.featFilter));
2069 
2070   MemSet ((Pointer) &fs.seqidFilter, (int) FALSE, sizeof (fs.seqidFilter));
2071 
2072   switch (datatype)
2073   {
2074     case OBJ_BIOSEQ:
2075       FindReplBioseqs ((BioseqPtr) objdata, &fs);
2076       break;
2077     case OBJ_SEQFEAT:
2078       FindReplFeats ((SeqFeatPtr) objdata, &fs);
2079       break;
2080     case OBJ_SEQALIGN:
2081       FindReplAligns ((SeqAlignPtr) objdata, &fs);
2082       break;
2083     case OBJ_SEQGRAPH:
2084       FindReplGraphs ((SeqGraphPtr) objdata, &fs);
2085       break;
2086     case OBJ_SEQDESC:
2087       FindReplDescs ((SeqDescrPtr) objdata, &fs);
2088       break;
2089     case OBJ_SEQSUB:
2090       FindReplSubmitBlock ((SeqSubmitPtr) objdata, &fs);
2091       break;
2092   }
2093 
2094   /* send select message, if applicable */
2095 
2096   if (fs.send_update == UPDATE_ONCE && fs.dirty) {
2097     ObjMgrSetDirtyFlag (entityID, TRUE);
2098     ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
2099   }
2100 }
2101 
2102 /*=======================================================================*/
2103 /*                                                                       */
2104 /*  FindReplaceInEntity() - New find/replace function.                   */
2105 /*                                                                       */
2106 /*=======================================================================*/
2107 
FindReplaceInEntity(Uint2 entityID,CharPtr find_string,CharPtr replace_string,Boolean case_counts,Boolean whole_word,Boolean do_replace,Boolean select_item,Int2 send_update,BoolPtr descFilter,BoolPtr featFilter,BoolPtr seqidFilter,Boolean do_seqid_local,FindReplProc callback,Pointer userdata)2108 NLM_EXTERN void FindReplaceInEntity (
2109   Uint2 entityID,
2110   CharPtr find_string,
2111   CharPtr replace_string,
2112   Boolean case_counts,
2113   Boolean whole_word,
2114   Boolean do_replace,
2115   Boolean select_item,
2116   Int2 send_update,
2117   BoolPtr descFilter,
2118   BoolPtr featFilter,
2119   BoolPtr seqidFilter,
2120   Boolean do_seqid_local,
2121   FindReplProc callback,
2122   Pointer userdata
2123 )
2124 
2125 {
2126   int            ch;
2127   FindStruct     fs;
2128   int            j;
2129   ObjMgrDataPtr  omdp;
2130   SeqEntryPtr    sep = NULL;
2131   SeqSubmitPtr   ssp = NULL;
2132   size_t         subLen;
2133 
2134   if (entityID == 0 || find_string == NULL
2135       || (whole_word && StringHasNoText (find_string))) return;
2136 
2137   omdp = ObjMgrGetData (entityID);
2138   if (omdp != NULL) {
2139     switch (omdp->datatype) {
2140       case OBJ_SEQSUB :
2141         ssp = (SeqSubmitPtr) omdp->dataptr;
2142         if (ssp != NULL && ssp->datatype == 1) {
2143           sep = (SeqEntryPtr) ssp->data;
2144         }
2145         break;
2146       case OBJ_BIOSEQ :
2147         sep = (SeqEntryPtr) omdp->choice;
2148       case OBJ_BIOSEQSET :
2149         sep = (SeqEntryPtr) omdp->choice;
2150       default :
2151         break;
2152     }
2153   }
2154   /* sep = GetTopSeqEntryForEntityID (entityID); */
2155   if (sep == NULL) return;
2156 
2157   MemSet ((Pointer) &fs, 0, sizeof (FindStruct));
2158 
2159   fs.entityID = entityID;
2160   if (do_replace) {
2161     fs.func = BoyerMooreReplaceString;
2162   } else {
2163     fs.func = BoyerMooreFindString;
2164   }
2165   fs.callback = callback;
2166   fs.userdata = userdata;
2167 
2168   fs.find_string = find_string;
2169   fs.replace_string = replace_string;
2170   fs.case_counts = case_counts;
2171   fs.whole_word = whole_word;
2172   fs.findLen = StringLen (find_string);
2173   fs.replaceLen = StringLen (replace_string);
2174 
2175   fs.select_item = select_item;
2176   fs.send_update = send_update;
2177   fs.did_find = FALSE;
2178   fs.did_replace = FALSE;
2179   fs.dirty = FALSE;
2180 
2181   /* build Boyer-Moore displacement array in advance */
2182 
2183   subLen = StringLen (find_string);
2184 
2185   for (ch = 0; ch < 256; ch++) {
2186     fs.d [ch] = subLen;
2187   }
2188   for (j = 0; j < (int) (subLen - 1); j++) {
2189     ch = (int) (case_counts ? find_string [j] : TO_UPPER (find_string [j]));
2190     if (ch >= 0 && ch <= 255) {
2191       fs.d [ch] = subLen - j - 1;
2192     }
2193   }
2194 
2195   /* if desc or feat filter arrays not supplied, default to all TRUE */
2196 
2197   if (descFilter != NULL) {
2198     MemCopy ((Pointer) &fs.descFilter, (Pointer) descFilter, sizeof (fs.descFilter));
2199   } else {
2200     MemSet ((Pointer) &fs.descFilter, (int) TRUE, sizeof (fs.descFilter));
2201   }
2202 
2203   if (featFilter != NULL) {
2204     MemCopy ((Pointer) &fs.featFilter, (Pointer) featFilter, sizeof (fs.featFilter));
2205   } else {
2206     MemSet ((Pointer) &fs.featFilter, (int) TRUE, sizeof (fs.featFilter));
2207   }
2208 
2209   /* if seqid filter array not supplied, default to all FALSE */
2210 
2211   if (seqidFilter != NULL) {
2212     MemCopy ((Pointer) &fs.seqidFilter, (Pointer) seqidFilter, sizeof (fs.seqidFilter));
2213   } else if (do_seqid_local) {
2214     MemSet ((Pointer) &fs.seqidFilter, (int) FALSE, sizeof (fs.seqidFilter));
2215     fs.seqidFilter [SEQID_LOCAL] = TRUE;
2216   } else {
2217     MemSet ((Pointer) &fs.seqidFilter, (int) FALSE, sizeof (fs.seqidFilter));
2218   }
2219 
2220   /* ensure feature subtype is set in sfp->idx block */
2221 
2222   AssignIDsInEntity (entityID, 0, NULL);
2223 
2224   /* visit callbacks that find/replace specific fields */
2225 
2226   VisitBioseqsInSep (sep, (Pointer) &fs, FindReplBioseqs);
2227 
2228   VisitFeaturesInSep (sep, (Pointer) &fs, FindReplFeats);
2229 
2230   VisitAlignmentsInSep (sep, (Pointer) &fs, FindReplAligns);
2231 
2232   VisitGraphsInSep (sep, (Pointer) &fs, FindReplGraphs);
2233 
2234   VisitDescriptorsInSep (sep, (Pointer) &fs, FindReplDescs);
2235 
2236   if (ssp != NULL) {
2237     FindReplSubmitBlock (ssp, &fs);
2238   }
2239 
2240   /* send select message, if applicable */
2241 
2242   if (fs.send_update == UPDATE_ONCE && fs.dirty) {
2243     ObjMgrSetDirtyFlag (entityID, TRUE);
2244     ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
2245   }
2246 }
2247 
2248 /*=======================================================================*/
2249 /*                                                                       */
2250 /*  FindStringsInEntity() - Multi-string find function.                  */
2251 /*                                                                       */
2252 /*=======================================================================*/
2253 
FindStringsInEntity(Uint2 entityID,CharPtr PNTR find_strings,Boolean case_counts,Boolean whole_word,Boolean select_item,Int2 send_update,BoolPtr descFilter,BoolPtr featFilter,BoolPtr seqidFilter,Boolean do_seqid_local,FindReplProc callback,Pointer userdata)2254 NLM_EXTERN void FindStringsInEntity (
2255   Uint2 entityID,
2256   CharPtr PNTR find_strings,
2257   Boolean case_counts,
2258   Boolean whole_word,
2259   Boolean select_item,
2260   Int2 send_update,
2261   BoolPtr descFilter,
2262   BoolPtr featFilter,
2263   BoolPtr seqidFilter,
2264   Boolean do_seqid_local,
2265   FindReplProc callback,
2266   Pointer userdata
2267 )
2268 
2269 {
2270   FindStruct     fs;
2271   int            j;
2272   ObjMgrDataPtr  omdp;
2273   SeqEntryPtr    sep = NULL;
2274   SeqSubmitPtr   ssp = NULL;
2275 
2276   if (entityID == 0 || find_strings == NULL) return;
2277 
2278   omdp = ObjMgrGetData (entityID);
2279   if (omdp != NULL) {
2280     switch (omdp->datatype) {
2281       case OBJ_SEQSUB :
2282         ssp = (SeqSubmitPtr) omdp->dataptr;
2283         if (ssp != NULL && ssp->datatype == 1) {
2284           sep = (SeqEntryPtr) ssp->data;
2285         }
2286         break;
2287       case OBJ_BIOSEQ :
2288         sep = (SeqEntryPtr) omdp->choice;
2289         break;
2290       case OBJ_BIOSEQSET :
2291         sep = (SeqEntryPtr) omdp->choice;
2292         break;
2293       default :
2294         break;
2295     }
2296   }
2297   /* sep = GetTopSeqEntryForEntityID (entityID); */
2298   if (sep == NULL) return;
2299 
2300   MemSet ((Pointer) &fs, 0, sizeof (FindStruct));
2301 
2302   fs.entityID = entityID;
2303   fs.func = FSAFindStrings;
2304   fs.callback = callback;
2305   fs.userdata = userdata;
2306 
2307   fs.find_string = NULL;
2308   fs.replace_string = NULL;
2309   fs.case_counts = case_counts;
2310   fs.whole_word = whole_word;
2311   fs.findLen = 0;
2312   fs.replaceLen = 0;
2313 
2314   fs.select_item = select_item;
2315   fs.send_update = send_update;
2316   fs.did_find = FALSE;
2317   fs.did_replace = FALSE;
2318   fs.dirty = FALSE;
2319 
2320   /* build finite state machine in advance */
2321 
2322   fs.fsa = TextFsaNew ();
2323 
2324   for (j = 0; find_strings [j] != NULL; j++) {
2325     TextFsaAdd (fs.fsa, find_strings [j]);
2326   }
2327 
2328   /* if desc or feat filter arrays not supplied, default to all TRUE */
2329 
2330   if (descFilter != NULL) {
2331     MemCopy ((Pointer) &fs.descFilter, (Pointer) descFilter, sizeof (fs.descFilter));
2332   } else {
2333     MemSet ((Pointer) &fs.descFilter, (int) TRUE, sizeof (fs.descFilter));
2334   }
2335 
2336   if (featFilter != NULL) {
2337     MemCopy ((Pointer) &fs.featFilter, (Pointer) featFilter, sizeof (fs.featFilter));
2338   } else {
2339     MemSet ((Pointer) &fs.featFilter, (int) TRUE, sizeof (fs.featFilter));
2340   }
2341 
2342   /* if seqid filter array not supplied, default to all FALSE */
2343 
2344   if (seqidFilter != NULL) {
2345     MemCopy ((Pointer) &fs.seqidFilter, (Pointer) seqidFilter, sizeof (fs.seqidFilter));
2346   } else if (do_seqid_local) {
2347     MemSet ((Pointer) &fs.seqidFilter, (int) FALSE, sizeof (fs.seqidFilter));
2348     fs.seqidFilter [SEQID_LOCAL] = TRUE;
2349   } else {
2350     MemSet ((Pointer) &fs.seqidFilter, (int) FALSE, sizeof (fs.seqidFilter));
2351   }
2352 
2353   /* ensure feature subtype is set in sfp->idx block */
2354 
2355   AssignIDsInEntity (entityID, 0, NULL);
2356 
2357   /* visit callbacks that find/replace specific fields */
2358 
2359   VisitBioseqsInSep (sep, (Pointer) &fs, FindReplBioseqs);
2360 
2361   VisitFeaturesInSep (sep, (Pointer) &fs, FindReplFeats);
2362 
2363   VisitAlignmentsInSep (sep, (Pointer) &fs, FindReplAligns);
2364 
2365   VisitGraphsInSep (sep, (Pointer) &fs, FindReplGraphs);
2366 
2367   VisitDescriptorsInSep (sep, (Pointer) &fs, FindReplDescs);
2368 
2369   if (ssp != NULL) {
2370     FindReplSubmitBlock (ssp, &fs);
2371   }
2372 
2373   /* clean up finite state machine */
2374 
2375   TextFsaFree (fs.fsa);
2376 
2377   /* send select message, if applicable */
2378 
2379   if (fs.send_update == UPDATE_ONCE && fs.dirty) {
2380     ObjMgrSetDirtyFlag (entityID, TRUE);
2381     ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
2382   }
2383 }
2384 
2385 /*=======================================================================*/
2386 /*                                                                       */
2387 /*  FindReplaceString() - find/replace just one string.                  */
2388 /*                                                                       */
2389 /*=======================================================================*/
2390 
FindReplaceString(CharPtr PNTR strp,CharPtr find_string,CharPtr replace_string,Boolean case_counts,Boolean whole_word)2391 NLM_EXTERN void FindReplaceString (
2392   CharPtr PNTR strp,
2393   CharPtr find_string,
2394   CharPtr replace_string,
2395   Boolean case_counts,
2396   Boolean whole_word
2397 )
2398 
2399 {
2400   int         ch;
2401   FindStruct  fs;
2402   int         j;
2403   size_t      subLen;
2404 
2405   if (strp == NULL || StringHasNoText (find_string)) return;
2406 
2407   MemSet ((Pointer) &fs, 0, sizeof (FindStruct));
2408 
2409   fs.entityID = 0;
2410   fs.func = BoyerMooreReplaceString;
2411   fs.callback = NULL;
2412   fs.userdata = NULL;
2413 
2414   fs.find_string = find_string;
2415   fs.replace_string = replace_string;
2416   fs.case_counts = case_counts;
2417   fs.whole_word = whole_word;
2418   fs.findLen = StringLen (find_string);
2419   fs.replaceLen = StringLen (replace_string);
2420 
2421   fs.select_item = FALSE;
2422   fs.send_update = UPDATE_NEVER;
2423   fs.did_find = FALSE;
2424   fs.did_replace = FALSE;
2425   fs.dirty = FALSE;
2426 
2427   /* build Boyer-Moore displacement array in advance */
2428 
2429   subLen = StringLen (find_string);
2430 
2431   for (ch = 0; ch < 256; ch++) {
2432     fs.d [ch] = subLen;
2433   }
2434   for (j = 0; j < (int) (subLen - 1); j++) {
2435     ch = (int) (case_counts ? find_string [j] : TO_UPPER (find_string [j]));
2436     if (ch >= 0 && ch <= 255) {
2437       fs.d [ch] = subLen - j - 1;
2438     }
2439   }
2440 
2441   FindReplString (strp, &fs);
2442 }
2443 
2444