]> git.donarmstrong.com Git - samtools.git/commitdiff
When bam_read1() returns an error (return value <= -2), propagate that error
authorOn behalf of John Marshall <lh3@sanger.ac.uk>
Wed, 22 Sep 2010 15:15:33 +0000 (15:15 +0000)
committerOn behalf of John Marshall <lh3@sanger.ac.uk>
Wed, 22 Sep 2010 15:15:33 +0000 (15:15 +0000)
to bam_iter_read()'s own return value.  Similarly, also propagate it up to
bam_fetch()'s return value.  Previously bam_fetch() always returned 0, and
callers ignored its return value anyway.  With this change, 0 continues to
indicate success, while <= -2 (which can be written as < 0, as -1 is never
returned) indicates corrupted input.

bam_iter_read() ought also to propagate errors returned by bam_seek().

main_samview() can now print an error message and fail when bam_fetch()
detects that a .bai index file is corrupted or otherwise does not correspond
to the .bam file it is being used with.

bam_index.c
sam_view.c

index 9d819d33aa30677384c2d1bdd97639a206f04003..263561b0c24f649848d583a6de2e7ff48451f9b2 100644 (file)
@@ -656,17 +656,17 @@ void bam_iter_destroy(bam_iter_t iter)
 
 int bam_iter_read(bamFile fp, bam_iter_t iter, bam1_t *b)
 {
+       int ret;
        if (iter && iter->finished) return -1;
        if (iter == 0 || iter->from_first) {
-               int ret = bam_read1(fp, b);
+               ret = bam_read1(fp, b);
                if (ret < 0 && iter) iter->finished = 1;
                return ret;
        }
        if (iter->off == 0) return -1;
        for (;;) {
-               int ret;
                if (iter->curr_off == 0 || iter->curr_off >= iter->off[iter->i].v) { // then jump to the next chunk
-                       if (iter->i == iter->n_off - 1) break; // no more chunks
+                       if (iter->i == iter->n_off - 1) { ret = -1; break; } // no more chunks
                        if (iter->i >= 0) assert(iter->curr_off == iter->off[iter->i].v); // otherwise bug
                        if (iter->i < 0 || iter->off[iter->i].v != iter->off[iter->i+1].u) { // not adjacent chunks; then seek
                                bam_seek(fp, iter->off[iter->i+1].u, SEEK_SET);
@@ -676,21 +676,22 @@ int bam_iter_read(bamFile fp, bam_iter_t iter, bam1_t *b)
                }
                if ((ret = bam_read1(fp, b)) >= 0) {
                        iter->curr_off = bam_tell(fp);
-                       if (b->core.tid != iter->tid || b->core.pos >= iter->end) break; // no need to proceed
+                       if (b->core.tid != iter->tid || b->core.pos >= iter->end) { ret = -1; break; } // no need to proceed
                        else if (is_overlap(iter->beg, iter->end, b)) return ret;
-               } else break; // end of file
+               } else break; // end of file or error
        }
        iter->finished = 1;
-       return -1;
+       return ret;
 }
 
 int bam_fetch(bamFile fp, const bam_index_t *idx, int tid, int beg, int end, void *data, bam_fetch_f func)
 {
+       int ret;
        bam_iter_t iter;
        bam1_t *b;
        b = bam_init1();
        iter = bam_iter_query(idx, tid, beg, end);
-       while (bam_iter_read(fp, iter, b) >= 0) func(b, data);
+       while ((ret = bam_iter_read(fp, iter, b)) >= 0) func(b, data);
        bam_destroy1(b);
-       return 0;
+       return (ret == -1)? 0 : ret;
 }
index 3b10e2e5372e98a2b9ebda4bd5791dc1b837a20f..41b651abbacd0aa69d04f94299b9b79680642d08 100644 (file)
@@ -164,7 +164,12 @@ int main_samview(int argc, char *argv[])
                                fprintf(stderr, "[main_samview] fail to get the reference name. Continue anyway.\n");
                                continue;
                        }
-                       bam_fetch(in->x.bam, idx, tid, beg, end, out, view_func); // fetch alignments
+                       // fetch alignments
+                       if (bam_fetch(in->x.bam, idx, tid, beg, end, out, view_func) < 0) {
+                               fprintf(stderr, "[main_samview] retrieval failed due to truncated file or corrupt BAM index file\n");
+                               ret = 1;
+                               break;
+                       }
                }
                bam_index_destroy(idx); // destroy the BAM index
        }