bio-bwa 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.document +5 -0
  2. data/Gemfile +15 -0
  3. data/Gemfile.lock +28 -0
  4. data/LICENSE.txt +35 -0
  5. data/README.rdoc +33 -0
  6. data/Rakefile +56 -0
  7. data/VERSION +1 -0
  8. data/bio-bwa.gemspec +152 -0
  9. data/doc/Bio.html +93 -0
  10. data/doc/Bio/BWA.html +2884 -0
  11. data/doc/Bio/BWA/Library.html +229 -0
  12. data/doc/_index.html +119 -0
  13. data/doc/class_list.html +36 -0
  14. data/doc/css/common.css +1 -0
  15. data/doc/css/full_list.css +53 -0
  16. data/doc/css/style.css +310 -0
  17. data/doc/file.LICENSE.html +88 -0
  18. data/doc/file.README.html +119 -0
  19. data/doc/file_list.html +41 -0
  20. data/doc/frames.html +13 -0
  21. data/doc/index.html +119 -0
  22. data/doc/js/app.js +203 -0
  23. data/doc/js/full_list.js +149 -0
  24. data/doc/js/jquery.js +154 -0
  25. data/doc/method_list.html +171 -0
  26. data/doc/top-level-namespace.html +88 -0
  27. data/ext/COPYING +674 -0
  28. data/ext/ChangeLog +3864 -0
  29. data/ext/NEWS +555 -0
  30. data/ext/README +29 -0
  31. data/ext/bamlite.c +155 -0
  32. data/ext/bamlite.h +94 -0
  33. data/ext/bntseq.c +303 -0
  34. data/ext/bntseq.h +80 -0
  35. data/ext/bwa.1 +562 -0
  36. data/ext/bwape.c +807 -0
  37. data/ext/bwase.c +686 -0
  38. data/ext/bwase.h +27 -0
  39. data/ext/bwaseqio.c +222 -0
  40. data/ext/bwt.c +250 -0
  41. data/ext/bwt.h +105 -0
  42. data/ext/bwt_gen/Makefile +23 -0
  43. data/ext/bwt_gen/QSufSort.c +496 -0
  44. data/ext/bwt_gen/QSufSort.h +40 -0
  45. data/ext/bwt_gen/bwt_gen.c +1547 -0
  46. data/ext/bwt_gen/bwt_gen.h +105 -0
  47. data/ext/bwt_lite.c +94 -0
  48. data/ext/bwt_lite.h +29 -0
  49. data/ext/bwtaln.c +345 -0
  50. data/ext/bwtaln.h +150 -0
  51. data/ext/bwtgap.c +264 -0
  52. data/ext/bwtgap.h +38 -0
  53. data/ext/bwtindex.c +186 -0
  54. data/ext/bwtio.c +77 -0
  55. data/ext/bwtmisc.c +269 -0
  56. data/ext/bwtsw2.h +51 -0
  57. data/ext/bwtsw2_aux.c +650 -0
  58. data/ext/bwtsw2_chain.c +107 -0
  59. data/ext/bwtsw2_core.c +594 -0
  60. data/ext/bwtsw2_main.c +100 -0
  61. data/ext/cs2nt.c +191 -0
  62. data/ext/is.c +218 -0
  63. data/ext/khash.h +506 -0
  64. data/ext/kseq.h +208 -0
  65. data/ext/ksort.h +269 -0
  66. data/ext/kstring.c +35 -0
  67. data/ext/kstring.h +46 -0
  68. data/ext/kvec.h +90 -0
  69. data/ext/main.c +63 -0
  70. data/ext/main.h +29 -0
  71. data/ext/mkrf_conf.rb +49 -0
  72. data/ext/qualfa2fq.pl +27 -0
  73. data/ext/simple_dp.c +162 -0
  74. data/ext/simpletest.c +23 -0
  75. data/ext/solid2fastq.pl +111 -0
  76. data/ext/stdaln.c +1072 -0
  77. data/ext/stdaln.h +162 -0
  78. data/ext/utils.c +82 -0
  79. data/ext/utils.h +54 -0
  80. data/lib/bio-bwa.rb +7 -0
  81. data/lib/bio/bwa.rb +312 -0
  82. data/lib/bio/bwa/library.rb +42 -0
  83. data/test/data/testdata.fa +602 -0
  84. data/test/data/testdata.long.fa +175 -0
  85. data/test/data/testdata.short.fa +2 -0
  86. data/test/helper.rb +18 -0
  87. data/test/test_bio-bwa_basic.rb +62 -0
  88. data/test/test_bio-bwa_make_index.rb +42 -0
  89. data/test/test_bio-bwa_run_aln.rb +49 -0
  90. data/test/test_bio-bwa_sam_conversion.rb +49 -0
  91. metadata +218 -0
