~ubuntu-branches/ubuntu/maverick/ncbi-tools6/maverick

« back to all changes in this revision

Viewing changes to tools/tfuns.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2002-04-04 22:13:09 UTC
  • Revision ID: james.westby@ubuntu.com-20020404221309-vfze028rfnlrldct
Tags: upstream-6.1.20011220a
ImportĀ upstreamĀ versionĀ 6.1.20011220a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <ncbi.h>
 
3
#include <objpub.h>
 
4
#include <toasn3.h>
 
5
#include <tfuns.h>
 
6
#include <subutil.h>
 
7
#include <utilpub.h>
 
8
#include <gather.h>
 
9
#include <terr.h>
 
10
 
 
11
static char *this_file = "tfuns.c";
 
12
#ifdef THIS_FILE
 
13
#undef THIS_FILE
 
14
#endif
 
15
#define THIS_FILE this_file
 
16
static char *this_module ="toasn3";
 
17
#ifdef THIS_MODULE
 
18
#undef THIS_MODULE
 
19
#endif
 
20
#define THIS_MODULE this_module
 
21
 
 
22
Uint1 AAForCodon (Uint1Ptr codon, CharPtr codes); /* in seqport.c */
 
23
 
 
24
CharPtr type[] = {
 
25
"chromosome", "map", "clone", "sub_clone", "haplotype", "genotype", "sex",
 
26
"cell_line", "cell_type", "tissue_type", "clone_lib", "dev_stage", 
 
27
"frequency", "germline", "rearranged", "lab_host", "pop_variant",
 
28
"tissue_lib", "plasmid", "transposon", "insertion_seq", "plastid"};
 
29
 
 
30
static ORGMOD orgmod_subtype[10] = {
 
31
        { "strain", 2 }, {"sub_strain", 3}, {"variety", 6}, {"serotype",7}, {"cultivar",10}, {"isolate", 17}, {"specific_host", 21}, {"sub_species", 22}, {"note", 255}, { NULL, 0 } 
 
32
};
 
33
 
 
34
CharPtr true_qual[3] = {"insertion_seq", "transposon", "clone"};
 
35
 
 
36
/*****************************************************************************
 
37
*   FlatSafeSize:
 
38
*     -- Set the limit to heap ptr used in Greg's error function
 
39
*     -- return truncated ptr (Greg's limit is 512)
 
40
******************************************************************************/
 
41
CharPtr FlatSafeSize(CharPtr ptr, Int4 limit)
 
42
{
 
43
        Int4 len;
 
44
        CharPtr retval = ptr;
 
45
        
 
46
        if (ptr != NULL) {
 
47
                len = StringLen(ptr);
 
48
                if (len > limit) {
 
49
                        retval = MemNew(limit+1);
 
50
                        StringNCpy(retval, ptr, limit);
 
51
                        MemFree(ptr);
 
52
                }
 
53
        }
 
54
        return retval;
 
55
}
 
56
/*****************************************************************************
 
57
*       Implementation of various string processing functions 
 
58
******************************************************************************/
 
59
/*============================================================================*\
 
60
 *      StrStripSpaces:
 
61
 *      Strips all spaces in string in following manner. If the function
 
62
 *      meet several spaces (spaces and tabs) in succession it replaces them
 
63
 *      with one space.
 
64
 
 
65
\*----------------------------------------------------------------------------*/
 
66
CharPtr StrStripSpaces(CharPtr pchSrc, CharPtr pchDest)
 
67
{
 
68
    CharPtr     pchReturn;
 
69
    Boolean     bSpace = FALSE;
 
70
 
 
71
    if (pchDest == NULL)
 
72
                pchDest = MemNew(StrLen(pchSrc));
 
73
 
 
74
    if (pchDest == NULL)
 
75
                return NULL;
 
76
 
 
77
    pchReturn = pchDest;
 
78
    
 
79
    while (*pchSrc != '\0') {
 
80
                if (*pchSrc == ' ' || *pchSrc == '\t') {
 
81
                if (!bSpace) {
 
82
                                *pchDest++ = ' ';
 
83
                                bSpace = TRUE;
 
84
                }
 
85
                } else {
 
86
                *pchDest++ = *pchSrc;
 
87
                bSpace = FALSE;
 
88
                }
 
89
                pchSrc++;
 
90
    }
 
91
    *pchDest = '\0';
 
92
 
 
93
    return pchReturn;
 
94
}
 
95
 
 
96
/*============================================================================*\
 
97
 *      StringIsEmpty:
 
98
 *      Checks is string empty. Empty means that string has zero length or
 
99
 *      contains white spaces (see isspace()) only.
 
100
 * Return:
 
101
 *      TRUE if string is empty otherwise FALSE.
 
102
 *      If pointer to a string equals NULL the function returns TRUE.
 
103
\*----------------------------------------------------------------------------*/
 
104
Boolean IsStringEmpty(CharPtr str)
 
105
{
 
106
        if (str == NULL)
 
107
                return TRUE;
 
108
        if (*str == '\0')
 
109
                return TRUE;
 
110
    while (*str) {
 
111
                if (!isspace(*str)) {
 
112
                return FALSE;
 
113
                } else {
 
114
                str++;
 
115
            }
 
116
        }
 
117
 
 
118
    return TRUE;
 
119
}
 
120
 
 
121
/*============================================================================*\
 
122
 *      ShortenString:
 
123
 *      Makes new copy of a string with new length <= given.
 
124
 *
 
125
 * Note:
 
126
 *      This function allocate memory for a new string by MemNew, so the caller
 
127
 *      have to call MemFree to free the memory.
 
128
\*----------------------------------------------------------------------------*/
 
129
CharPtr ShortenString(CharPtr str, Int4 iLen)
 
130
{
 
131
    CharPtr     pchNew;
 
132
    Int4        iNewLen;
 
133
 
 
134
    iNewLen = StringLen(str);
 
135
    iNewLen = iNewLen < iLen ? iNewLen + 1 : iLen + 1;
 
136
    pchNew = MemNew(iNewLen);
 
137
    if (pchNew == NULL)
 
138
        return NULL;
 
139
 
 
140
    StringNCpy(pchNew, str, iNewLen - 1);
 
141
 
 
142
    return pchNew;
 
143
}
 
144
 
 
145
/*============================================================================*\
 
146
 *      StringNStr:
 
147
 *      Like StringStr, but search is limited by given length.
 
148
 *
 
149
 * Note:
 
150
 *      If the substring is empty (has zero length) the function returns 
 
151
 *      pchSource. If length of substring is > cMax, the function returns NULL.
 
152
 *
 
153
\*----------------------------------------------------------------------------*/
 
154
CharPtr StringNStr(CharPtr pchSource, CharPtr pchTemplate, size_t cMax)
 
