1 /* @source enssequenceedit ****************************************************
2 **
3 ** Ensembl Sequence Edit functions
4 **
5 ** @author Copyright (C) 1999 Ensembl Developers
6 ** @author Copyright (C) 2006 Michael K. Schuster
7 ** @version $Revision: 1.35 $
8 ** @modified 2009 by Alan Bleasby for incorporation into EMBOSS core
9 ** @modified $Date: 2013/02/17 13:02:40 $ by $Author: mks $
10 ** @@
11 **
12 ** This library is free software; you can redistribute it and/or
13 ** modify it under the terms of the GNU Lesser General Public
14 ** License as published by the Free Software Foundation; either
15 ** version 2.1 of the License, or (at your option) any later version.
16 **
17 ** This library is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ** Lesser General Public License for more details.
21 **
22 ** You should have received a copy of the GNU Lesser General Public
23 ** License along with this library; if not, write to the Free Software
24 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 ** MA 02110-1301, USA.
26 **
27 ******************************************************************************/
28
29 /* ========================================================================= */
30 /* ============================= include files ============================= */
31 /* ========================================================================= */
32
33 #include "enssequenceedit.h"
34
35
36
37
38 /* ========================================================================= */
39 /* =============================== constants =============================== */
40 /* ========================================================================= */
41
42
43
44
45 /* ========================================================================= */
46 /* =========================== global variables ============================ */
47 /* ========================================================================= */
48
49
50
51
52 /* ========================================================================= */
53 /* ============================= private data ============================== */
54 /* ========================================================================= */
55
56
57
58
59 /* ========================================================================= */
60 /* =========================== private constants =========================== */
61 /* ========================================================================= */
62
63
64
65
66 /* ========================================================================= */
67 /* =========================== private variables =========================== */
68 /* ========================================================================= */
69
70
71
72
73 /* ========================================================================= */
74 /* =========================== private functions =========================== */
75 /* ========================================================================= */
76
77 static int listSequenceeditCompareStartAscending(
78 const void *item1,
79 const void *item2);
80
81 static int listSequenceeditCompareStartDescending(
82 const void *item1,
83 const void *item2);
84
85
86
87
88 /* ========================================================================= */
89 /* ======================= All functions by section ======================== */
90 /* ========================================================================= */
91
92
93
94
95 /* @filesection enssequenceedit ***********************************************
96 **
97 ** @nam1rule ens Function belongs to the Ensembl library
98 **
99 ******************************************************************************/
100
101
102
103
104 /* @datasection [EnsPSequenceedit] Ensembl Sequence Edit **********************
105 **
106 ** @nam2rule Sequenceedit Functions for manipulating
107 ** Ensembl Sequence Edit objects
108 **
109 ** @cc Bio::EnsEMBL::SeqEdit
110 ** @cc CVS Revision: 1.8
111 ** @cc CVS Tag: branch-ensembl-68
112 **
113 ******************************************************************************/
114
115
116
117
118 /* @section constructors ******************************************************
119 **
120 ** All constructors return a new Ensembl Sequence Edit by pointer.
121 ** It is the responsibility of the user to first destroy any previous
122 ** Sequence Edit. The target pointer does not need to be initialised to
123 ** NULL, but it is good programming practice to do so anyway.
124 **
125 ** @fdata [EnsPSequenceedit]
126 **
127 ** @nam3rule New Constructor
128 ** @nam4rule Attribute Constructor with an Ensembl Attribute object
129 ** @nam4rule Cpy Constructor with existing object
130 ** @nam4rule Ini Constructor with initial values
131 ** @nam4rule Ref Constructor by incrementing the reference counter
132 **
133 ** @argrule Attribute attribute [EnsPAttribute] Ensembl Attribute
134 ** @argrule Cpy se [const EnsPSequenceedit] Ensembl Sequence Edit
135 ** @argrule Ini at [EnsPAttributetype] Ensembl Attribute Type
136 ** @argrule Ini sequence [AjPStr] Alternative sequence
137 ** @argrule Ini start [ajuint] Start coordinate
138 ** @argrule Ini end [ajuint] End coordinate
139 ** @argrule Ref se [EnsPSequenceedit] Ensembl Sequence Edit
140 **
141 ** @valrule * [EnsPSequenceedit] Ensembl Sequence Edit or NULL
142 **
143 ** @fcategory new
144 ******************************************************************************/
145
146
147
148
149 /* @func ensSequenceeditNewAttribute ******************************************
150 **
151 ** Constructor for an Ensembl Sequence Edit with an Ensembl Attribute.
152 **
153 ** @cc Bio::EnsEMBL:SeqEdit::new
154 ** @param [u] attribute [EnsPAttribute] Ensembl Attribute
155 **
156 ** @return [EnsPSequenceedit] Ensembl Sequence Edit or NULL
157 **
158 ** @release 6.4.0
159 ** @@
160 ******************************************************************************/
161
ensSequenceeditNewAttribute(EnsPAttribute attribute)162 EnsPSequenceedit ensSequenceeditNewAttribute(EnsPAttribute attribute)
163 {
164 ajint start = 0;
165 ajint end = 0;
166
167 AjPStr altseq = NULL;
168
169 EnsPSequenceedit se = NULL;
170
171 if (!attribute)
172 return NULL;
173
174 altseq = ajStrNew();
175
176 ajFmtScanS(attribute->Value, "%d %d %S", &start, &end, &altseq);
177
178 if (start > (end + 1))
179 {
180 ajDebug("ensSequenceeditNewAttribute start %d must be less than or "
181 "equal to end %d + 1 in Ensembl Attribute value '%S'.\n",
182 start, end, attribute->Value);
183
184 return NULL;
185 }
186
187 if (start < 1)
188 {
189 ajDebug("ensSequenceeditNewAttribute start %d must be greater than or "
190 "equal to 1 in Ensembl Attribute value '%S'.\n",
191 start, attribute->Value);
192
193 return NULL;
194 }
195
196 if (end < 0)
197 {
198 ajDebug("ensSequenceeditNewAttribute end %d must be greater than or "
199 "equal to 0 in Ensembl Attribute value '%S' .\n",
200 end, attribute->Value);
201
202 return NULL;
203 }
204
205 AJNEW0(se);
206
207 se->Attribute = ensAttributeNewRef(attribute);
208
209 if (altseq)
210 se->Sequence = ajStrNewRef(altseq);
211 else
212 se->Sequence = ajStrNew();
213
214 se->Start = start;
215
216 se->End = end;
217
218 se->Use = 1U;
219
220 ajStrDel(&altseq);
221
222 return se;
223 }
224
225
226
227
228 /* @func ensSequenceeditNewCpy ************************************************
229 **
230 ** Object-based constructor function, which returns an independent object.
231 **
232 ** @param [r] se [const EnsPSequenceedit] Ensembl Sequence Edit
233 **
234 ** @return [EnsPSequenceedit] Ensembl Sequence Edit or NULL
235 **
236 ** @release 6.4.0
237 ** @@
238 ******************************************************************************/
239
ensSequenceeditNewCpy(const EnsPSequenceedit se)240 EnsPSequenceedit ensSequenceeditNewCpy(const EnsPSequenceedit se)
241 {
242 EnsPSequenceedit pthis = NULL;
243
244 AJNEW0(pthis);
245
246 pthis->Attribute = ensAttributeNewRef(se->Attribute);
247
248 if (se->Sequence)
249 pthis->Sequence = ajStrNewRef(se->Sequence);
250
251 pthis->Start = se->Start;
252
253 pthis->End = se->End;
254
255 pthis->Use = 1U;
256
257 return pthis;
258 }
259
260
261
262
263 /* @func ensSequenceeditNewIni ************************************************
264 **
265 ** Ensembl Sequence Edit constructor with initial values.
266 **
267 ** @cc Bio::EnsEMBL:SeqEdit::new
268 ** @param [u] at [EnsPAttributetype] Ensembl Attribute Type
269 ** @param [u] sequence [AjPStr] Alternative sequence
270 ** @param [r] start [ajuint] Start coordinate
271 ** @param [r] end [ajuint] End coordinate
272 **
273 ** @return [EnsPSequenceedit] Ensembl Sequence Edit or NULL
274 **
275 ** @release 6.4.0
276 ** @@
277 ******************************************************************************/
278
ensSequenceeditNewIni(EnsPAttributetype at,AjPStr sequence,ajuint start,ajuint end)279 EnsPSequenceedit ensSequenceeditNewIni(EnsPAttributetype at,
280 AjPStr sequence,
281 ajuint start,
282 ajuint end)
283 {
284 AjPStr value = NULL;
285
286 EnsPSequenceedit se = NULL;
287
288 if (!sequence)
289 {
290 ajDebug("ensSequenceeditNewIni requires an alternate sequence.\n");
291
292 return NULL;
293 }
294
295 if (start > (end + 1))
296 {
297 ajDebug("ensSequenceeditNewIni start %d must be less than or "
298 "equal to end %d + 1.\n", start, end);
299
300 return NULL;
301 }
302
303 if (start < 1)
304 {
305 ajDebug("ensSequenceeditNewIni start %d must be greater than or "
306 "equal to 1.\n", start);
307
308 return NULL;
309 }
310
311 value = ajFmtStr("%u %u %S", start, end, sequence);
312
313 AJNEW0(se);
314
315 se->Attribute = ensAttributeNewIni(at, value);
316
317 if (sequence)
318 se->Sequence = ajStrNewRef(sequence);
319 else
320 se->Sequence = ajStrNew();
321
322 se->Start = start;
323 se->End = end;
324 se->Use = 1U;
325
326 ajStrDel(&value);
327
328 return se;
329 }
330
331
332
333
334 /* @func ensSequenceeditNewRef ************************************************
335 **
336 ** Ensembl Object referencing function, which returns a pointer to the
337 ** Ensembl Object passed in and increases its reference count.
338 **
339 ** @param [u] se [EnsPSequenceedit] Ensembl Sequence Edit
340 **
341 ** @return [EnsPSequenceedit] Ensembl Sequence Edit or NULL
342 **
343 ** @release 6.4.0
344 ** @@
345 ******************************************************************************/
346
ensSequenceeditNewRef(EnsPSequenceedit se)347 EnsPSequenceedit ensSequenceeditNewRef(EnsPSequenceedit se)
348 {
349 if (!se)
350 return NULL;
351
352 se->Use++;
353
354 return se;
355 }
356
357
358
359
360 /* @section destructors *******************************************************
361 **
362 ** Destruction destroys all internal data structures and frees the memory
363 ** allocated for an Ensembl Sequence Edit object.
364 **
365 ** @fdata [EnsPSequenceedit]
366 **
367 ** @nam3rule Del Destroy (free) an Ensembl Sequence Edit
368 **
369 ** @argrule * Pse [EnsPSequenceedit*] Ensembl Sequence Edit address
370 **
371 ** @valrule * [void]
372 **
373 ** @fcategory delete
374 ******************************************************************************/
375
376
377
378
379 /* @func ensSequenceeditDel ***************************************************
380 **
381 ** Default destructor for an Ensembl Sequence Edit.
382 **
383 ** @param [d] Pse [EnsPSequenceedit*] Ensembl Sequence Edit address
384 **
385 ** @return [void]
386 **
387 ** @release 6.4.0
388 ** @@
389 ******************************************************************************/
390
ensSequenceeditDel(EnsPSequenceedit * Pse)391 void ensSequenceeditDel(EnsPSequenceedit *Pse)
392 {
393 EnsPSequenceedit pthis = NULL;
394
395 if (!Pse)
396 return;
397
398 #if defined(AJ_DEBUG) && AJ_DEBUG >= 1
399 if (ajDebugTest("ensSequenceeditDel"))
400 {
401 ajDebug("ensSequenceeditDel\n"
402 " *Pse %p\n",
403 *Pse);
404
405 ensSequenceeditTrace(*Pse, 1);
406 }
407 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 1 */
408
409 if (!(pthis = *Pse) || --pthis->Use)
410 {
411 *Pse = NULL;
412
413 return;
414 }
415
416 ensAttributeDel(&pthis->Attribute);
417
418 ajStrDel(&pthis->Sequence);
419
420 ajMemFree((void **) Pse);
421
422 return;
423 }
424
425
426
427
428 /* @section member retrieval **************************************************
429 **
430 ** Functions for returning members of an Ensembl Sequence Edit object.
431 **
432 ** @fdata [EnsPSequenceedit]
433 **
434 ** @nam3rule Get Return Sequence Edit attribute(s)
435 ** @nam4rule Attribute Return the Ensembl Attribute
436 ** @nam4rule Sequence Return the alternate sequence
437 ** @nam4rule Start Return the description
438 ** @nam4rule End Return the value
439 **
440 ** @argrule * se [const EnsPSequenceedit] Sequence Edit
441 **
442 ** @valrule Attribute [EnsPAttribute] Ensembl Attribute or NULL
443 ** @valrule Sequence [AjPStr] Alternate sequence or NULL
444 ** @valrule Start [ajuint] Start coordinate or 0U
445 ** @valrule End [ajuint] End coordinate or 0U
446 **
447 ** @fcategory use
448 ******************************************************************************/
449
450
451
452
453 /* @func ensSequenceeditGetAttribute ******************************************
454 **
455 ** Get the Ensembl Attribute member of an Ensembl Sequence Edit.
456 **
457 ** @cc Bio::EnsEMBL:SeqEdit::get_Attribute
458 ** @param [r] se [const EnsPSequenceedit] Ensembl Sequence Edit
459 **
460 ** @return [EnsPAttribute] Ensembl Attribute or NULL
461 **
462 ** @release 6.4.0
463 ** @@
464 ******************************************************************************/
465
ensSequenceeditGetAttribute(const EnsPSequenceedit se)466 EnsPAttribute ensSequenceeditGetAttribute(const EnsPSequenceedit se)
467 {
468 return (se) ? se->Attribute : NULL;
469 }
470
471
472
473
474 /* @func ensSequenceeditGetEnd ************************************************
475 **
476 ** Get the end coordinate member of an Ensembl Sequence Edit.
477 **
478 ** Coordinates are inclusive and one-based, which means that inserts are
479 ** unusually represented by a start one base pair higher than the end. Hence,
480 ** start = 1, end = 1 is a replacement of the first base, but
481 ** start = 1, end = 0 is an insert BEFORE the first base.
482 **
483 ** @cc Bio::EnsEMBL:SeqEdit::end
484 ** @param [r] se [const EnsPSequenceedit] Ensembl Sequence Edit
485 **
486 ** @return [ajuint] End coordinate or 0U
487 **
488 ** @release 6.4.0
489 ** @@
490 ******************************************************************************/
491
ensSequenceeditGetEnd(const EnsPSequenceedit se)492 ajuint ensSequenceeditGetEnd(const EnsPSequenceedit se)
493 {
494 return (se) ? se->End : 0U;
495 }
496
497
498
499
500 /* @func ensSequenceeditGetSequence *******************************************
501 **
502 ** Get the (alternative) sequence member of an Ensembl Sequence Edit.
503 **
504 ** The sequence may either be a string of amino acids or nucleotides depending
505 ** on the context in which this Sequence Edit is used.
506 ** In the case of a deletion the replacement sequence is an empty string.
507 **
508 ** @cc Bio::EnsEMBL:SeqEdit::alt_seq
509 ** @param [r] se [const EnsPSequenceedit] Ensembl Sequence Edit
510 **
511 ** @return [AjPStr] Alternative sequence or NULL
512 **
513 ** @release 6.4.0
514 ** @@
515 ******************************************************************************/
516
ensSequenceeditGetSequence(const EnsPSequenceedit se)517 AjPStr ensSequenceeditGetSequence(const EnsPSequenceedit se)
518 {
519 return (se) ? se->Sequence : NULL;
520 }
521
522
523
524
525 /* @func ensSequenceeditGetStart **********************************************
526 **
527 ** Get the start coordinate member of an Ensembl Sequence Edit.
528 **
529 ** Coordinates are inclusive and one-based, which means that inserts are
530 ** unusually represented by a start one base pair higher than the end. Hence,
531 ** start = 1, end = 1 is a replacement of the first base, but
532 ** start = 1, end = 0 is an insert BEFORE the first base.
533 **
534 ** @cc Bio::EnsEMBL:SeqEdit::start
535 ** @param [r] se [const EnsPSequenceedit] Ensembl Sequence Edit
536 **
537 ** @return [ajuint] Start coordinate or 0U
538 **
539 ** @release 6.4.0
540 ** @@
541 ******************************************************************************/
542
ensSequenceeditGetStart(const EnsPSequenceedit se)543 ajuint ensSequenceeditGetStart(const EnsPSequenceedit se)
544 {
545 return (se) ? se->Start : 0U;
546 }
547
548
549
550
551 /* @section debugging *********************************************************
552 **
553 ** Functions for reporting of an Ensembl Sequence Edit object.
554 **
555 ** @fdata [EnsPSequenceedit]
556 **
557 ** @nam3rule Trace Report Ensembl Sequence Edit members to debug file
558 **
559 ** @argrule Trace se [const EnsPSequenceedit] Ensembl Sequence Edit
560 ** @argrule Trace level [ajuint] Indentation level
561 **
562 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
563 **
564 ** @fcategory misc
565 ******************************************************************************/
566
567
568
569
570 /* @func ensSequenceeditTrace *************************************************
571 **
572 ** Trace an Ensembl Sequence Edit.
573 **
574 ** @param [r] se [const EnsPSequenceedit] Ensembl Sequence Edit
575 ** @param [r] level [ajuint] Indentation level
576 **
577 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
578 **
579 ** @release 6.4.0
580 ** @@
581 ******************************************************************************/
582
ensSequenceeditTrace(const EnsPSequenceedit se,ajuint level)583 AjBool ensSequenceeditTrace(const EnsPSequenceedit se, ajuint level)
584 {
585 AjPStr indent = NULL;
586
587 if (!se)
588 return ajFalse;
589
590 indent = ajStrNew();
591
592 ajStrAppendCountK(&indent, ' ', level * 2);
593
594 ajDebug("%SensSequenceeditTrace %p\n"
595 "%S Attribute %p\n"
596 "%S Sequence '%S'\n"
597 "%S Start %u\n"
598 "%S End %u\n"
599 "%S Use %u\n",
600 indent, se,
601 indent, se->Attribute,
602 indent, se->Sequence,
603 indent, se->Start,
604 indent, se->End,
605 indent, se->Use);
606
607 ensAttributeTrace(se->Attribute, level + 1);
608
609 ajStrDel(&indent);
610
611 return ajTrue;
612 }
613
614
615
616
617 /* @section calculate *********************************************************
618 **
619 ** Functions for calculating information from an Ensembl Sequence Edit object.
620 **
621 ** @fdata [EnsPSequenceedit]
622 **
623 ** @nam3rule Calculate Calculate Ensembl Sequence Edit information
624 ** @nam4rule Difference Calculate the length difference
625 ** @nam4rule Memsize Calculate the memory size in bytes
626 **
627 ** @argrule * se [const EnsPSequenceedit] Ensembl Sequence Edit
628 **
629 ** @valrule Difference [ajint] Length difference or 0
630 ** @valrule Memsize [size_t] Memory size in bytes or 0
631 **
632 ** @fcategory misc
633 ******************************************************************************/
634
635
636
637
638 /* @func ensSequenceeditCalculateDifference ***********************************
639 **
640 ** Calculate the length difference an Ensembl Sequence Edit would cause.
641 **
642 ** @cc Bio::EnsEMBL:SeqEdit::length_diff
643 ** @param [r] se [const EnsPSequenceedit] Ensembl Sequence Edit
644 **
645 ** @return [ajint] Length difference or 0
646 **
647 ** @release 6.4.0
648 ** @@
649 ******************************************************************************/
650
ensSequenceeditCalculateDifference(const EnsPSequenceedit se)651 ajint ensSequenceeditCalculateDifference(const EnsPSequenceedit se)
652 {
653 const char *Ptr = NULL;
654
655 register ajuint i = 0U;
656
657 if (!se)
658 return 0;
659
660 /*
661 ** NOTE: Since ajStrGetLen returns size_t, which exceeds ajint,
662 ** the length of the alternative sequence needs to be determined here.
663 **
664 ** return ajStrGetLen(se->Sequence) - (se->End - se->Start + 1);
665 */
666
667 for (i = 0U, Ptr = ajStrGetPtr(se->Sequence); (Ptr && *Ptr); i++, Ptr++)
668 if (i == UINT_MAX)
669 ajFatal("ensSequenceeditCalculateDifference exeeded UINT_MAX.");
670
671 return i - (se->End - se->Start + 1);
672 }
673
674
675
676
677 /* @func ensSequenceeditCalculateMemsize **************************************
678 **
679 ** Calculate the memory size in bytes of an Ensembl Sequence Edit.
680 **
681 ** @param [r] se [const EnsPSequenceedit] Ensembl Sequence Edit
682 **
683 ** @return [size_t] Memory size in bytes or 0
684 **
685 ** @release 6.4.0
686 ** @@
687 ******************************************************************************/
688
ensSequenceeditCalculateMemsize(const EnsPSequenceedit se)689 size_t ensSequenceeditCalculateMemsize(const EnsPSequenceedit se)
690 {
691 size_t size = 0;
692
693 if (!se)
694 return 0;
695
696 size += sizeof (EnsOSequenceedit);
697
698 size += ensAttributeCalculateMemsize(se->Attribute);
699
700 if (se->Sequence)
701 {
702 size += sizeof (AjOStr);
703
704 size += ajStrGetRes(se->Sequence);
705 }
706
707 return size;
708 }
709
710
711
712
713 /* @section apply *************************************************************
714 **
715 ** Functions for applying Ensembl Sequence Edit objects.
716 **
717 ** @fdata [EnsPSequenceedit]
718 **
719 ** @nam3rule Apply Apply Ensembl Sequence Edit objects
720 ** @nam4rule String Apply an Ensembl Sequence Edit to an AJAX String
721 **
722 ** @argrule String se [const EnsPSequenceedit] Ensembl Sequence Edit
723 ** @argrule String offset [ajint] Offset into sequence
724 ** @argrule String Psequence [AjPStr*] Sequence address
725 **
726 ** @valrule String [AjBool] ajTrue upon success, ajFalse otherwise
727 **
728 ** @fcategory misc
729 ******************************************************************************/
730
731
732
733
734 /* @func ensSequenceeditApplyString *******************************************
735 **
736 ** Apply an Ensembl Sequence Edit to an AJAX String.
737 **
738 ** @cc Bio::EnsEMBL:SeqEdit::apply_edit
739 ** @cc Bio::EnsEMBL::DBSQL::SequenceAdaptor::_rna_edit
740 ** @param [r] se [const EnsPSequenceedit] Ensembl Sequence Edit
741 ** @param [rE] offset [ajint] Offset into sequence
742 ** @param [u] Psequence [AjPStr*] Sequence address
743 **
744 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
745 **
746 ** @release 6.4.0
747 ** @@
748 ******************************************************************************/
749
ensSequenceeditApplyString(const EnsPSequenceedit se,ajint offset,AjPStr * Psequence)750 AjBool ensSequenceeditApplyString(const EnsPSequenceedit se,
751 ajint offset,
752 AjPStr *Psequence)
753 {
754 ajlong pos1 = 0;
755 ajlong pos2 = 0;
756
757 if (!se)
758 return ajFalse;
759
760 if (!Psequence)
761 return ajFalse;
762
763 if (!*Psequence)
764 return ajFalse;
765
766 pos1 = se->Start - offset;
767 pos2 = se->End - offset;
768
769 if (pos2 < 1)
770 {
771 ajDebug("ensSequenceeditApplyString got an Ensembl Sequence Edit, "
772 "which end position (%d) corrected for the offset (%d) lies "
773 "beyond the sequence start (1).",
774 se->End, offset);
775
776 return ajFalse;
777 }
778
779 if (pos1 > (ajlong) ajStrGetLen(*Psequence))
780 {
781 ajDebug("ensSequenceeditApplyString got an Ensembl Sequence Edit, "
782 "which start position (%d) corrected for the offset (%d) lies "
783 "beyond the sequence end (%lu).",
784 se->Start, offset, ajStrGetLen(*Psequence));
785 /* FIXME: size_t can be shorter than ajulong */
786
787 return ajFalse;
788 }
789
790 /* Adjust to zero-based coordinates. */
791
792 ajStrCutRange(Psequence, pos1 - 1, pos2 - 1);
793
794 ajStrInsertS(Psequence, pos1 - 1, se->Sequence);
795
796 return ajTrue;
797 }
798
799
800
801
802 /* @datasection [AjPList] AJAX List *******************************************
803 **
804 ** @nam2rule List Functions for manipulating AJAX List objects
805 **
806 ******************************************************************************/
807
808
809
810
811 /* @funcstatic listSequenceeditCompareStartAscending **************************
812 **
813 ** AJAX List of Ensembl Sequence Edit objects comparison function to sort by
814 ** start member in ascending order.
815 **
816 ** @param [r] item1 [const void*] Ensembl Sequence Edit address 1
817 ** @param [r] item2 [const void*] Ensembl Sequence Edit address 2
818 ** @see ajListSort
819 **
820 ** @return [int] The comparison function returns an integer less than,
821 ** equal to, or greater than zero if the first argument is
822 ** considered to be respectively less than, equal to, or
823 ** greater than the second.
824 **
825 ** @release 6.4.0
826 ** @@
827 ******************************************************************************/
828
listSequenceeditCompareStartAscending(const void * item1,const void * item2)829 static int listSequenceeditCompareStartAscending(
830 const void *item1,
831 const void *item2)
832 {
833 int result = 0;
834
835 EnsPSequenceedit se1 = *(EnsOSequenceedit *const *) item1;
836 EnsPSequenceedit se2 = *(EnsOSequenceedit *const *) item2;
837
838 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
839 if (ajDebugTest("listSequenceeditCompareStartAscending"))
840 {
841 ajDebug("listSequenceeditCompareStartAscending\n"
842 " se1 %p\n"
843 " se2 %p\n",
844 se1,
845 se2);
846
847 ensSequenceeditTrace(se1, 1);
848 ensSequenceeditTrace(se2, 1);
849 }
850 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
851
852 /* Sort empty values towards the end of the AJAX list. */
853
854 if (se1 && (!se2))
855 return -1;
856
857 if ((!se1) && (!se2))
858 return 0;
859
860 if ((!se1) && se2)
861 return +1;
862
863 if (se1->Start < se2->Start)
864 result = -1;
865
866 if (se1->Start > se2->Start)
867 result = +1;
868
869 return result;
870 }
871
872
873
874
875 /* @funcstatic listSequenceeditCompareStartDescending *************************
876 **
877 ** AJAX List of Ensembl Sequence Edit objects comparison function to sort by
878 ** start member in descending order.
879 **
880 ** @param [r] item1 [const void*] Ensembl Sequence Edit address 1
881 ** @param [r] item2 [const void*] Ensembl Sequence Edit address 2
882 ** @see ajListSort
883 **
884 ** @return [int] The comparison function returns an integer less than,
885 ** equal to, or greater than zero if the first argument is
886 ** considered to be respectively less than, equal to, or
887 ** greater than the second.
888 **
889 ** @release 6.4.0
890 ** @@
891 ******************************************************************************/
892
listSequenceeditCompareStartDescending(const void * item1,const void * item2)893 static int listSequenceeditCompareStartDescending(
894 const void *item1,
895 const void *item2)
896 {
897 int result = 0;
898
899 EnsPSequenceedit se1 = *(EnsOSequenceedit *const *) item1;
900 EnsPSequenceedit se2 = *(EnsOSequenceedit *const *) item2;
901
902 #if defined(AJ_DEBUG) && AJ_DEBUG >= 2
903 if (ajDebugTest("listSequenceeditCompareStartDescending"))
904 {
905 ajDebug("listSequenceeditCompareStartDescending\n"
906 " se1 %p\n"
907 " se2 %p\n",
908 se1,
909 se2);
910
911 ensSequenceeditTrace(se1, 1);
912 ensSequenceeditTrace(se2, 1);
913 }
914 #endif /* defined(AJ_DEBUG) && AJ_DEBUG >= 2 */
915
916 /* Sort empty values towards the end of the AJAX list. */
917
918 if (se1 && (!se2))
919 return -1;
920
921 if ((!se1) && (!se2))
922 return 0;
923
924 if ((!se1) && se2)
925 return +1;
926
927 if (se1->Start < se2->Start)
928 result = +1;
929
930 if (se1->Start > se2->Start)
931 result = -1;
932
933 return result;
934 }
935
936
937
938
939 /* @section list **************************************************************
940 **
941 ** Functions for manipulating AJAX List objects.
942 **
943 ** @fdata [AjPList]
944 **
945 ** @nam3rule Sequenceedit Functions for manipulating AJAX List objects of
946 ** Ensembl Sequence Edit objects
947 ** @nam4rule Sort Sort functions
948 ** @nam5rule Start Sort by start member
949 ** @nam6rule Ascending Sort in ascending order
950 ** @nam6rule Descending Sort in descending order
951 **
952 ** @argrule Ascending ses [AjPList] AJAX List of Ensembl Sequence Edit objects
953 ** @argrule Descending ses [AjPList] AJAX List of Ensembl Sequence Edit objects
954 **
955 ** @valrule * [AjBool] ajTrue upon success, ajFalse otherwise
956 **
957 ** @fcategory misc
958 ******************************************************************************/
959
960
961
962
963 /* @func ensListSequenceeditSortStartAscending ********************************
964 **
965 ** Sort an AJAX List of Ensembl Sequence Edit objects by start member in
966 ** ascending order.
967 **
968 ** @param [u] ses [AjPList] AJAX List of Ensembl Sequence Edit objects
969 **
970 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
971 **
972 ** @release 6.4.0
973 ** @@
974 ******************************************************************************/
975
ensListSequenceeditSortStartAscending(AjPList ses)976 AjBool ensListSequenceeditSortStartAscending(AjPList ses)
977 {
978 if (!ses)
979 return ajFalse;
980
981 ajListSort(ses, &listSequenceeditCompareStartAscending);
982
983 return ajTrue;
984 }
985
986
987
988
989 /* @func ensListSequenceeditSortStartDescending *******************************
990 **
991 ** Sort an AJAX List of Ensembl Sequence Edit objects by start member in
992 ** descending order.
993 **
994 ** @param [u] ses [AjPList] AJAX List of Ensembl Sequence Edit objects
995 **
996 ** @return [AjBool] ajTrue upon success, ajFalse otherwise
997 **
998 ** @release 6.4.0
999 ** @@
1000 ******************************************************************************/
1001
ensListSequenceeditSortStartDescending(AjPList ses)1002 AjBool ensListSequenceeditSortStartDescending(AjPList ses)
1003 {
1004 if (!ses)
1005 return ajFalse;
1006
1007 ajListSort(ses, &listSequenceeditCompareStartDescending);
1008
1009 return ajTrue;
1010 }
1011