data/ext/kseq.h ADDED
@@ -0,0 +1,208 @@
1
+ /* The MIT License
2
+
3
+ Copyright (c) 2008, by Heng Li <lh3@sanger.ac.uk>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
24
+ */
25
+
26
+ #ifndef AC_KSEQ_H
27
+ #define AC_KSEQ_H
28
+
29
+ #include <ctype.h>
30
+ #include <string.h>
31
+ #include <stdlib.h>
32
+
33
+ #define __KS_TYPE(type_t) \
34
+ typedef struct __kstream_t { \
35
+ char *buf; \
36
+ int begin, end, is_eof; \
37
+ type_t f; \
38
+ } kstream_t;
39
+
40
+ #define ks_eof(ks) ((ks)->is_eof && (ks)->begin >= (ks)->end)
41
+ #define ks_rewind(ks) ((ks)->is_eof = (ks)->begin = (ks)->end = 0)
42
+
43
+ #define __KS_BASIC(type_t, __bufsize) \
44
+ static inline kstream_t *ks_init(type_t f) \
45
+ { \
46
+ kstream_t *ks = (kstream_t*)calloc(1, sizeof(kstream_t)); \
47
+ ks->f = f; \
48
+ ks->buf = (char*)malloc(__bufsize); \
49
+ return ks; \
50
+ } \
51
+ static inline void ks_destroy(kstream_t *ks) \
52
+ { \
53
+ if (ks) { \
54
+ free(ks->buf); \
55
+ free(ks); \
56
+ } \
57
+ }
58
+
59
+ #define __KS_GETC(__read, __bufsize) \
60
+ static inline int ks_getc(kstream_t *ks) \
61
+ { \
62
+ if (ks->is_eof && ks->begin >= ks->end) return -1; \
63
+ if (ks->begin >= ks->end) { \
64
+ ks->begin = 0; \
65
+ ks->end = __read(ks->f, ks->buf, __bufsize); \
66
+ if (ks->end < __bufsize) ks->is_eof = 1; \
67
+ if (ks->end == 0) return -1; \
68
+ } \
69
+ return (int)ks->buf[ks->begin++]; \
70
+ }
71
+
72
+ #ifndef KSTRING_T
73
+ #define KSTRING_T kstring_t
74
+ typedef struct __kstring_t {
75
+ size_t l, m;
76
+ char *s;
77
+ } kstring_t;
78
+ #endif
79
+
80
+ #ifndef kroundup32
81
+ #define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
82
+ #endif
83
+
84
+ #define __KS_GETUNTIL(__read, __bufsize) \
85
+ static int ks_getuntil(kstream_t *ks, int delimiter, kstring_t *str, int *dret) \
86
+ { \
87
+ if (dret) *dret = 0; \
88
+ str->l = 0; \
89
+ if (ks->begin >= ks->end && ks->is_eof) return -1; \
90
+ for (;;) { \
91
+ int i; \
92
+ if (ks->begin >= ks->end) { \
93
+ if (!ks->is_eof) { \
94
+ ks->begin = 0; \
95
+ ks->end = __read(ks->f, ks->buf, __bufsize); \
96
+ if (ks->end < __bufsize) ks->is_eof = 1; \
97
+ if (ks->end == 0) break; \
98
+ } else break; \
99
+ } \
100
+ if (delimiter) { \
101
+ for (i = ks->begin; i < ks->end; ++i) \
102
+ if (ks->buf[i] == delimiter) break; \
103
+ } else { \
104
+ for (i = ks->begin; i < ks->end; ++i) \
105
+ if (isspace(ks->buf[i])) break; \
106
+ } \
107
+ if (str->m - str->l < i - ks->begin + 1) { \
108
+ str->m = str->l + (i - ks->begin) + 1; \
109
+ kroundup32(str->m); \
110
+ str->s = (char*)realloc(str->s, str->m); \
111
+ } \
112
+ memcpy(str->s + str->l, ks->buf + ks->begin, i - ks->begin); \
113
+ str->l = str->l + (i - ks->begin); \
114
+ ks->begin = i + 1; \
115
+ if (i < ks->end) { \
116
+ if (dret) *dret = ks->buf[i]; \
117
+ break; \
118
+ } \
119
+ } \
120
+ str->s[str->l] = '\0'; \
121
+ return str->l; \
122
+ }
123
+
124
+ #define KSTREAM_INIT(type_t, __read, __bufsize) \
125
+ __KS_TYPE(type_t) \
126
+ __KS_BASIC(type_t, __bufsize) \
127
+ __KS_GETC(__read, __bufsize) \
128
+ __KS_GETUNTIL(__read, __bufsize)
129
+
130
+ #define __KSEQ_BASIC(type_t) \
131
+ static inline kseq_t *kseq_init(type_t fd) \
132
+ { \
133
+ kseq_t *s = (kseq_t*)calloc(1, sizeof(kseq_t)); \
134
+ s->f = ks_init(fd); \
135
+ return s; \
136
+ } \
137
+ static inline void kseq_rewind(kseq_t *ks) \
138
+ { \
139
+ ks->last_char = 0; \
140
+ ks->f->is_eof = ks->f->begin = ks->f->end = 0; \
141
+ } \
142
+ static inline void kseq_destroy(kseq_t *ks) \
143
+ { \
144
+ if (!ks) return; \
145
+ free(ks->name.s); free(ks->comment.s); free(ks->seq.s); free(ks->qual.s); \
146
+ ks_destroy(ks->f); \
147
+ free(ks); \
148
+ }
149
+
150
+ /* Return value:
151
+ >=0 length of the sequence (normal)
152
+ -1 end-of-file
153
+ -2 truncated quality string
154
+ */
155
+ #define __KSEQ_READ \
156
+ static int kseq_read(kseq_t *seq) \
157
+ { \
158
+ int c; \
159
+ kstream_t *ks = seq->f; \
160
+ if (seq->last_char == 0) { /* then jump to the next header line */ \
161
+ while ((c = ks_getc(ks)) != -1 && c != '>' && c != '@'); \
162
+ if (c == -1) return -1; /* end of file */ \
163
+ seq->last_char = c; \
164
+ } /* the first header char has been read */ \
165
+ seq->comment.l = seq->seq.l = seq->qual.l = 0; \
166
+ if (ks_getuntil(ks, 0, &seq->name, &c) < 0) return -1; \
167
+ if (c != '\n') ks_getuntil(ks, '\n', &seq->comment, 0); \
168
+ while ((c = ks_getc(ks)) != -1 && c != '>' && c != '+' && c != '@') { \
169
+ if (isgraph(c)) { /* printable non-space character */ \
170
+ if (seq->seq.l + 1 >= seq->seq.m) { /* double the memory */ \
171
+ seq->seq.m = seq->seq.l + 2; \
172
+ kroundup32(seq->seq.m); /* rounded to next closest 2^k */ \
173
+ seq->seq.s = (char*)realloc(seq->seq.s, seq->seq.m); \
174
+ } \
175
+ seq->seq.s[seq->seq.l++] = (char)c; \
176
+ } \
177
+ } \
178
+ if (c == '>' || c == '@') seq->last_char = c; /* the first header char has been read */ \
179
+ seq->seq.s[seq->seq.l] = 0; /* null terminated string */ \
180
+ if (c != '+') return seq->seq.l; /* FASTA */ \
181
+ if (seq->qual.m < seq->seq.m) { /* allocate enough memory */ \
182
+ seq->qual.m = seq->seq.m; \
183
+ seq->qual.s = (char*)realloc(seq->qual.s, seq->qual.m); \
184
+ } \
185
+ while ((c = ks_getc(ks)) != -1 && c != '\n'); /* skip the rest of '+' line */ \
186
+ if (c == -1) return -2; /* we should not stop here */ \
187
+ while ((c = ks_getc(ks)) != -1 && seq->qual.l < seq->seq.l) \
188
+ if (c >= 33 && c <= 127) seq->qual.s[seq->qual.l++] = (unsigned char)c; \
189
+ seq->qual.s[seq->qual.l] = 0; /* null terminated string */ \
190
+ seq->last_char = 0; /* we have not come to the next header line */ \
191
+ if (seq->seq.l != seq->qual.l) return -2; /* qual string is shorter than seq string */ \
192
+ return seq->seq.l; \
193
+ }
194
+
195
+ #define __KSEQ_TYPE(type_t) \
196
+ typedef struct { \
197
+ kstring_t name, comment, seq, qual; \
198
+ int last_char; \
199
+ kstream_t *f; \
200
+ } kseq_t;
201
+
202
+ #define KSEQ_INIT(type_t, __read) \
203
+ KSTREAM_INIT(type_t, __read, 4096) \
204
+ __KSEQ_TYPE(type_t) \
205
+ __KSEQ_BASIC(type_t) \
206
+ __KSEQ_READ
207
+
208
+ #endif
data/ext/ksort.h ADDED
@@ -0,0 +1,269 @@
1
+ /* The MIT License
2
+
3
+ Copyright (c) 2008, by Attractive Chaos <attractivechaos@aol.co.uk>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
24
+ */
25
+
26
+ /*
27
+ 2008-11-16 (0.1.4):
28
+
29
+ * Fixed a bug in introsort() that happens in rare cases.
30
+
31
+ 2008-11-05 (0.1.3):
32
+
33
+ * Fixed a bug in introsort() for complex comparisons.
34
+
35
+ * Fixed a bug in mergesort(). The previous version is not stable.
36
+
37
+ 2008-09-15 (0.1.2):
38
+
39
+ * Accelerated introsort. On my Mac (not on another Linux machine),
40
+ my implementation is as fast as std::sort on random input.
41
+
42
+ * Added combsort and in introsort, switch to combsort if the
43
+ recursion is too deep.
44
+
45
+ 2008-09-13 (0.1.1):
46
+
47
+ * Added k-small algorithm
48
+
49
+ 2008-09-05 (0.1.0):
50
+
51
+ * Initial version
52
+
53
+ */
54
+
55
+ #ifndef AC_KSORT_H
56
+ #define AC_KSORT_H
57
+
58
+ #include <stdlib.h>
59
+ #include <string.h>
60
+
61
+ typedef struct {
62
+ void *left, *right;
63
+ int depth;
64
+ } ks_isort_stack_t;
65
+
66
+ #define KSORT_SWAP(type_t, a, b) { register type_t t=(a); (a)=(b); (b)=t; }
67
+
68
+ #define KSORT_INIT(name, type_t, __sort_lt) \
69
+ void ks_mergesort_##name(size_t n, type_t array[], type_t temp[]) \
70
+ { \
71
+ type_t *a2[2], *a, *b; \
72
+ int curr, shift; \
73
+ \
74
+ a2[0] = array; \
75
+ a2[1] = temp? temp : (type_t*)malloc(sizeof(type_t) * n); \
76
+ for (curr = 0, shift = 0; (1ul<<shift) < n; ++shift) { \
77
+ a = a2[curr]; b = a2[1-curr]; \
78
+ if (shift == 0) { \
79
+ type_t *p = b, *i, *eb = a + n; \
80
+ for (i = a; i < eb; i += 2) { \
81
+ if (i == eb - 1) *p++ = *i; \
82
+ else { \
83
+ if (__sort_lt(*(i+1), *i)) { \
84
+ *p++ = *(i+1); *p++ = *i; \
85
+ } else { \
86
+ *p++ = *i; *p++ = *(i+1); \
87
+ } \
88
+ } \
89
+ } \
90
+ } else { \
91
+ size_t i, step = 1ul<<shift; \
92
+ for (i = 0; i < n; i += step<<1) { \
93
+ type_t *p, *j, *k, *ea, *eb; \
94
+ if (n < i + step) { \
95
+ ea = a + n; eb = a; \
96
+ } else { \
97
+ ea = a + i + step; \
98
+ eb = a + (n < i + (step<<1)? n : i + (step<<1)); \
99
+ } \
100
+ j = a + i; k = a + i + step; p = b + i; \
101
+ while (j < ea && k < eb) { \
102
+ if (__sort_lt(*k, *j)) *p++ = *k++; \
103
+ else *p++ = *j++; \
104
+ } \
105
+ while (j < ea) *p++ = *j++; \
106
+ while (k < eb) *p++ = *k++; \
107
+ } \
108
+ } \
109
+ curr = 1 - curr; \
110
+ } \
111
+ if (curr == 1) { \
112
+ type_t *p = a2[0], *i = a2[1], *eb = array + n; \
113
+ for (; p < eb; ++i) *p++ = *i; \
114
+ } \
115
+ if (temp == 0) free(a2[1]); \
116
+ } \
117
+ void ks_heapadjust_##name(size_t i, size_t n, type_t l[]) \
118
+ { \
119
+ size_t k = i; \
120
+ type_t tmp = l[i]; \
121
+ while ((k = (k << 1) + 1) < n) { \
122
+ if (k != n - 1 && __sort_lt(l[k], l[k+1])) ++k; \
123
+ if (__sort_lt(l[k], tmp)) break; \
124
+ l[i] = l[k]; i = k; \
125
+ } \
126
+ l[i] = tmp; \
127
+ } \
128
+ void ks_heapmake_##name(size_t lsize, type_t l[]) \
129
+ { \
130
+ size_t i; \
131
+ for (i = (lsize >> 1) - 1; i != (size_t)(-1); --i) \
132
+ ks_heapadjust_##name(i, lsize, l); \
133
+ } \
134
+ void ks_heapsort_##name(size_t lsize, type_t l[]) \
135
+ { \
136
+ size_t i; \
137
+ for (i = lsize - 1; i > 0; --i) { \
138
+ type_t tmp; \
139
+ tmp = *l; *l = l[i]; l[i] = tmp; ks_heapadjust_##name(0, i, l); \
140
+ } \
141
+ } \
142
+ inline void __ks_insertsort_##name(type_t *s, type_t *t) \
143
+ { \
144
+ type_t *i, *j, swap_tmp; \
145
+ for (i = s + 1; i < t; ++i) \
146
+ for (j = i; j > s && __sort_lt(*j, *(j-1)); --j) { \
147
+ swap_tmp = *j; *j = *(j-1); *(j-1) = swap_tmp; \
148
+ } \
149
+ } \
150
+ void ks_combsort_##name(size_t n, type_t a[]) \
151
+ { \
152
+ const double shrink_factor = 1.2473309501039786540366528676643; \
153
+ int do_swap; \
154
+ size_t gap = n; \
155
+ type_t tmp, *i, *j; \
156
+ do { \
157
+ if (gap > 2) { \
158
+ gap = (size_t)(gap / shrink_factor); \
159
+ if (gap == 9 || gap == 10) gap = 11; \
160
+ } \
161
+ do_swap = 0; \
162
+ for (i = a; i < a + n - gap; ++i) { \
163
+ j = i + gap; \
164
+ if (__sort_lt(*j, *i)) { \
165
+ tmp = *i; *i = *j; *j = tmp; \
166
+ do_swap = 1; \
167
+ } \
168
+ } \
169
+ } while (do_swap || gap > 2); \
170
+ if (gap != 1) __ks_insertsort_##name(a, a + n); \
171
+ } \
172
+ void ks_introsort_##name(size_t n, type_t a[]) \
173
+ { \
174
+ int d; \
175
+ ks_isort_stack_t *top, *stack; \
176
+ type_t rp, swap_tmp; \
177
+ type_t *s, *t, *i, *j, *k; \
178
+ \
179
+ if (n < 1) return; \
180
+ else if (n == 2) { \
181
+ if (__sort_lt(a[1], a[0])) { swap_tmp = a[0]; a[0] = a[1]; a[1] = swap_tmp; } \
182
+ return; \
183
+ } \
184
+ for (d = 2; 1ul<<d < n; ++d); \
185
+ stack = (ks_isort_stack_t*)malloc(sizeof(ks_isort_stack_t) * ((sizeof(size_t)*d)+2)); \
186
+ top = stack; s = a; t = a + (n-1); d <<= 1; \
187
+ while (1) { \
188
+ if (s < t) { \
189
+ if (--d == 0) { \
190
+ ks_combsort_##name(t - s + 1, s); \
191
+ t = s; \
192
+ continue; \
193
+ } \
194
+ i = s; j = t; k = i + ((j-i)>>1) + 1; \
195
+ if (__sort_lt(*k, *i)) { \
196
+ if (__sort_lt(*k, *j)) k = j; \
197
+ } else k = __sort_lt(*j, *i)? i : j; \
198
+ rp = *k; \
199
+ if (k != t) { swap_tmp = *k; *k = *t; *t = swap_tmp; } \
200
+ for (;;) { \
201
+ do ++i; while (__sort_lt(*i, rp)); \
202
+ do --j; while (i <= j && __sort_lt(rp, *j)); \
203
+ if (j <= i) break; \
204
+ swap_tmp = *i; *i = *j; *j = swap_tmp; \
205
+ } \
206
+ swap_tmp = *i; *i = *t; *t = swap_tmp; \
207
+ if (i-s > t-i) { \
208
+ if (i-s > 16) { top->left = s; top->right = i-1; top->depth = d; ++top; } \
209
+ s = t-i > 16? i+1 : t; \
210
+ } else { \
211
+ if (t-i > 16) { top->left = i+1; top->right = t; top->depth = d; ++top; } \
212
+ t = i-s > 16? i-1 : s; \
213
+ } \
214
+ } else { \
215
+ if (top == stack) { \
216
+ free(stack); \
217
+ __ks_insertsort_##name(a, a+n); \
218
+ return; \
219
+ } else { --top; s = (type_t*)top->left; t = (type_t*)top->right; d = top->depth; } \
220
+ } \
221
+ } \
222
+ } \
223
+ /* This function is adapted from: http://ndevilla.free.fr/median/ */ \
224
+ /* 0 <= kk < n */ \
225
+ type_t ks_ksmall_##name(size_t n, type_t arr[], size_t kk) \
226
+ { \
227
+ type_t *low, *high, *k, *ll, *hh, *mid; \
228
+ low = arr; high = arr + n - 1; k = arr + kk; \
229
+ for (;;) { \
230
+ if (high <= low) return *k; \
231
+ if (high == low + 1) { \
232
+ if (__sort_lt(*high, *low)) KSORT_SWAP(type_t, *low, *high); \
233
+ return *k; \
234
+ } \
235
+ mid = low + (high - low) / 2; \
236
+ if (__sort_lt(*high, *mid)) KSORT_SWAP(type_t, *mid, *high); \
237
+ if (__sort_lt(*high, *low)) KSORT_SWAP(type_t, *low, *high); \
238
+ if (__sort_lt(*low, *mid)) KSORT_SWAP(type_t, *mid, *low); \
239
+ KSORT_SWAP(type_t, *mid, *(low+1)); \
240
+ ll = low + 1; hh = high; \
241
+ for (;;) { \
242
+ do ++ll; while (__sort_lt(*ll, *low)); \
243
+ do --hh; while (__sort_lt(*low, *hh)); \
244
+ if (hh < ll) break; \
245
+ KSORT_SWAP(type_t, *ll, *hh); \
246
+ } \
247
+ KSORT_SWAP(type_t, *low, *hh); \
248
+ if (hh <= k) low = ll; \
249
+ if (hh >= k) high = hh - 1; \
250
+ } \
251
+ }
252
+
253
+ #define ks_mergesort(name, n, a, t) ks_mergesort_##name(n, a, t)
254
+ #define ks_introsort(name, n, a) ks_introsort_##name(n, a)
255
+ #define ks_combsort(name, n, a) ks_combsort_##name(n, a)
256
+ #define ks_heapsort(name, n, a) ks_heapsort_##name(n, a)
257
+ #define ks_heapmake(name, n, a) ks_heapmake_##name(n, a)
258
+ #define ks_heapadjust(name, i, n, a) ks_heapadjust_##name(i, n, a)
259
+ #define ks_ksmall(name, n, a, k) ks_ksmall_##name(n, a, k)
260
+
261
+ #define ks_lt_generic(a, b) ((a) < (b))
262
+ #define ks_lt_str(a, b) (strcmp((a), (b)) < 0)
263
+
264
+ typedef const char *ksstr_t;
265
+
266
+ #define KSORT_INIT_GENERIC(type_t) KSORT_INIT(type_t, type_t, ks_lt_generic)
267
+ #define KSORT_INIT_STR KSORT_INIT(str, ksstr_t, ks_lt_str)
268
+
269
+ #endif