155
{
 
156
    CharPtr pchResult;
 
157
    size_t  cTemplLen;
 
158
 
 
159
    if (pchSource == NULL || pchTemplate == NULL || cMax == 0)
 
160
        return NULL;
 
161
 
 
162
    cTemplLen = StringLen(pchTemplate);
 
163
    if ( cTemplLen == 0)
 
164
                return pchSource;
 
165
 
 
166
    if (cTemplLen > cMax)
 
167
                return NULL;
 
168
 
 
169
    pchResult = StringStr(pchSource, pchTemplate);
 
170
    if (pchResult == NULL)
 
171
                return NULL;
 
172
 
 
173
    if (pchResult + cTemplLen > pchSource + cMax)
 
174
                return NULL;
 
175
 
 
176
    return pchResult;
 
177
}
 
178
 
 
179
Int2 StringExtCmp(CharPtr s1, CharPtr s2)
 
180
{
 
181
        if (s1 == NULL || s2 == NULL)
 
182
                return 1;
 
183
        return StringCmp(s1, s2);
 
184
}
 
185
 
 
186
CharPtr  StripAllSpace(CharPtr str) 
 
187
{
 
188
        CharPtr s, new;
 
189
 
 
190
        if (str == NULL) {
 
191
                return NULL;
 
192
        }
 
193
        new = MemNew(strlen(str) + 1);
 
194
        for (s = new; *str != '\0'; str++) {
 
195
                if (!isspace(*str)) {
 
196
                        *s++ = *str;
 
197
                }
 
198
        }
 
199
        *s = '\0';
 
200
        return new;
 
201
}
 
202
 
 
203
Int2 StringIgnoreSpaceCmp(CharPtr s1, CharPtr s2)
 
204
{
 
205
        Int2 retval = 0;
 
206
        
 
207
        if (s1 == NULL || s2 == NULL) {
 
208
                return retval;
 
209
        }
 
210
        s1 = StripAllSpace(s1);
 
211
        s2 = StripAllSpace(s2);
 
212
        retval = StringICmp(s1, s2);
 
213
        MemFree(s1);
 
214
        MemFree(s2);
 
215
        
 
216
        return retval;
 
217
}
 
218
Int2 AStringIgnoreSpaceCmp(CharPtr s1, CharPtr s2)
 
219
{
 
220
        Int2 retval = 0;
 
221
        Int2 c1, c2;
 
222
        
 
223
        if (s1 == NULL || s2 == NULL) {
 
224
                return retval;
 
225
        }
 
226
        for (; *s1 != '\0' && *s2 != '\0'; s1++, s2++) {
 
227
                for (; isspace(*s1); s1++) ;
 
228
                for (; isspace(*s2); s2++) ;
 
229
                c1 = islower(*s1) ? toupper(*s1) : *s1;
 
230
                c2 = islower(*s2) ? toupper(*s2) : *s2;
 
231
                if ((retval = (c1 - c2)) != 0) {
 
232
                        break;
 
233
                }
 
234
        }
 
235
        return retval;
 
236
}
 
237
 
 
238
/*----------------------------------------------------------------------------*/
 
239
 
 
240
WholeFeatPtr WholeFeatNew(void)
 
241
{
 
242
        WholeFeatPtr wfp;
 
243
        
 
244
        wfp = MemNew(sizeof(WholeFeat));
 
245
        wfp->count = 0;
 
246
        wfp->sfp = NULL;
 
247
        
 
248
        return wfp;
 
249
}
 
250
 
 
251
void WholeFeatFree(WholeFeatPtr wfp)
 
252
{
 
253
        SeqFeatPtr fp, fpnext;
 
254
        
 
255
        for (fp = wfp->sfp; fp; fp = fpnext) {
 
256
                fpnext = fp->next;
 
257
                MemFree(fp);
 
258
        }
 
259
        MemFree(wfp);
 
260
}
 
261
 
 
262
/****************************************************************************
 
263
*  tie_feat:
 
264
*  -- 
 
265
* links input to list specified by head pointer               01-12-94
 
266
****************************************************************************/
 
267
SeqFeatPtr tie_feat(SeqFeatPtr head, SeqFeatPtr next)
 
268
{
 
269
   SeqFeatPtr v;
 
270
 
 
271
   if (head == NULL) {
 
272
      return next;
 
273
   }
 
274
   for (v = head; v->next != NULL; v = v->next)
 
275
                continue;    
 
276
   v->next = next;
 
277
   return head;
 
278
}
 
279
 
 
280
MolFixPtr tie_next_mol(MolFixPtr head, MolFixPtr next)
 
281
{
 
282
        MolFixPtr v;
 
283
 
 
284
        if (head == NULL) {
 
285
                return next;
 
286
        }
 
287
        for (v = head; v->next != NULL; v = v->next) {
 
288
                v = v;
 
289
        }
 
290
        v->next = next;
 
291
        return head;
 
292
}
 
293
 
 
294
CodeBreakPtr tie_next_cbp(CodeBreakPtr head, CodeBreakPtr next)
 
295
{
 
296
   CodeBreakPtr v;
 
297
 
 
298
   if (head == NULL) {
 
299
      return next;
 
300
   }
 
301
   for (v = head; v->next != NULL; v = v->next)
 
302
                continue;    
 
303
   v->next = next;
 
304
   return head;
 
305
}
 
306
/****************************************************************************
 
307
*  tie_next_biosource:
 
308
*  -- ties next BioSource to the end of the chain
 
309
*                                                                    08-4-93
 
310
****************************************************************************/
 
311
OrgFixPtr tie_next_biosource(OrgFixPtr head, OrgFixPtr next)
 
312
{
 
313
        OrgFixPtr v;
 
314
 
 
315
        if (head == NULL) {
 
316
                return next;
 
317
        }
 
318
        for (v = head; v->next != NULL; v = v->next) {
 
319
                v = v;
 
320
        }
 
321
        v->next = next;
 
322
        return head;
 
323
}
 
324
 
 
325
/****************************************************************************
 
326
*  tie_next_subtype:
 
327
*  -- ties next SubSource to the end of the chain
 
328
****************************************************************************/
 
329
SubSourcePtr tie_next_subtype(SubSourcePtr head, SubSourcePtr next)
 
