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