~ubuntu-branches/ubuntu/jaunty/ncbi-tools6/jaunty

« back to all changes in this revision

Viewing changes to api/edutil.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2008-07-14 19:43:15 UTC
  • mfrom: (2.1.12 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080714194315-ed44u9ek7txva2rz
Tags: 6.1.20080302-3
tools/readdb.c: enable madvise()-based code on all glibc (hence all
Debian) systems, not just Linux.  (Closes: #490437.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
*   
30
30
* Version Creation Date: 2/4/94
31
31
*
32
 
* $Revision: 6.57 $
 
32
* $Revision: 6.63 $
33
33
*
34
34
* File Description:  Sequence editing utilities
35
35
*
39
39
* -------  ----------  -----------------------------------------------------
40
40
*
41
41
* $Log: edutil.c,v $
 
42
* Revision 6.63  2007/07/02 19:17:26  bollin
 
43
* Corrected functions for inserting and deleting from locations to handle
 
44
* locations on segmented sets, corrected functions for inserting and deleting
 
45
* from sequences to adjust the length of the master sequence when adjusting the
 
46
* length of a segment.
 
47
*
 
48
* Revision 6.62  2007/05/08 17:18:32  bollin
 
49
* Added functions for identifying AGP gap DeltaSeqs
 
50
*
 
51
* Revision 6.61  2007/05/07 17:43:03  bollin
 
52
* Made functions IsDeltaSeqGap and IsDeltaSeqUnknownGap extern.
 
53
*
 
54
* Revision 6.60  2007/05/07 17:35:02  kans
 
55
* can handle Seq-lit.seq-data.gap
 
56
*
 
57
* Revision 6.59  2007/05/07 13:28:35  kans
 
58
* added casts for Seq-data.gap (SeqDataPtr, SeqGapPtr, ByteStorePtr)
 
59
*
 
60
* Revision 6.58  2007/01/19 14:55:07  bollin
 
61
* Do not set partial when deleting location from feature.
 
62
*
42
63
* Revision 6.57  2006/07/13 17:06:38  bollin
43
64
* use Uint4 instead of Uint2 for itemID values
44
65
* removed unused variables
817
838
                                        case Seq_code_ncbi4na:
818
839
                                                newcode = Seq_code_iupacna;
819
840
                                                break;
 
841
                                        case Seq_code_gap:
 
842
                                                ErrPostEx(SEV_WARNING,0,0,"Seq_code_gap residue code in SeqLocsToDeltaSeqs");
 
843
                                                return DeltaSeqFree(dhead);
 
844
                                                break;
820
845
                                        default:
821
846
                                                ErrPostEx(SEV_FATAL,0,0,"Unrecognized residue code [%d] in SeqLocsToDeltaSeqs",
822
847
                                                        (int)(slitp->seq_data_type));
825
850
                                spps = MemNew(sizeof(SeqPort));
826
851
                                SeqPortSetUpFields (spps, strt, stp, strand, newcode);
827
852
                                SeqPortSetUpAlphabet(spps, slitp->seq_data_type, newcode);
828
 
                                spps->bp = slitp->seq_data;
 
853
                                spps->bp = (ByteStorePtr) slitp->seq_data;
829
854
                                slitp_new = SeqLitNew();
830
855
                                dcurr->data.ptrvalue = slitp_new;
831
856
                                slitp_new->seq_data_type = newcode;
832
857
                                slitp_new->length = (stp - strt + 1);
833
858
                                bsp = BSNew(slitp_new->length);
834
 
                                slitp_new->seq_data = bsp;
 
859
                                slitp_new->seq_data = (SeqDataPtr) bsp;
835
860
                                SeqPortSeek(spps, 0, SEEK_SET);
836
861
                                BSSeek(bsp, 0, SEEK_SET);
837
862
                            while (stp >= strt)
893
918
        len = to - from + 1;
894
919
                   /* if actual sequence present */
895
920
 
896
 
        if ((bsp->repr == Seq_repr_raw) || (bsp->repr == Seq_repr_const))
 
921
        if (((bsp->repr == Seq_repr_raw) || (bsp->repr == Seq_repr_const)) && bsp->seq_data_type != Seq_code_gap)
897
922
        {
898
923
                if (ISA_na(bsp->mol))
899
924
                {
906
931
                                BioseqRawConvert(bsp, Seq_code_ncbieaa);
907
932
                }
908
933
 
909
 
                BSSeek(bsp->seq_data, from, SEEK_SET);
910
 
                deleted = BSDelete(bsp->seq_data, len);
 
934
                BSSeek((ByteStorePtr) bsp->seq_data, from, SEEK_SET);
 
935
                deleted = BSDelete((ByteStorePtr) bsp->seq_data, len);
911
936
                if (deleted != len)  /* error */
912
937
                        ErrPost(CTX_NCBIOBJ, 1, "Delete of %ld residues failed", len);
913
938
                else
1086
1111
        if ((pos < 0) || (pos >= bsp->length)) return retval;
1087
1112
        if (bsp->repr != Seq_repr_raw) return retval;
1088
1113
 
 
1114
        if (bsp->seq_data_type == Seq_code_gap) return FALSE;
 
1115
 
1089
1116
        if (ISA_na(bsp->mol))
1090
1117
        {
1091
1118
                if (bsp->seq_data_type != Seq_code_iupacna)  /* need 1 byte/base */
1097
1124
                        BioseqRawConvert(bsp, Seq_code_ncbieaa);
1098
1125
        }
1099
1126
 
1100
 
        BSSeek(bsp->seq_data, pos, SEEK_SET);
1101
 
        BSPutByte(bsp->seq_data, (Int2)(TO_UPPER(residue)));
 
1127
        BSSeek((ByteStorePtr) bsp->seq_data, pos, SEEK_SET);
 
1128
        BSPutByte((ByteStorePtr) bsp->seq_data, (Int2)(TO_UPPER(residue)));
1102
1129
        retval = TRUE;
1103
1130
 
1104
1131
        return retval;
1355
1382
                        
1356
1383
        if (changed)
1357
1384
        {
1358
 
                sfp->partial = TRUE;
1359
1385
                return 1;
1360
1386
        }
1361
1387
        else
1965
1991
        if (newbsp->repr == Seq_repr_virtual)
1966
1992
                handled = TRUE;               /* no more to do */
1967
1993
 
1968
 
        if ((newbsp->repr == Seq_repr_raw) ||
1969
 
                (newbsp->repr == Seq_repr_const))
 
1994
        if (((newbsp->repr == Seq_repr_raw) ||
 
1995
                (newbsp->repr == Seq_repr_const)) && newbsp->seq_data_type != Seq_code_gap)
1970
1996
        {
1971
1997
                if (ISA_aa(newbsp->mol))
1972
1998
                {
1980
2006
                bsp = BSNew(len);
1981
2007
                if (bsp == NULL) goto erret;
1982
2008
 
1983
 
                newbsp->seq_data = bsp;
 
2009
                newbsp->seq_data = (SeqDataPtr) bsp;
1984
2010
                spp = SeqPortNew(oldbsp, from, to, strand, seqtype);
1985
2011
                if (spp == NULL) goto erret;
1986
2012
 
3180
3206
                handled = TRUE;                    /* just length and features */
3181
3207
        }
3182
3208
 
3183
 
        if ((tobsp->repr == Seq_repr_raw) || (tobsp->repr == Seq_repr_const))
 
3209
        if (((tobsp->repr == Seq_repr_raw) || (tobsp->repr == Seq_repr_const)) && tobsp->seq_data_type != Seq_code_gap)
3184
3210
        {
3185
3211
                if (ISA_na(tobsp->mol))
3186
3212
                {
3193
3219
 
3194
3220
                if (tobsp->seq_data_type != seqtype)
3195
3221
                        BioseqRawConvert(tobsp, seqtype);
3196
 
                BSSeek(tobsp->seq_data, pos, SEEK_SET);
 
3222
                BSSeek((ByteStorePtr) tobsp->seq_data, pos, SEEK_SET);
3197
3223
                if (do_bsadd) {
3198
 
                        Nlm_BSAdd(tobsp->seq_data, len, FALSE);
 
3224
                        Nlm_BSAdd((ByteStorePtr) tobsp->seq_data, len, FALSE);
3199
3225
                }
3200
3226
 
3201
3227
                i = 0;
3210
3236
                        }
3211
3237
                        else
3212
3238
                        {
3213
 
                                BSPutByte(tobsp->seq_data, residue);
 
3239
                                BSPutByte((ByteStorePtr) tobsp->seq_data, residue);
3214
3240
                                i++;
3215
3241
                        }
3216
3242
                }
4129
4155
  }
4130
4156
}
4131
4157
 
 
4158
 
 
4159
static BioseqPtr 
 
4160
GetParentForSegment
 
4161
(BioseqPtr bsp, Int4Ptr p_start, Int4Ptr p_stop)
 
4162
{
 
4163
  BioseqSetPtr parts_bssp, seg_bssp;
 
4164
  BioseqPtr    master_bsp, other_part;
 
4165
  SeqEntryPtr  sep;
 
4166
  Int4         offset = 0;
 
4167
 
 
4168
  if (bsp == NULL || bsp->idx.parentptr == NULL || bsp->idx.parenttype != OBJ_BIOSEQSET) return NULL;
 
4169
 
 
4170
  parts_bssp = (BioseqSetPtr) bsp->idx.parentptr;
 
4171
  if (parts_bssp->_class != BioseqseqSet_class_parts
 
4172
      || parts_bssp->idx.parentptr == NULL
 
4173
      || parts_bssp->idx.parenttype != OBJ_BIOSEQSET)
 
4174
  {
 
4175
    return NULL;
 
4176
  }
 
4177
 
 
4178
  seg_bssp = (BioseqSetPtr) parts_bssp->idx.parentptr;
 
4179
  if (seg_bssp->_class != BioseqseqSet_class_segset
 
4180
      || seg_bssp->seq_set == NULL 
 
4181
      || !IS_Bioseq (seg_bssp->seq_set)) 
 
4182
  {
 
4183
    return NULL;
 
4184
  }
 
4185
 
 
4186
  master_bsp = (BioseqPtr) seg_bssp->seq_set->data.ptrvalue;
 
4187
 
 
4188
  if (p_start != NULL || p_stop != NULL)
 
4189
  {
 
4190
    sep = parts_bssp->seq_set;
 
4191
    while (sep != NULL && sep->data.ptrvalue != bsp)
 
4192
    {
 
4193
      if (IS_Bioseq (sep) && sep->data.ptrvalue != NULL)
 
4194
      {
 
4195
        other_part = sep->data.ptrvalue;
 
4196
        offset += other_part->length;
 
4197
      }
 
4198
      sep = sep->next;
 
4199
    }
 
4200
    if (p_start != NULL)
 
4201
    {
 
4202
      *p_start = offset;
 
4203
    }
 
4204
    if (p_stop != NULL)
 
4205
    {
 
4206
      *p_stop = offset + bsp->length - 1;
 
4207
    }
 
4208
  }
 
4209
 
 
4210
  return master_bsp;
 
4211
}
 
4212
 
 
4213
 
 
4214
static Boolean AdjustOffsetsForSegment (SeqIdPtr del_id, SeqIdPtr target_id, Int4Ptr from, Int4Ptr to)
 
4215
{
 
4216
  BioseqPtr bsp_del, bsp_target, bsp_master;
 
4217
  Int4      seg_offset = 0, seg_end = 0;
 
4218
  Boolean   rval = FALSE;
 
4219
 
 
4220
  if (del_id == NULL || target_id == NULL || from == NULL || to == NULL)
 
4221
  {
 
4222
    return FALSE;
 
4223
  }
 
4224
 
 
4225
  bsp_del = BioseqFind (del_id);
 
4226
  bsp_target = BioseqFind (target_id);
 
4227
  if (bsp_del == NULL || bsp_target == NULL) return FALSE;
 
4228
 
 
4229
  bsp_master = GetParentForSegment (bsp_del, &seg_offset, &seg_end);
 
4230
  if (bsp_master != NULL)
 
4231
  {
 
4232
    if (bsp_master == bsp_target && seg_offset < *to)
 
4233
    {
 
4234
      /* loc to delete is in parent coordinates */
 
4235
      if (*from > seg_end || *to < seg_offset)
 
4236
      {
 
4237
        /* loc to delete is entirely past this segment */
 
4238
      }
 
4239
      else
 
4240
      {
 
4241
        *from = MAX (0, *from - seg_offset);
 
4242
        *to = MIN (bsp_target->length, *to - seg_offset);
 
4243
        rval = TRUE;
 
4244
      }
 
4245
    }
 
4246
  }
 
4247
  return rval;
 
4248
}
 
4249
 
 
4250
 
 
4251
static void SeqEdInsertSeqPnt (SeqPntPtr spp, SeqIdPtr target_id, Int4 pos, Int4 len, SeqIdPtr newid)
 
4252
{
 
4253
  Int4 to = pos + len;
 
4254
  Boolean id_in_list;
 
4255
 
 
4256
  if (spp == NULL) return;
 
4257
 
 
4258
  if ((id_in_list = SeqIdIn(spp->id, target_id))
 
4259
      || AdjustOffsetsForSegment (spp->id, target_id, &pos, &to))
 
4260
  {
 
4261
    if (id_in_list && newid != NULL)   /* change id? */
 
4262
    {
 
4263
      SeqIdFree(spp->id);
 
4264
      spp->id = SeqIdDup(newid);
 
4265
    }
 
4266
 
 
4267
    if (spp->point >= pos)
 
4268
    {
 
4269
      spp->point += len;
 
4270
    }
 
4271
  }
 
4272
}
 
4273
 
 
4274
 
 
4275
static void 
 
4276
SeqEdInsertSeqInt 
 
4277
(SeqIntPtr      sip,
 
4278
 SeqIdPtr       target_id,
 
4279
 Int4           pos,
 
4280
 Int4           len,
 
4281
 Boolean        split,
 
4282
 SeqIdPtr       newid,
 
4283
 SeqIntPtr PNTR split_end)
 
4284
{
 
4285
  Int4 to = pos + len;
 
4286
  Boolean id_in_list;
 
4287
  SeqIntPtr sip2;
 
4288
  SeqLocPtr slp;
 
4289
 
 
4290
  if (sip == NULL || split_end == NULL) return;
 
4291
  
 
4292
  if (!(id_in_list = SeqIdIn(sip->id, target_id))
 
4293
      && ! AdjustOffsetsForSegment(sip->id, target_id, &pos, &to))
 
4294
  {
 
4295
    return;
 
4296
  }
 
4297
 
 
4298
  if (newid != NULL && id_in_list)   /* change id? */
 
4299
  {
 
4300
    SeqIdFree(sip->id);
 
4301
    sip->id = SeqIdDup(newid);
 
4302
  }
 
4303
 
 
4304
  if (sip->to < pos)  /* completely before insertion */
 
4305
  {
 
4306
    return;
 
4307
  }
 
4308
 
 
4309
  if ((! split) || (sip->from >= pos))  /* interval unbroken */
 
4310
  {
 
4311
    if (sip->from >= pos)
 
4312
      sip->from += len;
 
4313
    sip->to += len;
 
4314
    return;
 
4315
  }
 
4316
                                    /* split interval */
 
4317
  sip2 = SeqIntNew();
 
4318
  slp = ValNodeNew(NULL);
 
4319
  slp->choice = SEQLOC_INT;
 
4320
  slp->data.ptrvalue = (Pointer)sip2;
 
4321
  sip2->strand = sip->strand;
 
4322
  sip2->id = SeqIdDup(sip->id);
 
4323
 
 
4324
  sip2->to = sip->to + len;
 
4325
  sip2->from = pos + len;
 
4326
  sip2->if_to = sip->if_to;
 
4327
  sip->if_to = NULL;
 
4328
  sip->to = pos - 1;
 
4329
 
 
4330
  *split_end = sip2;
 
4331
}
 
4332
 
 
4333
 
4132
4334
/*****************************************************************************
4133
4335
*
4134
4336
*   SeqEdSeqLocInsert()
4163
4365
NLM_EXTERN SeqLocPtr LIBCALL SeqEdSeqLocInsert (SeqLocPtr head, BioseqPtr target, Int4 pos, Int4 len,
4164
4366
                                               Boolean split, SeqIdPtr newid)
4165
4367
{
4166
 
        SeqIntPtr sip, sip2;
4167
 
        SeqPntPtr spp;
4168
 
        PackSeqPntPtr pspp, pspp2;
4169
 
        SeqBondPtr sbp;
4170
 
        SeqLocPtr slp, tmp, prev, next, thead, tmp2;
4171
 
        Int4 diff, numpnt, i, tpos;
4172
 
        Uint1 oldchoice;
4173
 
        ValNode vn;
4174
 
        SeqIdPtr sidp;
4175
 
 
4176
 
        if ((head == NULL) || (target == NULL))
4177
 
                return head;
4178
 
 
4179
 
        head->next = NULL;   /* caller maintains chains */
4180
 
 
4181
 
        diff = len;
4182
 
 
4183
 
    switch (head->choice)
4184
 
    {
4185
 
        case SEQLOC_BOND:   /* bond -- 2 seqs */
4186
 
                        vn.next = NULL;
4187
 
                        vn.choice = SEQLOC_PNT;
4188
 
 
4189
 
                        sbp = (SeqBondPtr)(head->data.ptrvalue);
4190
 
                        vn.data.ptrvalue = (Pointer)(sbp->a);
4191
 
                        SeqEdSeqLocInsert(&vn, target, pos, len, split, newid);
4192
 
                        sbp->a = (SeqPntPtr)(vn.data.ptrvalue);
4193
 
                        if (sbp->b != NULL)
4194
 
                        {
4195
 
                                vn.data.ptrvalue = (Pointer)(sbp->b);
4196
 
                                SeqEdSeqLocInsert(&vn, target, pos, len, split, newid);
4197
 
                                sbp->b = (SeqPntPtr)(vn.data.ptrvalue);
4198
 
                        }
4199
 
                        break;
4200
 
        case SEQLOC_FEAT:   /* feat -- can't track yet */
4201
 
        case SEQLOC_NULL:    /* NULL */
4202
 
                        break;
4203
 
        case SEQLOC_EMPTY:    /* empty */
4204
 
        case SEQLOC_WHOLE:    /* whole */
4205
 
                        if (newid != NULL)
4206
 
                        {
4207
 
                                sidp = (SeqIdPtr)(head->data.ptrvalue);
4208
 
                                if ( SeqIdIn(sidp, target->id))
4209
 
                                {
4210
 
                                        SeqIdFree(sidp);
4211
 
                                        sidp = SeqIdDup(newid);
4212
 
                                        head->data.ptrvalue = (Pointer)sidp;
4213
 
                                }
4214
 
                        }
4215
 
                        break;
4216
 
        case SEQLOC_MIX:    /* mix -- more than one seq */
4217
 
        case SEQLOC_EQUIV:    /* equiv -- ditto */
4218
 
        case SEQLOC_PACKED_INT:    /* packed int */
4219
 
                        prev = NULL;
4220
 
                        thead = NULL;
4221
 
                        for (slp = (SeqLocPtr)(head->data.ptrvalue); slp != NULL; slp = next)
4222
 
                        {
4223
 
                                next = slp->next;
4224
 
                                oldchoice = slp->choice;
4225
 
                                tmp = SeqEdSeqLocInsert(slp, target, pos, len, split, newid);
4226
 
                                if (tmp != NULL)
4227
 
                                {
4228
 
                                        if ((head->choice != SEQLOC_EQUIV) &&
4229
 
                                                (oldchoice != tmp->choice))  /* split interval? */
4230
 
                                        {
4231
 
                                                if ((oldchoice == SEQLOC_INT) &&
4232
 
                                                        (tmp->choice == SEQLOC_PACKED_INT))
4233
 
                                                {
4234
 
                                                        tmp2 = tmp;
4235
 
                                                        tmp = (SeqLocPtr)(tmp2->data.ptrvalue);
4236
 
                                                        MemFree(tmp2);
4237
 
                                                        while (tmp->next != NULL)
4238
 
                                                        {
4239
 
                                                                if (prev != NULL)
4240
 
                                                                        prev->next = tmp;
4241
 
                                                                else
4242
 
                                                                        thead = tmp;
4243
 
                                                                prev = tmp;
4244
 
                                                                tmp = tmp->next;
4245
 
                                                        }
4246
 
                                                }
4247
 
                                        }
4248
 
                                        if (prev != NULL)
4249
 
                                                prev->next = tmp;
4250
 
                                        else
4251
 
                                                thead = tmp;
4252
 
                                        prev = tmp;
4253
 
                                }
4254
 
                        }
4255
 
                        head->data.ptrvalue = thead;
4256
 
                        if (thead == NULL)
4257
 
                                head = SeqLocFree(head);
4258
 
            break;
4259
 
        case SEQLOC_INT:    /* int */
4260
 
                        sip = (SeqIntPtr)(head->data.ptrvalue);
4261
 
                        if (SeqIdIn(sip->id, target->id))
4262
 
                        {
4263
 
                                if (newid != NULL)   /* change id? */
4264
 
                                {
4265
 
                                        SeqIdFree(sip->id);
4266
 
                                        sip->id = SeqIdDup(newid);
4267
 
                                }
4268
 
 
4269
 
                                if (sip->to < pos)  /* completely before insertion */
4270
 
                                {
4271
 
                                        break;
4272
 
                                }
4273
 
 
4274
 
                                if ((! split) || (sip->from >= pos))  /* interval unbroken */
4275
 
                                {
4276
 
                                        if (sip->from >= pos)
4277
 
                                                sip->from += len;
4278
 
                                        sip->to += len;
4279
 
                                        break;
4280
 
                                }
4281
 
 
4282
 
                                                                          /* split interval */
4283
 
                                sip2 = SeqIntNew();
4284
 
                                slp = ValNodeNew(NULL);
4285
 
                                slp->choice = SEQLOC_INT;
4286
 
                                slp->data.ptrvalue = (Pointer)sip2;
4287
 
                                sip2->strand = sip->strand;
4288
 
                                sip2->id = SeqIdDup(sip->id);
4289
 
 
4290
 
                                sip2->to = sip->to + len;
4291
 
                                sip2->from = pos + len;
4292
 
                                sip2->if_to = sip->if_to;
4293
 
                                sip->if_to = NULL;
4294
 
                                sip->to = pos - 1;
4295
 
                                head->next = slp;
4296
 
 
4297
 
                                if (sip->strand == Seq_strand_minus)  /* reverse order */
4298
 
                                {
4299
 
                                        head->data.ptrvalue = (Pointer)sip2;
4300
 
                                        slp->data.ptrvalue = (Pointer)sip;
4301
 
                                }
4302
 
 
4303
 
                                thead = head;   /* make split interval into PACKED_INT */
4304
 
                                head = ValNodeNew(NULL);
4305
 
                                head->choice = SEQLOC_PACKED_INT;
4306
 
                                head->data.ptrvalue = thead;
4307
 
 
4308
 
                        }
4309
 
            break;
4310
 
        case SEQLOC_PNT:    /* pnt */
4311
 
                        spp = (SeqPntPtr)(head->data.ptrvalue);
4312
 
                        if (SeqIdIn(spp->id, target->id))
4313
 
                        {
4314
 
                                if (newid != NULL)   /* change id? */
4315
 
                                {
4316
 
                                        SeqIdFree(spp->id);
4317
 
                                        spp->id = SeqIdDup(newid);
4318
 
                                }
4319
 
 
4320
 
                                if (spp->point >= pos)
4321
 
                                        spp->point += len;
4322
 
                        }
4323
 
            break;
4324
 
        case SEQLOC_PACKED_PNT:    /* packed pnt */
4325
 
                        pspp = (PackSeqPntPtr)(head->data.ptrvalue);
4326
 
                        if (SeqIdIn(pspp->id, target->id))
4327
 
                        {
4328
 
                                if (newid != NULL)   /* change id? */
4329
 
                                {
4330
 
                                        SeqIdFree(pspp->id);
4331
 
                                        pspp->id = SeqIdDup(newid);
4332
 
                                }
4333
 
 
4334
 
                                numpnt = PackSeqPntNum(pspp);
4335
 
                                pspp2 = PackSeqPntNew();
4336
 
                                head->data.ptrvalue = pspp2;
4337
 
                                for (i = 0; i < numpnt; i++)
4338
 
                                {
4339
 
                                        tpos = PackSeqPntGet(pspp, i);
4340
 
                                        if (tpos >= pos)
4341
 
                                                tpos += len;
4342
 
                                        PackSeqPntPut(pspp2, tpos);
4343
 
                                }
4344
 
                                pspp2->id = pspp->id;
4345
 
                                pspp->id = NULL;
4346
 
                                pspp2->fuzz = pspp->fuzz;
 
4368
  SeqIntPtr sip, sip2;
 
4369
  SeqPntPtr spp;
 
4370
  PackSeqPntPtr pspp, pspp2;
 
4371
  SeqBondPtr sbp;
 
4372
  SeqLocPtr slp, tmp, prev, next, thead, tmp2;
 
4373
  Int4 diff, numpnt, i, tpos;
 
4374
  Uint1 oldchoice;
 
4375
  SeqIdPtr sidp;
 
4376
  Boolean id_in_list;
 
4377
 
 
4378
  if ((head == NULL) || (target == NULL))
 
4379
    return head;
 
4380
 
 
4381
  head->next = NULL;   /* caller maintains chains */
 
4382
 
 
4383
  diff = len;
 
4384
 
 
4385
  switch (head->choice)
 
4386
  {
 
4387
    case SEQLOC_BOND:   /* bond -- 2 seqs */
 
4388
      sbp = (SeqBondPtr)(head->data.ptrvalue);
 
4389
      SeqEdInsertSeqPnt (sbp->a, target->id, pos, len, newid);
 
4390
      SeqEdInsertSeqPnt (sbp->b, target->id, pos, len, newid);
 
4391
      break;
 
4392
    case SEQLOC_FEAT:   /* feat -- can't track yet */
 
4393
    case SEQLOC_NULL:    /* NULL */
 
4394
      break;
 
4395
    case SEQLOC_EMPTY:    /* empty */
 
4396
    case SEQLOC_WHOLE:    /* whole */
 
4397
      if (newid != NULL)
 
4398
      {
 
4399
        sidp = (SeqIdPtr)(head->data.ptrvalue);
 
4400
        if ( SeqIdIn(sidp, target->id))
 
4401
        {
 
4402
          SeqIdFree(sidp);
 
4403
          sidp = SeqIdDup(newid);
 
4404
          head->data.ptrvalue = (Pointer)sidp;
 
4405
        }
 
4406
      }
 
4407
      break;
 
4408
    case SEQLOC_MIX:    /* mix -- more than one seq */
 
4409
    case SEQLOC_EQUIV:    /* equiv -- ditto */
 
4410
    case SEQLOC_PACKED_INT:    /* packed int */
 
4411
      prev = NULL;
 
4412
      thead = NULL;
 
4413
      for (slp = (SeqLocPtr)(head->data.ptrvalue); slp != NULL; slp = next)
 
4414
      {
 
4415
        next = slp->next;
 
4416
        oldchoice = slp->choice;
 
4417
        tmp = SeqEdSeqLocInsert(slp, target, pos, len, split, newid);
 
4418
        if (tmp != NULL)
 
4419
        {
 
4420
          if ((head->choice != SEQLOC_EQUIV) &&
 
4421
            (oldchoice != tmp->choice))  /* split interval? */
 
4422
          {
 
4423
            if ((oldchoice == SEQLOC_INT) &&
 
4424
              (tmp->choice == SEQLOC_PACKED_INT))
 
4425
            {
 
4426
              tmp2 = tmp;
 
4427
              tmp = (SeqLocPtr)(tmp2->data.ptrvalue);
 
4428
              MemFree(tmp2);
 
4429
              while (tmp->next != NULL)
 
4430
              {
 
4431
                if (prev != NULL)
 
4432
                  prev->next = tmp;
 
4433
                else
 
4434
                  thead = tmp;
 
4435
                prev = tmp;
 
4436
                tmp = tmp->next;
 
4437
              }
 
4438
            }
 
4439
          }
 
4440
          if (prev != NULL)
 
4441
            prev->next = tmp;
 
4442
          else
 
4443
            thead = tmp;
 
4444
          prev = tmp;
 
4445
        }
 
4446
      }
 
4447
      head->data.ptrvalue = thead;
 
4448
      if (thead == NULL)
 
4449
        head = SeqLocFree(head);
 
4450
      break;
 
4451
    case SEQLOC_INT:    /* int */
 
4452
      sip = (SeqIntPtr)(head->data.ptrvalue);
 
4453
      sip2 = NULL;
 
4454
      SeqEdInsertSeqInt (sip, target->id, pos, len, split, newid, &sip2);
 
4455
      if (sip2 != NULL)
 
4456
      {
 
4457
        thead = head;   /* make split interval into PACKED_INT */
 
4458
        head = ValNodeNew (NULL);
 
4459
        head->choice = SEQLOC_PACKED_INT;
 
4460
 
 
4461
        slp = ValNodeNew (NULL);
 
4462
        slp->choice = SEQLOC_INT;
 
4463
        slp->data.ptrvalue = sip2;
 
4464
        
 
4465
        if (sip->strand == Seq_strand_minus)  /* reverse order */
 
4466
        {
 
4467
          head->data.ptrvalue = slp;
 
4468
          slp->next = thead;
 
4469
        }
 
4470
        else
 
4471
        {
 
4472
          head->data.ptrvalue = thead;
 
4473
          thead->next = slp;
 
4474
        }
 
4475
      }
 
4476
      break;
 
4477
    case SEQLOC_PNT:    /* pnt */
 
4478
      spp = (SeqPntPtr)(head->data.ptrvalue);
 
4479
      SeqEdInsertSeqPnt (spp, target->id, pos, len, newid);
 
4480
      break;
 
4481
    case SEQLOC_PACKED_PNT:    /* packed pnt */
 
4482
      pspp = (PackSeqPntPtr)(head->data.ptrvalue);
 
4483
      if ((id_in_list = SeqIdIn(pspp->id, target->id))
 
4484
          || AdjustOffsetsForSegment(pspp->id, target->id, &pos, NULL))
 
4485
      {
 
4486
        if (id_in_list && newid != NULL)   /* change id? */
 
4487
        {
 
4488
          SeqIdFree(pspp->id);
 
4489
          pspp->id = SeqIdDup(newid);
 
4490
        }
 
4491
 
 
4492
        numpnt = PackSeqPntNum(pspp);
 
4493
        pspp2 = PackSeqPntNew();
 
4494
        head->data.ptrvalue = pspp2;
 
4495
        for (i = 0; i < numpnt; i++)
 
4496
        {
 
4497
          tpos = PackSeqPntGet(pspp, i);
 
4498
          if (tpos >= pos)
 
4499
            tpos += len;
 
4500
          PackSeqPntPut(pspp2, tpos);
 
4501
        }
 
4502
        pspp2->id = pspp->id;
 
4503
        pspp->id = NULL;
 
4504
        pspp2->fuzz = pspp->fuzz;
4347
4505
                                pspp->fuzz = NULL;
4348
4506
                                pspp2->strand = pspp->strand;
4349
4507
                                PackSeqPntFree(pspp);
4350
4508
                        }
4351
 
            break;
4352
 
        default:
4353
 
            break;
4354
 
    }
4355
 
 
4356
 
        if (head == NULL)
4357
 
                ErrPost(CTX_NCBIOBJ, 1, "SeqEdSeqLocInsert: lost a SeqLoc");
4358
 
 
4359
 
        return head;
4360
 
}
 
4509
      break;
 
4510
    default:
 
4511
      break;
 
4512
  }
 
4513
 
 
4514
  if (head == NULL)
 
4515
    ErrPost(CTX_NCBIOBJ, 1, "SeqEdSeqLocInsert: lost a SeqLoc");
 
4516
 
 
4517
  return head;
 
4518
}
 
4519
 
 
4520
 
 
4521
/* return TRUE if spp should be deleted */
 
4522
static Boolean SeqEdDeleteFromSeqPnt (SeqPntPtr spp, SeqIdPtr target_id, Int4 from, Int4 to)
 
4523
{
 
4524
  Boolean rval = FALSE;
 
4525
  Int4    diff = to - from + 1;
 
4526
 
 
4527
  if (spp == NULL) return FALSE;
 
4528
 
 
4529
        if (SeqIdIn (spp->id, target_id)
 
4530
      || AdjustOffsetsForSegment (spp->id, target_id, &from, &to))
 
4531
  {
 
4532
    if ((spp->point >= from) && (spp->point <= to))
 
4533
    {
 
4534
      rval = TRUE;
 
4535
    }
 
4536
    else if (spp->point > to)
 
4537
    {
 
4538
      spp->point -= diff;
 
4539
    }
 
4540
  }
 
4541
  return rval;
 
4542
}
 
4543
 
4361
4544
 
4362
4545
static SeqLocPtr 
4363
4546
SeqEdDeleteFromSeqLocBond (SeqLocPtr head, SeqIdPtr target, Int4 from, Int4 to, Boolean merge, BoolPtr changed)
4364
4547
{
4365
4548
  SeqBondPtr sbp;
4366
 
  SeqPntPtr  spp;
4367
 
  Int4       diff;
4368
4549
 
4369
4550
  if (head == NULL || target == NULL || head->choice != SEQLOC_BOND) return NULL;
4370
4551
  sbp = (SeqBondPtr)(head->data.ptrvalue);
4371
 
  spp = sbp->a;
4372
 
  diff = to - from + 1;
4373
 
 
4374
 
  if (SeqIdForSameBioseq(spp->id, target))
4375
 
  {
4376
 
        if (spp->point >= from)
4377
 
        {
4378
 
          if (spp->point <= to)   /* delete it */
4379
 
          {
4380
 
            *changed = TRUE;
4381
 
                sbp->a = SeqPntFree(spp);
4382
 
          }
4383
 
      else if (merge)
4384
 
          {
4385
 
                spp->point -= diff;
4386
 
          }
4387
 
        }
4388
 
  }
4389
 
  spp = sbp->b;
4390
 
  if (spp != NULL)
4391
 
  {
4392
 
        if (SeqIdForSameBioseq(spp->id, target))
4393
 
        {
4394
 
          if (spp->point >= from)
4395
 
          {
4396
 
                if (spp->point <= to)   /* delete it */
4397
 
                {
4398
 
                  *changed = TRUE;
4399
 
                  sbp->b = SeqPntFree(spp);
4400
 
                }
4401
 
                else if (merge)
4402
 
                {
4403
 
                  spp->point -= diff;
4404
 
                }
4405
 
      }
4406
 
        }
4407
 
  }
 
4552
 
 
4553
  if (SeqEdDeleteFromSeqPnt (sbp->a, target, from, to))
 
4554
  {
 
4555
    *changed = TRUE;
 
4556
    sbp->a = SeqPntFree(sbp->a);
 
4557
  }
 
4558
 
 
4559
  if (SeqEdDeleteFromSeqPnt (sbp->b, target, from, to))
 
4560
  {
 
4561
    *changed = TRUE;
 
4562
    sbp->b = SeqPntFree(sbp->b);
 
4563
  }
 
4564
 
4408
4565
  if (sbp->a == NULL)
4409
4566
  {
4410
 
        if (sbp->b != NULL)   /* only a required */
4411
 
        {
 
4567
    if (sbp->b != NULL)   /* only a required */
 
4568
    {
4412
4569
      sbp->a = sbp->b;
4413
4570
      sbp->b = NULL;
4414
 
        }
4415
 
        else
4416
 
        {
4417
 
          head = SeqLocFree(head);
4418
 
        }
 
4571
    }
 
4572
    else
 
4573
    {
 
4574
      head = SeqLocFree(head);
 
4575
    }
4419
4576
  }
4420
4577
  return head;
4421
4578
}
4598
4755
  return head;
4599
4756
}
4600
4757
 
 
4758
 