330
{
 
331
        SubSourcePtr v;
 
332
        CharPtr sv, sn;
 
333
        static Char msg1[51], msg2[51];
 
334
        CharPtr p;
 
335
        CharPtr q;
 
336
 
 
337
        if (head == NULL) {
 
338
                return next;
 
339
        }
 
340
        if (next == NULL) {
 
341
                return head;
 
342
        }
 
343
        if ((sn = next->name) == NULL) {
 
344
                sn = "";
 
345
        }
 
346
        for (v = head; v != NULL; v = v->next) {
 
347
                if ((sv = v->name) == NULL) {
 
348
                        sv = "";
 
349
                }
 
350
                if (v->subtype == next->subtype) { 
 
351
                        if (AStringIgnoreSpaceCmp(sv, sn) == 0) {
 
352
                                SubSourceFree(next);
 
353
                                return head;
 
354
                        } else {
 
355
                                p = StringSave(sv);
 
356
                                StringNCpy(msg1, p, 50);
 
357
                                MemFree(p);
 
358
                                q = StringSave(sn);
 
359
                                StringNCpy(msg2, q, 50);
 
360
                                MemFree(q);
 
361
                                if (v->subtype <  23) {
 
362
                                        ErrPostEx(SEV_WARNING, ERR_SOURCE_QualDiffValues,
 
363
                                                "/%s different values: %s|%s", type[v->subtype-1], msg1, msg2);
 
364
                                } else if (v->subtype == 255) {
 
365
                                        ErrPostEx(SEV_WARNING, ERR_SOURCE_QualDiffValues,
 
366
                                                "/note different values: %s|%s", msg1, msg2);
 
367
                                } else {
 
368
                                        ErrPostEx(SEV_WARNING, ERR_SOURCE_IllegalQual,
 
369
                                                "%d", v->subtype);
 
370
                                }
 
371
                        }
 
372
                }
 
373
                if (v->next == NULL) {
 
374
                        break;
 
375
                }
 
376
        }
 
377
        v->next = next;
 
378
        return head;
 
379
}
 
380
 
 
381
/****************************************************************************
 
382
*  tie_next_OrgMod:
 
383
*  -- ties next OrgMod to the end of the chain
 
384
*                                                                    08-4-93
 
385
****************************************************************************/
 
386
OrgModPtr tie_next_OrgMod(OrgModPtr head, OrgModPtr next)
 
387
{
 
388
        OrgModPtr v;
 
389
        CharPtr sv, sn;
 
390
        Int2 i;
 
391
        static Char msg1[51], msg2[51];
 
392
        CharPtr p;
 
393
        CharPtr q;
 
394
 
 
395
        if (head == NULL) {
 
396
                return next;
 
397
        }
 
398
        if ((sn = next->subname) == NULL) {
 
399
                sn = "";
 
400
        }
 
401
        for (v = head; v != NULL; v = v->next) {
 
402
                if ((sv = v->subname) == NULL) {
 
403
                        sv = "";
 
404
                }
 
405
                if (v->subtype == next->subtype) {
 
406
                        if (AStringIgnoreSpaceCmp(v->subname, next->subname) == 0) {
 
407
                                OrgModFree(next);
 
408
                                return head;
 
409
                        } else {
 
410
                                for (i=0; i < 10; i++) {
 
411
                                        if (v->subtype == orgmod_subtype[i].num)
 
412
                                                break;
 
413
                                }
 
414
                                if (i == 10) {
 
415
                                        ErrPostEx(SEV_INFO, ERR_SOURCE_QualUnknown,
 
416
                "OrgMod.subtype [%d] can't be mapped to GenBank qualifier", v->subtype);
 
417
                                } else {
 
418
                                        p = StringSave(sv);
 
419
                                        StringNCpy(msg1, p, 50);
 
420
                                        MemFree(p);
 
421
                                        q = StringSave(sn);
 
422
                                        StringNCpy(msg2, q, 50);
 
423
                                        MemFree(q);
 
424
                                        ErrPostEx(SEV_WARNING, ERR_SOURCE_QualDiffValues,
 
425
                                "/%s different values: %s|%s", 
 
426
                                                                orgmod_subtype[i].name, msg1, msg2);
 
427
                                }
 
428
                        }
 
429
                }
 
430
                if (v->next == NULL) {
 
431
                        break;
 
432
                }
 
433
        }
 
434
        v->next = next;
 
435
        return head;
 
436
}
 
437
 
 
438
/*****************************************************************************
 
439
*
 
440
*   SeqFeatPtr SeqFeatExtract(headptr, choice)
 
441
*       removes first feature in chain where ->choice == choice
 
442
*       rejoins chain after removing the node
 
443
*       sets node->next to NULL
 
444
*
 
445
*****************************************************************************/
 
446
SeqFeatPtr SeqFeatExtract (SeqFeatPtr PNTR headptr, Nlm_Int2 choice)
 
447
{
 
448
    SeqFeatPtr last = NULL,
 
449
        vnp = * headptr;
 
450
 
 
451
    while (vnp != NULL)
 
452
    {
 
453
        if (vnp->data.choice == (Nlm_Uint1)choice)
 
454
        {
 
455
            if (last == NULL)    /* first one */
 
456
                * headptr = vnp->next;
 
457
            else
 
458
                last->next = vnp->next;
 
459
 
 
460
            vnp->next = NULL;
 
461
            return vnp;
 
462
        }
 
463
        else
 
464
        {
 
465
            last = vnp;
 
466
            vnp = vnp->next;
 
467
        }
 
468
    }
 
469
 
 
470
    return NULL;    /* not found */
 
471
}
 
472
 
 
473
/*****************************************************************************
 
474
*
 
475
*   SeqFeatPtr SeqFeatExtractList(headptr, choice)
 
476
*       removes ALL features in chain where ->choice == choice
 
477
*       rejoins chain after removing the nodes
 
478
*       returns independent chain of extracted nodes
 
479
*
 
480
*****************************************************************************/
 
481
SeqFeatPtr SeqFeatExtractList (SeqFeatPtr PNTR headptr, Nlm_Int2 choice)
 
482
{
 
483
    SeqFeatPtr last = NULL, first = NULL, vnp;
 
484
 
 
485
    while ((vnp = SeqFeatExtract(headptr, choice)) != NULL)
 
486
    {
 
487
                if (last == NULL)
 
488
                {
 
489
                        last = vnp;
 
490
                        first = vnp;
 
491
                }
 
492
                else
 
493
                        last->next = vnp;
 
494
                last = vnp;
 
495
        }
 
496
 
 
497
    return first;
 
498
}
 
499
/*****************************************************************************
 
500
*
 
501
*   SeqFeatPtr SourceFeatExtract(headptr)
 
502
*       removes first feature in chain where ->choice == SEQFEAT_IMP
 
503
*       and qual "source"
 
504
*       rejoins chain after removing the node
 
505
*       sets node->next to NULL
 
506
*
 
507
*****************************************************************************/
 
508
SeqFeatPtr SourceFeatExtract (SeqFeatPtr PNTR headptr)
 
