]> git.kaiwu.me - klib.git/commitdiff
Fix ks_getuntil2() extra empty record at EOF bug
authorJohn Marshall <jm18@sanger.ac.uk>
Thu, 13 Nov 2014 14:28:46 +0000 (14:28 +0000)
committerJohn Marshall <jm18@sanger.ac.uk>
Thu, 13 Nov 2014 14:39:59 +0000 (14:39 +0000)
When the stream is an exact multiple of the buffer size, ks_getuntil2()
was returning a final empty record when it should have returned -1.
Fixed by moving the "EOF => return -1" check to after the read loop.

(See samtools/samtools#318 for an example of an error caused by a
spurious empty line at the end of a SAM file.)

kseq.h

diff --git a/kseq.h b/kseq.h
index 4d8a46e1966264bc24299e89859d1156d51ffb0a..b2238d1d3ac922ee353964a7e73710794b68b004 100644 (file)
--- a/kseq.h
+++ b/kseq.h
@@ -90,9 +90,9 @@ typedef struct __kstring_t {
 #define __KS_GETUNTIL(__read, __bufsize)                                                               \
        static int ks_getuntil2(kstream_t *ks, int delimiter, kstring_t *str, int *dret, int append) \
        {                                                                                                                                       \
+               int gotany = 0;                                                                                                 \
                if (dret) *dret = 0;                                                                                    \
                str->l = append? str->l : 0;                                                                    \
-               if (ks->begin >= ks->end && ks->is_eof) return -1;                              \
                for (;;) {                                                                                                              \
                        int i;                                                                                                          \
                        if (ks->begin >= ks->end) {                                                                     \
@@ -120,6 +120,7 @@ typedef struct __kstring_t {
                                kroundup32(str->m);                                                                             \
                                str->s = (char*)realloc(str->s, str->m);                                \
                        }                                                                                                                       \
+                       gotany = 1;                                                                                                     \
                        memcpy(str->s + str->l, ks->buf + ks->begin, i - ks->begin); \
                        str->l = str->l + (i - ks->begin);                                                      \
                        ks->begin = i + 1;                                                                                      \
@@ -128,6 +129,7 @@ typedef struct __kstring_t {
                                break;                                                                                                  \
                        }                                                                                                                       \
                }                                                                                                                               \
+               if (!gotany && ks_eof(ks)) return -1;                                                   \
                if (str->s == 0) {                                                                                              \
                        str->m = 1;                                                                                                     \
                        str->s = (char*)calloc(1, 1);                                                           \