4601
4759
static SeqLocPtr SeqEdDeleteFromSeqLocInt (SeqLocPtr head, BioseqPtr target, Int4 from, Int4 to, Boolean merge, BoolPtr changed, BoolPtr partial5, BoolPtr partial3)
4602
4760
{
4603
4761
  Int4      diff;
4607
4765
  if (head == NULL || target == NULL || head->choice != SEQLOC_INT) return NULL;
4608
4766
 
4609
4767
  sip = (SeqIntPtr)(head->data.ptrvalue);
4610
 
  if ( !SeqIdIn(sip->id, target->id)) return head;
 
4768
  if ( !SeqIdIn(sip->id, target->id)
 
4769
      && ! AdjustOffsetsForSegment (sip->id, target->id, &from, &to))
 
4770
  {
 
4771
    return head;
 
4772
  }
4611
4773
 
4612
4774
  diff = to - from + 1;
4613
4775
 
4795
4957
      break;
4796
4958
    case SEQLOC_PNT:    /* pnt */
4797
4959
                        spp = (SeqPntPtr)(head->data.ptrvalue);
4798
 
                        if (SeqIdIn (spp->id, target->id)) 
4799
 
                        {
4800
 
                                if ((spp->point >= from) && (spp->point <= to))
4801
 
                                {
4802
 
                                        head = SeqLocFree(head);
4803
 
                                        *changed = TRUE;
4804
 
                                }
4805
 
                                else if (spp->point > to)
4806
 
                                {
4807
 
                                                spp->point -= diff;
4808
 
                                }
4809
 
                        }
 
4960
      if (SeqEdDeleteFromSeqPnt (spp, target->id, from, to))
 
4961
      {
 
4962
        head = SeqLocFree(head);
 
4963
        *changed = TRUE;
 
4964
      }
4810
4965
      break;
4811
4966
    case SEQLOC_PACKED_PNT:    /* packed pnt */
4812
4967
      head = SeqEdDeleteFromSeqLocPackedPnt (head, target, from, to, merge, changed);
4818
4973
        return head;
4819
4974
}
4820
4975
 
 
4976
 