509
{
 
510
    SeqFeatPtr last = NULL,
 
511
        vnp = * headptr;
 
512
    ImpFeatPtr  ifp;
 
513
 
 
514
    while (vnp != NULL)
 
515
    {
 
516
        if (vnp->data.choice == SEQFEAT_IMP) {
 
517
                ifp = (ImpFeatPtr) vnp->data.value.ptrvalue;
 
518
                if (StringCmp(ifp->key, "source") == 0) {
 
519
                if (last == NULL)    /* first one */
 
520
                        * headptr = vnp->next;
 
521
                else
 
522
                        last->next = vnp->next;
 
523
 
 
524
                vnp->next = NULL;
 
525
                return vnp;
 
526
            } else {
 
527
                last = vnp;
 
528
                vnp = vnp->next;
 
529
            }
 
530
        } else {
 
531
            last = vnp;
 
532
            vnp = vnp->next;
 
533
        }
 
534
    }
 
535
 
 
536
    return NULL;    /* not found */
 
537
}
 
538
/*****************************************************************************
 
539
*
 
540
*   SeqFeatPtr ExtractSourceFeatList(headptr, choice)
 
541
*       removes ALL features in chain where ->choice == choice
 
542
*       and qual "source"
 
543
*       rejoins chain after removing the nodes
 
544
*       returns independent chain of extracted nodes
 
545
*
 
546
*****************************************************************************/
 
547
SeqFeatPtr ExtractSourceFeatList (SeqFeatPtr PNTR headptr)
 
548
{
 
549
    SeqFeatPtr last = NULL, first = NULL, vnp;
 
550
 
 
551
    while ((vnp = SourceFeatExtract(headptr)) != NULL)
 
552
    {
 
553
                if (last == NULL)
 
554
                {
 
555
                        last = vnp;
 
556
                        first = vnp;
 
557
                }
 
558
                else
 
559
                        last->next = vnp;
 
560
                last = vnp;
 
561
        }
 
562
 
 
563
    return first;
 
564
}
 
565
 
 
566
SeqIdPtr find_id(SeqEntryPtr sep)
 
567
{
 
568
        SeqIdPtr sip;
 
569
        BioseqPtr       bsp;
 
570
        
 
571
                if (IS_Bioseq(sep))
 
572
        {
 
573
                bsp = (BioseqPtr)(sep->data.ptrvalue);
 
574
                sip = (SeqIdPtr) SeqIdDup(bsp->id);
 
575
                return sip;
 
576
        }
 
577
        else {
 
578
                return NULL;
 
579
        }
 
580
 
 
581
}
 
582
 
 
583
SubSourcePtr remove_subtype(SubSourcePtr head, SubSourcePtr x)
 
584
{
 
585
        SubSourcePtr    v, p;
 
586
        
 
587
        if (head == NULL) {
 
588
                return NULL;
 
589
        }
 
590
        if (x == NULL) {
 
591
                return SubSourceSetFree (head);
 
592
        }
 
593
        if (x == head) {
 
594
                head = x->next;
 
595
                x->next = NULL;
 
596
                SubSourceFree(x);
 
597
                return head;
 
598
        }
 
599
        for (v = head; v != NULL && v != x; v = v->next) {
 
600
                p = v;
 
601
        }
 
602
        if (v != NULL) {
 
603
                p->next = x->next;
 
604
                x->next = NULL;
 
605
                SubSourceFree(x);
 
606
        }
 
607
        return head;
 
608
}
 
609
 
 
610
OrgModPtr remove_OrgMod(OrgModPtr head, OrgModPtr x)
 
611
{
 
612
        OrgModPtr       v, p;
 
613
        
 
614
        if (head == NULL) {
 
615
                return NULL;
 
616
        }
 
617
        if (x == NULL) {
 
618
                return OrgModSetFree (head);
 
619
        }
 
620
        if (x == head) {
 
621
                head = x->next;
 
622
                x->next = NULL;
 
623
                OrgModFree(x);
 
624
                return head;
 
625
        }
 
626
        for (v = head; v != NULL && v != x; v = v->next) {
 
627
                p = v;
 
628
        }
 
629
        if (v != NULL) {
 
630
                p->next = x->next;
 
631
                x->next = NULL;
 
632
                OrgModFree(x);
 
633
        }
 
634
        return head;
 
635
}
 
636
 
 
637
SeqFeatXrefPtr remove_xref(SeqFeatXrefPtr head, SeqFeatXrefPtr x)
 
638
{
 
639
        SeqFeatXrefPtr  v, p;
 
640
        
 
641
        if (head == NULL) {
 
642
                return NULL;
 
643
        }
 
644
        if (x == head) {
 
645
                head = x->next;
 
646
                x->next = NULL;
 
647
                SeqFeatXrefFree(x);
 
648
                return head;
 
649
        }
 
650
        for (v = head; v != NULL && v != x; v = v->next) {
 
651
                p = v;
 
652
        }
 
653
        if (v != NULL) {
 
654
                p->next = x->next;
 
655
                x->next = NULL;
 
656
                SeqFeatXrefFree(x);
 
657
        }
 
658
        return head;
 
659
}
 
660
 
 
661
GBQualPtr remove_qual(GBQualPtr head, GBQualPtr x)
 
662
{
 
663
        GBQualPtr       v, p;
 
664
        
 
665
        if (head == NULL) {
 
666
                return NULL;
 
667
        }
 
668
        if (x == head) {
 
669
                head = x->next;
 
670
                x->next = NULL;
 
671
                GBQualFree(x);
 
672
                return head;
 
673
        }
 
674
        for (v = head; v != NULL && v != x; v = v->next) {
 
675
                p = v;
 
676
        }
 
677
        if (v != NULL) {
 
678
                p->next = x->next;
 
679
                x->next = NULL;
 
680
                GBQualFree(x);
 
681
        }
 
682
        return head;
 
683
}
 
684
 
 
685
Boolean check_whole(SeqFeatPtr f, Int4 len)
 
686
{
 
687
        Boolean whole = FALSE;
 
688
        SeqLocPtr               slp;
 
689
        SeqIntPtr               sip;
 
690
        
 
691
                slp = f->location;
 
692
                if (slp->choice == SEQLOC_WHOLE) {
 
693
                        whole = TRUE;
 
694
                } else if (slp->choice == SEQLOC_INT) {
 
695
                        sip = slp->data.ptrvalue;
 
696
                        if (sip->from == 0 && sip->to == len-1) {
 
697
                                whole = TRUE;
 
698
                        }
 
699
                }
 
700
        return whole;
 
701
}
 
702
 
 
703
/* check for /transposon and /insertion_seq and /clone*/
 
704
 
 
705
Boolean true_multiple(SeqAnnotPtr sap, Int4 len)
 
