1 /**
2  * @file
3  *
4  * @author jeffrey.daily@gmail.com
5  *
6  * Copyright (c) 2015 Battelle Memorial Institute.
7  */
8 #include "config.h"
9 
10 #include <assert.h>
11 #include <ctype.h>
12 #include <limits.h>
13 #ifdef HAVE_MALLOC_H
14 #include <malloc.h>
15 #endif
16 #include <stddef.h>
17 #include <stdint.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include "parasail.h"
23 #include "parasail/memory.h"
24 
parasail_memalign(size_t alignment,size_t size)25 void* parasail_memalign(size_t alignment, size_t size)
26 {
27     void *ptr = NULL;
28 #if defined(HAVE__ALIGNED_MALLOC)
29     ptr = _aligned_malloc(size, alignment);
30 #elif defined(HAVE_POSIX_MEMALIGN)
31     int retcode = posix_memalign(&ptr, alignment, size);
32     assert(0 == retcode);
33 #elif defined(HAVE_ALIGNED_ALLOC)
34     ptr = aligned_alloc(alignment, size);
35 #elif defined(HAVE_MEMALIGN)
36     ptr = memalign(alignment, size);
37 #else
38 #error "No suitable memory alignment routine found."
39 #endif
40     assert(NULL != ptr);
41     return ptr;
42 }
43 
parasail_free(void * ptr)44 void parasail_free(void *ptr)
45 {
46 #if defined(HAVE__ALIGNED_MALLOC)
47      _aligned_free(ptr);
48 #else
49     free(ptr);
50 #endif
51 }
52 
parasail_free_unaligned(void * ptr)53 void parasail_free_unaligned(void *ptr)
54 {
55     free(ptr);
56 }
57 
parasail_memalign_int(size_t alignment,size_t size)58 int * parasail_memalign_int(size_t alignment, size_t size)
59 {
60     return (int *) parasail_memalign(alignment, size*sizeof(int));
61 }
62 
parasail_memalign_int8_t(size_t alignment,size_t size)63 int8_t * parasail_memalign_int8_t(size_t alignment, size_t size)
64 {
65     return (int8_t *) parasail_memalign(alignment, size*sizeof(int8_t));
66 }
67 
parasail_memalign_int16_t(size_t alignment,size_t size)68 int16_t * parasail_memalign_int16_t(size_t alignment, size_t size)
69 {
70     return (int16_t *) parasail_memalign(alignment, size*sizeof(int16_t));
71 }
72 
parasail_memalign_int32_t(size_t alignment,size_t size)73 int32_t * parasail_memalign_int32_t(size_t alignment, size_t size)
74 {
75     return (int32_t *) parasail_memalign(alignment, size*sizeof(int32_t));
76 }
77 
parasail_memalign_int64_t(size_t alignment,size_t size)78 int64_t * parasail_memalign_int64_t(size_t alignment, size_t size)
79 {
80     return (int64_t *) parasail_memalign(alignment, size*sizeof(int64_t));
81 }
82 
parasail_memset(void * b,int c,size_t len)83 void parasail_memset(void *b, int c, size_t len)
84 {
85     (void)memset(b, c, len);
86 }
87 
parasail_memset_int(int * b,int c,size_t len)88 void parasail_memset_int(int *b, int c, size_t len)
89 {
90     size_t i;
91     for (i=0; i<len; ++i) {
92         b[i] = c;
93     }
94 }
95 
parasail_memset_int8_t(int8_t * b,int8_t c,size_t len)96 void parasail_memset_int8_t(int8_t *b, int8_t c, size_t len)
97 {
98     size_t i;
99     for (i=0; i<len; ++i) {
100         b[i] = c;
101     }
102 }
103 
parasail_memset_int16_t(int16_t * b,int16_t c,size_t len)104 void parasail_memset_int16_t(int16_t *b, int16_t c, size_t len)
105 {
106     size_t i;
107     for (i=0; i<len; ++i) {
108         b[i] = c;
109     }
110 }
111 
parasail_memset_int32_t(int32_t * b,int32_t c,size_t len)112 void parasail_memset_int32_t(int32_t *b, int32_t c, size_t len)
113 {
114     size_t i;
115     for (i=0; i<len; ++i) {
116         b[i] = c;
117     }
118 }
119 
parasail_memset_int64_t(int64_t * b,int64_t c,size_t len)120 void parasail_memset_int64_t(int64_t *b, int64_t c, size_t len)
121 {
122     size_t i;
123     for (i=0; i<len; ++i) {
124         b[i] = c;
125     }
126 }
127 
parasail_result_new()128 parasail_result_t* parasail_result_new()
129 {
130     /* declare all variables */
131     parasail_result_t *result = NULL;
132 
133     result = (parasail_result_t*)malloc(sizeof(parasail_result_t));
134     assert(result);
135 
136     result->score = 0;
137     result->end_query = 0;
138     result->end_ref = 0;
139     result->flag = 0;
140     result->extra = NULL;
141 
142     return result;
143 }
144 
parasail_result_new_stats()145 parasail_result_t* parasail_result_new_stats()
146 {
147     /* declare all variables */
148     parasail_result_t *result = NULL;
149 
150     /* allocate struct to hold memory */
151     result = parasail_result_new();
152 
153     /* allocate only tables */
154     result->stats = (parasail_result_extra_stats_t*)
155         malloc(sizeof(parasail_result_extra_stats_t));
156     assert(result->stats);
157 
158     return result;
159 }
160 
parasail_result_new_table1(const int a,const int b)161 parasail_result_t* parasail_result_new_table1(const int a, const int b)
162 {
163     /* declare all variables */
164     parasail_result_t *result = NULL;
165 
166     /* validate inputs */
167     assert(a > 0);
168     assert(b > 0);
169 
170     /* allocate struct to hold memory */
171     result = parasail_result_new();
172 
173     /* allocate only score table */
174     result->tables = (parasail_result_extra_tables_t*)malloc(sizeof(parasail_result_extra_tables_t));
175     assert(result->tables);
176     result->tables->score_table = (int *)malloc(sizeof(int)*a*b);
177     assert(result->tables->score_table);
178 
179     return result;
180 }
181 
parasail_result_new_rowcol1(const int a,const int b)182 parasail_result_t* parasail_result_new_rowcol1(const int a, const int b)
183 {
184     /* declare all variables */
185     parasail_result_t *result = NULL;
186 
187     /* validate inputs */
188     assert(a > 0);
189     assert(b > 0);
190 
191     /* allocate struct to hold memory */
192     result = parasail_result_new();
193 
194     /* allocate only score col and row */
195     result->rowcols = (parasail_result_extra_rowcols_t*)malloc(sizeof(parasail_result_extra_rowcols_t));
196     assert(result->rowcols);
197     result->rowcols->score_row = (int *)malloc(sizeof(int)*b);
198     assert(result->rowcols->score_row);
199     result->rowcols->score_col = (int *)malloc(sizeof(int)*a);
200     assert(result->rowcols->score_col);
201 
202     return result;
203 }
204 
parasail_result_new_table3(const int a,const int b)205 parasail_result_t* parasail_result_new_table3(const int a, const int b)
206 {
207     /* declare all variables */
208     parasail_result_t *result = NULL;
209 
210     /* validate inputs */
211     assert(a > 0);
212     assert(b > 0);
213 
214     /* allocate struct to hold memory */
215     result = parasail_result_new();
216 
217     /* allocate only tables */
218     result->stats = (parasail_result_extra_stats_t*)
219         malloc(sizeof(parasail_result_extra_stats_t));
220     assert(result->stats);
221 
222     result->stats->tables = (parasail_result_extra_stats_tables_t*)
223         malloc(sizeof(parasail_result_extra_stats_tables_t));
224     assert(result->stats->tables);
225 
226     result->stats->tables->score_table = (int *)malloc(sizeof(int)*a*b);
227     assert(result->stats->tables->score_table);
228     result->stats->tables->matches_table = (int *)malloc(sizeof(int)*a*b);
229     assert(result->stats->tables->matches_table);
230     result->stats->tables->similar_table = (int *)malloc(sizeof(int)*a*b);
231     assert(result->stats->tables->similar_table);
232     result->stats->tables->length_table = (int *)malloc(sizeof(int)*a*b);
233     assert(result->stats->tables->length_table);
234 
235     return result;
236 }
237 
parasail_result_new_trace(const int a,const int b,const size_t alignment,const size_t size)238 parasail_result_t* parasail_result_new_trace(const int a, const int b, const size_t alignment, const size_t size)
239 {
240     /* declare all variables */
241     parasail_result_t *result = NULL;
242 
243     /* validate inputs */
244     assert(a > 0);
245     assert(b > 0);
246 
247     /* allocate struct to hold memory */
248     result = parasail_result_new();
249 
250     result->trace = (parasail_result_extra_trace_t*)malloc(sizeof(parasail_result_extra_trace_t));
251     assert(result->trace);
252     result->trace->trace_table = parasail_memalign(alignment, size*a*b);
253     assert(result->trace->trace_table);
254     result->trace->trace_ins_table = NULL;
255     result->trace->trace_del_table = NULL;
256 
257     return result;
258 }
259 
parasail_result_new_rowcol3(const int a,const int b)260 parasail_result_t* parasail_result_new_rowcol3(const int a, const int b)
261 {
262     /* declare all variables */
263     parasail_result_t *result = NULL;
264 
265     /* validate inputs */
266     assert(a > 0);
267     assert(b > 0);
268 
269     /* allocate struct to hold memory */
270     result = parasail_result_new();
271 
272     result->stats = (parasail_result_extra_stats_t*)
273         malloc(sizeof(parasail_result_extra_stats_t));
274     assert(result->stats);
275 
276     result->stats->rowcols = (parasail_result_extra_stats_rowcols_t*)
277         malloc(sizeof(parasail_result_extra_stats_rowcols_t));
278     assert(result->stats->rowcols);
279 
280     result->stats->rowcols->score_row = (int *)malloc(sizeof(int)*b);
281     assert(result->stats->rowcols->score_row);
282     result->stats->rowcols->matches_row = (int *)malloc(sizeof(int)*b);
283     assert(result->stats->rowcols->matches_row);
284     result->stats->rowcols->similar_row = (int *)malloc(sizeof(int)*b);
285     assert(result->stats->rowcols->similar_row);
286     result->stats->rowcols->length_row = (int *)malloc(sizeof(int)*b);
287     assert(result->stats->rowcols->length_row);
288 
289     result->stats->rowcols->score_col = (int *)malloc(sizeof(int)*a);
290     assert(result->stats->rowcols->score_col);
291     result->stats->rowcols->matches_col = (int *)malloc(sizeof(int)*a);
292     assert(result->stats->rowcols->matches_col);
293     result->stats->rowcols->similar_col = (int *)malloc(sizeof(int)*a);
294     assert(result->stats->rowcols->similar_col);
295     result->stats->rowcols->length_col = (int *)malloc(sizeof(int)*a);
296     assert(result->stats->rowcols->length_col);
297 
298     return result;
299 }
300 
parasail_result_free(parasail_result_t * result)301 void parasail_result_free(parasail_result_t *result)
302 {
303     /* validate inputs */
304     assert(NULL != result);
305 
306     if (result->flag & PARASAIL_FLAG_STATS) {
307         if (result->flag & PARASAIL_FLAG_TABLE) {
308             free(result->stats->tables->score_table);
309             free(result->stats->tables->matches_table);
310             free(result->stats->tables->similar_table);
311             free(result->stats->tables->length_table);
312             free(result->stats->tables);
313         }
314         if (result->flag & PARASAIL_FLAG_ROWCOL) {
315             free(result->stats->rowcols->score_row);
316             free(result->stats->rowcols->matches_row);
317             free(result->stats->rowcols->similar_row);
318             free(result->stats->rowcols->length_row);
319             free(result->stats->rowcols->score_col);
320             free(result->stats->rowcols->matches_col);
321             free(result->stats->rowcols->similar_col);
322             free(result->stats->rowcols->length_col);
323             free(result->stats->rowcols);
324         }
325         free(result->stats);
326     }
327     else {
328         if (result->flag & PARASAIL_FLAG_TABLE) {
329             free(result->tables->score_table);
330             free(result->tables);
331         }
332         if (result->flag & PARASAIL_FLAG_ROWCOL) {
333             free(result->rowcols->score_row);
334             free(result->rowcols->score_col);
335             free(result->rowcols);
336         }
337     }
338     if (result->flag & PARASAIL_FLAG_TRACE) {
339         parasail_free(result->trace->trace_table);
340         if (NULL != result->trace->trace_ins_table)
341             parasail_free(result->trace->trace_ins_table);
342         if (NULL != result->trace->trace_del_table)
343             parasail_free(result->trace->trace_del_table);
344         free(result->trace);
345     }
346 
347     free(result);
348 }
349 
parasail_version(int * major,int * minor,int * patch)350 void parasail_version(int *major, int *minor, int *patch)
351 {
352     *major = PARASAIL_VERSION_MAJOR;
353     *minor = PARASAIL_VERSION_MINOR;
354     *patch = PARASAIL_VERSION_PATCH;
355 }
356 
parasail_matrix_create_internal(const char * alphabet,const int match,const int mismatch,int case_sensitive)357 static parasail_matrix_t* parasail_matrix_create_internal(
358         const char *alphabet, const int match, const int mismatch, int case_sensitive)
359 {
360     parasail_matrix_t *retval = NULL;
361     int *matrix = NULL;
362     int *mapper = NULL;
363     size_t size = 0;
364     size_t size1 = 0;
365     size_t i = 0;
366     size_t j = 0;
367     size_t c = 0;
368 
369     size = strlen(alphabet);
370     assert(size < INT_MAX);
371     size1 = size + 1;
372 
373     matrix = (int*)malloc(sizeof(int)*size1*size1);
374     assert(matrix);
375     for (i=0; i<size; ++i) {
376         for (j=0; j<size; ++j) {
377             if (i == j) {
378                 matrix[c++] = match;
379             }
380             else {
381                 matrix[c++] = mismatch;
382             }
383         }
384         matrix[c++] = 0;
385     }
386     for (j=0; j<size1; ++j) {
387         matrix[c++] = 0;
388     }
389 
390     mapper = (int*)malloc(sizeof(int)*256);
391     assert(mapper);
392     parasail_memset_int(mapper, (int)size, 256);
393     if (case_sensitive) {
394         for (i=0; i<size; ++i) {
395             mapper[(unsigned char)alphabet[i]] = (int)i;
396         }
397     }
398     else {
399         for (i=0; i<size; ++i) {
400             mapper[toupper((unsigned char)alphabet[i])] = (int)i;
401             mapper[tolower((unsigned char)alphabet[i])] = (int)i;
402         }
403     }
404 
405     retval = (parasail_matrix_t*)malloc(sizeof(parasail_matrix_t));
406     assert(retval);
407     retval->name = "";
408     retval->matrix = matrix;
409     retval->mapper = mapper;
410     retval->size = (int)size1;
411     retval->max = match > mismatch ? match : mismatch;
412     retval->min = match > mismatch ? mismatch : match;
413     retval->user_matrix = matrix;
414     return retval;
415 }
416 
parasail_matrix_create(const char * alphabet,const int match,const int mismatch)417 parasail_matrix_t* parasail_matrix_create(
418         const char *alphabet, const int match, const int mismatch)
419 {
420     return parasail_matrix_create_internal(alphabet, match, mismatch, 0);
421 }
422 
parasail_matrix_create_case_sensitive(const char * alphabet,const int match,const int mismatch)423 parasail_matrix_t* parasail_matrix_create_case_sensitive(
424         const char *alphabet, const int match, const int mismatch)
425 {
426     return parasail_matrix_create_internal(alphabet, match, mismatch, 1);
427 }
428 
parasail_matrix_copy(const parasail_matrix_t * original)429 parasail_matrix_t* parasail_matrix_copy(const parasail_matrix_t *original)
430 {
431     parasail_matrix_t *retval = NULL;
432 
433     retval = (parasail_matrix_t*)malloc(sizeof(parasail_matrix_t));
434     assert(retval);
435     retval->name = original->name;
436     retval->size = original->size;
437     retval->max = original->max;
438     retval->min = original->min;
439 
440     {
441         size_t matrix_size = sizeof(int)*original->size*original->size;
442         size_t mapper_size = sizeof(int)*256;
443         int *new_mapper = NULL;
444         int *new_matrix = NULL;
445 
446         new_mapper = (int*)malloc(mapper_size);
447         assert(new_mapper);
448         (void)memcpy(new_mapper, original->mapper, mapper_size);
449 
450         new_matrix = (int*)malloc(matrix_size);
451         assert(new_matrix);
452         (void)memcpy(new_matrix, original->matrix, matrix_size);
453 
454         retval->mapper = new_mapper;
455         retval->matrix = new_matrix;
456         retval->user_matrix = new_matrix;
457     }
458 
459     return retval;
460 }
461 
parasail_matrix_set_value(parasail_matrix_t * matrix,int row,int col,int value)462 void parasail_matrix_set_value(parasail_matrix_t *matrix, int row, int col, int value)
463 {
464     assert(matrix);
465 
466     if (NULL == matrix->user_matrix) {
467         fprintf(stderr, "attempted to set value of built-in matrix '%s'\n",
468                 matrix->name);
469         return;
470     }
471 
472     matrix->user_matrix[row*matrix->size + col] = value;
473     if (value > matrix->max) {
474         matrix->max = value;
475     }
476     if (value < matrix->min) {
477         matrix->min = value;
478     }
479 }
480 
parasail_matrix_free(parasail_matrix_t * matrix)481 void parasail_matrix_free(parasail_matrix_t *matrix)
482 {
483     /* validate inputs */
484     assert(NULL != matrix);
485     if (NULL != matrix->user_matrix) {
486         free((void*)matrix->matrix);
487         free((void*)matrix->mapper);
488         free(matrix);
489     }
490     else {
491         fprintf(stderr, "attempted to free built-in matrix '%s'\n",
492                 matrix->name);
493     }
494 }
495 
parasail_profile_new(const char * s1,const int s1Len,const parasail_matrix_t * matrix)496 parasail_profile_t* parasail_profile_new(
497         const char * s1, const int s1Len, const parasail_matrix_t *matrix)
498 {
499     /* declare all variables */
500     parasail_profile_t *profile = NULL;
501 
502     profile = (parasail_profile_t*)malloc(sizeof(parasail_profile_t));
503     assert(profile);
504 
505     profile->s1 = s1;
506     profile->s1Len = s1Len;
507     profile->matrix = matrix;
508     profile->profile8.score = NULL;
509     profile->profile8.matches = NULL;
510     profile->profile8.similar = NULL;
511     profile->profile16.score = NULL;
512     profile->profile16.matches = NULL;
513     profile->profile16.similar = NULL;
514     profile->profile32.score = NULL;
515     profile->profile32.matches = NULL;
516     profile->profile32.similar = NULL;
517     profile->profile64.score = NULL;
518     profile->profile64.matches = NULL;
519     profile->profile64.similar = NULL;
520     profile->free = NULL;
521     profile->stop = INT32_MAX;
522 
523     return profile;
524 }
525 
parasail_profile_free(parasail_profile_t * profile)526 void parasail_profile_free(parasail_profile_t *profile)
527 {
528     if (NULL != profile->profile8.score) {
529         profile->free(profile->profile8.score);
530     }
531     if (NULL != profile->profile8.matches) {
532         profile->free(profile->profile8.matches);
533     }
534     if (NULL != profile->profile8.similar) {
535         profile->free(profile->profile8.similar);
536     }
537 
538     if (NULL != profile->profile16.score) {
539         profile->free(profile->profile16.score);
540     }
541     if (NULL != profile->profile16.matches) {
542         profile->free(profile->profile16.matches);
543     }
544     if (NULL != profile->profile16.similar) {
545         profile->free(profile->profile16.similar);
546     }
547 
548     if (NULL != profile->profile32.score) {
549         profile->free(profile->profile32.score);
550     }
551     if (NULL != profile->profile32.matches) {
552         profile->free(profile->profile32.matches);
553     }
554     if (NULL != profile->profile32.similar) {
555         profile->free(profile->profile32.similar);
556     }
557 
558     if (NULL != profile->profile64.score) {
559         profile->free(profile->profile64.score);
560     }
561     if (NULL != profile->profile64.matches) {
562         profile->free(profile->profile64.matches);
563     }
564     if (NULL != profile->profile64.similar) {
565         profile->free(profile->profile64.similar);
566     }
567 
568     free(profile);
569 }
570 
parasail_reverse(const char * s,size_t length)571 char* parasail_reverse(const char *s, size_t length)
572 {
573     char *r = NULL;
574     size_t i = 0;
575     size_t j = 0;
576 
577     r = (char*)malloc(sizeof(char)*(length + 1));
578     r[length] = '\0';
579     for (i=0,j=length-1; i<length; ++i,--j) {
580         r[i] = s[j];
581     }
582 
583     return r;
584 }
585 
parasail_reverse_uint32_t(const uint32_t * s,size_t length)586 uint32_t* parasail_reverse_uint32_t(const uint32_t *s, size_t length)
587 {
588     uint32_t *r = NULL;
589     size_t i = 0;
590     size_t j = 0;
591 
592     r = (uint32_t*)malloc(sizeof(uint32_t)*(length));
593     for (i=0,j=length-1; i<length; ++i,--j) {
594         r[i] = s[j];
595     }
596 
597     return r;
598 }
599 
parasail_result_is_nw(const parasail_result_t * const restrict result)600 int parasail_result_is_nw(const parasail_result_t * const restrict result)
601 {
602     return result->flag & PARASAIL_FLAG_NW;
603 }
604 
parasail_result_is_sg(const parasail_result_t * const restrict result)605 int parasail_result_is_sg(const parasail_result_t * const restrict result)
606 {
607     return result->flag & PARASAIL_FLAG_SG;
608 }
609 
parasail_result_is_sw(const parasail_result_t * const restrict result)610 int parasail_result_is_sw(const parasail_result_t * const restrict result)
611 {
612     return result->flag & PARASAIL_FLAG_SW;
613 }
614 
parasail_result_is_saturated(const parasail_result_t * const restrict result)615 int parasail_result_is_saturated(const parasail_result_t * const restrict result)
616 {
617     return result->flag & PARASAIL_FLAG_SATURATED;
618 }
619 
parasail_result_is_banded(const parasail_result_t * const restrict result)620 int parasail_result_is_banded(const parasail_result_t * const restrict result)
621 {
622     return result->flag & PARASAIL_FLAG_BANDED;
623 }
624 
parasail_result_is_scan(const parasail_result_t * const restrict result)625 int parasail_result_is_scan(const parasail_result_t * const restrict result)
626 {
627     return result->flag & PARASAIL_FLAG_SCAN;
628 }
629 
parasail_result_is_striped(const parasail_result_t * const restrict result)630 int parasail_result_is_striped(const parasail_result_t * const restrict result)
631 {
632     return result->flag & PARASAIL_FLAG_STRIPED;
633 }
634 
parasail_result_is_diag(const parasail_result_t * const restrict result)635 int parasail_result_is_diag(const parasail_result_t * const restrict result)
636 {
637     return result->flag & PARASAIL_FLAG_DIAG;
638 }
639 
parasail_result_is_blocked(const parasail_result_t * const restrict result)640 int parasail_result_is_blocked(const parasail_result_t * const restrict result)
641 {
642     return result->flag & PARASAIL_FLAG_BLOCKED;
643 }
644 
parasail_result_is_stats(const parasail_result_t * const restrict result)645 int parasail_result_is_stats(const parasail_result_t * const restrict result)
646 {
647     return result->flag & PARASAIL_FLAG_STATS;
648 }
649 
parasail_result_is_stats_table(const parasail_result_t * const restrict result)650 int parasail_result_is_stats_table(const parasail_result_t * const restrict result)
651 {
652     return (result->flag & PARASAIL_FLAG_STATS) && (result->flag & PARASAIL_FLAG_TABLE);
653 }
654 
parasail_result_is_stats_rowcol(const parasail_result_t * const restrict result)655 int parasail_result_is_stats_rowcol(const parasail_result_t * const restrict result)
656 {
657     return (result->flag & PARASAIL_FLAG_STATS) && (result->flag & PARASAIL_FLAG_ROWCOL);
658 }
659 
parasail_result_is_table(const parasail_result_t * const restrict result)660 int parasail_result_is_table(const parasail_result_t * const restrict result)
661 {
662     return result->flag & PARASAIL_FLAG_TABLE;
663 }
664 
parasail_result_is_rowcol(const parasail_result_t * const restrict result)665 int parasail_result_is_rowcol(const parasail_result_t * const restrict result)
666 {
667     return result->flag & PARASAIL_FLAG_ROWCOL;
668 }
669 
parasail_result_is_trace(const parasail_result_t * const restrict result)670 int parasail_result_is_trace(const parasail_result_t * const restrict result)
671 {
672     return result->flag & PARASAIL_FLAG_TRACE;
673 }
674 
parasail_result_get_score(const parasail_result_t * const restrict result)675 int parasail_result_get_score(const parasail_result_t * const restrict result)
676 {
677     return result->score;
678 }
679 
parasail_result_get_end_query(const parasail_result_t * const restrict result)680 int parasail_result_get_end_query(const parasail_result_t * const restrict result)
681 {
682     return result->end_query;
683 }
684 
parasail_result_get_end_ref(const parasail_result_t * const restrict result)685 int parasail_result_get_end_ref(const parasail_result_t * const restrict result)
686 {
687     return result->end_ref;
688 }
689 
parasail_result_get_matches(const parasail_result_t * const restrict result)690 int parasail_result_get_matches(const parasail_result_t * const restrict result)
691 {
692     assert(parasail_result_is_stats(result));
693     return result->stats->matches;
694 }
695 
parasail_result_get_similar(const parasail_result_t * const restrict result)696 int parasail_result_get_similar(const parasail_result_t * const restrict result)
697 {
698     assert(parasail_result_is_stats(result));
699     return result->stats->similar;
700 }
701 
parasail_result_get_length(const parasail_result_t * const restrict result)702 int parasail_result_get_length(const parasail_result_t * const restrict result)
703 {
704     assert(parasail_result_is_stats(result));
705     return result->stats->length;
706 }
707 
parasail_result_get_score_table(const parasail_result_t * const restrict result)708 int* parasail_result_get_score_table(const parasail_result_t * const restrict result)
709 {
710     assert(parasail_result_is_table(result) || parasail_result_is_stats_table(result));
711     if (parasail_result_is_stats_table(result)) {
712         return result->stats->tables->score_table;
713     }
714     if (parasail_result_is_table(result)) {
715         return result->tables->score_table;
716     }
717     return NULL; /* should not reach */
718 }
719 
parasail_result_get_matches_table(const parasail_result_t * const restrict result)720 int* parasail_result_get_matches_table(const parasail_result_t * const restrict result)
721 {
722     assert(parasail_result_is_stats_table(result));
723     return result->stats->tables->matches_table;
724 }
725 
parasail_result_get_similar_table(const parasail_result_t * const restrict result)726 int* parasail_result_get_similar_table(const parasail_result_t * const restrict result)
727 {
728     assert(parasail_result_is_stats_table(result));
729     return result->stats->tables->similar_table;
730 }
731 
parasail_result_get_length_table(const parasail_result_t * const restrict result)732 int* parasail_result_get_length_table(const parasail_result_t * const restrict result)
733 {
734     assert(parasail_result_is_stats_table(result));
735     return result->stats->tables->length_table;
736 }
737 
parasail_result_get_score_row(const parasail_result_t * const restrict result)738 int* parasail_result_get_score_row(const parasail_result_t * const restrict result)
739 {
740     assert(parasail_result_is_stats_rowcol(result) || parasail_result_is_rowcol(result));
741     if (parasail_result_is_stats_rowcol(result)) {
742         return result->stats->rowcols->score_row;
743     }
744     if (parasail_result_is_rowcol(result)) {
745         return result->rowcols->score_row;
746     }
747     return NULL; /* should not reach */
748 }
749 
parasail_result_get_matches_row(const parasail_result_t * const restrict result)750 int* parasail_result_get_matches_row(const parasail_result_t * const restrict result)
751 {
752     assert(parasail_result_is_stats_rowcol(result));
753     return result->stats->rowcols->matches_row;
754 }
755 
parasail_result_get_similar_row(const parasail_result_t * const restrict result)756 int* parasail_result_get_similar_row(const parasail_result_t * const restrict result)
757 {
758     assert(parasail_result_is_stats_rowcol(result));
759     return result->stats->rowcols->similar_row;
760 }
761 
parasail_result_get_length_row(const parasail_result_t * const restrict result)762 int* parasail_result_get_length_row(const parasail_result_t * const restrict result)
763 {
764     assert(parasail_result_is_stats_rowcol(result));
765     return result->stats->rowcols->length_row;
766 }
767 
parasail_result_get_score_col(const parasail_result_t * const restrict result)768 int* parasail_result_get_score_col(const parasail_result_t * const restrict result)
769 {
770     assert(parasail_result_is_stats_rowcol(result) || parasail_result_is_rowcol(result));
771     if (parasail_result_is_stats_rowcol(result)) {
772         return result->stats->rowcols->score_col;
773     }
774     if (parasail_result_is_rowcol(result)) {
775         return result->rowcols->score_col;
776     }
777     return NULL; /* should not reach */
778 }
779 
parasail_result_get_matches_col(const parasail_result_t * const restrict result)780 int* parasail_result_get_matches_col(const parasail_result_t * const restrict result)
781 {
782     assert(parasail_result_is_stats_rowcol(result));
783     return result->stats->rowcols->matches_col;
784 }
785 
parasail_result_get_similar_col(const parasail_result_t * const restrict result)786 int* parasail_result_get_similar_col(const parasail_result_t * const restrict result)
787 {
788     assert(parasail_result_is_stats_rowcol(result));
789     return result->stats->rowcols->similar_col;
790 }
791 
parasail_result_get_length_col(const parasail_result_t * const restrict result)792 int* parasail_result_get_length_col(const parasail_result_t * const restrict result)
793 {
794     assert(parasail_result_is_stats_rowcol(result));
795     return result->stats->rowcols->length_col;
796 }
797 
parasail_result_get_trace_table(const parasail_result_t * const restrict result)798 int* parasail_result_get_trace_table(const parasail_result_t * const restrict result)
799 {
800     assert(parasail_result_is_trace(result));
801     return result->trace->trace_table;
802 }
803 
parasail_result_get_trace_ins_table(const parasail_result_t * const restrict result)804 int* parasail_result_get_trace_ins_table(const parasail_result_t * const restrict result)
805 {
806     assert(parasail_result_is_trace(result));
807     return result->trace->trace_ins_table;
808 }
809 
parasail_result_get_trace_del_table(const parasail_result_t * const restrict result)810 int* parasail_result_get_trace_del_table(const parasail_result_t * const restrict result)
811 {
812     assert(parasail_result_is_trace(result));
813     return result->trace->trace_del_table;
814 }
815 
816