4821
4977
NLM_EXTERN SeqFeatPtr 
4822
4978
SeqEdGetNextFeature 
4823
4979
(BioseqPtr bsp, 
4832
4988
{
4833
4989
  SMFeatItemPtr PNTR  array = NULL;
4834
4990
  BioseqExtraPtr      bspextra;
4835
 
  Int4               i;
 
4991
  Int4                i;
4836
4992
  SMFeatItemPtr       item;
4837
4993
  Int4                num = 0;
4838
4994
  ObjMgrDataPtr       omdp;
4843
4999
 
4844
5000
  /* if curr is NULL, initialize context fields (in user's stack) */
4845
5001
 
4846
 
 
4847
5002
  if (curr == NULL) {
4848
5003
    if (bsp == NULL) return NULL;
4849
5004
    omdp = (ObjMgrDataPtr) bsp->omdp;
4968
5123
  AffectedFeatPtr afp = NULL;
4969
5124
  SeqLocPtr       tmp_loc;
4970
5125
  Boolean         split_mode;
 
5126
  BioseqPtr       bsp;
 
5127
  Int4            insert_offset;
4971
5128
  
4972
5129
  if (sfp == NULL || sejp == NULL)
4973
5130
  {
4974
5131
    return;
4975
5132
  }
4976
 
  
 
5133
 
 
5134
  bsp = GetParentForSegment (sejp->bsp, &insert_offset, NULL);
 
5135
  if (bsp == NULL)
 
5136
  {
 
5137
    bsp = sejp->bsp;
 
5138
  }
 
5139
  else
 
5140
  {
 
5141
    insert_point += insert_offset;
 
5142
  }  
 
5143
 
4977
5144
  for (vnp = sejp->affected_feats; vnp != NULL && afp == NULL; vnp = vnp->next)
4978
5145
  {
4979
5146
    afp = (AffectedFeatPtr) vnp->data.ptrvalue;
5004
5171
  }
5005
5172
  else
5006
5173
  {
5007
 
    sfp->location = SeqEdSeqLocInsert (sfp->location, sejp->bsp, insert_point,
 
5174
    sfp->location = SeqEdSeqLocInsert (sfp->location, bsp, insert_point,
5008
5175
                                       sejp->num_chars, split_mode, NULL);
5009
5176
  }
5010
5177
        switch (sfp->data.choice)
5011
5178
        {
5012
5179
    case SEQFEAT_CDREGION:   /* cdregion */
5013
 
      SeqEdInsertAdjustCdRgn (sfp, sejp->bsp, insert_point, sejp->num_chars,
 
5180
      SeqEdInsertAdjustCdRgn (sfp, bsp, insert_point, sejp->num_chars,
5014
5181
                              split_mode);
5015
5182
      break;
5016
5183
    case SEQFEAT_RNA:
5017
 
      SeqEdInsertAdjustRNA (sfp, sejp->bsp, insert_point, sejp->num_chars,
 
5184
      SeqEdInsertAdjustRNA (sfp, bsp, insert_point, sejp->num_chars,
5018
5185
                            split_mode);
5019
5186
      break;
5020
5187
    default:
5022
5189
  }
5023
5190
}
5024
5191
 
5025
 
static Boolean IsDeltaSeqGap (DeltaSeqPtr dsp)
5026
 
{
5027
 
  SeqLitPtr   slip;
5028
 
  if (dsp == NULL || dsp->choice != 2 || dsp->data.ptrvalue == NULL)
5029
 
  {
5030
 
    return FALSE;
5031
 
  }
5032
 
  slip = (SeqLitPtr) (dsp->data.ptrvalue);
5033
 
  if (slip->seq_data == NULL)
5034
 
  {
5035
 
    return TRUE;
5036
 
  }
5037
 
  else
5038
 
  {
5039
 
    return FALSE;
5040
 
  }
5041
 
}
5042
 
 
5043
 
static Boolean IsDeltaSeqUnknownGap (DeltaSeqPtr dsp)
5044
 
{
5045
 
  SeqLitPtr   slip;
5046
 
  if (dsp == NULL || dsp->choice != 2 || dsp->data.ptrvalue == NULL)
5047
 
  {
5048
 
    return FALSE;
5049
 
  }
5050
 
  slip = (SeqLitPtr) (dsp->data.ptrvalue);
5051
 
  if (slip->seq_data == NULL && slip->fuzz != NULL && slip->fuzz->choice == 4)
5052
 
  {
5053
 
    return TRUE;
5054
 
  }
5055
 
  else
5056
 
  {
 
5192
extern Boolean IsDeltaSeqGap (DeltaSeqPtr dsp)
 
5193
{
 
5194
  SeqLitPtr   slip;
 
5195
  if (dsp == NULL || dsp->choice != 2 || dsp->data.ptrvalue == NULL)
 
5196
  {
 
5197
    return FALSE;
 
5198
  }
 
5199
  slip = (SeqLitPtr) (dsp->data.ptrvalue);
 
5200
  if (slip->seq_data == NULL || slip->seq_data_type == Seq_code_gap)
 
5201
  {
 
5202
    return TRUE;
 
5203
  }
 
5204
  else
 
5205
  {
 
5206
    return FALSE;
 
5207
  }
 
5208
}
 
5209
 
 
5210
extern Boolean IsDeltaSeqUnknownGap (DeltaSeqPtr dsp)
 
5211
{
 
5212
  SeqLitPtr   slip;
 
5213
  if (dsp == NULL || dsp->choice != 2 || dsp->data.ptrvalue == NULL)
 
5214
  {
 
5215
    return FALSE;
 
5216
  }
 
5217
  slip = (SeqLitPtr) (dsp->data.ptrvalue);
 
5218
  if ((slip->seq_data == NULL || slip->seq_data_type == Seq_code_gap) &&
 
5219
      slip->fuzz != NULL && slip->fuzz->choice == 4)
 
5220
  {
 
5221
    return TRUE;
 
5222
  }
 
5223
  else
 
5224
  {
 
5225
    return FALSE;
 
5226
  }
 
5227
}
 
5228
 
 
5229
 
 
5230
extern Boolean IsDeltaSeqKnownGap (DeltaSeqPtr dsp)
 
5231
{
 
5232
  SeqLitPtr   slip;
 
5233
  if (dsp == NULL || dsp->choice != 2 || dsp->data.ptrvalue == NULL)
 
5234
  {
 
5235
    return FALSE;
 
5236
  }
 
5237
  slip = (SeqLitPtr) (dsp->data.ptrvalue);
 
5238
  if ((slip->seq_data == NULL || slip->seq_data_type == Seq_code_gap) &&
 
5239
      slip->fuzz == NULL)
 
5240
  {
 
5241
    return TRUE;
 
5242
  }
 
5243
  else
 
5244
  {
 
5245
    return FALSE;
 
5246
  }
 
5247
}
 
5248
 
 
5249
 
 
5250
extern Boolean DoesSeqLitHaveGapTypeOrLinkage (SeqLitPtr slip)
 
5251
{
 
5252
  if (slip != NULL && slip->seq_data_type == Seq_code_gap) {
 
5253
    return TRUE;
 
5254
  } else {
 
5255
    return FALSE;
 
5256
  }
 
5257
}
 
5258
 
 
5259
extern Boolean DoesDeltaSeqHaveGapTypeOrLinkage (DeltaSeqPtr dsp)
 
5260
{
 
5261
  if (dsp != NULL && dsp->choice == 2) {
 
5262
    return DoesSeqLitHaveGapTypeOrLinkage ((SeqLitPtr) dsp->data.ptrvalue);
 
5263
  } else {
5057
5264
    return FALSE;
5058
5265
  }
5059
5266
}
5151
5358
static Boolean SeqEdInsertRaw (SeqEdJournalPtr sejp, Int4 insert_point)
5152
5359
{
5153
5360
  Boolean      rval;
 
5361
  BioseqPtr    bsp;
5154
5362
 
5155
5363
  if (sejp == NULL || sejp->bsp == NULL || sejp->bsp->repr != Seq_repr_raw 
5156
5364
      || sejp->char_data == NULL || sejp->num_chars == 0 || insert_point < 0) 
5157
5365
  {
5158
5366
    return FALSE;    
5159
5367
  }
 
5368
  if (sejp->bsp->seq_data_type == Seq_code_gap) return FALSE;
5160
5369
 
5161
 
  rval = SeqEdInsertByteStore (sejp->bsp->seq_data, insert_point, 
 
5370
  rval = SeqEdInsertByteStore ((ByteStorePtr) sejp->bsp->seq_data, insert_point, 
5162
5371
                               sejp->char_data, sejp->num_chars, sejp->moltype);
5163
5372
 
5164
5373
  if (rval)
5165
5374
  {
5166
5375
    sejp->bsp->length += sejp->num_chars;
 
5376
    bsp = GetParentForSegment (sejp->bsp, NULL, NULL);
 
5377
    if (bsp != NULL)
 
5378
    {
 
5379
      bsp->length += sejp->num_chars;
 
5380
    }
5167
5381
  }
5168
5382
  return rval;
5169
5383
}
5184
5398
    return rval;
5185
5399
  }
5186
5400
  slip = (SeqLitPtr) dsp->data.ptrvalue;
5187
 
  if (slip->seq_data != NULL)
 
5401
  if (slip->seq_data != NULL && slip->seq_data_type != Seq_code_gap)
5188
5402
  {
5189
5403
    return rval;
5190
5404
  }
5198
5412
  /* split the gap in two and create a new DeltaSeqPtr in the middle */
5199
5413
  slip_data = SeqLitNew ();
5200
5414
  slip_data->seq_data_type = Seq_code_iupacna;
5201
 
  slip_data->seq_data = BSNew (sejp->num_chars);
5202
 
  rval = SeqEdInsertByteStore (slip_data->seq_data, 0, 
 
5415
  slip_data->seq_data = (SeqDataPtr) BSNew (sejp->num_chars);
 
5416
  rval = SeqEdInsertByteStore ((ByteStorePtr) slip_data->seq_data, 0, 
5203
5417
                               sejp->char_data, sejp->num_chars, sejp->moltype);
5204
5418
  if (rval)
5205
5419
  {
5282
5496
  }
5283
5497
  else
5284
5498
  {
5285
 
    if (slip->seq_data_type != Seq_code_iupacna)
 
5499
    if (slip->seq_data_type != Seq_code_iupacna && slip->seq_data_type != Seq_code_gap)
5286
5500
    {
5287
 
      bs_new = BSConvertSeq(slip->seq_data, Seq_code_iupacna, 
 
5501
      bs_new = BSConvertSeq((ByteStorePtr) slip->seq_data, Seq_code_iupacna, 
5288
5502
                            slip->seq_data_type, 
5289
5503
                            slip->length);
5290
5504
      slip->seq_data_type = Seq_code_iupacna;
5291
 
      slip->seq_data = bs_new;
 
5505
      slip->seq_data = (SeqDataPtr) bs_new;
5292
5506
    }
5293
5507
 
5294
 
    rval = SeqEdInsertByteStore (slip->seq_data, insert_point, 
 
5508
    rval = SeqEdInsertByteStore ((ByteStorePtr) slip->seq_data, insert_point, 
5295
5509
                                 sejp->char_data, sejp->num_chars,
5296
5510
                                 sejp->moltype);
5297
5511
    if (rval)
5385
5599
    slip_after->seq_data_type = Seq_code_iupacna;
5386
5600
    slip_after->length = slip->length - insert_point;
5387
5601
    
5388
 
    if (slip->seq_data != NULL)
 
5602
    if (slip->seq_data != NULL && slip->seq_data_type != Seq_code_gap)
5389
5603
    {
5390
 
      if (slip->seq_data_type != Seq_code_iupacna)
 
5604
      if (slip->seq_data_type != Seq_code_iupacna && slip->seq_data_type != Seq_code_gap)
5391
5605
      {
5392
 
        bs_new = BSConvertSeq(slip->seq_data, Seq_code_iupacna, 
 
5606
        bs_new = BSConvertSeq((ByteStorePtr) slip->seq_data, Seq_code_iupacna, 
5393
5607
                              slip->seq_data_type, 
5394
5608
                              slip->length);
5395
5609
        slip->seq_data_type = Seq_code_iupacna;
5396
 
        slip->seq_data = bs_new;
 
5610
        slip->seq_data = (SeqDataPtr) bs_new;
5397
5611
      }
5398
 
      slip_before->seq_data = BSNew (slip_before->length);
5399
 
      slip_after->seq_data = BSNew (slip_after->length);
 
5612
      slip_before->seq_data = (SeqDataPtr) BSNew (slip_before->length);
 
5613
      slip_after->seq_data = (SeqDataPtr) BSNew (slip_after->length);
5400
5614
      
5401
 
      BSSeek(slip->seq_data, 0, SEEK_SET);
5402
 
      BSInsertFromBS (slip_before->seq_data, slip->seq_data, slip_before->length);
5403
 
      BSInsertFromBS (slip_after->seq_data, slip->seq_data, slip_after->length);
 
5615
      BSSeek((ByteStorePtr) slip->seq_data, 0, SEEK_SET);
 
5616
      BSInsertFromBS ((ByteStorePtr) slip_before->seq_data, (ByteStorePtr) slip->seq_data, slip_before->length);
 
5617
      BSInsertFromBS ((ByteStorePtr) slip_after->seq_data, (ByteStorePtr) slip->seq_data, slip_after->length);
5404
5618
    }
5405
5619
   
5406
5620
    dsp_after = ValNodeNew (NULL);
5434
5648
  Int4              insert_point;
5435
5649
  Boolean           recreated_feats = FALSE;
5436
5650
  Boolean           rval = FALSE;
 
5651
  BioseqPtr         bsp;
 
5652
  Int4              insert_offset = 0;
5437
5653
  
5438
5654
  if (sejp == NULL || sejp->bsp == NULL 
5439
5655
      || sejp->char_data == NULL || sejp->num_chars == 0) 
5477
5693
  if (sejp->entityID > 0 && SeqMgrFeaturesAreIndexed (sejp->entityID)) 
5478
5694
  {
5479
5695
    sfp = NULL;
5480
 
    while ((sfp = SeqEdGetNextFeature (sejp->bsp, sfp, 0, 0, &fcontext, FALSE, FALSE, sejp->entityID)) != NULL)
 
5696
    bsp = GetParentForSegment (sejp->bsp, &insert_offset, NULL);
 
5697
    if (bsp == NULL)
 
5698
    {
 
5699
      bsp = sejp->bsp;
 
5700
    }
 
5701
    
 
5702
    while ((sfp = SeqEdGetNextFeature (bsp, sfp, 0, 0, &fcontext, FALSE, FALSE, sejp->entityID)) != NULL)
5481
5703
    {
5482
5704
      SeqEdInsertAdjustFeat (sfp, sejp, insert_point);
5483
5705
          }
5484
5706
 
 
5707
    if (bsp != sejp->bsp)
 
5708
    {
 
5709
      insert_point += insert_offset;
 
5710
    }
 
5711
 
5485
5712
          /* adjust features pointing by product */
5486
5713
          prods = SeqMgrGetSfpProductList (sejp->bsp);
5487
5714
          for (vnp = prods; vnp != NULL; vnp = vnp->next) 
5488
5715
          {
5489
5716
      sfp = (SeqFeatPtr) vnp->data.ptrvalue;
5490
5717
      if (sfp == NULL) continue;
5491
 
      sfp->product = SeqEdSeqLocInsert (sfp->product, sejp->bsp, insert_point, sejp->num_chars, sejp->spliteditmode, NULL);
 
5718
      sfp->product = SeqEdSeqLocInsert (sfp->product, bsp, insert_point, sejp->num_chars, sejp->spliteditmode, NULL);
5492
5719
          }
5493
5720
  } else {
5494
5721
    bcp = BioseqContextNew(sejp->bsp);
5672
5899
    to = slip->length - 1;
5673
5900
  }
5674
5901
  
5675
 
  if (slip->seq_data != NULL)
 
5902
  if (slip->seq_data != NULL && slip->seq_data_type != Seq_code_gap)
5676
5903
  {
5677
 
    if (slip->seq_data_type != Seq_code_iupacna)
 
5904
    if (slip->seq_data_type != Seq_code_iupacna && slip->seq_data_type != Seq_code_gap)
5678
5905
    {
5679
 
      bs_new = BSConvertSeq(slip->seq_data, Seq_code_iupacna, 
 
5906
      bs_new = BSConvertSeq((ByteStorePtr) slip->seq_data, Seq_code_iupacna, 
5680
5907
                            slip->seq_data_type, 
5681
5908
                            slip->length);
5682
5909
      slip->seq_data_type = Seq_code_iupacna;
5683
 
      slip->seq_data = bs_new;
 
5910
      slip->seq_data = (SeqDataPtr) bs_new;
5684
5911
    }
5685
 
    BSSeek(slip->seq_data, from, SEEK_SET);
5686
 
    Nlm_BSDelete (slip->seq_data, to - from + 1);    
 
5912
    BSSeek((ByteStorePtr) slip->seq_data, from, SEEK_SET);
 
5913
    Nlm_BSDelete ((ByteStorePtr) slip->seq_data, to - from + 1);    
5687
5914
  }
5688
5915
  slip->length -= (to - from + 1);
5689
5916
}
6069
6296
  SeqFeatPtr        tmp_sfp;
6070
6297
  AffectedFeatPtr   afp;
6071
6298
  Boolean           merge_mode;
6072
 
  Boolean           location_restitched = FALSE;
 
6299
  Boolean           location_restitched = FALSE, adjusted_master = FALSE;
 
6300
  BioseqPtr         bsp;
 
6301
  Int4              cut_offset = 0, offset = 0;
6073
6302
 
6074
6303
  if (sejp == NULL || sejp->bsp == NULL || sejp->offset < 0 || sejp->offset >= sejp->bsp->length
6075
6304
          || sejp->offset + sejp->num_chars + 1 < 0 || sejp->offset + sejp->num_chars > sejp->bsp->length
6082
6311
  {
6083
6312
    sejp->affected_feats = SeqEdJournalAffectedFeatsFree (sejp->affected_feats);
6084
6313
  }
 
6314
 
 
6315
  bsp = GetParentForSegment (sejp->bsp, &offset, NULL);
 
6316
  if (bsp == NULL)
 
6317
  {
 
6318
    bsp = sejp->bsp;
 
6319
    cut_offset = sejp->offset;
 
6320
  }
 
6321
  else
 
6322
  {
 
6323
    cut_offset = sejp->offset + offset;
 
6324
  }
6085
6325
  
6086
6326
  /* fix features */
6087
6327
  if (sejp->entityID > 0 && SeqMgrFeaturesAreIndexed (sejp->entityID)) {
 
6328
 
6088
6329
    sfp = NULL;
6089
 
    while ((sfp = SeqEdGetNextFeature (sejp->bsp, sfp, 0, 0, &fcontext, FALSE, FALSE, sejp->entityID)) != NULL)
 
6330
    while ((sfp = SeqEdGetNextFeature (bsp, sfp, 0, 0, &fcontext, FALSE, FALSE, sejp->entityID)) != NULL)
6090
6331
    {
6091
 
      if ((sejp->offset <= fcontext.left && sejp->offset + sejp->num_chars >= fcontext.left)
6092
 
          || (sejp->offset >= fcontext.left && sejp->offset + sejp->num_chars <= fcontext.right)
6093
 
          || (sejp->offset <= fcontext.right && sejp->offset + sejp->num_chars >= fcontext.right))
 
6332
      if ((cut_offset <= fcontext.left && cut_offset + sejp->num_chars >= fcontext.left)
 
6333
          || (cut_offset >= fcontext.left && cut_offset + sejp->num_chars <= fcontext.right)
 
6334
          || (cut_offset <= fcontext.right && cut_offset + sejp->num_chars >= fcontext.right))
6094
6335
      {
6095
6336
        tmp_sfp = (SeqFeatPtr)AsnIoMemCopy((Pointer)sfp, (AsnReadFunc)SeqFeatAsnRead, (AsnWriteFunc)SeqFeatAsnWrite);        
6096
6337
      }
6107
6348
        merge_mode = TRUE;
6108
6349
      }
6109
6350
 
6110
 
      feat_change = SeqEdSeqFeatDelete (sfp, sejp->bsp, sejp->offset, 
6111
 
                                        sejp->offset + sejp->num_chars - 1,
 
6351
      feat_change = SeqEdSeqFeatDelete (sfp, bsp, cut_offset, 
 
6352
                                        cut_offset + sejp->num_chars - 1,
6112
6353
                                        sejp->spliteditmode);
6113
6354
                                        
6114
6355
      if (feat_change == 0 || feat_change == 1)
6115
6356
      {
6116
 
        if (ReStitchLocation (sejp->offset, sfp))
 
6357
        if (ReStitchLocation (cut_offset, sfp))
6117
6358
        {
6118
6359
          feat_change = 1;
6119
6360
          location_restitched = TRUE;
6149
6390
            {
6150
6391
              SeqFeatFree (tmp_sfp);
6151
6392
            }
 
6393
      if (bsp != sejp->bsp)
 
6394
      {
 
6395
        adjusted_master = TRUE;
 
6396
      }
6152
6397
          }
6153
 
 
6154
6398
  } else {
6155
6399
    bcp = BioseqContextNew(sejp->bsp);
6156
6400
    sfp = NULL;
6166
6410
      {
6167
6411
        merge_mode = TRUE;
6168
6412
      }      
6169
 
      feat_change = SeqEdSeqFeatDelete (sfp, sejp->bsp, sejp->offset, 
6170
 
                                        sejp->offset + sejp->num_chars - 1, 
 
6413
      feat_change = SeqEdSeqFeatDelete (sfp, bsp, cut_offset, 
 
6414
                                        cut_offset + sejp->num_chars - 1, 
6171
6415
                                        sejp->spliteditmode);
6172
6416
 
6173
6417
      if (feat_change == 0 || feat_change == 1)
6174
6418
      {
6175
 
        if (ReStitchLocation (sejp->offset, sfp))
 
6419
        if (ReStitchLocation (cut_offset, sfp))
6176
6420
        {
6177
6421
          feat_change = 1;
6178
6422
          location_restitched = TRUE;
6209
6453
  {
6210
6454
    case Seq_repr_raw:
6211
6455
    case Seq_repr_const:
6212
 
      /* if actual sequence present */
6213
 
      if (ISA_na(sejp->bsp->mol))
6214
 
      {
6215
 
        if (sejp->bsp->seq_data_type != Seq_code_iupacna)  /* need 1 byte/base */
6216
 
          BioseqRawConvert(sejp->bsp, Seq_code_iupacna);
6217
 
            }
6218
 
      else
6219
 
      {
6220
 
        if (sejp->bsp->seq_data_type != Seq_code_ncbieaa)
6221
 
          BioseqRawConvert(sejp->bsp, Seq_code_ncbieaa);
 
6456
      if (sejp->bsp->seq_data_type != Seq_code_gap) {
 
6457
        /* if actual sequence present */
 
6458
        if (ISA_na(sejp->bsp->mol))
 
6459
        {
 
6460
          if (sejp->bsp->seq_data_type != Seq_code_iupacna)  /* need 1 byte/base */
 
6461
            BioseqRawConvert(sejp->bsp, Seq_code_iupacna);
 
6462
              }
 
6463
        else
 
6464
        {
 
6465
          if (sejp->bsp->seq_data_type != Seq_code_ncbieaa)
 
6466
            BioseqRawConvert(sejp->bsp, Seq_code_ncbieaa);
 
6467
        }
 
6468
 
 
6469
        BSSeek((ByteStorePtr) sejp->bsp->seq_data, sejp->offset, SEEK_SET);
 
6470
        deleted = BSDelete((ByteStorePtr) sejp->bsp->seq_data, sejp->num_chars);
 
6471
        if (deleted != sejp->num_chars)  /* error */
 
6472
          ErrPost(CTX_NCBIOBJ, 1, "Delete of %ld residues failed", sejp->num_chars);
 
6473
        else
 
6474
          retval = TRUE;
6222
6475
      }
6223
 
 
6224
 
      BSSeek(sejp->bsp->seq_data, sejp->offset, SEEK_SET);
6225
 
      deleted = BSDelete(sejp->bsp->seq_data, sejp->num_chars);
6226
 
      if (deleted != sejp->num_chars)  /* error */
6227
 
        ErrPost(CTX_NCBIOBJ, 1, "Delete of %ld residues failed", sejp->num_chars);
6228
 
      else
6229
 
        retval = TRUE;
6230
6476
      break;
6231
6477
    case Seq_repr_seg:
6232
6478
      /* update segmented sequence */
6246
6492
  }
6247
6493
 
6248
6494
  if (retval)
 
6495
  {
6249
6496
    sejp->bsp->length -= sejp->num_chars;
 
6497
    if (bsp != sejp->bsp)
 
6498
    {
 
6499
      bsp->length -= sejp->num_chars;
 
6500
    }
 
6501
  }
6250
6502
  
6251
6503
  if (feats_deleted)
6252
6504
  {
6253
6505
    DeleteMarkedObjects (sejp->entityID, 0, NULL);
6254
6506
    SeqMgrIndexFeatures (sejp->entityID, NULL);
6255
6507
  }
6256
 
  else if (location_restitched)
 
6508
  else if (location_restitched || adjusted_master)
6257
6509
  {
6258
6510
    SeqMgrIndexFeatures (sejp->entityID, NULL);
6259
6511
  }