706
{
 
707
        SeqFeatPtr      tmp_sfp, sfp, f;
 
708
        Boolean first = TRUE;
 
709
        CharPtr word = NULL;
 
710
        GBQualPtr               q;
 
711
        Int2    i;
 
712
 
 
713
                tmp_sfp = (SeqFeatPtr) (sap->data);
 
714
                sfp = ExtractSourceFeatList(&(tmp_sfp)); 
 
715
                for (f = sfp; f != NULL; f = f->next) {
 
716
                        if (check_whole(f, len)) {
 
717
                                continue;
 
718
                        }
 
719
                        for(q = f->qual; q != NULL; q = q->next) {
 
720
                                if (first) {
 
721
                                        for (i=0; i<3; i++) {
 
722
                                                if (StringCmp(q->qual, true_qual[i]) == 0) {
 
723
                                                        first = FALSE;
 
724
                                                        word = true_qual[i];
 
725
                                                        break;
 
726
                                                }
 
727
                                        }
 
728
                                if (word != NULL)
 
729
                                        break;
 
730
                                } else {
 
731
                                        if (StringCmp(q->qual, word) == 0) {
 
732
                                                break;
 
733
                                        }
 
734
                                }
 
735
                        }
 
736
                        if (word == NULL) {
 
737
                                sfp = tie_feat(sfp, tmp_sfp);
 
738
                                if (sap != NULL && sap->type == 1) {
 
739
                                        if (sfp)
 
740
                                                sap->data = sfp;
 
741
                                } 
 
742
                                return TRUE;
 
743
                        }
 
744
                        if (q == NULL) {
 
745
                                sfp = tie_feat(sfp, tmp_sfp);
 
746
                                if (sap != NULL && sap->type == 1) {
 
747
                                        if (sfp)
 
748
                                                sap->data = sfp;
 
749
                                } 
 
750
                                return TRUE;
 
751
                        }
 
752
                }
 
753
                sfp = tie_feat(sfp, tmp_sfp);
 
754
                if (sap != NULL && sap->type == 1) {
 
755
                        if (sfp)
 
756
                                sap->data = sfp;
 
757
                } 
 
758
                return FALSE;
 
759
}
 
760
 
 
761
/***************************************************************************
 
762
*  copy_qvalue:
 
763
*  -- return qual's value if found the "qual" in the "qlist",
 
764
***************************************************************************/
 
765
CharPtr copy_qvalue(GBQualPtr qlist, CharPtr qual)
 
766
{
 
767
   GBQualPtr curq;
 
768
   CharPtr   qvalue = NULL;
 
769
 
 
770
   for (curq = qlist; curq != NULL; curq = curq->next) {
 
771
       if (StringCmp(curq->qual, qual) == 0) {
 
772
          if (curq->val != NULL) { 
 
773
                if (StringCmp(curq->val, "\"\"") == 0) {
 
774
                          return (NULL);
 
775
                } else {
 
776
              qvalue = StringSave(curq->val);
 
777
                          return (qvalue);
 
778
                        }
 
779
                  }
 
780
       }
 
781
   }
 
782
 
 
783
   return (qvalue);
 
784
 
 
785
}
 
786
 
 
787
/**********************************************************/
 
788
CharPtr get_qvalue(GBQualPtr curq, CharPtr qual)
 
789
{
 
790
    for(; curq != NULL; curq = curq->next)
 
791
        if(StringCmp(curq->qual, qual) == 0 && curq->val != NULL)
 
792
            break;
 
793
 
 
794
    if(curq == NULL || StringCmp(curq->val, "\"\"") == 0)
 
795
        return(NULL);
 
796
 
 
797
    return(curq->val);
 
798
}
 
799
 
 
800
/*****************************************************************************
 
801
*   laststr:
 
802
*     -- strstr, last occurance
 
803
******************************************************************************/
 
804
CharPtr laststr(CharPtr str, CharPtr word)
 
805
{
 
806
        CharPtr s, s1;
 
807
        
 
808
        s1 = str-1;
 
809
        while(( s = StringStr(s1+1, word)) !=NULL) {
 
810
                s1 = s;
 
811
        }
 
812
        if (s1 == str-1) {
 
813
                return NULL;
 
814
        }
 
815
        return s1;
 
816
}
 
817
 
 
818
void DelFeatFromList (SeqFeatPtr PNTR gbqp, SeqFeatPtr curq, SeqFeatPtr preq)
 
819
{
 
820
    SeqFeatPtr   temp;
 
821
     
 
822
          if (preq == NULL)
 
823
             *gbqp = curq->next;  /* will change first_q in calling function */
 
824
          else
 
825
             preq->next = curq->next;  /* will cause next_q == preq -> next */
 
826
 
 
827
          temp = curq;
 
828
          temp->next = NULL;
 
829
          SeqFeatFree(temp);
 
830
}
 
831
 
 
832
void DelNodeFromList (ValNodePtr PNTR gbqp, ValNodePtr curq, ValNodePtr preq)
 
833
{
 
834
    ValNodePtr   temp;
 
835
     
 
836
          if (preq == NULL)
 
837
             *gbqp = curq->next;  /* will change first_q in calling function */
 
838
          else
 
839
             preq->next = curq->next;  /* will cause next_q == preq -> next */
 
840
 
 
841
          temp = curq;
 
842
          temp->next = NULL;
 
843
          ValNodeFree(temp);
 
844
}
 
845
 
 
846
/*****************************************************************************
 
847
*  orf
 
848
******************************************************************************/
 
849
 
 
850
static void find_orf(SeqPortPtr spp, Int2 ir, CharPtr vals, CharPtr codes, ValNodePtr PNTR list, Uint1 strand, SeqIdPtr id, Int2 limit)
 
851
{
 
852
        Int4 pos;
 
853
        Uint1 codon[3], aa;
 
854
        Int4 len;
 
855
        Int4 start = -1, stop = -1, met_start = -1;
 
856
        SeqLocPtr slp = NULL, m_slp = NULL;
 
857
        ValNodePtr prev = NULL;
 
858
        IntFuzzPtr infrom=NULL, into=NULL;
 
859
 
 
860
        SeqPortSeek(spp, ir, SEEK_SET);
 
861
        len = spp->totlen;
 
862
        for (pos=0; pos < len-2; pos += 3) {
 
863
                codon[0] = SeqPortGetResidue(spp);
 
864
                codon[1] = SeqPortGetResidue(spp);
 
865
                codon[2] = SeqPortGetResidue(spp);
 
866
                aa = AAForCodon(codon, codes);
 
867
                if (aa == '*') {
 
868
                        stop = pos+2;
 
869
                        if (met_start != -2) {
 
870
                                if (met_start == -1) {
 
871
                                        met_start = 0;
 
872
                                }       
 
873
                                if (stop - met_start > limit) {
 
874
                                        if (strand == Seq_strand_plus) {
 
875
                                                m_slp = SeqLocIntNew(met_start+ir, stop+ir, strand, id);
 
876
                                        } else {
 
877
                                                m_slp = SeqLocIntNew(len-1-(stop+ir), 
 
878
                                                                len-1-(met_start+ir),strand, id);
 
879
                                        }
 
880
                                }
 
881
                                met_start = -2;
 
882
                        }
 
883
                        if (start != -2) {
 
884
                                if (start == -1) {
 
885
                                        start = 0;
 
886
                                }       
 
887
                                if (stop - start > limit) {
 
888
                                        if (strand == Seq_strand_plus) {
 
889
                                                slp = SeqLocIntNew(start+ir, stop+ir, strand, id);
 
890
                                        } else {
 
891
                                                slp = SeqLocIntNew(len-1-(stop+ir), len-1-(start+ir),
 
892
                                                                                                                 strand, id);
 
893
                                        }
 
894
                                }
 
895
                                start = -2;
 
896
                        }
 
897
                }
 
898
                if (m_slp && slp) {
 
899
                        m_slp->next = slp;
 
900
                        if (prev == NULL) {
 
901
                                prev = ValNodeAddPointer(list, ir, m_slp);
 
902
                        } else {
 
903
                                prev = ValNodeAddPointer(&prev, ir, m_slp);
 
904
                        }
 
905
                        m_slp = slp = NULL;
 
906
                }
 
907
                if (aa == 'M') {
 
908
                        if (met_start < 0) {
 
909
                                met_start = pos;
 
910
                        }
 
911
                }
 
912
                aa = AAForCodon(codon, vals);
 
913
                if (aa == 'M') {
 
914
                        if (start < 0) {
 
915
                                start = pos;
 
916
                        }
 
917
                }
 
918
        }
 
919
/*  treat end of sequence as a stop */
 
920
        if (met_start != -2) {
 
921
                stop = pos-1;   
 
922
                if (met_start == -1) {
 
923
                        met_start = 0;
 
924
                }
 
925
                if (stop-met_start > limit) {
 
926
                        if (strand == Seq_strand_plus) {
 
927
                                stop = stop+ir;
 
928
                                if (stop > len-1) {
 
929
                                        stop = len-1;
 
930
                                }
 
931
                                m_slp = SeqLocIntNew(met_start+ir, stop, strand, id);
 
932
                        } else {
 
933
                                m_slp = SeqLocIntNew(len-1-(stop+ir), len-1-(met_start+ir), strand, id);
 
934
                        }
 
935
                }
 
936
        }
 
937
        if (start != -2) {
 
938
                stop = pos-1;   
 
939
                if (start == -1) {
 
940
                        start = 0;
 
941
                }
 
942
                if (stop-start > limit) {
 
943
                        if (strand == Seq_strand_plus) {
 
944
                                stop = stop+ir;
 
945
                                if (stop > len-1) {
 
946
                                        stop = len-1;
 
947
                                }
 
948
                                slp = SeqLocIntNew(start+ir, stop, strand, id);
 
949
                        } else {
 
950
                                slp = SeqLocIntNew(len-1-(stop+ir), len-1-(start+ir), strand, id);
 
951
                        }
 
952
                }
 
953
        }
 
954
        if (m_slp) {
 
955
                m_slp->next = slp;
 
956
                ValNodeAddPointer(list, ir, m_slp);
 
957
                m_slp = slp = NULL;
 
958
        } else if (slp) {
 
959
                m_slp = ValNodeNew(NULL);
 
960
                m_slp->next = slp;
 
961
                ValNodeAddPointer(list, ir, m_slp);
 
962
                m_slp = slp = NULL;
 
963
        }
 
964
        return;
 
965
}
 
966
 
 
967
 
 
968
static void find_orf_from_circle (SeqPortPtr spp, Boolean flagIsCircle,
 
969
                                  CharPtr icodes, CharPtr codes,
 
970
                                  ValNodePtr PNTR list, Uint1 strand,
 
971
                                  SeqIdPtr id, Int2 limit)
 
972
{
 
973
  Int4 pos;
 
974
  Int2 loop, spec3;
 
975
  Uint1 codon[3], aa;
 
976
  Int4 len, checklen;
 
977
  Int4 start, stop, spec1, spec2;
 
978
  SeqLocPtr slp, slpwrap = NULL;
 
979
  ValNodePtr smp;
 
980
  ValNodePtr prev = NULL;
 
981
  Char charcheck;
 
982
  CharPtr this_code;
 
983
 
 
984
  loop = 0;
 
985
  SeqPortSeek (spp, loop, SEEK_SET);
 
986
  if (flagIsCircle)
 
987
    SeqPortSet_is_circle (spp, TRUE);
 
988
 
 
989
  checklen = 0;
 
990
  charcheck = 'M';
 
991
  this_code = icodes;
 
992
 
 
993
  len = spp->totlen;
 
994
  start = 0;
 
995
  for (pos = 0; pos < len && loop < 3; pos += 3)
 
996
  {
 
997
    codon[0] = SeqPortGetResidue (spp);
 
998
    codon[1] = SeqPortGetResidue (spp);
 
999
    codon[2] = SeqPortGetResidue (spp);
 
1000
    aa = AAForCodon (codon, this_code);
 
1001
    if (aa == charcheck || slpwrap != NULL)
 
1002
    {
 
1003
      if (aa == '*' && charcheck == '*')
 
1004
      {
 
1005
        checklen += pos+2-start+1;
 
1006
        if (checklen > limit)
 
1007
        {
 
1008
/* check for stop codon on junction */
 
1009
          if (pos+2 < len)
 
1010
          {
 
1011
            if (strand == Seq_strand_plus)
 
1012
            {
 
1013
              stop = pos+2;
 
1014
              slp = SeqLocIntNew (start, stop, strand, id);
 
1015
            }
 
1016
            else
 
1017
            {
 
1018
              stop = len-pos-3;
 
1019
              slp = SeqLocIntNew (len-start-1, stop, strand, id);
 
1020
            }
 
1021
          }
 
1022
          else
 
1023
          {
 
1024
            if (strand == Seq_strand_plus)
 
1025
            {
 
1026
              stop = pos+2-len;
 
1027
              slp = SeqLocIntNew (start, len-1, strand, id);
 
1028
              slp->next = SeqLocIntNew (0, stop, strand, id);
 
1029
            }
 
1030
            else
 
1031
            {
 
1032
              stop = len+len-pos-3;
 
1033
              slp = SeqLocIntNew (stop, len-1, strand, id);
 
1034
              slp->next = SeqLocIntNew (0, len-start-1, strand, id);
 
1035
            }
 
1036
          }
 
1037
          if (slpwrap != NULL)
 
1038
          {
 
1039
            ValNodeLink (&slpwrap, slp);
 
1040
            smp = ValNodeNew (NULL);
 
1041
            smp->choice = 8;               /* SeqLocMix */
 
1042
            smp->data.ptrvalue = slpwrap;
 
1043
            slp = (SeqLocPtr) smp;
 
1044
          }
 
1045
          if (prev == NULL)
 
1046
            prev = ValNodeAddPointer (list, loop, slp);
 
1047
          else
 
1048
            prev = ValNodeAddPointer (&prev, loop, slp);
 
1049
          slpwrap = NULL;
 
1050
        }
 
1051
        else /* didn't make the cut */
 
1052
        {
 
1053
          if (slpwrap != NULL)
 
1054
            slpwrap = SeqLocFree (slpwrap);
 
1055
        }
 
1056
        checklen = 0;
 
1057
        charcheck = 'M';
 
1058
        this_code = icodes;
 
1059
      }
 
1060
      if (aa == 'M' && charcheck == 'M')
 
1061
      {
 
1062
        start = pos;
 
1063
        charcheck = '*';
 
1064
        this_code = codes;
 
1065
      }
 
1066
    }
 
1067
    if (pos+3 < len)
 
1068
      continue;
 
1069
/* treat end of sequence special if circle and in or out of frame on loop */
 
1070
    if (flagIsCircle)
 
1071
    {
 
1072
      if (charcheck == '*') /* check for cross junction ORF */
 
1073
      {
 
1074
        if (len%3 == 0) /* in frame */
 
1075
        {
 
1076
          spec1 = loop;
 
1077
          spec2 = start+1; /* cause the A could be part of stop codon */
 
1078
          spec3 = loop - 1;
 
1079
        }
 
1080
        else
 
1081
        {
 
1082
          spec1 = pos-len+3;
 
1083
          spec2 = len;
 
1084
          spec3 = loop - 3;
 
1085
        }
 
1086
        if (strand == Seq_strand_plus)
 
1087
          slp = SeqLocIntNew (start, len-1, strand, id);
 
1088
        else
 
1089
          slp = SeqLocIntNew (0, len-start-1, strand, id);
 
1090
        if (slpwrap != NULL)
 
1091
          ValNodeLink (&slpwrap, slp);
 
1092
        else
 
1093
          slpwrap = slp;
 
1094
        checklen += len-start;
 
1095
        for (pos = spec1; pos < spec2 && spec3 < loop; pos += 3)
 
1096
        {
 
1097
          codon[0] = SeqPortGetResidue (spp);
 
1098
          codon[1] = SeqPortGetResidue (spp);
 
1099
          codon[2] = SeqPortGetResidue (spp);
 
1100
          aa = AAForCodon (codon, this_code);
 
1101
          if (aa == '*')
 
1102
          {
 
1103
            checklen += pos;
 
1104
            if (checklen > limit)
 
1105
            {
 
1106
/* check for stop codon on junction */
 
1107
              if (pos+2 < len)
 
1108
              {
 
1109
                if (strand == Seq_strand_plus)
 
1110
                {
 
1111
                  stop = pos+2;
 
1112
                  slp = SeqLocIntNew (spec1, stop, strand, id);
 
1113
                }
 
1114
                else
 
1115
                {
 
1116
                  stop = len-pos-3;
 
1117
                  slp = SeqLocIntNew (stop, len-1, strand, id);
 
1118
                }
 
1119
              }
 
1120
              else
 
1121
              {
 
1122
                if (strand == Seq_strand_plus)
 
1123
                {
 
1124
                  stop = pos+2-len;
 
1125
                  slp = SeqLocIntNew (pos, len-1, strand, id);
 
1126
                  slp->next = SeqLocIntNew (0, stop, strand, id);
 
1127
                }
 
1128
                else
 
1129
                {
 
1130
                  stop = len+len-pos-3;
 
1131
                  slp = SeqLocIntNew (stop, len-1, strand, id);
 
1132
                  slp->next = SeqLocIntNew (0, len-spec1-1, strand, id);
 
1133
                }
 
1134
              }
 
1135
              ValNodeLink (&slpwrap, slp);  /* slpwrap set to get this far */
 
1136
              smp = ValNodeNew (NULL);
 
1137
              smp->choice = 8;              /* SeqLocMix */
 
1138
              smp->data.ptrvalue = slpwrap;
 
1139
              slpwrap = (SeqLocPtr) smp;
 
1140
              if (prev == NULL)
 
1141
                prev = ValNodeAddPointer (list, loop, slpwrap);
 
1142
              else
 
1143
                prev = ValNodeAddPointer (&prev, loop, slpwrap);
 
1144
              slpwrap = NULL;
 
1145
            }
 
1146
            break;
 
1147
          }
 
1148
          if (pos+3 < spec2)
 
1149
            continue;
 
1150
          if (len%3 != 0)
 
1151
          {
 
1152
            if (strand == Seq_strand_plus)
 
1153
              slp = SeqLocIntNew (spec1, len-1, strand, id);
 
1154
            else
 
1155
              slp = SeqLocIntNew (0, len-spec1-1, strand, id);
 
1156
            ValNodeLink (&slpwrap, slp);    /* slpwrap set to get this far */
 
1157
            checklen += spec2-spec1;
 
1158
          }
 
1159
          SeqPortSeek (spp, pos-spec2+3, SEEK_SET); /* redundant check */
 
1160
          pos = pos-spec2;
 
1161
          spec1 = pos+3;
 
1162
          spec3++;
 
1163
        }                   /* for (pos = ... break to here */
 
1164
        if (slpwrap != NULL)
 
1165
          slpwrap = SeqLocFree (slpwrap);
 
1166
      }                     /* if (charcheck == '*') looking for a stop */
 
1167
    }                       /* if (flagCircle) has to be round */
 
1168
    pos = loop+1;
 
1169
    SeqPortSeek (spp, pos, SEEK_SET);
 
1170
    pos -= 3;
 
1171
    checklen = 0;
 
1172
    charcheck = 'M';
 
1173
    this_code = icodes;
 
1174
    loop++;
 
1175
  }
 
1176
  if (slpwrap != NULL)
 
1177
    slpwrap = SeqLocFree (slpwrap);
 
1178
  return;
 
1179
}
 
1180
 
 
1181
static int LIBCALLBACK CompareLoc (VoidPtr vp1, VoidPtr vp2)
 
1182
{
 
1183
        ValNodePtr vnp1, vnp2;
 
1184
        ValNodePtr PNTR vnpp1;
 
1185
        ValNodePtr PNTR vnpp2;
 
1186
        Int4 l1, l2;
 
1187
 
 
1188
        vnpp1 = (ValNodePtr PNTR) vp1;
 
1189
        vnpp2 = (ValNodePtr PNTR) vp2;
 
1190
        vnp1 = *vnpp1;
 
1191
        vnp2 = *vnpp2;
 
1192
        l1 = SeqLocLen((SeqLocPtr) vnp1->data.ptrvalue);
 
1193
        l2 = SeqLocLen((SeqLocPtr) vnp2->data.ptrvalue);
 
1194
        
 
1195
        if (l1 > l2)
 
1196
                return -1;
 
1197
        else if (l1 < l2)
 
1198
                return 1;
 
1199
        else 
 
1200
                return 0;
 
1201
}
 
1202
 
 
1203
static ValNodePtr find_all_orf(BioseqPtr bsp, CharPtr vals, CharPtr codes, Int2 limit, Int4 from, Int4 to)
 
1204
{
 
1205
        Int2 ir;
 
1206
        ValNodePtr list = NULL;
 
1207
        SeqPortPtr spp;
 
1208
        SeqLocPtr slp = NULL;
 
1209
        
 
1210
        if (from > 0 || to > 0) {
 
1211
                slp = SeqLocIntNew(from, to, Seq_strand_plus, bsp->id);
 
1212
                spp = SeqPortNewByLoc(slp, Seq_code_ncbi4na);
 
1213
        } else {
 
1214
                spp = SeqPortNew(bsp, 0, -1, Seq_strand_plus, Seq_code_ncbi4na);
 
1215
        }
 
1216
        for (ir=0; ir < 3; ir++) {
 
1217
                find_orf(spp, ir, vals, codes, &list, Seq_strand_plus, bsp->id, limit);
 
1218
        }
 
1219
        SeqPortFree(spp);
 
1220
        if (slp) {
 
1221
                SeqLocFree(slp);
 
1222
        }
 
1223
        if (from > 0 || to > 0) {
 
1224
                slp = SeqLocIntNew(from, to, Seq_strand_minus, bsp->id);
 
1225
                spp = SeqPortNewByLoc(slp, Seq_code_ncbi4na);
 
1226
        } else {
 
1227
                spp = SeqPortNew(bsp, 0, -1, Seq_strand_minus, Seq_code_ncbi4na);
 
1228
        }
 
1229
        for (ir=0; ir < 3; ir++) {
 
1230
                find_orf(spp, ir, vals, codes, &list, Seq_strand_minus, bsp->id, limit);
 
1231
        }
 
1232
        SeqPortFree(spp);
 
1233
        if (slp) {
 
1234
                SeqLocFree(slp);
 
1235
        }
 
1236
        if (list != NULL) {
 
1237
                VnpHeapSort(&list, CompareLoc);
 
1238
        }
 
1239
        return list;
 
1240
}
 
1241
 
 
1242
static Boolean get_src (GatherContextPtr gcp)
 
1243
{
 
1244
        ValNodePtr      vnp, new;
 
1245
        ValNodePtr      PNTR vnpp;
 
1246
        
 
1247
        vnpp = gcp->userdata;
 
1248
        switch (gcp->thistype)
 
1249
        {
 
1250
                case OBJ_SEQDESC:
 
1251
                        vnp = (ValNodePtr) (gcp->thisitem);
 
1252
                        if (vnp->choice == Seq_descr_source) {
 
1253
                                if (vnp->data.ptrvalue != NULL) {
 
1254
                                        new = SeqDescrNew(NULL);
 
1255
                                        new = MemCopy(new, vnp, sizeof(ValNode));
 
1256
                                        new->next = NULL;
 
1257
                                        *vnpp = new;
 
1258
                                        return FALSE;  /*only top level BioSource will be returned*/
 
1259
                                }
 
1260
                        } 
 
1261
                        break;
 
1262
                default:
 
1263
                        break;
 
1264
        }
 
1265
        return TRUE;
 
1266
}
 
1267
 
 
1268
static Int2 GetGcodeFromBioseq(BioseqPtr bsp)
 
1269
{
 
1270
        GatherScope gs;
 
1271
        BioSourcePtr biop;
 
1272
        Int2 code = -1;
 
1273
        Uint2   entityID;
 
1274
        ValNodePtr vnp = NULL;  
 
1275
           
 
1276
        entityID = ObjMgrGetEntityIDForPointer(bsp);
 
1277
        MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
 
1278
        gs.get_feats_location = TRUE;
 
1279
        MemSet ((Pointer) (gs.ignore), (int)(TRUE), (size_t) (OBJ_MAX * sizeof(Boolean)));
 
1280
        gs.ignore[OBJ_SEQDESC] = FALSE;
 
1281
        
 
1282
        GatherEntity(entityID, &vnp, get_src, &gs);
 
1283
        if (vnp == NULL) {
 
1284
                ErrPostStr(SEV_WARNING, 0, 0, "BioSource not found");
 
1285
                return code;
 
1286
        }
 
1287
        if (vnp) {
 
1288
                biop = vnp->data.ptrvalue;
 
1289
                code = BioSourceToGeneticCode(biop);
 
1290
                if (code == 0) {
 
1291
                        code = 1;  /* try standard genetic code if it's not found */
 
1292
                }
 
1293
        }
 
1294
        return code;
 
1295
}
 
1296
 
 
1297
extern ValNodePtr GetOrfList (BioseqPtr bsp, Int2 limit)
 
1298
{
 
1299
        Int2 gcode;
 
1300
        GeneticCodePtr gcp;
 
1301
        CharPtr vals, codes;
 
1302
        ValNodePtr vnp, list;
 
1303
 
 
1304
        gcode = GetGcodeFromBioseq(bsp);
 
1305
        if (gcode == -1)
 
1306
                gcode = 1;   /* use universal */
 
1307
        gcp = GeneticCodeFind(gcode, NULL);
 
1308
        vals = NULL;
 
1309
        codes = NULL;
 
1310
        if (gcp == NULL) {
 
1311
                return NULL;
 
1312
        }
 
1313
        for (vnp = (ValNodePtr)gcp->data.ptrvalue; vnp != NULL; vnp = vnp->next)
 
1314
        {
 
1315
                if (vnp->choice == 6)   /* sncbieaa */
 
1316
                        vals = (CharPtr)vnp->data.ptrvalue;
 
1317
                else if (vnp->choice == 3)  /* ncbieaa */
 
1318
                        codes = (CharPtr)vnp->data.ptrvalue;
 
1319
        }
 
1320
        if (vals == NULL) {
 
1321
                vals = codes;
 
1322
        }
 
1323
        list = find_all_orf(bsp, vals, codes, limit, 0, 0);
 
1324
        
 
1325
        return list;
 
1326
}
 
1327
 
 
1328
extern ValNodePtr GetAltList (ValNodePtr list)
 
1329
{
 
1330
        ValNodePtr vnp;
 
1331
        SeqLocPtr slp, slpnext;
 
1332
        
 
1333
        
 
1334
        for (vnp = list; vnp; vnp = vnp->next) {
 
1335
                slp = (SeqLocPtr) vnp->data.ptrvalue;
 
1336
                if (slp && slp->next) {
 
1337
                        slpnext = slp->next;
 
1338
                        slp->next = NULL;
 
1339
                        slpnext->next = slp;
 
1340
                        vnp->data.ptrvalue = slpnext;
 
1341
                }
 
1342
        }
 
1343
        return list;
 
1344
}
 
1345