fuzzer_parser_init:
   33|  5.31k|readstat_parser_t *fuzzer_parser_init(const uint8_t *Data, size_t Size) {
   34|  5.31k|    readstat_parser_t *parser = readstat_parser_init();
   35|  5.31k|    readstat_set_open_handler(parser, rt_open_handler);
   36|  5.31k|    readstat_set_close_handler(parser, rt_close_handler);
   37|  5.31k|    readstat_set_seek_handler(parser, rt_seek_handler);
   38|  5.31k|    readstat_set_read_handler(parser, rt_read_handler);
   39|  5.31k|    readstat_set_update_handler(parser, rt_update_handler);
   40|       |
   41|  5.31k|    readstat_set_metadata_handler(parser, &handle_metadata);
   42|  5.31k|    readstat_set_note_handler(parser, &handle_note);
   43|  5.31k|    readstat_set_variable_handler(parser, &handle_variable);
   44|  5.31k|    readstat_set_fweight_handler(parser, &handle_fweight);
   45|  5.31k|    readstat_set_value_handler(parser, &handle_value);
   46|  5.31k|    readstat_set_value_label_handler(parser, &handle_value_label);
   47|       |
   48|  5.31k|    return parser;
   49|  5.31k|}
fuzz_format.c:handle_metadata:
    8|  1.56k|static int handle_metadata(readstat_metadata_t *metadata, void *ctx) {
    9|  1.56k|    return READSTAT_HANDLER_OK;
   10|  1.56k|}
fuzz_format.c:handle_note:
   12|    396|static int handle_note(int index, const char *note, void *ctx) {
   13|    396|    return READSTAT_HANDLER_OK;
   14|    396|}
fuzz_format.c:handle_variable:
   21|   165k|                           const char *val_labels, void *ctx) {
   22|   165k|    return READSTAT_HANDLER_OK;
   23|   165k|}
fuzz_format.c:handle_fweight:
   16|     18|static int handle_fweight(readstat_variable_t *variable, void *ctx) {
   17|     18|    return READSTAT_HANDLER_OK;
   18|     18|}
fuzz_format.c:handle_value:
   25|  2.29M|static int handle_value(int obs_index, readstat_variable_t *variable, readstat_value_t value, void *ctx) {
   26|  2.29M|    return READSTAT_HANDLER_OK;
   27|  2.29M|}
fuzz_format.c:handle_value_label:
   29|  71.4k|static int handle_value_label(const char *val_labels, readstat_value_t value, const char *label, void *ctx) {
   30|  71.4k|    return READSTAT_HANDLER_OK;
   31|  71.4k|}

LLVMFuzzerTestOneInput:
   10|  5.31k|int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
   11|  5.31k|    rt_buffer_t buffer = { .bytes = (char *)Data, .size = Size, .used = Size };
   12|  5.31k|    rt_buffer_ctx_t buffer_ctx = { .buffer = &buffer };
   13|       |
   14|  5.31k|    readstat_parser_t *parser = fuzzer_parser_init(Data, Size);
   15|  5.31k|    readstat_set_io_ctx(parser, &buffer_ctx);
   16|       |
   17|  5.31k|    readstat_parse_sav(parser, NULL, NULL);
   18|  5.31k|    readstat_parser_free(parser);
   19|  5.31k|    return 0;
   20|  5.31k|}

machine_is_little_endian:
   11|  5.26k|int machine_is_little_endian() {
   12|  5.26k|    int test_byte_order = 1;
   13|  5.26k|    return ((char *)&test_byte_order)[0];
   14|  5.26k|}
byteswap4:
   44|   419k|uint32_t byteswap4(uint32_t num) {
   45|   419k|    num = ((num & 0xFFFF0000) >> 16) | ((num & 0x0000FFFF) << 16);
   46|   419k|    return ((num & 0xFF00FF00) >> 8) | ((num & 0x00FF00FF) << 8);
   47|   419k|}
byteswap8:
   49|  3.64M|uint64_t byteswap8(uint64_t num) {
   50|  3.64M|    num = ((num & 0xFFFFFFFF00000000) >> 32) | ((num & 0x00000000FFFFFFFF) << 32);
   51|  3.64M|    num = ((num & 0xFFFF0000FFFF0000) >> 16) | ((num & 0x0000FFFF0000FFFF) << 16);
   52|  3.64M|    return ((num & 0xFF00FF00FF00FF00) >> 8) | ((num & 0x00FF00FF00FF00FF) << 8);
   53|  3.64M|}
byteswap_double:
   63|  2.25M|double byteswap_double(double num) {
   64|  2.25M|    uint64_t answer = 0;
   65|  2.25M|    memcpy(&answer, &num, 8);
   66|  2.25M|    answer = byteswap8(answer);
   67|  2.25M|    memcpy(&num, &answer, 8);
   68|  2.25M|    return num;
   69|  2.25M|}

readstat_convert:
    7|  1.86M|readstat_error_t readstat_convert(char *dst, size_t dst_len, const char *src, size_t src_len, iconv_t converter) {
    8|       |    /* strip off spaces from the input because the programs use ASCII space
    9|       |     * padding even with non-ASCII encoding. */
   10|  16.4M|    while (src_len && (src[src_len-1] == ' ' || src[src_len-1] == '\0')) {
  ------------------
  |  Branch (10:12): [True: 16.3M, False: 17.5k]
  |  Branch (10:24): [True: 1.98M, False: 14.4M]
  |  Branch (10:49): [True: 12.5M, False: 1.84M]
  ------------------
   11|  14.5M|        src_len--;
   12|  14.5M|    }
   13|  1.86M|    if (dst_len == 0) {
  ------------------
  |  Branch (13:9): [True: 0, False: 1.86M]
  ------------------
   14|      0|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   15|  1.86M|    } else if (converter) {
  ------------------
  |  Branch (15:16): [True: 1.24k, False: 1.86M]
  ------------------
   16|  1.24k|        size_t dst_left = dst_len - 1;
   17|  1.24k|        char *dst_end = dst;
   18|  1.24k|        size_t status = iconv(converter, (readstat_iconv_inbuf_t)&src, &src_len, &dst_end, &dst_left);
   19|  1.24k|        if (status == (size_t)-1) {
  ------------------
  |  Branch (19:13): [True: 827, False: 413]
  ------------------
   20|    827|            if (errno == E2BIG) {
  ------------------
  |  Branch (20:17): [True: 1, False: 826]
  ------------------
   21|      1|                return READSTAT_ERROR_CONVERT_LONG_STRING;
   22|    826|            } else if (errno == EILSEQ) {
  ------------------
  |  Branch (22:24): [True: 277, False: 549]
  ------------------
   23|    277|                return READSTAT_ERROR_CONVERT_BAD_STRING;
   24|    549|            } else if (errno != EINVAL) { /* EINVAL indicates improper truncation; accept it */
  ------------------
  |  Branch (24:24): [True: 0, False: 549]
  ------------------
   25|      0|                return READSTAT_ERROR_CONVERT;
   26|      0|            }
   27|    827|        }
   28|    962|        dst[dst_len - dst_left - 1] = '\0';
   29|  1.86M|    } else if (src_len + 1 > dst_len) {
  ------------------
  |  Branch (29:16): [True: 20, False: 1.86M]
  ------------------
   30|     20|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   31|  1.86M|    } else {
   32|  1.86M|        memcpy(dst, src, src_len);
   33|  1.86M|        dst[src_len] = '\0';
   34|  1.86M|    }
   35|  1.86M|    return READSTAT_OK;
   36|  1.86M|}

unistd_io_init:
  121|  5.31k|readstat_error_t unistd_io_init(readstat_parser_t *parser) {
  122|  5.31k|    readstat_error_t retval = READSTAT_OK;
  123|  5.31k|    unistd_io_ctx_t *io_ctx = NULL;
  124|       |
  125|  5.31k|    if ((retval = readstat_set_open_handler(parser, unistd_open_handler)) != READSTAT_OK)
  ------------------
  |  Branch (125:9): [True: 0, False: 5.31k]
  ------------------
  126|      0|        return retval;
  127|       |
  128|  5.31k|    if ((retval = readstat_set_close_handler(parser, unistd_close_handler)) != READSTAT_OK)
  ------------------
  |  Branch (128:9): [True: 0, False: 5.31k]
  ------------------
  129|      0|        return retval;
  130|       |
  131|  5.31k|    if ((retval = readstat_set_seek_handler(parser, unistd_seek_handler)) != READSTAT_OK)
  ------------------
  |  Branch (131:9): [True: 0, False: 5.31k]
  ------------------
  132|      0|        return retval;
  133|       |
  134|  5.31k|    if ((retval = readstat_set_read_handler(parser, unistd_read_handler)) != READSTAT_OK)
  ------------------
  |  Branch (134:9): [True: 0, False: 5.31k]
  ------------------
  135|      0|        return retval;
  136|       |
  137|  5.31k|    if ((readstat_set_update_handler(parser, unistd_update_handler)) != READSTAT_OK)
  ------------------
  |  Branch (137:9): [True: 0, False: 5.31k]
  ------------------
  138|      0|        return retval;
  139|       |
  140|  5.31k|    io_ctx = calloc(1, sizeof(unistd_io_ctx_t));
  141|  5.31k|    io_ctx->fd = -1;
  142|       |
  143|  5.31k|    retval = readstat_set_io_ctx(parser, (void*) io_ctx);
  144|  5.31k|    parser->io->io_ctx_needs_free = 1;
  145|       |
  146|  5.31k|    return retval;
  147|  5.31k|}

readstat_malloc:
   10|  91.5k|void *readstat_malloc(size_t len) {
   11|  91.5k|    if (len > MAX_MALLOC_SIZE || len == 0) {
  ------------------
  |  |    3|   183k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (11:9): [True: 178, False: 91.3k]
  |  Branch (11:34): [True: 1.04k, False: 90.3k]
  ------------------
   12|  1.22k|        return NULL;
   13|  1.22k|    }
   14|  90.3k|    return malloc(len);
   15|  91.5k|}
readstat_calloc:
   17|   314k|void *readstat_calloc(size_t count, size_t size) {
   18|   314k|    if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|   628k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
                  if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|   628k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
                  if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|   314k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (18:9): [True: 25, False: 314k]
  |  Branch (18:36): [True: 0, False: 314k]
  |  Branch (18:62): [True: 1, False: 314k]
  ------------------
   19|     26|        return NULL;
   20|     26|    }
   21|   314k|    if (count == 0 || size == 0) {
  ------------------
  |  Branch (21:9): [True: 9, False: 313k]
  |  Branch (21:23): [True: 0, False: 313k]
  ------------------
   22|      9|        return NULL;
   23|      9|    }
   24|   313k|    return calloc(count, size);
   25|   314k|}
readstat_realloc:
   27|  3.65k|void *readstat_realloc(void *ptr, size_t len) {
   28|  3.65k|    if (len > MAX_MALLOC_SIZE || len == 0) {
  ------------------
  |  |    3|  7.30k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (28:9): [True: 131, False: 3.52k]
  |  Branch (28:34): [True: 5, False: 3.51k]
  ------------------
   29|    136|        if (ptr)
  ------------------
  |  Branch (29:13): [True: 76, False: 60]
  ------------------
   30|     76|            free(ptr);
   31|    136|        return NULL;
   32|    136|    }
   33|  3.51k|    return realloc(ptr, len);
   34|  3.65k|}

readstat_parser_init:
    6|  5.31k|readstat_parser_t *readstat_parser_init() {
    7|  5.31k|    readstat_parser_t *parser = calloc(1, sizeof(readstat_parser_t));
    8|  5.31k|    parser->io = calloc(1, sizeof(readstat_io_t));
    9|  5.31k|    if (unistd_io_init(parser) != READSTAT_OK) {
  ------------------
  |  Branch (9:9): [True: 0, False: 5.31k]
  ------------------
   10|      0|        readstat_parser_free(parser);
   11|      0|        return NULL;
   12|      0|    }
   13|  5.31k|    parser->output_encoding = "UTF-8";
   14|  5.31k|    return parser;
   15|  5.31k|}
readstat_parser_free:
   17|  5.31k|void readstat_parser_free(readstat_parser_t *parser) {
   18|  5.31k|    if (parser) {
  ------------------
  |  Branch (18:9): [True: 5.31k, False: 0]
  ------------------
   19|  5.31k|        if (parser->io) {
  ------------------
  |  Branch (19:13): [True: 5.31k, False: 0]
  ------------------
   20|  5.31k|            readstat_set_io_ctx(parser, NULL);
   21|  5.31k|            free(parser->io);
   22|  5.31k|        }
   23|  5.31k|        free(parser);
   24|  5.31k|    }
   25|  5.31k|}
readstat_set_metadata_handler:
   27|  5.31k|readstat_error_t readstat_set_metadata_handler(readstat_parser_t *parser, readstat_metadata_handler metadata_handler) {
   28|  5.31k|    parser->handlers.metadata = metadata_handler;
   29|  5.31k|    return READSTAT_OK;
   30|  5.31k|}
readstat_set_note_handler:
   32|  5.31k|readstat_error_t readstat_set_note_handler(readstat_parser_t *parser, readstat_note_handler note_handler) {
   33|  5.31k|    parser->handlers.note = note_handler;
   34|  5.31k|    return READSTAT_OK;
   35|  5.31k|}
readstat_set_variable_handler:
   37|  5.31k|readstat_error_t readstat_set_variable_handler(readstat_parser_t *parser, readstat_variable_handler variable_handler) {
   38|  5.31k|    parser->handlers.variable = variable_handler;
   39|  5.31k|    return READSTAT_OK;
   40|  5.31k|}
readstat_set_value_handler:
   42|  5.31k|readstat_error_t readstat_set_value_handler(readstat_parser_t *parser, readstat_value_handler value_handler) {
   43|  5.31k|    parser->handlers.value = value_handler;
   44|  5.31k|    return READSTAT_OK;
   45|  5.31k|}
readstat_set_value_label_handler:
   47|  5.31k|readstat_error_t readstat_set_value_label_handler(readstat_parser_t *parser, readstat_value_label_handler label_handler) {
   48|  5.31k|    parser->handlers.value_label = label_handler;
   49|  5.31k|    return READSTAT_OK;
   50|  5.31k|}
readstat_set_fweight_handler:
   62|  5.31k|readstat_error_t readstat_set_fweight_handler(readstat_parser_t *parser, readstat_fweight_handler fweight_handler) {
   63|  5.31k|    parser->handlers.fweight = fweight_handler;
   64|  5.31k|    return READSTAT_OK;
   65|  5.31k|}
readstat_set_open_handler:
   67|  10.6k|readstat_error_t readstat_set_open_handler(readstat_parser_t *parser, readstat_open_handler open_handler) {
   68|  10.6k|    parser->io->open = open_handler;
   69|  10.6k|    return READSTAT_OK;
   70|  10.6k|}
readstat_set_close_handler:
   72|  10.6k|readstat_error_t readstat_set_close_handler(readstat_parser_t *parser, readstat_close_handler close_handler) {
   73|  10.6k|    parser->io->close = close_handler;
   74|  10.6k|    return READSTAT_OK;
   75|  10.6k|}
readstat_set_seek_handler:
   77|  10.6k|readstat_error_t readstat_set_seek_handler(readstat_parser_t *parser, readstat_seek_handler seek_handler) {
   78|  10.6k|    parser->io->seek = seek_handler;
   79|  10.6k|    return READSTAT_OK;
   80|  10.6k|}
readstat_set_read_handler:
   82|  10.6k|readstat_error_t readstat_set_read_handler(readstat_parser_t *parser, readstat_read_handler read_handler) {
   83|  10.6k|    parser->io->read = read_handler;
   84|  10.6k|    return READSTAT_OK;
   85|  10.6k|}
readstat_set_update_handler:
   87|  10.6k|readstat_error_t readstat_set_update_handler(readstat_parser_t *parser, readstat_update_handler update_handler) {
   88|  10.6k|    parser->io->update = update_handler;
   89|  10.6k|    return READSTAT_OK;
   90|  10.6k|}
readstat_set_io_ctx:
   92|  15.9k|readstat_error_t readstat_set_io_ctx(readstat_parser_t *parser, void *io_ctx) {
   93|  15.9k|    if (parser->io->io_ctx_needs_free) {
  ------------------
  |  Branch (93:9): [True: 5.31k, False: 10.6k]
  ------------------
   94|  5.31k|        free(parser->io->io_ctx);
   95|  5.31k|    }
   96|       |
   97|  15.9k|    parser->io->io_ctx = io_ctx;
   98|  15.9k|    parser->io->io_ctx_needs_free = 0;
   99|       |
  100|  15.9k|    return READSTAT_OK;
  101|  15.9k|}

sav_ctx_init:
   23|  5.29k|sav_ctx_t *sav_ctx_init(sav_file_header_record_t *header, readstat_io_t *io) {
   24|  5.29k|    sav_ctx_t *ctx = readstat_calloc(1, sizeof(sav_ctx_t));
   25|  5.29k|    if (ctx == NULL) {
  ------------------
  |  Branch (25:9): [True: 0, False: 5.29k]
  ------------------
   26|      0|        return NULL;
   27|      0|    }
   28|       |
   29|  5.29k|    if (memcmp(&header->rec_type, "$FL2", 4) == 0) {
  ------------------
  |  Branch (29:9): [True: 3.29k, False: 2.00k]
  ------------------
   30|  3.29k|        ctx->format_version = 2;
   31|  3.29k|    } else if (memcmp(&header->rec_type, "$FL3", 4) == 0) {
  ------------------
  |  Branch (31:16): [True: 1.97k, False: 31]
  ------------------
   32|  1.97k|        ctx->format_version = 3;
   33|  1.97k|    } else {
   34|     31|        sav_ctx_free(ctx);
   35|     31|        return NULL;
   36|     31|    }
   37|       |    
   38|  5.26k|    ctx->bswap = !(header->layout_code == 2 || header->layout_code == 3);
  ------------------
  |  Branch (38:20): [True: 3.61k, False: 1.65k]
  |  Branch (38:48): [True: 142, False: 1.50k]
  ------------------
   39|  5.26k|    ctx->endianness = (machine_is_little_endian() ^ ctx->bswap) ? READSTAT_ENDIAN_LITTLE : READSTAT_ENDIAN_BIG;
  ------------------
  |  Branch (39:23): [True: 3.75k, False: 1.50k]
  ------------------
   40|       |
   41|  5.26k|    if (header->compression == 1 || byteswap4(header->compression) == 1) {
  ------------------
  |  Branch (41:9): [True: 390, False: 4.87k]
  |  Branch (41:37): [True: 245, False: 4.62k]
  ------------------
   42|    635|        ctx->compression = READSTAT_COMPRESS_ROWS;
   43|  4.62k|    } else if (header->compression == 2 || byteswap4(header->compression) == 2) {
  ------------------
  |  Branch (43:16): [True: 575, False: 4.05k]
  |  Branch (43:44): [True: 101, False: 3.95k]
  ------------------
   44|    676|        ctx->compression = READSTAT_COMPRESS_BINARY;
   45|    676|    }
   46|  5.26k|    ctx->record_count = ctx->bswap ? byteswap4(header->ncases) : header->ncases;
  ------------------
  |  Branch (46:25): [True: 1.50k, False: 3.75k]
  ------------------
   47|  5.26k|    ctx->fweight_index = ctx->bswap ? byteswap4(header->weight_index) : header->weight_index;
  ------------------
  |  Branch (47:26): [True: 1.50k, False: 3.75k]
  ------------------
   48|       |
   49|  5.26k|    ctx->missing_double = SAV_MISSING_DOUBLE;
  ------------------
  |  |   43|  5.26k|#define SAV_MISSING_DOUBLE   0xFFEFFFFFFFFFFFFFUL
  ------------------
   50|  5.26k|    ctx->lowest_double = SAV_LOWEST_DOUBLE;
  ------------------
  |  |   44|  5.26k|#define SAV_LOWEST_DOUBLE    0xFFEFFFFFFFFFFFFEUL
  ------------------
   51|  5.26k|    ctx->highest_double = SAV_HIGHEST_DOUBLE;
  ------------------
  |  |   42|  5.26k|#define SAV_HIGHEST_DOUBLE   0x7FEFFFFFFFFFFFFFUL
  ------------------
   52|       |    
   53|  5.26k|    ctx->bias = ctx->bswap ? byteswap_double(header->bias) : header->bias;
  ------------------
  |  Branch (53:17): [True: 1.50k, False: 3.75k]
  ------------------
   54|       |    
   55|  5.26k|    ctx->varinfo_capacity = SAV_VARINFO_INITIAL_CAPACITY;
  ------------------
  |  |   21|  5.26k|#define SAV_VARINFO_INITIAL_CAPACITY  512
  ------------------
   56|       |    
   57|  5.26k|    if ((ctx->varinfo = readstat_calloc(ctx->varinfo_capacity, sizeof(spss_varinfo_t *))) == NULL) {
  ------------------
  |  Branch (57:9): [True: 0, False: 5.26k]
  ------------------
   58|      0|        sav_ctx_free(ctx);
   59|      0|        return NULL;
   60|      0|    }
   61|       |
   62|  5.26k|    ctx->io = io;
   63|       |    
   64|  5.26k|    return ctx;
   65|  5.26k|}
sav_ctx_free:
   67|  5.29k|void sav_ctx_free(sav_ctx_t *ctx) {
   68|  5.29k|    if (ctx->varinfo) {
  ------------------
  |  Branch (68:9): [True: 5.26k, False: 31]
  ------------------
   69|  5.26k|        int i;
   70|   305k|        for (i=0; i<ctx->var_index; i++) {
  ------------------
  |  Branch (70:19): [True: 299k, False: 5.26k]
  ------------------
   71|   299k|            spss_varinfo_free(ctx->varinfo[i]);
   72|   299k|        }
   73|  5.26k|        free(ctx->varinfo);
   74|  5.26k|    }
   75|  5.29k|    if (ctx->variables) {
  ------------------
  |  Branch (75:9): [True: 1.56k, False: 3.73k]
  ------------------
   76|  1.56k|        int i;
   77|   167k|        for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (77:19): [True: 166k, False: 1.56k]
  ------------------
   78|   166k|            if (ctx->variables[i])
  ------------------
  |  Branch (78:17): [True: 165k, False: 350]
  ------------------
   79|   165k|                free(ctx->variables[i]);
   80|   166k|        }
   81|  1.56k|        free(ctx->variables);
   82|  1.56k|    }
   83|  5.29k|    if (ctx->raw_string)
  ------------------
  |  Branch (83:9): [True: 1.50k, False: 3.79k]
  ------------------
   84|  1.50k|        free(ctx->raw_string);
   85|  5.29k|    if (ctx->utf8_string)
  ------------------
  |  Branch (85:9): [True: 1.49k, False: 3.80k]
  ------------------
   86|  1.49k|        free(ctx->utf8_string);
   87|  5.29k|    if (ctx->converter)
  ------------------
  |  Branch (87:9): [True: 96, False: 5.19k]
  ------------------
   88|     96|        iconv_close(ctx->converter);
   89|  5.29k|    if (ctx->variable_display_values) {
  ------------------
  |  Branch (89:9): [True: 245, False: 5.05k]
  ------------------
   90|    245|        free(ctx->variable_display_values);
   91|    245|    }
   92|  5.29k|    free(ctx);
   93|  5.29k|}

sav_decompress_row:
   77|  2.26M|void sav_decompress_row(struct sav_row_stream_s *state) {
   78|  2.26M|    double fp_value;
   79|  2.26M|    uint64_t missing_value = state->bswap ? byteswap8(state->missing_value) : state->missing_value;
  ------------------
  |  Branch (79:30): [True: 1.35M, False: 909k]
  ------------------
   80|  2.26M|    int i = 8 - state->i;
   81|  2.51M|    while (1) {
  ------------------
  |  Branch (81:12): [Folded - Ignored]
  ------------------
   82|  2.51M|        if (i == 8) {
  ------------------
  |  Branch (82:13): [True: 531k, False: 1.98M]
  ------------------
   83|   531k|            if (state->avail_in < 8) {
  ------------------
  |  Branch (83:17): [True: 307, False: 530k]
  ------------------
   84|    307|                state->status = SAV_ROW_STREAM_NEED_DATA;
   85|    307|                goto done;
   86|    307|            }
   87|       |
   88|   530k|            memcpy(state->chunk, state->next_in, 8);
   89|   530k|            state->next_in += 8;
   90|   530k|            state->avail_in -= 8;
   91|   530k|            i = 0;
   92|   530k|        }
   93|       |
   94|  4.49M|        while (i<8) {
  ------------------
  |  Branch (94:16): [True: 4.24M, False: 251k]
  ------------------
   95|  4.24M|            switch (state->chunk[i]) {
   96|  1.69M|                case 0:
  ------------------
  |  Branch (96:17): [True: 1.69M, False: 2.55M]
  ------------------
   97|  1.69M|                    break;
   98|     70|                case 252:
  ------------------
  |  Branch (98:17): [True: 70, False: 4.24M]
  ------------------
   99|     70|                    state->status = SAV_ROW_STREAM_FINISHED_ALL;
  100|     70|                    goto done;
  101|  96.5k|                case 253:
  ------------------
  |  Branch (101:17): [True: 96.5k, False: 4.15M]
  ------------------
  102|  96.5k|                    if (state->avail_in < 8) {
  ------------------
  |  Branch (102:25): [True: 57, False: 96.5k]
  ------------------
  103|     57|                        state->status = SAV_ROW_STREAM_NEED_DATA;
  104|     57|                        goto done;
  105|     57|                    }
  106|  96.5k|                    memcpy(state->next_out, state->next_in, 8);
  107|  96.5k|                    state->next_out += 8;
  108|  96.5k|                    state->avail_out -= 8;
  109|  96.5k|                    state->next_in += 8;
  110|  96.5k|                    state->avail_in -= 8;
  111|  96.5k|                    break;
  112|  7.11k|                case 254:
  ------------------
  |  Branch (112:17): [True: 7.11k, False: 4.24M]
  ------------------
  113|  7.11k|                    memset(state->next_out, ' ', 8);
  114|  7.11k|                    state->next_out += 8;
  115|  7.11k|                    state->avail_out -= 8;
  116|  7.11k|                    break;
  117|   147k|                case 255:
  ------------------
  |  Branch (117:17): [True: 147k, False: 4.09M]
  ------------------
  118|   147k|                    memcpy(state->next_out, &missing_value, sizeof(uint64_t));
  119|   147k|                    state->next_out += 8;
  120|   147k|                    state->avail_out -= 8;
  121|   147k|                    break;
  122|  2.30M|                default:
  ------------------
  |  Branch (122:17): [True: 2.30M, False: 1.94M]
  ------------------
  123|  2.30M|                    fp_value = state->chunk[i] - state->bias;
  124|  2.30M|                    fp_value = state->bswap ? byteswap_double(fp_value) : fp_value;
  ------------------
  |  Branch (124:32): [True: 1.24M, False: 1.06M]
  ------------------
  125|  2.30M|                    memcpy(state->next_out, &fp_value, sizeof(double));
  126|  2.30M|                    state->next_out += 8;
  127|  2.30M|                    state->avail_out -= 8;
  128|  2.30M|                    break;
  129|  4.24M|            }
  130|  4.24M|            i++;
  131|  4.24M|            if (state->avail_out < 8) {
  ------------------
  |  Branch (131:17): [True: 2.26M, False: 1.98M]
  ------------------
  132|  2.26M|                state->status = SAV_ROW_STREAM_FINISHED_ROW;
  133|  2.26M|                goto done;
  134|  2.26M|            }
  135|  4.24M|        }
  136|  2.51M|    }
  137|  2.26M|done:
  138|  2.26M|    state->i = 8 - i;
  139|  2.26M|}

sav_parse_long_variable_names_record:
  329|  1.11k|readstat_error_t sav_parse_long_variable_names_record(void *data, int count, sav_ctx_t *ctx) {
  330|  1.11k|	unsigned char *c_data = (unsigned char *)data;
  331|  1.11k|	int var_count = count_vars(ctx);
  332|  1.11k|	readstat_error_t retval = READSTAT_OK;
  333|       |	
  334|  1.11k|	char temp_key[8+1];
  335|  1.11k|	char temp_val[64+1];
  336|  1.11k|	unsigned char *str_start = NULL;
  337|  1.11k|	size_t str_len = 0;
  338|       |	
  339|  1.11k|	char error_buf[8192];
  340|  1.11k|	unsigned char *p = c_data;
  341|  1.11k|	unsigned char *pe = c_data + count;
  342|       |	
  343|  1.11k|	varlookup_t *table = build_lookup_table(var_count, ctx);
  344|       |	
  345|  1.11k|	unsigned char *eof = pe;
  346|       |	
  347|  1.11k|	int cs;
  348|       |	
  349|       |	
  350|  1.11k|#line 351 "src/spss/readstat_sav_parse.c"
  351|  1.11k|	{
  352|  1.11k|		cs = (int)sav_long_variable_parse_start;
  353|  1.11k|	}
  354|       |	
  355|  1.11k|#line 356 "src/spss/readstat_sav_parse.c"
  356|  1.11k|	{
  357|  1.11k|		int _klen;
  358|  1.11k|		unsigned int _trans = 0;
  359|  1.11k|		const unsigned char * _keys;
  360|  1.11k|		const signed char * _acts;
  361|  1.11k|		unsigned int _nacts;
  362|  9.93k|		_resume: {}
  363|  9.93k|		if ( p == pe && p != eof )
  ------------------
  |  Branch (363:8): [True: 1.07k, False: 8.86k]
  |  Branch (363:19): [True: 0, False: 1.07k]
  ------------------
  364|      0|			goto _out;
  365|  9.93k|		if ( p == eof ) {
  ------------------
  |  Branch (365:8): [True: 1.07k, False: 8.86k]
  ------------------
  366|  1.07k|			if ( _sav_long_variable_parse_eof_trans[cs] > 0 ) {
  ------------------
  |  Branch (366:9): [True: 1.07k, False: 0]
  ------------------
  367|  1.07k|				_trans = (unsigned int)_sav_long_variable_parse_eof_trans[cs] - 1;
  368|  1.07k|			}
  369|  1.07k|		}
  370|  8.86k|		else {
  371|  8.86k|			_keys = ( _sav_long_variable_parse_trans_keys + (_sav_long_variable_parse_key_offsets[cs]));
  372|  8.86k|			_trans = (unsigned int)_sav_long_variable_parse_index_offsets[cs];
  373|       |			
  374|  8.86k|			_klen = (int)_sav_long_variable_parse_single_lengths[cs];
  375|  8.86k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (375:9): [True: 8.86k, False: 0]
  ------------------
  376|  8.86k|				const unsigned char *_lower = _keys;
  377|  8.86k|				const unsigned char *_upper = _keys + _klen - 1;
  378|  8.86k|				const unsigned char *_mid;
  379|  18.3k|				while ( 1 ) {
  ------------------
  |  Branch (379:13): [Folded - Ignored]
  ------------------
  380|  18.3k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (380:11): [True: 5.87k, False: 12.4k]
  ------------------
  381|  5.87k|						_keys += _klen;
  382|  5.87k|						_trans += (unsigned int)_klen;
  383|  5.87k|						break;
  384|  5.87k|					}
  385|       |					
  386|  12.4k|					_mid = _lower + ((_upper-_lower) >> 1);
  387|  12.4k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (387:11): [True: 6.99k, False: 5.46k]
  ------------------
  388|  6.99k|						_upper = _mid - 1;
  389|  5.46k|					else if ( ( (*( p))) > (*( _mid)) )
  ------------------
  |  Branch (389:16): [True: 2.47k, False: 2.98k]
  ------------------
  390|  2.47k|						_lower = _mid + 1;
  391|  2.98k|					else {
  392|  2.98k|						_trans += (unsigned int)(_mid - _keys);
  393|  2.98k|						goto _match;
  394|  2.98k|					}
  395|  12.4k|				}
  396|  8.86k|			}
  397|       |			
  398|  5.87k|			_klen = (int)_sav_long_variable_parse_range_lengths[cs];
  399|  5.87k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (399:9): [True: 5.86k, False: 4]
  ------------------
  400|  5.86k|				const unsigned char *_lower = _keys;
  401|  5.86k|				const unsigned char *_upper = _keys + (_klen<<1) - 2;
  402|  5.86k|				const unsigned char *_mid;
  403|  15.4k|				while ( 1 ) {
  ------------------
  |  Branch (403:13): [Folded - Ignored]
  ------------------
  404|  15.4k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (404:11): [True: 5.83k, False: 9.59k]
  ------------------
  405|  5.83k|						_trans += (unsigned int)_klen;
  406|  5.83k|						break;
  407|  5.83k|					}
  408|       |					
  409|  9.59k|					_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  410|  9.59k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (410:11): [True: 1.80k, False: 7.79k]
  ------------------
  411|  1.80k|						_upper = _mid - 2;
  412|  7.79k|					else if ( ( (*( p))) > (*( _mid + 1)) )
  ------------------
  |  Branch (412:16): [True: 7.76k, False: 29]
  ------------------
  413|  7.76k|						_lower = _mid + 2;
  414|     29|					else {
  415|     29|						_trans += (unsigned int)((_mid - _keys)>>1);
  416|     29|						break;
  417|     29|					}
  418|  9.59k|				}
  419|  5.86k|			}
  420|       |			
  421|  8.86k|			_match: {}
  422|  8.86k|		}
  423|  9.93k|		cs = (int)_sav_long_variable_parse_cond_targs[_trans];
  424|       |		
  425|  9.93k|		if ( _sav_long_variable_parse_cond_actions[_trans] != 0 ) {
  ------------------
  |  Branch (425:8): [True: 7.97k, False: 1.95k]
  ------------------
  426|       |			
  427|  7.97k|			_acts = ( _sav_long_variable_parse_actions + (_sav_long_variable_parse_cond_actions[_trans]));
  428|  7.97k|			_nacts = (unsigned int)(*( _acts));
  429|  7.97k|			_acts += 1;
  430|  21.8k|			while ( _nacts > 0 ) {
  ------------------
  |  Branch (430:12): [True: 13.8k, False: 7.97k]
  ------------------
  431|  13.8k|				switch ( (*( _acts)) )
  ------------------
  |  Branch (431:14): [True: 0, False: 13.8k]
  ------------------
  432|  13.8k|				{
  433|  1.96k|					case 0:  {
  ------------------
  |  Branch (433:6): [True: 1.96k, False: 11.8k]
  ------------------
  434|  1.96k|						{
  435|  1.96k|#line 13 "src/spss/readstat_sav_parse.rl"
  436|       |							
  437|  1.96k|							memcpy(temp_key, str_start, str_len);
  438|  1.96k|							temp_key[str_len] = '\0';
  439|  1.96k|						}
  440|       |						
  441|  1.96k|#line 442 "src/spss/readstat_sav_parse.c"
  442|       |						
  443|  1.96k|						break; 
  444|      0|					}
  445|  2.10k|					case 1:  {
  ------------------
  |  Branch (445:6): [True: 2.10k, False: 11.7k]
  ------------------
  446|  2.10k|						{
  447|  2.10k|#line 20 "src/spss/readstat_sav_parse.rl"
  448|  2.10k|							str_start = p; }
  449|       |						
  450|  2.10k|#line 451 "src/spss/readstat_sav_parse.c"
  451|       |						
  452|  2.10k|						break; 
  453|      0|					}
  454|  1.96k|					case 2:  {
  ------------------
  |  Branch (454:6): [True: 1.96k, False: 11.8k]
  ------------------
  455|  1.96k|						{
  456|  1.96k|#line 20 "src/spss/readstat_sav_parse.rl"
  457|  1.96k|							str_len = p - str_start; }
  458|       |						
  459|  1.96k|#line 460 "src/spss/readstat_sav_parse.c"
  460|       |						
  461|  1.96k|						break; 
  462|      0|					}
  463|  1.95k|					case 3:  {
  ------------------
  |  Branch (463:6): [True: 1.95k, False: 11.8k]
  ------------------
  464|  1.95k|						{
  465|  1.95k|#line 102 "src/spss/readstat_sav_parse.rl"
  466|       |							
  467|  1.95k|							varlookup_t *found = bsearch(temp_key, table, var_count, sizeof(varlookup_t), &compare_key_varlookup);
  468|  1.95k|							if (found) {
  ------------------
  |  Branch (468:12): [True: 196, False: 1.75k]
  ------------------
  469|    196|								spss_varinfo_t *info = ctx->varinfo[found->index];
  470|    196|								memcpy(info->longname, temp_val, str_len);
  471|    196|								info->longname[str_len] = '\0';
  472|  1.75k|							} else if (ctx->handle.error) {
  ------------------
  |  Branch (472:19): [True: 0, False: 1.75k]
  ------------------
  473|      0|								snprintf(error_buf, sizeof(error_buf), "Failed to find %s", temp_key);
  474|      0|								ctx->handle.error(error_buf, ctx->user_ctx);
  475|      0|							}
  476|  1.95k|						}
  477|       |						
  478|  1.95k|#line 479 "src/spss/readstat_sav_parse.c"
  479|       |						
  480|  1.95k|						break; 
  481|      0|					}
  482|  1.95k|					case 4:  {
  ------------------
  |  Branch (482:6): [True: 1.95k, False: 11.8k]
  ------------------
  483|  1.95k|						{
  484|  1.95k|#line 114 "src/spss/readstat_sav_parse.rl"
  485|       |							
  486|  1.95k|							memcpy(temp_val, str_start, str_len);
  487|  1.95k|							temp_val[str_len] = '\0';
  488|  1.95k|						}
  489|       |						
  490|  1.95k|#line 491 "src/spss/readstat_sav_parse.c"
  491|       |						
  492|  1.95k|						break; 
  493|      0|					}
  494|  1.95k|					case 5:  {
  ------------------
  |  Branch (494:6): [True: 1.95k, False: 11.8k]
  ------------------
  495|  1.95k|						{
  496|  1.95k|#line 119 "src/spss/readstat_sav_parse.rl"
  497|  1.95k|							str_start = p; }
  498|       |						
  499|  1.95k|#line 500 "src/spss/readstat_sav_parse.c"
  500|       |						
  501|  1.95k|						break; 
  502|      0|					}
  503|  1.95k|					case 6:  {
  ------------------
  |  Branch (503:6): [True: 1.95k, False: 11.8k]
  ------------------
  504|  1.95k|						{
  505|  1.95k|#line 119 "src/spss/readstat_sav_parse.rl"
  506|  1.95k|							str_len = p - str_start; }
  507|       |						
  508|  1.95k|#line 509 "src/spss/readstat_sav_parse.c"
  509|       |						
  510|  1.95k|						break; 
  511|      0|					}
  512|  13.8k|				}
  513|  13.8k|				_nacts -= 1;
  514|  13.8k|				_acts += 1;
  515|  13.8k|			}
  516|       |			
  517|  7.97k|		}
  518|       |		
  519|  9.93k|		if ( p == eof ) {
  ------------------
  |  Branch (519:8): [True: 1.07k, False: 8.86k]
  ------------------
  520|  1.07k|			if ( cs >= 11 )
  ------------------
  |  Branch (520:9): [True: 937, False: 134]
  ------------------
  521|    937|				goto _out;
  522|  1.07k|		}
  523|  8.86k|		else {
  524|  8.86k|			if ( cs != 0 ) {
  ------------------
  |  Branch (524:9): [True: 8.81k, False: 41]
  ------------------
  525|  8.81k|				p += 1;
  526|  8.81k|				goto _resume;
  527|  8.81k|			}
  528|  8.86k|		}
  529|  1.11k|		_out: {}
  530|  1.11k|	}
  531|       |	
  532|      0|#line 127 "src/spss/readstat_sav_parse.rl"
  533|       |	
  534|       |	
  535|  1.11k|	if (cs < 
  ------------------
  |  Branch (535:6): [True: 175, False: 937]
  ------------------
  536|  1.11k|#line 537 "src/spss/readstat_sav_parse.c"
  537|  1.11k|	11
  538|  1.11k|#line 129 "src/spss/readstat_sav_parse.rl"
  539|  1.11k|	|| p != pe) {
  ------------------
  |  Branch (539:5): [True: 0, False: 937]
  ------------------
  540|    175|		if (ctx->handle.error) {
  ------------------
  |  Branch (540:7): [True: 0, False: 175]
  ------------------
  541|      0|			snprintf(error_buf, sizeof(error_buf), "Error parsing string \"%.*s\" around byte #%ld/%d, character %c", 
  542|      0|			count, (char *)data, (long)(p - c_data), count, *p);
  543|      0|			ctx->handle.error(error_buf, ctx->user_ctx);
  544|      0|		}
  545|    175|		retval = READSTAT_ERROR_PARSE;
  546|    175|	}
  547|       |	
  548|       |	
  549|  1.11k|	if (table)
  ------------------
  |  Branch (549:6): [True: 595, False: 517]
  ------------------
  550|    595|		free(table);
  551|       |	
  552|       |	/* suppress warning */
  553|  1.11k|	(void)sav_long_variable_parse_en_main;
  554|       |	
  555|  1.11k|	return retval;
  556|  9.93k|}
sav_parse_very_long_string_record:
  648|  2.22k|readstat_error_t sav_parse_very_long_string_record(void *data, int count, sav_ctx_t *ctx) {
  649|  2.22k|	unsigned char *c_data = (unsigned char *)data;
  650|  2.22k|	int var_count = count_vars(ctx);
  651|  2.22k|	readstat_error_t retval = READSTAT_OK;
  652|       |	
  653|  2.22k|	char temp_key[8*4+1];
  654|  2.22k|	unsigned int temp_val = 0;
  655|  2.22k|	unsigned char *str_start = NULL;
  656|  2.22k|	size_t str_len = 0;
  657|       |	
  658|  2.22k|	size_t error_buf_len = 1024 + count;
  659|  2.22k|	char *error_buf = NULL;
  660|  2.22k|	unsigned char *p = c_data;
  661|  2.22k|	unsigned char *pe = c_data + count;
  662|  2.22k|	unsigned char *eof = pe;
  663|       |	
  664|  2.22k|	varlookup_t *table = NULL;
  665|  2.22k|	int cs;
  666|       |	
  667|  2.22k|	error_buf = readstat_malloc(error_buf_len);
  668|  2.22k|	table = build_lookup_table(var_count, ctx);
  669|       |	
  670|       |	
  671|  2.22k|#line 672 "src/spss/readstat_sav_parse.c"
  672|  2.22k|	{
  673|  2.22k|		cs = (int)sav_very_long_string_parse_start;
  674|  2.22k|	}
  675|       |	
  676|  2.22k|#line 677 "src/spss/readstat_sav_parse.c"
  677|  2.22k|	{
  678|  2.22k|		int _klen;
  679|  2.22k|		unsigned int _trans = 0;
  680|  2.22k|		const unsigned char * _keys;
  681|  2.22k|		const signed char * _acts;
  682|  2.22k|		unsigned int _nacts;
  683|  23.0k|		_resume: {}
  684|  23.0k|		if ( p == pe && p != eof )
  ------------------
  |  Branch (684:8): [True: 1.93k, False: 21.1k]
  |  Branch (684:19): [True: 0, False: 1.93k]
  ------------------
  685|      0|			goto _out;
  686|  23.0k|		if ( p == eof ) {
  ------------------
  |  Branch (686:8): [True: 1.93k, False: 21.1k]
  ------------------
  687|  1.93k|			if ( _sav_very_long_string_parse_eof_trans[cs] > 0 ) {
  ------------------
  |  Branch (687:9): [True: 1.93k, False: 0]
  ------------------
  688|  1.93k|				_trans = (unsigned int)_sav_very_long_string_parse_eof_trans[cs] - 1;
  689|  1.93k|			}
  690|  1.93k|		}
  691|  21.1k|		else {
  692|  21.1k|			_keys = ( _sav_very_long_string_parse_trans_keys + (_sav_very_long_string_parse_key_offsets[cs]));
  693|  21.1k|			_trans = (unsigned int)_sav_very_long_string_parse_index_offsets[cs];
  694|       |			
  695|  21.1k|			_klen = (int)_sav_very_long_string_parse_single_lengths[cs];
  696|  21.1k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (696:9): [True: 18.3k, False: 2.81k]
  ------------------
  697|  18.3k|				const unsigned char *_lower = _keys;
  698|  18.3k|				const unsigned char *_upper = _keys + _klen - 1;
  699|  18.3k|				const unsigned char *_mid;
  700|  38.4k|				while ( 1 ) {
  ------------------
  |  Branch (700:13): [Folded - Ignored]
  ------------------
  701|  38.4k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (701:11): [True: 10.9k, False: 27.5k]
  ------------------
  702|  10.9k|						_keys += _klen;
  703|  10.9k|						_trans += (unsigned int)_klen;
  704|  10.9k|						break;
  705|  10.9k|					}
  706|       |					
  707|  27.5k|					_mid = _lower + ((_upper-_lower) >> 1);
  708|  27.5k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (708:11): [True: 4.89k, False: 22.6k]
  ------------------
  709|  4.89k|						_upper = _mid - 1;
  710|  22.6k|					else if ( ( (*( p))) > (*( _mid)) )
  ------------------
  |  Branch (710:16): [True: 15.2k, False: 7.38k]
  ------------------
  711|  15.2k|						_lower = _mid + 1;
  712|  7.38k|					else {
  713|  7.38k|						_trans += (unsigned int)(_mid - _keys);
  714|  7.38k|						goto _match;
  715|  7.38k|					}
  716|  27.5k|				}
  717|  18.3k|			}
  718|       |			
  719|  13.7k|			_klen = (int)_sav_very_long_string_parse_range_lengths[cs];
  720|  13.7k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (720:9): [True: 13.7k, False: 9]
  ------------------
  721|  13.7k|				const unsigned char *_lower = _keys;
  722|  13.7k|				const unsigned char *_upper = _keys + (_klen<<1) - 2;
  723|  13.7k|				const unsigned char *_mid;
  724|  24.3k|				while ( 1 ) {
  ------------------
  |  Branch (724:13): [Folded - Ignored]
  ------------------
  725|  24.3k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (725:11): [True: 4.72k, False: 19.6k]
  ------------------
  726|  4.72k|						_trans += (unsigned int)_klen;
  727|  4.72k|						break;
  728|  4.72k|					}
  729|       |					
  730|  19.6k|					_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  731|  19.6k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (731:11): [True: 3.17k, False: 16.4k]
  ------------------
  732|  3.17k|						_upper = _mid - 2;
  733|  16.4k|					else if ( ( (*( p))) > (*( _mid + 1)) )
  ------------------
  |  Branch (733:16): [True: 7.46k, False: 9.00k]
  ------------------
  734|  7.46k|						_lower = _mid + 2;
  735|  9.00k|					else {
  736|  9.00k|						_trans += (unsigned int)((_mid - _keys)>>1);
  737|  9.00k|						break;
  738|  9.00k|					}
  739|  19.6k|				}
  740|  13.7k|			}
  741|       |			
  742|  21.1k|			_match: {}
  743|  21.1k|		}
  744|  23.0k|		cs = (int)_sav_very_long_string_parse_cond_targs[_trans];
  745|       |		
  746|  23.0k|		if ( _sav_very_long_string_parse_cond_actions[_trans] != 0 ) {
  ------------------
  |  Branch (746:8): [True: 17.2k, False: 5.75k]
  ------------------
  747|       |			
  748|  17.2k|			_acts = ( _sav_very_long_string_parse_actions + (_sav_very_long_string_parse_cond_actions[_trans]));
  749|  17.2k|			_nacts = (unsigned int)(*( _acts));
  750|  17.2k|			_acts += 1;
  751|  40.0k|			while ( _nacts > 0 ) {
  ------------------
  |  Branch (751:12): [True: 22.9k, False: 17.0k]
  ------------------
  752|  22.9k|				switch ( (*( _acts)) )
  ------------------
  |  Branch (752:14): [True: 0, False: 22.9k]
  ------------------
  753|  22.9k|				{
  754|  2.82k|					case 0:  {
  ------------------
  |  Branch (754:6): [True: 2.82k, False: 20.1k]
  ------------------
  755|  2.82k|						{
  756|  2.82k|#line 13 "src/spss/readstat_sav_parse.rl"
  757|       |							
  758|  2.82k|							memcpy(temp_key, str_start, str_len);
  759|  2.82k|							temp_key[str_len] = '\0';
  760|  2.82k|						}
  761|       |						
  762|  2.82k|#line 763 "src/spss/readstat_sav_parse.c"
  763|       |						
  764|  2.82k|						break; 
  765|      0|					}
  766|  2.94k|					case 1:  {
  ------------------
  |  Branch (766:6): [True: 2.94k, False: 19.9k]
  ------------------
  767|  2.94k|						{
  768|  2.94k|#line 20 "src/spss/readstat_sav_parse.rl"
  769|  2.94k|							str_start = p; }
  770|       |						
  771|  2.94k|#line 772 "src/spss/readstat_sav_parse.c"
  772|       |						
  773|  2.94k|						break; 
  774|      0|					}
  775|  2.82k|					case 2:  {
  ------------------
  |  Branch (775:6): [True: 2.82k, False: 20.1k]
  ------------------
  776|  2.82k|						{
  777|  2.82k|#line 20 "src/spss/readstat_sav_parse.rl"
  778|  2.82k|							str_len = p - str_start; }
  779|       |						
  780|  2.82k|#line 781 "src/spss/readstat_sav_parse.c"
  781|       |						
  782|  2.82k|						break; 
  783|      0|					}
  784|  2.58k|					case 3:  {
  ------------------
  |  Branch (784:6): [True: 2.58k, False: 20.3k]
  ------------------
  785|  2.58k|						{
  786|  2.58k|#line 178 "src/spss/readstat_sav_parse.rl"
  787|       |							
  788|  2.58k|							varlookup_t *found = bsearch(temp_key, table, var_count, sizeof(varlookup_t), &compare_key_varlookup);
  789|  2.58k|							if (found) {
  ------------------
  |  Branch (789:12): [True: 922, False: 1.65k]
  ------------------
  790|    922|								ctx->varinfo[found->index]->string_length = temp_val;
  791|    922|								ctx->varinfo[found->index]->write_format.width = temp_val;
  792|    922|								ctx->varinfo[found->index]->print_format.width = temp_val;
  793|    922|							}
  794|  2.58k|						}
  795|       |						
  796|  2.58k|#line 797 "src/spss/readstat_sav_parse.c"
  797|       |						
  798|  2.58k|						break; 
  799|      0|					}
  800|  8.95k|					case 4:  {
  ------------------
  |  Branch (800:6): [True: 8.95k, False: 13.9k]
  ------------------
  801|  8.95k|						{
  802|  8.95k|#line 187 "src/spss/readstat_sav_parse.rl"
  803|       |							
  804|  8.95k|							if ((( (*( p)))) != '\0') {
  ------------------
  |  Branch (804:12): [True: 8.95k, False: 0]
  ------------------
  805|  8.95k|								unsigned char digit = (( (*( p)))) - '0';
  806|  8.95k|								if (temp_val <= (UINT_MAX - digit) / 10) {
  ------------------
  |  Branch (806:13): [True: 8.73k, False: 226]
  ------------------
  807|  8.73k|									temp_val = 10 * temp_val + digit;
  808|  8.73k|								} else {
  809|    226|									{p += 1; goto _out; }
  810|    226|								}
  811|  8.95k|							}
  812|  8.95k|						}
  813|       |						
  814|  8.73k|#line 815 "src/spss/readstat_sav_parse.c"
  815|       |						
  816|  8.73k|						break; 
  817|  8.95k|					}
  818|  8.73k|					case 5:  {
  ------------------
  |  Branch (818:6): [True: 2.81k, False: 20.1k]
  ------------------
  819|  2.81k|						{
  820|  2.81k|#line 198 "src/spss/readstat_sav_parse.rl"
  821|  2.81k|							temp_val = 0; }
  822|       |						
  823|  2.81k|#line 824 "src/spss/readstat_sav_parse.c"
  824|       |						
  825|  2.81k|						break; 
  826|  8.95k|					}
  827|  22.9k|				}
  828|  22.7k|				_nacts -= 1;
  829|  22.7k|				_acts += 1;
  830|  22.7k|			}
  831|       |			
  832|  17.2k|		}
  833|       |		
  834|  22.8k|		if ( p == eof ) {
  ------------------
  |  Branch (834:8): [True: 1.93k, False: 20.8k]
  ------------------
  835|  1.93k|			if ( cs >= 11 )
  ------------------
  |  Branch (835:9): [True: 1.82k, False: 111]
  ------------------
  836|  1.82k|				goto _out;
  837|  1.93k|		}
  838|  20.8k|		else {
  839|  20.8k|			if ( cs != 0 ) {
  ------------------
  |  Branch (839:9): [True: 20.8k, False: 65]
  ------------------
  840|  20.8k|				p += 1;
  841|  20.8k|				goto _resume;
  842|  20.8k|			}
  843|  20.8k|		}
  844|  2.22k|		_out: {}
  845|  2.22k|	}
  846|       |	
  847|      0|#line 206 "src/spss/readstat_sav_parse.rl"
  848|       |	
  849|       |	
  850|  2.22k|	if (cs < 
  ------------------
  |  Branch (850:6): [True: 176, False: 2.05k]
  ------------------
  851|  2.22k|#line 852 "src/spss/readstat_sav_parse.c"
  852|  2.22k|	11
  853|  2.22k|#line 208 "src/spss/readstat_sav_parse.rl"
  854|  2.22k|	|| p != pe) {
  ------------------
  |  Branch (854:5): [True: 2, False: 2.04k]
  ------------------
  855|    178|		if (ctx->handle.error) {
  ------------------
  |  Branch (855:7): [True: 0, False: 178]
  ------------------
  856|      0|			snprintf(error_buf, error_buf_len, "Parsed %ld of %ld bytes. Remaining bytes: %.*s",
  857|      0|			(long)(p - c_data), (long)(pe - c_data), (int)(pe - p), p);
  858|      0|			ctx->handle.error(error_buf, ctx->user_ctx);
  859|      0|		}
  860|    178|		retval = READSTAT_ERROR_PARSE;
  861|    178|	}
  862|       |	
  863|  2.22k|	if (table)
  ------------------
  |  Branch (863:6): [True: 1.69k, False: 530]
  ------------------
  864|  1.69k|		free(table);
  865|  2.22k|	if (error_buf)
  ------------------
  |  Branch (865:6): [True: 2.22k, False: 0]
  ------------------
  866|  2.22k|		free(error_buf);
  867|       |	
  868|       |	/* suppress warning */
  869|  2.22k|	(void)sav_very_long_string_parse_en_main;
  870|       |	
  871|  2.22k|	return retval;
  872|  22.8k|}
readstat_sav_parse.c:count_vars:
   32|  3.33k|static int count_vars(sav_ctx_t *ctx) {
   33|  3.33k|	int i;
   34|  3.33k|	spss_varinfo_t *last_info = NULL;
   35|  3.33k|	int var_count = 0;
   36|  1.20M|	for (i=0; i<ctx->var_index; i++) {
  ------------------
  |  Branch (36:12): [True: 1.20M, False: 3.33k]
  ------------------
   37|  1.20M|		spss_varinfo_t *info = ctx->varinfo[i];
   38|  1.20M|		if (last_info == NULL || strcmp(info->name, last_info->name) != 0) {
  ------------------
  |  Branch (38:7): [True: 2.29k, False: 1.20M]
  |  Branch (38:28): [True: 1.14M, False: 56.7k]
  ------------------
   39|  1.14M|			var_count++;
   40|  1.14M|		}
   41|  1.20M|		last_info = info;
   42|  1.20M|	}
   43|  3.33k|	return var_count;
   44|  3.33k|}
readstat_sav_parse.c:build_lookup_table:
   46|  3.33k|static varlookup_t *build_lookup_table(int var_count, sav_ctx_t *ctx) {
   47|  3.33k|	varlookup_t *table = readstat_malloc(var_count * sizeof(varlookup_t));
   48|  3.33k|	int offset = 0;
   49|  3.33k|	int i;
   50|  3.33k|	spss_varinfo_t *last_info = NULL;
   51|  1.20M|	for (i=0; i<ctx->var_index; i++) {
  ------------------
  |  Branch (51:12): [True: 1.20M, False: 3.33k]
  ------------------
   52|  1.20M|		spss_varinfo_t *info = ctx->varinfo[i];
   53|       |		
   54|  1.20M|		if (last_info == NULL || strcmp(info->name, last_info->name) != 0) {
  ------------------
  |  Branch (54:7): [True: 2.29k, False: 1.20M]
  |  Branch (54:28): [True: 1.14M, False: 56.7k]
  ------------------
   55|  1.14M|			varlookup_t *entry = &table[offset++];
   56|       |			
   57|  1.14M|			memcpy(entry->name, info->name, sizeof(info->name));
   58|  1.14M|			entry->index = info->index;
   59|  1.14M|		}
   60|  1.20M|		last_info = info;
   61|  1.20M|	}
   62|  3.33k|	qsort(table, var_count, sizeof(varlookup_t), &compare_varlookups);
   63|  3.33k|	return table;
   64|  3.33k|}
readstat_sav_parse.c:compare_varlookups:
   26|  12.0M|static int compare_varlookups(const void *elem1, const void *elem2) {
   27|  12.0M|	const varlookup_t *v1 = (const varlookup_t *)elem1;
   28|  12.0M|	const varlookup_t *v2 = (const varlookup_t *)elem2;
   29|  12.0M|	return strcasecmp(v1->name, v2->name);
   30|  12.0M|}
readstat_sav_parse.c:compare_key_varlookup:
   20|  7.21k|static int compare_key_varlookup(const void *elem1, const void *elem2) {
   21|  7.21k|	const char *key = (const char *)elem1;
   22|  7.21k|	const varlookup_t *v = (const varlookup_t *)elem2;
   23|  7.21k|	return strcasecmp(key, v->name);
   24|  7.21k|}

sav_parse_time:
   73|  5.26k|readstat_error_handler error_cb, void *user_ctx) {
   74|  5.26k|	readstat_error_t retval = READSTAT_OK;
   75|  5.26k|	char error_buf[8192];
   76|  5.26k|	const char *p = data;
   77|  5.26k|	const char *pe = p + len;
   78|  5.26k|	const char *eof = pe;
   79|  5.26k|	int cs;
   80|  5.26k|	int temp_val = 0;
   81|       |	
   82|  5.26k|#line 83 "src/spss/readstat_sav_parse_timestamp.c"
   83|  5.26k|	{
   84|  5.26k|		cs = (int)sav_time_parse_start;
   85|  5.26k|	}
   86|       |	
   87|  5.26k|#line 88 "src/spss/readstat_sav_parse_timestamp.c"
   88|  5.26k|	{
   89|  5.26k|		int _klen;
   90|  5.26k|		unsigned int _trans = 0;
   91|  5.26k|		const char * _keys;
   92|  5.26k|		const signed char * _acts;
   93|  5.26k|		unsigned int _nacts;
   94|  21.0k|		_resume: {}
   95|  21.0k|		if ( p == pe && p != eof )
  ------------------
  |  Branch (95:8): [True: 1.69k, False: 19.3k]
  |  Branch (95:19): [True: 0, False: 1.69k]
  ------------------
   96|      0|			goto _out;
   97|  21.0k|		if ( p == eof ) {
  ------------------
  |  Branch (97:8): [True: 1.69k, False: 19.3k]
  ------------------
   98|  1.69k|			if ( _sav_time_parse_eof_trans[cs] > 0 ) {
  ------------------
  |  Branch (98:9): [True: 1.69k, False: 0]
  ------------------
   99|  1.69k|				_trans = (unsigned int)_sav_time_parse_eof_trans[cs] - 1;
  100|  1.69k|			}
  101|  1.69k|		}
  102|  19.3k|		else {
  103|  19.3k|			_keys = ( _sav_time_parse_trans_keys + (_sav_time_parse_key_offsets[cs]));
  104|  19.3k|			_trans = (unsigned int)_sav_time_parse_index_offsets[cs];
  105|       |			
  106|  19.3k|			_klen = (int)_sav_time_parse_single_lengths[cs];
  107|  19.3k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (107:9): [True: 13.1k, False: 6.13k]
  ------------------
  108|  13.1k|				const char *_lower = _keys;
  109|  13.1k|				const char *_upper = _keys + _klen - 1;
  110|  13.1k|				const char *_mid;
  111|  22.2k|				while ( 1 ) {
  ------------------
  |  Branch (111:13): [Folded - Ignored]
  ------------------
  112|  22.2k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (112:11): [True: 9.02k, False: 13.1k]
  ------------------
  113|  9.02k|						_keys += _klen;
  114|  9.02k|						_trans += (unsigned int)_klen;
  115|  9.02k|						break;
  116|  9.02k|					}
  117|       |					
  118|  13.1k|					_mid = _lower + ((_upper-_lower) >> 1);
  119|  13.1k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (119:11): [True: 2.57k, False: 10.6k]
  ------------------
  120|  2.57k|						_upper = _mid - 1;
  121|  10.6k|					else if ( ( (*( p))) > (*( _mid)) )
  ------------------
  |  Branch (121:16): [True: 6.45k, False: 4.16k]
  ------------------
  122|  6.45k|						_lower = _mid + 1;
  123|  4.16k|					else {
  124|  4.16k|						_trans += (unsigned int)(_mid - _keys);
  125|  4.16k|						goto _match;
  126|  4.16k|					}
  127|  13.1k|				}
  128|  13.1k|			}
  129|       |			
  130|  15.1k|			_klen = (int)_sav_time_parse_range_lengths[cs];
  131|  15.1k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (131:9): [True: 14.8k, False: 271]
  ------------------
  132|  14.8k|				const char *_lower = _keys;
  133|  14.8k|				const char *_upper = _keys + (_klen<<1) - 2;
  134|  14.8k|				const char *_mid;
  135|  18.1k|				while ( 1 ) {
  ------------------
  |  Branch (135:13): [Folded - Ignored]
  ------------------
  136|  18.1k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (136:11): [True: 3.30k, False: 14.8k]
  ------------------
  137|  3.30k|						_trans += (unsigned int)_klen;
  138|  3.30k|						break;
  139|  3.30k|					}
  140|       |					
  141|  14.8k|					_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  142|  14.8k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (142:11): [True: 2.69k, False: 12.1k]
  ------------------
  143|  2.69k|						_upper = _mid - 2;
  144|  12.1k|					else if ( ( (*( p))) > (*( _mid + 1)) )
  ------------------
  |  Branch (144:16): [True: 604, False: 11.5k]
  ------------------
  145|    604|						_lower = _mid + 2;
  146|  11.5k|					else {
  147|  11.5k|						_trans += (unsigned int)((_mid - _keys)>>1);
  148|  11.5k|						break;
  149|  11.5k|					}
  150|  14.8k|				}
  151|  14.8k|			}
  152|       |			
  153|  19.3k|			_match: {}
  154|  19.3k|		}
  155|  21.0k|		cs = (int)_sav_time_parse_cond_targs[_trans];
  156|       |		
  157|  21.0k|		if ( _sav_time_parse_cond_actions[_trans] != 0 ) {
  ------------------
  |  Branch (157:8): [True: 17.1k, False: 3.90k]
  ------------------
  158|       |			
  159|  17.1k|			_acts = ( _sav_time_parse_actions + (_sav_time_parse_cond_actions[_trans]));
  160|  17.1k|			_nacts = (unsigned int)(*( _acts));
  161|  17.1k|			_acts += 1;
  162|  34.4k|			while ( _nacts > 0 ) {
  ------------------
  |  Branch (162:12): [True: 17.3k, False: 17.1k]
  ------------------
  163|  17.3k|				switch ( (*( _acts)) )
  ------------------
  |  Branch (163:14): [True: 0, False: 17.3k]
  ------------------
  164|  17.3k|				{
  165|  5.79k|					case 0:  {
  ------------------
  |  Branch (165:6): [True: 5.79k, False: 11.5k]
  ------------------
  166|  5.79k|						{
  167|  5.79k|#line 24 "src/spss/readstat_sav_parse_timestamp.rl"
  168|       |							
  169|  5.79k|							temp_val = 10 * temp_val + ((( (*( p)))) - '0');
  170|  5.79k|						}
  171|       |						
  172|  5.79k|#line 173 "src/spss/readstat_sav_parse_timestamp.c"
  173|       |						
  174|  5.79k|						break; 
  175|      0|					}
  176|    231|					case 1:  {
  ------------------
  |  Branch (176:6): [True: 231, False: 17.1k]
  ------------------
  177|    231|						{
  178|    231|#line 28 "src/spss/readstat_sav_parse_timestamp.rl"
  179|    231|							temp_val = 0; }
  180|       |						
  181|    231|#line 182 "src/spss/readstat_sav_parse_timestamp.c"
  182|       |						
  183|    231|						break; 
  184|      0|					}
  185|  5.79k|					case 2:  {
  ------------------
  |  Branch (185:6): [True: 5.79k, False: 11.5k]
  ------------------
  186|  5.79k|						{
  187|  5.79k|#line 28 "src/spss/readstat_sav_parse_timestamp.rl"
  188|  5.79k|							temp_val = (( (*( p)))) - '0'; }
  189|       |						
  190|  5.79k|#line 191 "src/spss/readstat_sav_parse_timestamp.c"
  191|       |						
  192|  5.79k|						break; 
  193|      0|					}
  194|  2.00k|					case 3:  {
  ------------------
  |  Branch (194:6): [True: 2.00k, False: 15.3k]
  ------------------
  195|  2.00k|						{
  196|  2.00k|#line 30 "src/spss/readstat_sav_parse_timestamp.rl"
  197|  2.00k|							timestamp->tm_hour = temp_val; }
  198|       |						
  199|  2.00k|#line 200 "src/spss/readstat_sav_parse_timestamp.c"
  200|       |						
  201|  2.00k|						break; 
  202|      0|					}
  203|  1.82k|					case 4:  {
  ------------------
  |  Branch (203:6): [True: 1.82k, False: 15.5k]
  ------------------
  204|  1.82k|						{
  205|  1.82k|#line 32 "src/spss/readstat_sav_parse_timestamp.rl"
  206|  1.82k|							timestamp->tm_min = temp_val; }
  207|       |						
  208|  1.82k|#line 209 "src/spss/readstat_sav_parse_timestamp.c"
  209|       |						
  210|  1.82k|						break; 
  211|      0|					}
  212|  1.69k|					case 5:  {
  ------------------
  |  Branch (212:6): [True: 1.69k, False: 15.6k]
  ------------------
  213|  1.69k|						{
  214|  1.69k|#line 34 "src/spss/readstat_sav_parse_timestamp.rl"
  215|  1.69k|							timestamp->tm_sec = temp_val; }
  216|       |						
  217|  1.69k|#line 218 "src/spss/readstat_sav_parse_timestamp.c"
  218|       |						
  219|  1.69k|						break; 
  220|      0|					}
  221|  17.3k|				}
  222|  17.3k|				_nacts -= 1;
  223|  17.3k|				_acts += 1;
  224|  17.3k|			}
  225|       |			
  226|  17.1k|		}
  227|       |		
  228|  21.0k|		if ( p == eof ) {
  ------------------
  |  Branch (228:8): [True: 1.69k, False: 19.3k]
  ------------------
  229|  1.69k|			if ( cs >= 12 )
  ------------------
  |  Branch (229:9): [True: 1.69k, False: 0]
  ------------------
  230|  1.69k|				goto _out;
  231|  1.69k|		}
  232|  19.3k|		else {
  233|  19.3k|			if ( cs != 0 ) {
  ------------------
  |  Branch (233:9): [True: 15.7k, False: 3.57k]
  ------------------
  234|  15.7k|				p += 1;
  235|  15.7k|				goto _resume;
  236|  15.7k|			}
  237|  19.3k|		}
  238|  5.26k|		_out: {}
  239|  5.26k|	}
  240|       |	
  241|      0|#line 40 "src/spss/readstat_sav_parse_timestamp.rl"
  242|       |	
  243|       |	
  244|  5.26k|	if (cs < 
  ------------------
  |  Branch (244:6): [True: 3.57k, False: 1.69k]
  ------------------
  245|  5.26k|#line 246 "src/spss/readstat_sav_parse_timestamp.c"
  246|  5.26k|	12
  247|  5.26k|#line 42 "src/spss/readstat_sav_parse_timestamp.rl"
  248|  5.26k|	|| p != pe) {
  ------------------
  |  Branch (248:5): [True: 0, False: 1.69k]
  ------------------
  249|  3.57k|		if (error_cb) {
  ------------------
  |  Branch (249:7): [True: 0, False: 3.57k]
  ------------------
  250|      0|			snprintf(error_buf, sizeof(error_buf),
  251|      0|			"Invalid time string (length=%d): %.*s", (int)len, (int)len, data);
  252|      0|			error_cb(error_buf, user_ctx);
  253|      0|		}
  254|  3.57k|		retval = READSTAT_ERROR_BAD_TIMESTAMP_STRING;
  255|  3.57k|	}
  256|       |	
  257|  5.26k|	(void)sav_time_parse_en_main;
  258|       |	
  259|  5.26k|	return retval;
  260|  21.0k|}
sav_parse_date:
  398|  1.69k|readstat_error_handler error_cb, void *user_ctx) {
  399|  1.69k|	readstat_error_t retval = READSTAT_OK;
  400|  1.69k|	char error_buf[8192];
  401|  1.69k|	const char *p = data;
  402|  1.69k|	const char *pe = p + len;
  403|  1.69k|	const char *eof = pe;
  404|  1.69k|	int cs;
  405|  1.69k|	int temp_val = 0;
  406|       |	
  407|  1.69k|#line 408 "src/spss/readstat_sav_parse_timestamp.c"
  408|  1.69k|	{
  409|  1.69k|		cs = (int)sav_date_parse_start;
  410|  1.69k|	}
  411|       |	
  412|  1.69k|#line 413 "src/spss/readstat_sav_parse_timestamp.c"
  413|  1.69k|	{
  414|  1.69k|		int _klen;
  415|  1.69k|		unsigned int _trans = 0;
  416|  1.69k|		const char * _keys;
  417|  1.69k|		const signed char * _acts;
  418|  1.69k|		unsigned int _nacts;
  419|  14.1k|		_resume: {}
  420|  14.1k|		if ( p == pe && p != eof )
  ------------------
  |  Branch (420:8): [True: 1.26k, False: 12.8k]
  |  Branch (420:19): [True: 0, False: 1.26k]
  ------------------
  421|      0|			goto _out;
  422|  14.1k|		if ( p == eof ) {
  ------------------
  |  Branch (422:8): [True: 1.26k, False: 12.8k]
  ------------------
  423|  1.26k|			if ( _sav_date_parse_eof_trans[cs] > 0 ) {
  ------------------
  |  Branch (423:9): [True: 1.26k, False: 0]
  ------------------
  424|  1.26k|				_trans = (unsigned int)_sav_date_parse_eof_trans[cs] - 1;
  425|  1.26k|			}
  426|  1.26k|		}
  427|  12.8k|		else {
  428|  12.8k|			_keys = ( _sav_date_parse_trans_keys + (_sav_date_parse_key_offsets[cs]));
  429|  12.8k|			_trans = (unsigned int)_sav_date_parse_index_offsets[cs];
  430|       |			
  431|  12.8k|			_klen = (int)_sav_date_parse_single_lengths[cs];
  432|  12.8k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (432:9): [True: 12.8k, False: 0]
  ------------------
  433|  12.8k|				const char *_lower = _keys;
  434|  12.8k|				const char *_upper = _keys + _klen - 1;
  435|  12.8k|				const char *_mid;
  436|  21.8k|				while ( 1 ) {
  ------------------
  |  Branch (436:13): [Folded - Ignored]
  ------------------
  437|  21.8k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (437:11): [True: 5.91k, False: 15.9k]
  ------------------
  438|  5.91k|						_keys += _klen;
  439|  5.91k|						_trans += (unsigned int)_klen;
  440|  5.91k|						break;
  441|  5.91k|					}
  442|       |					
  443|  15.9k|					_mid = _lower + ((_upper-_lower) >> 1);
  444|  15.9k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (444:11): [True: 886, False: 15.0k]
  ------------------
  445|    886|						_upper = _mid - 1;
  446|  15.0k|					else if ( ( (*( p))) > (*( _mid)) )
  ------------------
  |  Branch (446:16): [True: 8.12k, False: 6.94k]
  ------------------
  447|  8.12k|						_lower = _mid + 1;
  448|  6.94k|					else {
  449|  6.94k|						_trans += (unsigned int)(_mid - _keys);
  450|  6.94k|						goto _match;
  451|  6.94k|					}
  452|  15.9k|				}
  453|  12.8k|			}
  454|       |			
  455|  5.91k|			_klen = (int)_sav_date_parse_range_lengths[cs];
  456|  5.91k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (456:9): [True: 5.69k, False: 219]
  ------------------
  457|  5.69k|				const char *_lower = _keys;
  458|  5.69k|				const char *_upper = _keys + (_klen<<1) - 2;
  459|  5.69k|				const char *_mid;
  460|  5.90k|				while ( 1 ) {
  ------------------
  |  Branch (460:13): [Folded - Ignored]
  ------------------
  461|  5.90k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (461:11): [True: 210, False: 5.69k]
  ------------------
  462|    210|						_trans += (unsigned int)_klen;
  463|    210|						break;
  464|    210|					}
  465|       |					
  466|  5.69k|					_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  467|  5.69k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (467:11): [True: 126, False: 5.56k]
  ------------------
  468|    126|						_upper = _mid - 2;
  469|  5.56k|					else if ( ( (*( p))) > (*( _mid + 1)) )
  ------------------
  |  Branch (469:16): [True: 84, False: 5.48k]
  ------------------
  470|     84|						_lower = _mid + 2;
  471|  5.48k|					else {
  472|  5.48k|						_trans += (unsigned int)((_mid - _keys)>>1);
  473|  5.48k|						break;
  474|  5.48k|					}
  475|  5.69k|				}
  476|  5.69k|			}
  477|       |			
  478|  12.8k|			_match: {}
  479|  12.8k|		}
  480|  14.1k|		cs = (int)_sav_date_parse_cond_targs[_trans];
  481|       |		
  482|  14.1k|		if ( _sav_date_parse_cond_actions[_trans] != 0 ) {
  ------------------
  |  Branch (482:8): [True: 9.62k, False: 4.50k]
  ------------------
  483|       |			
  484|  9.62k|			_acts = ( _sav_date_parse_actions + (_sav_date_parse_cond_actions[_trans]));
  485|  9.62k|			_nacts = (unsigned int)(*( _acts));
  486|  9.62k|			_acts += 1;
  487|  22.0k|			while ( _nacts > 0 ) {
  ------------------
  |  Branch (487:12): [True: 12.4k, False: 9.62k]
  ------------------
  488|  12.4k|				switch ( (*( _acts)) )
  ------------------
  |  Branch (488:14): [True: 0, False: 12.4k]
  ------------------
  489|  12.4k|				{
  490|  5.61k|					case 0:  {
  ------------------
  |  Branch (490:6): [True: 5.61k, False: 6.84k]
  ------------------
  491|  5.61k|						{
  492|  5.61k|#line 71 "src/spss/readstat_sav_parse_timestamp.rl"
  493|       |							
  494|  5.61k|							char digit = ((( (*( p)))) - '0');
  495|  5.61k|							if (digit >= 0 && digit <= 9) {
  ------------------
  |  Branch (495:12): [True: 5.48k, False: 137]
  |  Branch (495:26): [True: 5.48k, False: 0]
  ------------------
  496|  5.48k|								temp_val = 10 * temp_val + digit;
  497|  5.48k|							}
  498|  5.61k|						}
  499|       |						
  500|  5.61k|#line 501 "src/spss/readstat_sav_parse_timestamp.c"
  501|       |						
  502|  5.61k|						break; 
  503|      0|					}
  504|  1.26k|					case 1:  {
  ------------------
  |  Branch (504:6): [True: 1.26k, False: 11.2k]
  ------------------
  505|  1.26k|						{
  506|  1.26k|#line 78 "src/spss/readstat_sav_parse_timestamp.rl"
  507|       |							
  508|  1.26k|							if (temp_val < 70) {
  ------------------
  |  Branch (508:12): [True: 1.03k, False: 228]
  ------------------
  509|  1.03k|								timestamp->tm_year = 100 + temp_val;
  510|  1.03k|							} else {
  511|    228|								timestamp->tm_year = temp_val;
  512|    228|							}
  513|  1.26k|						}
  514|       |						
  515|  1.26k|#line 516 "src/spss/readstat_sav_parse_timestamp.c"
  516|       |						
  517|  1.26k|						break; 
  518|      0|					}
  519|  2.84k|					case 2:  {
  ------------------
  |  Branch (519:6): [True: 2.84k, False: 9.62k]
  ------------------
  520|  2.84k|						{
  521|  2.84k|#line 87 "src/spss/readstat_sav_parse_timestamp.rl"
  522|  2.84k|							temp_val = 0; }
  523|       |						
  524|  2.84k|#line 525 "src/spss/readstat_sav_parse_timestamp.c"
  525|       |						
  526|  2.84k|						break; 
  527|      0|					}
  528|  1.44k|					case 3:  {
  ------------------
  |  Branch (528:6): [True: 1.44k, False: 11.0k]
  ------------------
  529|  1.44k|						{
  530|  1.44k|#line 89 "src/spss/readstat_sav_parse_timestamp.rl"
  531|  1.44k|							timestamp->tm_mday = temp_val; }
  532|       |						
  533|  1.44k|#line 534 "src/spss/readstat_sav_parse_timestamp.c"
  534|       |						
  535|  1.44k|						break; 
  536|      0|					}
  537|    509|					case 4:  {
  ------------------
  |  Branch (537:6): [True: 509, False: 11.9k]
  ------------------
  538|    509|						{
  539|    509|#line 94 "src/spss/readstat_sav_parse_timestamp.rl"
  540|    509|							timestamp->tm_mon = 0; }
  541|       |						
  542|    509|#line 543 "src/spss/readstat_sav_parse_timestamp.c"
  543|       |						
  544|    509|						break; 
  545|      0|					}
  546|      1|					case 5:  {
  ------------------
  |  Branch (546:6): [True: 1, False: 12.4k]
  ------------------
  547|      1|						{
  548|      1|#line 95 "src/spss/readstat_sav_parse_timestamp.rl"
  549|      1|							timestamp->tm_mon = 1; }
  550|       |						
  551|      1|#line 552 "src/spss/readstat_sav_parse_timestamp.c"
  552|       |						
  553|      1|						break; 
  554|      0|					}
  555|    261|					case 6:  {
  ------------------
  |  Branch (555:6): [True: 261, False: 12.2k]
  ------------------
  556|    261|						{
  557|    261|#line 96 "src/spss/readstat_sav_parse_timestamp.rl"
  558|    261|							timestamp->tm_mon = 2; }
  559|       |						
  560|    261|#line 561 "src/spss/readstat_sav_parse_timestamp.c"
  561|       |						
  562|    261|						break; 
  563|      0|					}
  564|     18|					case 7:  {
  ------------------
  |  Branch (564:6): [True: 18, False: 12.4k]
  ------------------
  565|     18|						{
  566|     18|#line 97 "src/spss/readstat_sav_parse_timestamp.rl"
  567|     18|							timestamp->tm_mon = 3; }
  568|       |						
  569|     18|#line 570 "src/spss/readstat_sav_parse_timestamp.c"
  570|       |						
  571|     18|						break; 
  572|      0|					}
  573|      2|					case 8:  {
  ------------------
  |  Branch (573:6): [True: 2, False: 12.4k]
  ------------------
  574|      2|						{
  575|      2|#line 98 "src/spss/readstat_sav_parse_timestamp.rl"
  576|      2|							timestamp->tm_mon = 4; }
  577|       |						
  578|      2|#line 579 "src/spss/readstat_sav_parse_timestamp.c"
  579|       |						
  580|      2|						break; 
  581|      0|					}
  582|    299|					case 9:  {
  ------------------
  |  Branch (582:6): [True: 299, False: 12.1k]
  ------------------
  583|    299|						{
  584|    299|#line 99 "src/spss/readstat_sav_parse_timestamp.rl"
  585|    299|							timestamp->tm_mon = 5; }
  586|       |						
  587|    299|#line 588 "src/spss/readstat_sav_parse_timestamp.c"
  588|       |						
  589|    299|						break; 
  590|      0|					}
  591|     20|					case 10:  {
  ------------------
  |  Branch (591:6): [True: 20, False: 12.4k]
  ------------------
  592|     20|						{
  593|     20|#line 100 "src/spss/readstat_sav_parse_timestamp.rl"
  594|     20|							timestamp->tm_mon = 6; }
  595|       |						
  596|     20|#line 597 "src/spss/readstat_sav_parse_timestamp.c"
  597|       |						
  598|     20|						break; 
  599|      0|					}
  600|     17|					case 11:  {
  ------------------
  |  Branch (600:6): [True: 17, False: 12.4k]
  ------------------
  601|     17|						{
  602|     17|#line 101 "src/spss/readstat_sav_parse_timestamp.rl"
  603|     17|							timestamp->tm_mon = 7; }
  604|       |						
  605|     17|#line 606 "src/spss/readstat_sav_parse_timestamp.c"
  606|       |						
  607|     17|						break; 
  608|      0|					}
  609|      9|					case 12:  {
  ------------------
  |  Branch (609:6): [True: 9, False: 12.4k]
  ------------------
  610|      9|						{
  611|      9|#line 102 "src/spss/readstat_sav_parse_timestamp.rl"
  612|      9|							timestamp->tm_mon = 8; }
  613|       |						
  614|      9|#line 615 "src/spss/readstat_sav_parse_timestamp.c"
  615|       |						
  616|      9|						break; 
  617|      0|					}
  618|      6|					case 13:  {
  ------------------
  |  Branch (618:6): [True: 6, False: 12.4k]
  ------------------
  619|      6|						{
  620|      6|#line 103 "src/spss/readstat_sav_parse_timestamp.rl"
  621|      6|							timestamp->tm_mon = 9; }
  622|       |						
  623|      6|#line 624 "src/spss/readstat_sav_parse_timestamp.c"
  624|       |						
  625|      6|						break; 
  626|      0|					}
  627|      2|					case 14:  {
  ------------------
  |  Branch (627:6): [True: 2, False: 12.4k]
  ------------------
  628|      2|						{
  629|      2|#line 104 "src/spss/readstat_sav_parse_timestamp.rl"
  630|      2|							timestamp->tm_mon = 10; }
  631|       |						
  632|      2|#line 633 "src/spss/readstat_sav_parse_timestamp.c"
  633|       |						
  634|      2|						break; 
  635|      0|					}
  636|    150|					case 15:  {
  ------------------
  |  Branch (636:6): [True: 150, False: 12.3k]
  ------------------
  637|    150|						{
  638|    150|#line 105 "src/spss/readstat_sav_parse_timestamp.rl"
  639|    150|							timestamp->tm_mon = 11; }
  640|       |						
  641|    150|#line 642 "src/spss/readstat_sav_parse_timestamp.c"
  642|       |						
  643|    150|						break; 
  644|      0|					}
  645|  12.4k|				}
  646|  12.4k|				_nacts -= 1;
  647|  12.4k|				_acts += 1;
  648|  12.4k|			}
  649|       |			
  650|  9.62k|		}
  651|       |		
  652|  14.1k|		if ( p == eof ) {
  ------------------
  |  Branch (652:8): [True: 1.26k, False: 12.8k]
  ------------------
  653|  1.26k|			if ( cs >= 47 )
  ------------------
  |  Branch (653:9): [True: 1.26k, False: 0]
  ------------------
  654|  1.26k|				goto _out;
  655|  1.26k|		}
  656|  12.8k|		else {
  657|  12.8k|			if ( cs != 0 ) {
  ------------------
  |  Branch (657:9): [True: 12.4k, False: 429]
  ------------------
  658|  12.4k|				p += 1;
  659|  12.4k|				goto _resume;
  660|  12.4k|			}
  661|  12.8k|		}
  662|  1.69k|		_out: {}
  663|  1.69k|	}
  664|       |	
  665|      0|#line 112 "src/spss/readstat_sav_parse_timestamp.rl"
  666|       |	
  667|       |	
  668|  1.69k|	if (cs < 
  ------------------
  |  Branch (668:6): [True: 429, False: 1.26k]
  ------------------
  669|  1.69k|#line 670 "src/spss/readstat_sav_parse_timestamp.c"
  670|  1.69k|	47
  671|  1.69k|#line 114 "src/spss/readstat_sav_parse_timestamp.rl"
  672|  1.69k|	|| p != pe) {
  ------------------
  |  Branch (672:5): [True: 0, False: 1.26k]
  ------------------
  673|    429|		if (error_cb) {
  ------------------
  |  Branch (673:7): [True: 0, False: 429]
  ------------------
  674|      0|			snprintf(error_buf, sizeof(error_buf),
  675|      0|			"Invalid date string (length=%d): %.*s", (int)len, (int)len, data);
  676|      0|			error_cb(error_buf, user_ctx);
  677|      0|		}
  678|    429|		retval = READSTAT_ERROR_BAD_TIMESTAMP_STRING;
  679|    429|	}
  680|       |	
  681|  1.69k|	(void)sav_date_parse_en_main;
  682|       |	
  683|  1.69k|	return retval;
  684|  14.1k|}

sav_parse_timestamp:
 1550|  5.26k|readstat_error_t sav_parse_timestamp(sav_ctx_t *ctx, sav_file_header_record_t *header) {
 1551|  5.26k|    readstat_error_t retval = READSTAT_OK;
 1552|  5.26k|    struct tm timestamp = { .tm_isdst = -1 };
 1553|       |
 1554|  5.26k|    if ((retval = sav_parse_time(header->creation_time, sizeof(header->creation_time),
  ------------------
  |  Branch (1554:9): [True: 3.57k, False: 1.69k]
  ------------------
 1555|  5.26k|                    &timestamp, ctx->handle.error, ctx->user_ctx)) 
 1556|  5.26k|            != READSTAT_OK)
 1557|  3.57k|        goto cleanup;
 1558|       |
 1559|  1.69k|    if ((retval = sav_parse_date(header->creation_date, sizeof(header->creation_date),
  ------------------
  |  Branch (1559:9): [True: 429, False: 1.26k]
  ------------------
 1560|  1.69k|                    &timestamp, ctx->handle.error, ctx->user_ctx)) 
 1561|  1.69k|            != READSTAT_OK)
 1562|    429|        goto cleanup;
 1563|       |
 1564|  1.26k|    ctx->timestamp = mktime(&timestamp);
 1565|       |
 1566|  5.26k|cleanup:
 1567|  5.26k|    return retval;
 1568|  1.26k|}
readstat_parse_sav:
 1570|  5.31k|readstat_error_t readstat_parse_sav(readstat_parser_t *parser, const char *path, void *user_ctx) {
 1571|  5.31k|    readstat_error_t retval = READSTAT_OK;
 1572|  5.31k|    readstat_io_t *io = parser->io;
 1573|  5.31k|    sav_file_header_record_t header;
 1574|  5.31k|    sav_ctx_t *ctx = NULL;
 1575|  5.31k|    size_t file_size = 0;
 1576|       |    
 1577|  5.31k|    if (io->open(path, io->io_ctx) == -1) {
  ------------------
  |  Branch (1577:9): [True: 0, False: 5.31k]
  ------------------
 1578|      0|        return READSTAT_ERROR_OPEN;
 1579|      0|    }
 1580|       |
 1581|  5.31k|    file_size = io->seek(0, READSTAT_SEEK_END, io->io_ctx);
 1582|  5.31k|    if (file_size == -1) {
  ------------------
  |  Branch (1582:9): [True: 0, False: 5.31k]
  ------------------
 1583|      0|        retval = READSTAT_ERROR_SEEK;
 1584|      0|        goto cleanup;
 1585|      0|    }
 1586|       |
 1587|  5.31k|    if (io->seek(0, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (1587:9): [True: 0, False: 5.31k]
  ------------------
 1588|      0|        retval = READSTAT_ERROR_SEEK;
 1589|      0|        goto cleanup;
 1590|      0|    }
 1591|       |
 1592|  5.31k|    if (io->read(&header, sizeof(sav_file_header_record_t), io->io_ctx) < sizeof(sav_file_header_record_t)) {
  ------------------
  |  Branch (1592:9): [True: 18, False: 5.29k]
  ------------------
 1593|     18|        retval = READSTAT_ERROR_READ;
 1594|     18|        goto cleanup;
 1595|     18|    }
 1596|       |
 1597|  5.29k|    ctx = sav_ctx_init(&header, io);
 1598|  5.29k|    if (ctx == NULL) {
  ------------------
  |  Branch (1598:9): [True: 31, False: 5.26k]
  ------------------
 1599|     31|        retval = READSTAT_ERROR_PARSE;
 1600|     31|        goto cleanup;
 1601|     31|    }
 1602|       |
 1603|  5.26k|    ctx->handle = parser->handlers;
 1604|  5.26k|    ctx->input_encoding = parser->input_encoding;
 1605|  5.26k|    ctx->output_encoding = parser->output_encoding;
 1606|  5.26k|    ctx->user_ctx = user_ctx;
 1607|  5.26k|    ctx->file_size = file_size;
 1608|  5.26k|    if (parser->row_offset > 0)
  ------------------
  |  Branch (1608:9): [True: 0, False: 5.26k]
  ------------------
 1609|      0|        ctx->row_offset = parser->row_offset;
 1610|  5.26k|    if (ctx->record_count >= 0) {
  ------------------
  |  Branch (1610:9): [True: 3.83k, False: 1.43k]
  ------------------
 1611|  3.83k|        int record_count_after_skipping = ctx->record_count - ctx->row_offset;
 1612|  3.83k|        if (record_count_after_skipping < 0) {
  ------------------
  |  Branch (1612:13): [True: 0, False: 3.83k]
  ------------------
 1613|      0|            record_count_after_skipping = 0;
 1614|      0|            ctx->row_offset = ctx->record_count;
 1615|      0|        }
 1616|  3.83k|        ctx->row_limit = record_count_after_skipping;
 1617|  3.83k|        if (parser->row_limit > 0 && parser->row_limit < record_count_after_skipping) 
  ------------------
  |  Branch (1617:13): [True: 0, False: 3.83k]
  |  Branch (1617:38): [True: 0, False: 0]
  ------------------
 1618|      0|            ctx->row_limit = parser->row_limit;
 1619|  3.83k|    } else if (parser->row_limit > 0) {
  ------------------
  |  Branch (1619:16): [True: 0, False: 1.43k]
  ------------------
 1620|      0|        ctx->row_limit = parser->row_limit;
 1621|      0|    }
 1622|       |    
 1623|       |    /* ignore errors */
 1624|  5.26k|    sav_parse_timestamp(ctx, &header);
 1625|       |
 1626|  5.26k|    if ((retval = sav_parse_records_pass1(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1626:9): [True: 993, False: 4.27k]
  ------------------
 1627|    993|        goto cleanup;
 1628|       |    
 1629|  4.27k|    if (io->seek(sizeof(sav_file_header_record_t), READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (1629:9): [True: 0, False: 4.27k]
  ------------------
 1630|      0|        retval = READSTAT_ERROR_SEEK;
 1631|      0|        goto cleanup;
 1632|      0|    }
 1633|       |
 1634|  4.27k|    if ((retval = sav_update_progress(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1634:9): [True: 0, False: 4.27k]
  ------------------
 1635|      0|        goto cleanup;
 1636|       |
 1637|  4.27k|    if ((retval = sav_parse_records_pass2(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1637:9): [True: 2.66k, False: 1.60k]
  ------------------
 1638|  2.66k|        goto cleanup;
 1639|       | 
 1640|  1.60k|    if ((retval = sav_set_n_segments_and_var_count(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1640:9): [True: 32, False: 1.57k]
  ------------------
 1641|     32|        goto cleanup;
 1642|       |
 1643|  1.57k|    if (ctx->var_count == 0) {
  ------------------
  |  Branch (1643:9): [True: 9, False: 1.56k]
  ------------------
 1644|      9|        retval = READSTAT_ERROR_PARSE;
 1645|      9|        goto cleanup;
 1646|      9|    }
 1647|       |
 1648|  1.56k|    if (ctx->handle.metadata) {
  ------------------
  |  Branch (1648:9): [True: 1.56k, False: 0]
  ------------------
 1649|  1.56k|        readstat_metadata_t metadata = {
 1650|  1.56k|            .row_count = ctx->record_count < 0 ? -1 : ctx->row_limit,
  ------------------
  |  Branch (1650:26): [True: 458, False: 1.10k]
  ------------------
 1651|  1.56k|            .var_count = ctx->var_count,
 1652|  1.56k|            .file_encoding = ctx->input_encoding,
 1653|  1.56k|            .file_format_version = ctx->format_version,
 1654|  1.56k|            .creation_time = ctx->timestamp,
 1655|  1.56k|            .modified_time = ctx->timestamp,
 1656|  1.56k|            .compression = ctx->compression,
 1657|  1.56k|            .endianness = ctx->endianness
 1658|  1.56k|        };
 1659|  1.56k|        if ((retval = readstat_convert(ctx->file_label, sizeof(ctx->file_label),
  ------------------
  |  Branch (1659:13): [True: 1, False: 1.56k]
  ------------------
 1660|  1.56k|                        header.file_label, sizeof(header.file_label), ctx->converter)) != READSTAT_OK)
 1661|      1|            goto cleanup;
 1662|       |
 1663|  1.56k|        metadata.file_label = ctx->file_label;
 1664|       |
 1665|  1.56k|        if (ctx->handle.metadata(&metadata, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (1665:13): [True: 0, False: 1.56k]
  ------------------
 1666|      0|            retval = READSTAT_ERROR_USER_ABORT;
 1667|      0|            goto cleanup;
 1668|      0|        }
 1669|  1.56k|    }
 1670|       |
 1671|  1.56k|    if ((retval = sav_parse_variable_display_parameter_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1671:9): [True: 36, False: 1.52k]
  ------------------
 1672|     36|        goto cleanup;
 1673|       |
 1674|  1.52k|    if ((retval = sav_handle_variables(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1674:9): [True: 0, False: 1.52k]
  ------------------
 1675|      0|        goto cleanup;
 1676|       |
 1677|  1.52k|    if ((retval = sav_handle_fweight(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1677:9): [True: 0, False: 1.52k]
  ------------------
 1678|      0|        goto cleanup;
 1679|       |
 1680|  1.52k|    if (ctx->handle.value) {
  ------------------
  |  Branch (1680:9): [True: 1.52k, False: 0]
  ------------------
 1681|  1.52k|        retval = sav_read_data(ctx);
 1682|  1.52k|    }
 1683|       |    
 1684|  5.31k|cleanup:
 1685|  5.31k|    io->close(io->io_ctx);
 1686|  5.31k|    if (ctx)
  ------------------
  |  Branch (1686:9): [True: 5.26k, False: 49]
  ------------------
 1687|  5.26k|        sav_ctx_free(ctx);
 1688|       |    
 1689|  5.31k|    return retval;
 1690|  1.52k|}
readstat_sav_read.c:sav_parse_records_pass1:
 1275|  5.26k|static readstat_error_t sav_parse_records_pass1(sav_ctx_t *ctx) {
 1276|  5.26k|    char data_buf[4096];
 1277|  5.26k|    readstat_error_t retval = READSTAT_OK;
 1278|  5.26k|    readstat_io_t *io = ctx->io;
 1279|   325k|    while (1) {
  ------------------
  |  Branch (1279:12): [Folded - Ignored]
  ------------------
 1280|   325k|        uint32_t rec_type;
 1281|   325k|        uint32_t extra_info[3];
 1282|   325k|        size_t data_len = 0;
 1283|   325k|        int i;
 1284|   325k|        int done = 0;
 1285|   325k|        if (io->read(&rec_type, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (1285:13): [True: 294, False: 325k]
  ------------------
 1286|    294|            retval = READSTAT_ERROR_READ;
 1287|    294|            goto cleanup;
 1288|    294|        }
 1289|       |        
 1290|   325k|        if (ctx->bswap) {
  ------------------
  |  Branch (1290:13): [True: 38.9k, False: 286k]
  ------------------
 1291|  38.9k|            rec_type = byteswap4(rec_type);
 1292|  38.9k|        }
 1293|       |        
 1294|   325k|        switch (rec_type) {
 1295|   281k|            case SAV_RECORD_TYPE_VARIABLE:
  ------------------
  |  |  111|   281k|#define SAV_RECORD_TYPE_VARIABLE                2
  ------------------
  |  Branch (1295:13): [True: 281k, False: 43.3k]
  ------------------
 1296|   281k|                retval = sav_skip_variable_record(ctx);
 1297|   281k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1297:21): [True: 145, False: 281k]
  ------------------
 1298|    145|                    goto cleanup;
 1299|   281k|                break;
 1300|   281k|            case SAV_RECORD_TYPE_VALUE_LABEL:
  ------------------
  |  |  112|  28.5k|#define SAV_RECORD_TYPE_VALUE_LABEL             3
  ------------------
  |  Branch (1300:13): [True: 28.5k, False: 296k]
  ------------------
 1301|  28.5k|                retval = sav_skip_value_label_record(ctx);
 1302|  28.5k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1302:21): [True: 187, False: 28.4k]
  ------------------
 1303|    187|                    goto cleanup;
 1304|  28.4k|                break;
 1305|  28.4k|            case SAV_RECORD_TYPE_DOCUMENT:
  ------------------
  |  |  114|  1.92k|#define SAV_RECORD_TYPE_DOCUMENT                6
  ------------------
  |  Branch (1305:13): [True: 1.92k, False: 323k]
  ------------------
 1306|  1.92k|                retval = sav_skip_document_record(ctx);
 1307|  1.92k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1307:21): [True: 57, False: 1.86k]
  ------------------
 1308|     57|                    goto cleanup;
 1309|  1.86k|                break;
 1310|  4.27k|            case SAV_RECORD_TYPE_DICT_TERMINATION:
  ------------------
  |  |  116|  4.27k|#define SAV_RECORD_TYPE_DICT_TERMINATION        999
  ------------------
  |  Branch (1310:13): [True: 4.27k, False: 320k]
  ------------------
 1311|  4.27k|                done = 1;
 1312|  4.27k|                break;
 1313|  8.47k|            case SAV_RECORD_TYPE_HAS_DATA:
  ------------------
  |  |  115|  8.47k|#define SAV_RECORD_TYPE_HAS_DATA                7
  ------------------
  |  Branch (1313:13): [True: 8.47k, False: 316k]
  ------------------
 1314|  8.47k|                if (io->read(extra_info, sizeof(extra_info), io->io_ctx) < sizeof(extra_info)) {
  ------------------
  |  Branch (1314:21): [True: 8, False: 8.46k]
  ------------------
 1315|      8|                    retval = READSTAT_ERROR_READ;
 1316|      8|                    goto cleanup;
 1317|      8|                }
 1318|  8.46k|                if (ctx->bswap) {
  ------------------
  |  Branch (1318:21): [True: 2.24k, False: 6.22k]
  ------------------
 1319|  8.97k|                    for (i=0; i<3; i++)
  ------------------
  |  Branch (1319:31): [True: 6.72k, False: 2.24k]
  ------------------
 1320|  6.72k|                        extra_info[i] = byteswap4(extra_info[i]);
 1321|  2.24k|                }
 1322|  8.46k|                uint32_t subtype = extra_info[0];
 1323|  8.46k|                size_t size = extra_info[1];
 1324|  8.46k|                size_t count = extra_info[2];
 1325|  8.46k|                data_len = size * count;
 1326|  8.46k|                if (subtype == SAV_RECORD_SUBTYPE_INTEGER_INFO) {
  ------------------
  |  |  118|  8.46k|#define SAV_RECORD_SUBTYPE_INTEGER_INFO       3
  ------------------
  |  Branch (1326:21): [True: 882, False: 7.58k]
  ------------------
 1327|    882|                    if (data_len > sizeof(data_buf)) {
  ------------------
  |  Branch (1327:25): [True: 63, False: 819]
  ------------------
 1328|     63|                        retval = READSTAT_ERROR_PARSE;
 1329|     63|                        goto cleanup;
 1330|     63|                    }
 1331|    819|                    if (io->read(data_buf, data_len, io->io_ctx) < data_len) {
  ------------------
  |  Branch (1331:25): [True: 17, False: 802]
  ------------------
 1332|     17|                        retval = READSTAT_ERROR_PARSE;
 1333|     17|                        goto cleanup;
 1334|     17|                    }
 1335|    802|                    retval = sav_parse_machine_integer_info_record(data_buf, data_len, ctx);
 1336|    802|                    if (retval != READSTAT_OK)
  ------------------
  |  Branch (1336:25): [True: 30, False: 772]
  ------------------
 1337|     30|                        goto cleanup;
 1338|  7.58k|                } else {
 1339|  7.58k|                    if (io->seek(data_len, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (1339:25): [True: 115, False: 7.46k]
  ------------------
 1340|    115|                        retval = READSTAT_ERROR_SEEK;
 1341|    115|                        goto cleanup;
 1342|    115|                    }
 1343|  7.58k|                }
 1344|  8.24k|                break;
 1345|  8.24k|            default:
  ------------------
  |  Branch (1345:13): [True: 77, False: 325k]
  ------------------
 1346|     77|                retval = READSTAT_ERROR_PARSE;
 1347|     77|                goto cleanup;
 1348|      0|                break;
 1349|   325k|        }
 1350|   324k|        if (done)
  ------------------
  |  Branch (1350:13): [True: 4.27k, False: 320k]
  ------------------
 1351|  4.27k|            break;
 1352|   324k|    }
 1353|  5.26k|cleanup:
 1354|  5.26k|    return retval;
 1355|  5.26k|}
readstat_sav_read.c:sav_skip_variable_record:
  168|   281k|static readstat_error_t sav_skip_variable_record(sav_ctx_t *ctx) {
  169|   281k|    sav_variable_record_t variable;
  170|   281k|    readstat_error_t retval = READSTAT_OK;
  171|   281k|    readstat_io_t *io = ctx->io;
  172|   281k|    if (io->read(&variable, sizeof(sav_variable_record_t), io->io_ctx) < sizeof(sav_variable_record_t)) {
  ------------------
  |  Branch (172:9): [True: 9, False: 281k]
  ------------------
  173|      9|        retval = READSTAT_ERROR_READ;
  174|      9|        goto cleanup;
  175|      9|    }
  176|   281k|    if (variable.has_var_label) {
  ------------------
  |  Branch (176:9): [True: 4.59k, False: 277k]
  ------------------
  177|  4.59k|        uint32_t label_len;
  178|  4.59k|        if (io->read(&label_len, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (178:13): [True: 50, False: 4.54k]
  ------------------
  179|     50|            retval = READSTAT_ERROR_READ;
  180|     50|            goto cleanup;
  181|     50|        }
  182|  4.54k|        label_len = ctx->bswap ? byteswap4(label_len) : label_len;
  ------------------
  |  Branch (182:21): [True: 3.74k, False: 795]
  ------------------
  183|  4.54k|        uint32_t label_capacity = (label_len + 3) / 4 * 4;
  184|  4.54k|        if (io->seek(label_capacity, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (184:13): [True: 6, False: 4.53k]
  ------------------
  185|      6|            retval = READSTAT_ERROR_SEEK;
  186|      6|            goto cleanup;
  187|      6|        }
  188|  4.54k|    }
  189|   281k|    if (variable.n_missing_values) {
  ------------------
  |  Branch (189:9): [True: 6.63k, False: 275k]
  ------------------
  190|  6.63k|        int n_missing_values = ctx->bswap ? byteswap4(variable.n_missing_values) : variable.n_missing_values;
  ------------------
  |  Branch (190:32): [True: 4.12k, False: 2.50k]
  ------------------
  191|  6.63k|        if (io->seek(abs(n_missing_values) * sizeof(double), READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (191:13): [True: 80, False: 6.55k]
  ------------------
  192|     80|            retval = READSTAT_ERROR_SEEK;
  193|     80|            goto cleanup;
  194|     80|        }
  195|  6.63k|    }
  196|   281k|cleanup:
  197|   281k|    return retval;
  198|   281k|}
readstat_sav_read.c:sav_skip_value_label_record:
  403|  28.5k|static readstat_error_t sav_skip_value_label_record(sav_ctx_t *ctx) {
  404|  28.5k|    uint32_t label_count;
  405|  28.5k|    uint32_t rec_type;
  406|  28.5k|    uint32_t var_count;
  407|  28.5k|    readstat_error_t retval = READSTAT_OK;
  408|  28.5k|    readstat_io_t *io = ctx->io;
  409|  28.5k|    if (io->read(&label_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (409:9): [True: 3, False: 28.5k]
  ------------------
  410|      3|        retval = READSTAT_ERROR_READ;
  411|      3|        goto cleanup;
  412|      3|    }
  413|  28.5k|    if (ctx->bswap)
  ------------------
  |  Branch (413:9): [True: 27.2k, False: 1.35k]
  ------------------
  414|  27.2k|        label_count = byteswap4(label_count);
  415|  28.5k|    int i;
  416|   235k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (416:15): [True: 207k, False: 28.4k]
  ------------------
  417|   207k|        unsigned char unpadded_len = 0;
  418|   207k|        size_t padded_len = 0;
  419|   207k|        if (io->seek(8, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (419:13): [True: 79, False: 207k]
  ------------------
  420|     79|            retval = READSTAT_ERROR_SEEK;
  421|     79|            goto cleanup;
  422|     79|        }
  423|   207k|        if (io->read(&unpadded_len, 1, io->io_ctx) < 1) {
  ------------------
  |  Branch (423:13): [True: 19, False: 207k]
  ------------------
  424|     19|            retval = READSTAT_ERROR_READ;
  425|     19|            goto cleanup;
  426|     19|        }
  427|   207k|        padded_len = (unpadded_len + 8) / 8 * 8 - 1;
  428|   207k|        if (io->seek(padded_len, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (428:13): [True: 3, False: 207k]
  ------------------
  429|      3|            retval = READSTAT_ERROR_SEEK;
  430|      3|            goto cleanup;
  431|      3|        }
  432|   207k|    }
  433|       |
  434|  28.4k|    if (io->read(&rec_type, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (434:9): [True: 17, False: 28.4k]
  ------------------
  435|     17|        retval = READSTAT_ERROR_READ;
  436|     17|        goto cleanup;
  437|     17|    }
  438|  28.4k|    if (ctx->bswap)
  ------------------
  |  Branch (438:9): [True: 27.1k, False: 1.29k]
  ------------------
  439|  27.1k|        rec_type = byteswap4(rec_type);
  440|       |    
  441|  28.4k|    if (rec_type != 4) {
  ------------------
  |  Branch (441:9): [True: 52, False: 28.4k]
  ------------------
  442|     52|        retval = READSTAT_ERROR_PARSE;
  443|     52|        goto cleanup;
  444|     52|    }
  445|  28.4k|    if (io->read(&var_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (445:9): [True: 5, False: 28.4k]
  ------------------
  446|      5|        retval = READSTAT_ERROR_READ;
  447|      5|        goto cleanup;
  448|      5|    }
  449|  28.4k|    if (ctx->bswap)
  ------------------
  |  Branch (449:9): [True: 27.1k, False: 1.27k]
  ------------------
  450|  27.1k|        var_count = byteswap4(var_count);
  451|       |    
  452|  28.4k|    if (io->seek(var_count * sizeof(uint32_t), READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (452:9): [True: 9, False: 28.4k]
  ------------------
  453|      9|        retval = READSTAT_ERROR_SEEK;
  454|      9|        goto cleanup;
  455|      9|    }
  456|       |
  457|  28.5k|cleanup:
  458|  28.5k|    return retval;
  459|  28.4k|}
readstat_sav_read.c:sav_skip_document_record:
  615|  1.92k|static readstat_error_t sav_skip_document_record(sav_ctx_t *ctx) {
  616|  1.92k|    uint32_t n_lines;
  617|  1.92k|    readstat_error_t retval = READSTAT_OK;
  618|  1.92k|    readstat_io_t *io = ctx->io;
  619|  1.92k|    if (io->read(&n_lines, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (619:9): [True: 3, False: 1.92k]
  ------------------
  620|      3|        retval = READSTAT_ERROR_READ;
  621|      3|        goto cleanup;
  622|      3|    }
  623|  1.92k|    if (ctx->bswap)
  ------------------
  |  Branch (623:9): [True: 1.48k, False: 434]
  ------------------
  624|  1.48k|        n_lines = byteswap4(n_lines);
  625|  1.92k|    if (io->seek(n_lines * SPSS_DOC_LINE_SIZE, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  |   40|  1.92k|#define SPSS_DOC_LINE_SIZE  80
  ------------------
  |  Branch (625:9): [True: 54, False: 1.86k]
  ------------------
  626|     54|        retval = READSTAT_ERROR_SEEK;
  627|     54|        goto cleanup;
  628|     54|    }
  629|       |    
  630|  1.92k|cleanup:
  631|  1.92k|    return retval;
  632|  1.92k|}
readstat_sav_read.c:sav_parse_machine_integer_info_record:
  917|    802|static readstat_error_t sav_parse_machine_integer_info_record(const void *data, size_t data_len, sav_ctx_t *ctx) {
  918|    802|    if (data_len != 32)
  ------------------
  |  Branch (918:9): [True: 10, False: 792]
  ------------------
  919|     10|        return READSTAT_ERROR_PARSE;
  920|       |
  921|    792|    const char *src_charset = NULL;
  922|    792|    const char *dst_charset = ctx->output_encoding;
  923|    792|    sav_machine_integer_info_record_t record;
  924|    792|    memcpy(&record, data, data_len);
  925|    792|    if (ctx->bswap) {
  ------------------
  |  Branch (925:9): [True: 339, False: 453]
  ------------------
  926|    339|        record.character_code = byteswap4(record.character_code);
  927|    339|    }
  928|    792|    if (ctx->input_encoding) {
  ------------------
  |  Branch (928:9): [True: 676, False: 116]
  ------------------
  929|    676|        src_charset = ctx->input_encoding;
  930|    676|    } else {
  931|    116|        int i;
  932|  6.93k|        for (i=0; i<sizeof(_charset_table)/sizeof(_charset_table[0]); i++) {
  ------------------
  |  Branch (932:19): [True: 6.91k, False: 19]
  ------------------
  933|  6.91k|            if (record.character_code  == _charset_table[i].code) {
  ------------------
  |  Branch (933:17): [True: 97, False: 6.81k]
  ------------------
  934|     97|                src_charset = _charset_table[i].name;
  935|     97|                break;
  936|     97|            }
  937|  6.91k|        }
  938|    116|        if (src_charset == NULL) {
  ------------------
  |  Branch (938:13): [True: 19, False: 97]
  ------------------
  939|     19|            if (ctx->handle.error) {
  ------------------
  |  Branch (939:17): [True: 0, False: 19]
  ------------------
  940|      0|                char error_buf[1024];
  941|      0|                snprintf(error_buf, sizeof(error_buf), "Unsupported character set: %d\n", record.character_code);
  942|      0|                ctx->handle.error(error_buf, ctx->user_ctx);
  943|      0|            }
  944|     19|            return READSTAT_ERROR_UNSUPPORTED_CHARSET;
  945|     19|        }
  946|     97|        ctx->input_encoding = src_charset;
  947|     97|    }
  948|    773|    if (src_charset && dst_charset) {
  ------------------
  |  Branch (948:9): [True: 773, False: 0]
  |  Branch (948:24): [True: 773, False: 0]
  ------------------
  949|       |        // You might be tempted to skip the charset conversion when src_charset
  950|       |        // and dst_charset are the same. However, some versions of SPSS insert
  951|       |        // illegally truncated strings (e.g. the last character is three bytes
  952|       |        // but the field only has room for two bytes). So to prevent the client
  953|       |        // from receiving an invalid byte sequence, we ram everything through
  954|       |        // our iconv machinery.
  955|    773|        iconv_t converter = iconv_open(dst_charset, src_charset);
  956|    773|        if (converter == (iconv_t)-1) {
  ------------------
  |  Branch (956:13): [True: 1, False: 772]
  ------------------
  957|      1|            return READSTAT_ERROR_UNSUPPORTED_CHARSET;
  958|      1|        }
  959|    772|        if (ctx->converter) {
  ------------------
  |  Branch (959:13): [True: 676, False: 96]
  ------------------
  960|    676|            iconv_close(ctx->converter);
  961|    676|        }
  962|    772|        ctx->converter = converter;
  963|    772|    }
  964|    772|    return READSTAT_OK;
  965|    773|}
readstat_sav_read.c:sav_update_progress:
  163|  6.07k|static readstat_error_t sav_update_progress(sav_ctx_t *ctx) {
  164|  6.07k|    readstat_io_t *io = ctx->io;
  165|  6.07k|    return io->update(ctx->file_size, ctx->handle.progress, ctx->user_ctx, io->io_ctx);
  166|  6.07k|}
readstat_sav_read.c:sav_parse_records_pass2:
 1357|  4.27k|static readstat_error_t sav_parse_records_pass2(sav_ctx_t *ctx) {
 1358|  4.27k|    void *data_buf = NULL;
 1359|  4.27k|    size_t data_buf_capacity = 4096;
 1360|  4.27k|    readstat_error_t retval = READSTAT_OK;
 1361|  4.27k|    readstat_io_t *io = ctx->io;
 1362|       |
 1363|  4.27k|    if ((data_buf = readstat_malloc(data_buf_capacity)) == NULL) {
  ------------------
  |  Branch (1363:9): [True: 0, False: 4.27k]
  ------------------
 1364|      0|        retval = READSTAT_ERROR_MALLOC;
 1365|      0|        goto cleanup;
 1366|      0|    }
 1367|       |
 1368|   331k|    while (1) {
  ------------------
  |  Branch (1368:12): [Folded - Ignored]
  ------------------
 1369|   331k|        uint32_t rec_type;
 1370|   331k|        uint32_t extra_info[3];
 1371|   331k|        size_t data_len = 0;
 1372|   331k|        int i;
 1373|   331k|        int done = 0;
 1374|   331k|        if (io->read(&rec_type, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (1374:13): [True: 33, False: 331k]
  ------------------
 1375|     33|            retval = READSTAT_ERROR_READ;
 1376|     33|            goto cleanup;
 1377|     33|        }
 1378|       |        
 1379|   331k|        if (ctx->bswap) {
  ------------------
  |  Branch (1379:13): [True: 23.7k, False: 307k]
  ------------------
 1380|  23.7k|            rec_type = byteswap4(rec_type);
 1381|  23.7k|        }
 1382|       |        
 1383|   331k|        switch (rec_type) {
 1384|   302k|            case SAV_RECORD_TYPE_VARIABLE:
  ------------------
  |  |  111|   302k|#define SAV_RECORD_TYPE_VARIABLE                2
  ------------------
  |  Branch (1384:13): [True: 302k, False: 29.1k]
  ------------------
 1385|   302k|                if ((retval = sav_read_variable_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1385:21): [True: 172, False: 302k]
  ------------------
 1386|    172|                    goto cleanup;
 1387|   302k|                break;
 1388|   302k|            case SAV_RECORD_TYPE_VALUE_LABEL:
  ------------------
  |  |  112|  18.4k|#define SAV_RECORD_TYPE_VALUE_LABEL             3
  ------------------
  |  Branch (1388:13): [True: 18.4k, False: 313k]
  ------------------
 1389|  18.4k|                if ((retval = sav_read_value_label_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1389:21): [True: 179, False: 18.2k]
  ------------------
 1390|    179|                    goto cleanup;
 1391|  18.2k|                break;
 1392|  18.2k|            case SAV_RECORD_TYPE_DOCUMENT:
  ------------------
  |  |  114|  1.06k|#define SAV_RECORD_TYPE_DOCUMENT                6
  ------------------
  |  Branch (1392:13): [True: 1.06k, False: 330k]
  ------------------
 1393|  1.06k|                if ((retval = sav_read_document_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1393:21): [True: 66, False: 996]
  ------------------
 1394|     66|                    goto cleanup;
 1395|    996|                break;
 1396|  2.76k|            case SAV_RECORD_TYPE_DICT_TERMINATION:
  ------------------
  |  |  116|  2.76k|#define SAV_RECORD_TYPE_DICT_TERMINATION        999
  ------------------
  |  Branch (1396:13): [True: 2.76k, False: 328k]
  ------------------
 1397|  2.76k|                if ((retval = sav_read_dictionary_termination_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1397:21): [True: 1.16k, False: 1.60k]
  ------------------
 1398|  1.16k|                    goto cleanup;
 1399|  1.60k|                done = 1;
 1400|  1.60k|                break;
 1401|  6.74k|            case SAV_RECORD_TYPE_HAS_DATA:
  ------------------
  |  |  115|  6.74k|#define SAV_RECORD_TYPE_HAS_DATA                7
  ------------------
  |  Branch (1401:13): [True: 6.74k, False: 324k]
  ------------------
 1402|  6.74k|                if (io->read(extra_info, sizeof(extra_info), io->io_ctx) < sizeof(extra_info)) {
  ------------------
  |  Branch (1402:21): [True: 7, False: 6.74k]
  ------------------
 1403|      7|                    retval = READSTAT_ERROR_READ;
 1404|      7|                    goto cleanup;
 1405|      7|                }
 1406|  6.74k|                if (ctx->bswap) {
  ------------------
  |  Branch (1406:21): [True: 1.72k, False: 5.01k]
  ------------------
 1407|  6.89k|                    for (i=0; i<3; i++)
  ------------------
  |  Branch (1407:31): [True: 5.16k, False: 1.72k]
  ------------------
 1408|  5.16k|                        extra_info[i] = byteswap4(extra_info[i]);
 1409|  1.72k|                }
 1410|  6.74k|                uint32_t subtype = extra_info[0];
 1411|  6.74k|                size_t size = extra_info[1];
 1412|  6.74k|                size_t count = extra_info[2];
 1413|  6.74k|                data_len = size * count;
 1414|  6.74k|                if (data_buf_capacity < data_len) {
  ------------------
  |  Branch (1414:21): [True: 171, False: 6.57k]
  ------------------
 1415|    171|                    if ((data_buf = readstat_realloc(data_buf, data_buf_capacity = data_len)) == NULL) {
  ------------------
  |  Branch (1415:25): [True: 65, False: 106]
  ------------------
 1416|     65|                        retval = READSTAT_ERROR_MALLOC;
 1417|     65|                        goto cleanup;
 1418|     65|                    }
 1419|    171|                }
 1420|  6.67k|                if (data_len == 0 || io->read(data_buf, data_len, io->io_ctx) < data_len) {
  ------------------
  |  Branch (1420:21): [True: 17, False: 6.66k]
  |  Branch (1420:38): [True: 41, False: 6.61k]
  ------------------
 1421|     58|                    retval = READSTAT_ERROR_PARSE;
 1422|     58|                    goto cleanup;
 1423|     58|                }
 1424|       |                
 1425|  6.61k|                switch (subtype) {
 1426|     67|                    case SAV_RECORD_SUBTYPE_INTEGER_INFO:
  ------------------
  |  |  118|     67|#define SAV_RECORD_SUBTYPE_INTEGER_INFO       3
  ------------------
  |  Branch (1426:21): [True: 67, False: 6.55k]
  ------------------
 1427|       |                        /* parsed in pass 1 */
 1428|     67|                        break;
 1429|    457|                    case SAV_RECORD_SUBTYPE_FP_INFO:
  ------------------
  |  |  119|    457|#define SAV_RECORD_SUBTYPE_FP_INFO            4
  ------------------
  |  Branch (1429:21): [True: 457, False: 6.16k]
  ------------------
 1430|    457|                        retval = sav_parse_machine_floating_point_record(data_buf, size, count, ctx);
 1431|    457|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1431:29): [True: 35, False: 422]
  ------------------
 1432|     35|                            goto cleanup;
 1433|    422|                        break;
 1434|    524|                    case SAV_RECORD_SUBTYPE_VAR_DISPLAY:
  ------------------
  |  |  121|    524|#define SAV_RECORD_SUBTYPE_VAR_DISPLAY       11
  ------------------
  |  Branch (1434:21): [True: 524, False: 6.09k]
  ------------------
 1435|    524|                        retval = sav_store_variable_display_parameter_record(data_buf, size, count, ctx);
 1436|    524|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1436:29): [True: 9, False: 515]
  ------------------
 1437|      9|                            goto cleanup;
 1438|    515|                        break;
 1439|  1.11k|                    case SAV_RECORD_SUBTYPE_LONG_VAR_NAME:
  ------------------
  |  |  122|  1.11k|#define SAV_RECORD_SUBTYPE_LONG_VAR_NAME     13
  ------------------
  |  Branch (1439:21): [True: 1.11k, False: 5.50k]
  ------------------
 1440|  1.11k|                        retval = sav_parse_long_variable_names_record(data_buf, count, ctx);
 1441|  1.11k|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1441:29): [True: 175, False: 937]
  ------------------
 1442|    175|                            goto cleanup;
 1443|    937|                        break;
 1444|  2.22k|                    case SAV_RECORD_SUBTYPE_VERY_LONG_STR:
  ------------------
  |  |  123|  2.22k|#define SAV_RECORD_SUBTYPE_VERY_LONG_STR     14
  ------------------
  |  Branch (1444:21): [True: 2.22k, False: 4.39k]
  ------------------
 1445|  2.22k|                        retval = sav_parse_very_long_string_record(data_buf, count, ctx);
 1446|  2.22k|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1446:29): [True: 178, False: 2.04k]
  ------------------
 1447|    178|                            goto cleanup;
 1448|  2.04k|                        break;
 1449|  2.04k|                    case SAV_RECORD_SUBTYPE_LONG_STRING_VALUE_LABELS:
  ------------------
  |  |  128|    719|#define SAV_RECORD_SUBTYPE_LONG_STRING_VALUE_LABELS   21
  ------------------
  |  Branch (1449:21): [True: 719, False: 5.90k]
  ------------------
 1450|    719|                        retval = sav_parse_long_string_value_labels_record(data_buf, size, count, ctx);
 1451|    719|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1451:29): [True: 255, False: 464]
  ------------------
 1452|    255|                            goto cleanup;
 1453|    464|                        break;
 1454|    470|                    case SAV_RECORD_SUBTYPE_LONG_STRING_MISSING_VALUES:
  ------------------
  |  |  129|    470|#define SAV_RECORD_SUBTYPE_LONG_STRING_MISSING_VALUES 22
  ------------------
  |  Branch (1454:21): [True: 470, False: 6.14k]
  ------------------
 1455|    470|                        retval = sav_parse_long_string_missing_values_record(data_buf, size, count, ctx);
 1456|    470|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1456:29): [True: 199, False: 271]
  ------------------
 1457|    199|                            goto cleanup;
 1458|    271|                        break;
 1459|  1.04k|                    default: /* misc. info */
  ------------------
  |  Branch (1459:21): [True: 1.04k, False: 5.57k]
  ------------------
 1460|  1.04k|                        break;
 1461|  6.61k|                }
 1462|  5.76k|                break;
 1463|  5.76k|            default:
  ------------------
  |  Branch (1463:13): [True: 71, False: 331k]
  ------------------
 1464|     71|                retval = READSTAT_ERROR_PARSE;
 1465|     71|                goto cleanup;
 1466|      0|                break;
 1467|   331k|        }
 1468|   328k|        if (done)
  ------------------
  |  Branch (1468:13): [True: 1.60k, False: 327k]
  ------------------
 1469|  1.60k|            break;
 1470|   328k|    }
 1471|  4.27k|cleanup:
 1472|  4.27k|    if (data_buf)
  ------------------
  |  Branch (1472:9): [True: 4.20k, False: 65]
  ------------------
 1473|  4.20k|        free(data_buf);
 1474|  4.27k|    return retval;
 1475|  4.27k|}
readstat_sav_read.c:sav_read_variable_record:
  315|   302k|static readstat_error_t sav_read_variable_record(sav_ctx_t *ctx) {
  316|   302k|    readstat_io_t *io = ctx->io;
  317|   302k|    sav_variable_record_t variable = { 0 };
  318|   302k|    spss_varinfo_t *info = NULL;
  319|   302k|    readstat_error_t retval = READSTAT_OK;
  320|   302k|    if (ctx->var_index == ctx->varinfo_capacity) {
  ------------------
  |  Branch (320:9): [True: 178, False: 302k]
  ------------------
  321|    178|        if ((ctx->varinfo = readstat_realloc(ctx->varinfo, (ctx->varinfo_capacity *= 2) * sizeof(spss_varinfo_t *))) == NULL) {
  ------------------
  |  Branch (321:13): [True: 0, False: 178]
  ------------------
  322|      0|            retval = READSTAT_ERROR_MALLOC;
  323|      0|            goto cleanup;
  324|      0|        }
  325|    178|    }
  326|   302k|    if (io->read(&variable, sizeof(sav_variable_record_t), io->io_ctx) < sizeof(sav_variable_record_t)) {
  ------------------
  |  Branch (326:9): [True: 9, False: 302k]
  ------------------
  327|      9|        retval = READSTAT_ERROR_READ;
  328|      9|        goto cleanup;
  329|      9|    }
  330|   302k|    variable.print = ctx->bswap ? byteswap4(variable.print) : variable.print;
  ------------------
  |  Branch (330:22): [True: 3.15k, False: 299k]
  ------------------
  331|   302k|    variable.write = ctx->bswap ? byteswap4(variable.write) : variable.write;
  ------------------
  |  Branch (331:22): [True: 3.15k, False: 299k]
  ------------------
  332|       |
  333|   302k|    int32_t type = ctx->bswap ? byteswap4(variable.type) : variable.type;
  ------------------
  |  Branch (333:20): [True: 3.15k, False: 299k]
  ------------------
  334|   302k|    if (type < 0) {
  ------------------
  |  Branch (334:9): [True: 2.40k, False: 300k]
  ------------------
  335|  2.40k|        if (ctx->var_index == 0) {
  ------------------
  |  Branch (335:13): [True: 33, False: 2.37k]
  ------------------
  336|     33|            return READSTAT_ERROR_PARSE;
  337|     33|        }
  338|  2.37k|        ctx->var_offset++;
  339|  2.37k|        ctx->varinfo[ctx->var_index-1]->width++;
  340|  2.37k|        return 0;
  341|  2.40k|    }
  342|       |
  343|   300k|    if ((info = readstat_calloc(1, sizeof(spss_varinfo_t))) == NULL) {
  ------------------
  |  Branch (343:9): [True: 0, False: 300k]
  ------------------
  344|      0|        retval = READSTAT_ERROR_MALLOC;
  345|      0|        goto cleanup;
  346|      0|    }
  347|   300k|    info->width = 1;
  348|   300k|    info->n_segments = 1;
  349|   300k|    info->index = ctx->var_index;
  350|   300k|    info->offset = ctx->var_offset;
  351|   300k|    info->labels_index = -1;
  352|       |
  353|   300k|    retval = readstat_convert(info->name, sizeof(info->name),
  354|   300k|            variable.name, sizeof(variable.name), NULL);
  355|   300k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (355:9): [True: 0, False: 300k]
  ------------------
  356|      0|        goto cleanup;
  357|       |
  358|   300k|    retval = readstat_convert(info->longname, sizeof(info->longname), 
  359|   300k|            variable.name, sizeof(variable.name), NULL);
  360|   300k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (360:9): [True: 0, False: 300k]
  ------------------
  361|      0|        goto cleanup;
  362|       |
  363|   300k|    info->print_format.decimal_places = (variable.print & 0x000000FF);
  364|   300k|    info->print_format.width = (variable.print & 0x0000FF00) >> 8;
  365|   300k|    info->print_format.type = (variable.print  & 0x00FF0000) >> 16;
  366|       |
  367|   300k|    info->write_format.decimal_places = (variable.write & 0x000000FF);
  368|   300k|    info->write_format.width = (variable.write & 0x0000FF00) >> 8;
  369|   300k|    info->write_format.type = (variable.write  & 0x00FF0000) >> 16;
  370|       |
  371|   300k|    if (type > 0 || info->print_format.type == SPSS_FORMAT_TYPE_A || info->write_format.type == SPSS_FORMAT_TYPE_A) {
  ------------------
  |  |    2|   514k|#define SPSS_FORMAT_TYPE_A        1
  ------------------
                  if (type > 0 || info->print_format.type == SPSS_FORMAT_TYPE_A || info->write_format.type == SPSS_FORMAT_TYPE_A) {
  ------------------
  |  |    2|   127k|#define SPSS_FORMAT_TYPE_A        1
  ------------------
  |  Branch (371:9): [True: 85.9k, False: 214k]
  |  Branch (371:21): [True: 86.7k, False: 127k]
  |  Branch (371:70): [True: 73.1k, False: 54.1k]
  ------------------
  372|   245k|        info->type = READSTAT_TYPE_STRING;
  373|   245k|    } else {
  374|  54.1k|        info->type = READSTAT_TYPE_DOUBLE;
  375|  54.1k|    }
  376|       |    
  377|   300k|    if (variable.has_var_label) {
  ------------------
  |  Branch (377:9): [True: 1.67k, False: 298k]
  ------------------
  378|  1.67k|        if ((retval = sav_read_variable_label(info, ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (378:13): [True: 66, False: 1.61k]
  ------------------
  379|     66|            goto cleanup;
  380|     66|        }
  381|  1.67k|    }
  382|       |    
  383|   299k|    if (variable.n_missing_values) {
  ------------------
  |  Branch (383:9): [True: 2.55k, False: 297k]
  ------------------
  384|  2.55k|        info->n_missing_values = ctx->bswap ? byteswap4(variable.n_missing_values) : variable.n_missing_values;
  ------------------
  |  Branch (384:34): [True: 858, False: 1.70k]
  ------------------
  385|  2.55k|        if ((retval = sav_read_variable_missing_values(info, ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (385:13): [True: 64, False: 2.49k]
  ------------------
  386|     64|            goto cleanup;
  387|     64|        }
  388|  2.55k|    }
  389|       |    
  390|   299k|    ctx->varinfo[ctx->var_index] = info;
  391|       |
  392|   299k|    ctx->var_index++;
  393|   299k|    ctx->var_offset++;
  394|       |    
  395|   300k|cleanup:
  396|   300k|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (396:9): [True: 139, False: 299k]
  ------------------
  397|    139|        spss_varinfo_free(info);
  398|    139|    }
  399|       |
  400|   300k|    return retval;
  401|   299k|}
readstat_sav_read.c:sav_read_variable_label:
  200|  1.67k|static readstat_error_t sav_read_variable_label(spss_varinfo_t *info, sav_ctx_t *ctx) {
  201|  1.67k|    readstat_io_t *io = ctx->io;
  202|  1.67k|    readstat_error_t retval = READSTAT_OK;
  203|  1.67k|    uint32_t label_len, label_capacity;
  204|  1.67k|    size_t out_label_len;
  205|  1.67k|    char *label_buf = NULL;
  206|  1.67k|    if (io->read(&label_len, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (206:9): [True: 6, False: 1.67k]
  ------------------
  207|      6|        retval = READSTAT_ERROR_READ;
  208|      6|        goto cleanup;
  209|      6|    }
  210|  1.67k|    label_len = ctx->bswap ? byteswap4(label_len) : label_len;
  ------------------
  |  Branch (210:17): [True: 987, False: 684]
  ------------------
  211|       |
  212|  1.67k|    if (label_len == 0)
  ------------------
  |  Branch (212:9): [True: 876, False: 795]
  ------------------
  213|    876|        goto cleanup;
  214|       |
  215|    795|    label_capacity = (label_len + 3) / 4 * 4;
  216|    795|    if ((label_buf = readstat_malloc(label_capacity)) == NULL) {
  ------------------
  |  Branch (216:9): [True: 34, False: 761]
  ------------------
  217|     34|        retval = READSTAT_ERROR_MALLOC;
  218|     34|        goto cleanup;
  219|     34|    }
  220|       |
  221|    761|    out_label_len = (size_t)label_len*4+1;
  222|    761|    if ((info->label = readstat_malloc(out_label_len)) == NULL) {
  ------------------
  |  Branch (222:9): [True: 2, False: 759]
  ------------------
  223|      2|        retval = READSTAT_ERROR_MALLOC;
  224|      2|        goto cleanup;
  225|      2|    }
  226|       |
  227|    759|    if (io->read(label_buf, label_capacity, io->io_ctx) < label_capacity) {
  ------------------
  |  Branch (227:9): [True: 24, False: 735]
  ------------------
  228|     24|        retval = READSTAT_ERROR_READ;
  229|     24|        goto cleanup;
  230|     24|    }
  231|       |
  232|    735|    retval = readstat_convert(info->label, out_label_len, label_buf, label_len, ctx->converter);
  233|    735|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (233:9): [True: 0, False: 735]
  ------------------
  234|      0|        goto cleanup;
  235|       |
  236|  1.67k|cleanup:
  237|  1.67k|    if (label_buf)
  ------------------
  |  Branch (237:9): [True: 761, False: 916]
  ------------------
  238|    761|        free(label_buf);
  239|       |
  240|  1.67k|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (240:9): [True: 66, False: 1.61k]
  ------------------
  241|     66|        if (info->label) {
  ------------------
  |  Branch (241:13): [True: 24, False: 42]
  ------------------
  242|     24|            free(info->label);
  243|     24|            info->label = NULL;
  244|     24|        }
  245|     66|    }
  246|       |
  247|  1.67k|    return retval;
  248|    735|}
readstat_sav_read.c:sav_read_variable_missing_values:
  299|  2.55k|static readstat_error_t sav_read_variable_missing_values(spss_varinfo_t *info, sav_ctx_t *ctx) {
  300|  2.55k|    if (info->n_missing_values > 3 || info->n_missing_values < -3) {
  ------------------
  |  Branch (300:9): [True: 4, False: 2.55k]
  |  Branch (300:39): [True: 48, False: 2.50k]
  ------------------
  301|     52|        return READSTAT_ERROR_PARSE;
  302|     52|    }
  303|  2.50k|    if (info->n_missing_values < 0) {
  ------------------
  |  Branch (303:9): [True: 1.54k, False: 957]
  ------------------
  304|  1.54k|        info->missing_range = 1;
  305|  1.54k|        info->n_missing_values = abs(info->n_missing_values);
  306|  1.54k|    } else {
  307|    957|        info->missing_range = 0;
  308|    957|    }
  309|  2.50k|    if (info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (309:9): [True: 1.43k, False: 1.07k]
  ------------------
  310|  1.43k|        return sav_read_variable_missing_double_values(info, ctx);
  311|  1.43k|    }
  312|  1.07k|    return sav_read_variable_missing_string_values(info, ctx);
  313|  2.50k|}
readstat_sav_read.c:sav_read_variable_missing_double_values:
  250|  1.43k|static readstat_error_t sav_read_variable_missing_double_values(spss_varinfo_t *info, sav_ctx_t *ctx) {
  251|  1.43k|    readstat_io_t *io = ctx->io;
  252|  1.43k|    int i;
  253|  1.43k|    readstat_error_t retval = READSTAT_OK;
  254|  1.43k|    if (io->read(info->missing_double_values, info->n_missing_values * sizeof(double), io->io_ctx)
  ------------------
  |  Branch (254:9): [True: 6, False: 1.42k]
  ------------------
  255|  1.43k|            < info->n_missing_values * sizeof(double)) {
  256|      6|        retval = READSTAT_ERROR_READ;
  257|      6|        goto cleanup;
  258|      6|    }
  259|  4.08k|    for (i=0; i<info->n_missing_values; i++) {
  ------------------
  |  Branch (259:15): [True: 2.65k, False: 1.42k]
  ------------------
  260|  2.65k|        if (ctx->bswap) {
  ------------------
  |  Branch (260:13): [True: 1.08k, False: 1.57k]
  ------------------
  261|  1.08k|            info->missing_double_values[i] = byteswap_double(info->missing_double_values[i]);
  262|  1.08k|        }
  263|       |
  264|  2.65k|        uint64_t long_value = 0;
  265|  2.65k|        memcpy(&long_value, &info->missing_double_values[i], 8);
  266|       |
  267|  2.65k|        if (long_value == ctx->missing_double)
  ------------------
  |  Branch (267:13): [True: 197, False: 2.46k]
  ------------------
  268|    197|            info->missing_double_values[i] = NAN;
  269|  2.65k|        if (long_value == ctx->lowest_double)
  ------------------
  |  Branch (269:13): [True: 283, False: 2.37k]
  ------------------
  270|    283|            info->missing_double_values[i] = -HUGE_VAL;
  271|  2.65k|        if (long_value == ctx->highest_double)
  ------------------
  |  Branch (271:13): [True: 289, False: 2.36k]
  ------------------
  272|    289|            info->missing_double_values[i] = HUGE_VAL;
  273|  2.65k|    }
  274|       |
  275|  1.43k|cleanup:
  276|  1.43k|    return retval;
  277|  1.42k|}
readstat_sav_read.c:sav_read_variable_missing_string_values:
  279|  1.07k|static readstat_error_t sav_read_variable_missing_string_values(spss_varinfo_t *info, sav_ctx_t *ctx) {
  280|  1.07k|    readstat_io_t *io = ctx->io;
  281|  1.07k|    int i;
  282|  1.07k|    readstat_error_t retval = READSTAT_OK;
  283|  3.51k|    for (i=0; i<info->n_missing_values; i++) {
  ------------------
  |  Branch (283:15): [True: 2.44k, False: 1.07k]
  ------------------
  284|  2.44k|        char missing_value[8];
  285|  2.44k|        if (io->read(missing_value, sizeof(missing_value), io->io_ctx) < sizeof(missing_value)) {
  ------------------
  |  Branch (285:13): [True: 5, False: 2.43k]
  ------------------
  286|      5|            retval = READSTAT_ERROR_READ;
  287|      5|            goto cleanup;
  288|      5|        }
  289|  2.43k|        retval = readstat_convert(info->missing_string_values[i], sizeof(info->missing_string_values[0]),
  290|  2.43k|                missing_value, sizeof(missing_value), ctx->converter);
  291|  2.43k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (291:13): [True: 1, False: 2.43k]
  ------------------
  292|      1|            goto cleanup;
  293|  2.43k|    }
  294|       |
  295|  1.07k|cleanup:
  296|  1.07k|    return retval;
  297|  1.07k|}
readstat_sav_read.c:sav_read_value_label_record:
  480|  18.4k|static readstat_error_t sav_read_value_label_record(sav_ctx_t *ctx) {
  481|  18.4k|    uint32_t label_count;
  482|  18.4k|    readstat_error_t retval = READSTAT_OK;
  483|  18.4k|    readstat_io_t *io = ctx->io;
  484|  18.4k|    uint32_t *vars = NULL;
  485|  18.4k|    uint32_t var_count;
  486|  18.4k|    int32_t rec_type;
  487|  18.4k|    readstat_type_t value_type = READSTAT_TYPE_STRING;
  488|  18.4k|    char label_buf[256];
  489|  18.4k|    value_label_t *value_labels = NULL;
  490|       |
  491|  18.4k|    if (io->read(&label_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (491:9): [True: 3, False: 18.4k]
  ------------------
  492|      3|        retval = READSTAT_ERROR_READ;
  493|      3|        goto cleanup;
  494|      3|    }
  495|  18.4k|    if (ctx->bswap)
  ------------------
  |  Branch (495:9): [True: 17.5k, False: 886]
  ------------------
  496|  17.5k|        label_count = byteswap4(label_count);
  497|       |    
  498|  18.4k|    if (label_count && (value_labels = readstat_calloc(label_count, sizeof(value_label_t))) == NULL) {
  ------------------
  |  Branch (498:9): [True: 1.86k, False: 16.5k]
  |  Branch (498:24): [True: 26, False: 1.83k]
  ------------------
  499|     26|        retval = READSTAT_ERROR_MALLOC;
  500|     26|        goto cleanup;
  501|     26|    }
  502|       |    
  503|  18.4k|    int i;
  504|  88.6k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (504:15): [True: 70.2k, False: 18.3k]
  ------------------
  505|  70.2k|        value_label_t *vlabel = &value_labels[i];
  506|  70.2k|        unsigned char unpadded_label_len = 0;
  507|  70.2k|        size_t padded_label_len = 0, utf8_label_len = 0;
  508|       |
  509|  70.2k|        if (io->read(vlabel->raw_value, 8, io->io_ctx) < 8) {
  ------------------
  |  Branch (509:13): [True: 30, False: 70.2k]
  ------------------
  510|     30|            retval = READSTAT_ERROR_READ;
  511|     30|            goto cleanup;
  512|     30|        }
  513|  70.2k|        if (io->read(&unpadded_label_len, 1, io->io_ctx) < 1) {
  ------------------
  |  Branch (513:13): [True: 1, False: 70.2k]
  ------------------
  514|      1|            retval = READSTAT_ERROR_READ;
  515|      1|            goto cleanup;
  516|      1|        }
  517|       |
  518|  70.2k|        padded_label_len = (unpadded_label_len + 8) / 8 * 8 - 1;
  519|  70.2k|        if (io->read(label_buf, padded_label_len, io->io_ctx) < padded_label_len) {
  ------------------
  |  Branch (519:13): [True: 3, False: 70.2k]
  ------------------
  520|      3|            retval = READSTAT_ERROR_READ;
  521|      3|            goto cleanup;
  522|      3|        }
  523|       |
  524|  70.2k|        utf8_label_len = padded_label_len*4+1;
  525|  70.2k|        if ((vlabel->label = readstat_malloc(utf8_label_len)) == NULL) {
  ------------------
  |  Branch (525:13): [True: 0, False: 70.2k]
  ------------------
  526|      0|            retval = READSTAT_ERROR_MALLOC;
  527|      0|            goto cleanup;
  528|      0|        }
  529|       |
  530|  70.2k|        retval = readstat_convert(vlabel->label, utf8_label_len, label_buf, padded_label_len, ctx->converter);
  531|  70.2k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (531:13): [True: 1, False: 70.2k]
  ------------------
  532|      1|            goto cleanup;
  533|  70.2k|    }
  534|       |
  535|  18.3k|    if (io->read(&rec_type, sizeof(int32_t), io->io_ctx) < sizeof(int32_t)) {
  ------------------
  |  Branch (535:9): [True: 3, False: 18.3k]
  ------------------
  536|      3|        retval = READSTAT_ERROR_READ;
  537|      3|        goto cleanup;
  538|      3|    }
  539|  18.3k|    if (ctx->bswap)
  ------------------
  |  Branch (539:9): [True: 17.5k, False: 825]
  ------------------
  540|  17.5k|        rec_type = byteswap4(rec_type);
  541|       |    
  542|  18.3k|    if (rec_type != 4) {
  ------------------
  |  Branch (542:9): [True: 46, False: 18.3k]
  ------------------
  543|     46|        retval = READSTAT_ERROR_PARSE;
  544|     46|        goto cleanup;
  545|     46|    }
  546|  18.3k|    if (io->read(&var_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (546:9): [True: 3, False: 18.3k]
  ------------------
  547|      3|        retval = READSTAT_ERROR_READ;
  548|      3|        goto cleanup;
  549|      3|    }
  550|  18.3k|    if (ctx->bswap)
  ------------------
  |  Branch (550:9): [True: 17.5k, False: 807]
  ------------------
  551|  17.5k|        var_count = byteswap4(var_count);
  552|       |    
  553|  18.3k|    if (var_count && (vars = readstat_malloc(var_count * sizeof(uint32_t))) == NULL) {
  ------------------
  |  Branch (553:9): [True: 5.38k, False: 12.9k]
  |  Branch (553:22): [True: 37, False: 5.34k]
  ------------------
  554|     37|        retval = READSTAT_ERROR_MALLOC;
  555|     37|        goto cleanup;
  556|     37|    }
  557|  18.3k|    if (io->read(vars, var_count * sizeof(uint32_t), io->io_ctx) < var_count * sizeof(uint32_t)) {
  ------------------
  |  Branch (557:9): [True: 24, False: 18.2k]
  ------------------
  558|     24|        retval = READSTAT_ERROR_READ;
  559|     24|        goto cleanup;
  560|     24|    }
  561|   100k|    for (i=0; i<var_count; i++) {
  ------------------
  |  Branch (561:15): [True: 82.5k, False: 18.2k]
  ------------------
  562|  82.5k|        uint32_t var_offset = vars[i];
  563|  82.5k|        if (ctx->bswap)
  ------------------
  |  Branch (563:13): [True: 15.2k, False: 67.3k]
  ------------------
  564|  15.2k|            var_offset = byteswap4(var_offset);
  565|       |
  566|  82.5k|        var_offset--; // Why subtract 1????
  567|  82.5k|        spss_varinfo_t **var = bsearch(&var_offset, ctx->varinfo, ctx->var_index, sizeof(spss_varinfo_t *),
  568|  82.5k|                &spss_varinfo_compare);
  569|  82.5k|        if (var) {
  ------------------
  |  Branch (569:13): [True: 12.7k, False: 69.7k]
  ------------------
  570|  12.7k|            (*var)->labels_index = ctx->value_labels_count;
  571|  12.7k|            value_type = (*var)->type;
  572|  12.7k|        }
  573|  82.5k|    }
  574|       |
  575|  88.5k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (575:15): [True: 70.2k, False: 18.2k]
  ------------------
  576|  70.2k|        value_label_t *vlabel = &value_labels[i];
  577|  70.2k|        double val_d = 0.0;
  578|  70.2k|        vlabel->final_value.type = value_type;
  579|  70.2k|        if (value_type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (579:13): [True: 15.1k, False: 55.0k]
  ------------------
  580|  15.1k|            memcpy(&val_d, vlabel->raw_value, 8);
  581|  15.1k|            if (ctx->bswap)
  ------------------
  |  Branch (581:17): [True: 14.6k, False: 577]
  ------------------
  582|  14.6k|                val_d = byteswap_double(val_d);
  583|       |
  584|  15.1k|            vlabel->final_value.v.double_value = val_d;
  585|  15.1k|            sav_tag_missing_double(&vlabel->final_value, ctx);
  586|  55.0k|        } else {
  587|  55.0k|            retval = readstat_convert(vlabel->utf8_string_value, sizeof(vlabel->utf8_string_value),
  588|  55.0k|                    vlabel->raw_value, 8, ctx->converter);
  589|  55.0k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (589:17): [True: 2, False: 55.0k]
  ------------------
  590|      2|                break;
  591|       |
  592|  55.0k|            vlabel->final_value.v.string_value = vlabel->utf8_string_value;
  593|  55.0k|        }
  594|  70.2k|    }
  595|       |
  596|  18.2k|    if (ctx->handle.value_label) {
  ------------------
  |  Branch (596:9): [True: 18.2k, False: 0]
  ------------------
  597|  18.2k|        sav_submit_value_labels(value_labels, label_count, value_type, ctx);
  598|  18.2k|    }
  599|  18.2k|    ctx->value_labels_count++;
  600|  18.4k|cleanup:
  601|  18.4k|    if (vars)
  ------------------
  |  Branch (601:9): [True: 5.34k, False: 13.1k]
  ------------------
  602|  5.34k|        free(vars);
  603|  18.4k|    if (value_labels) {
  ------------------
  |  Branch (603:9): [True: 1.83k, False: 16.6k]
  ------------------
  604|  6.06M|        for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (604:19): [True: 6.06M, False: 1.83k]
  ------------------
  605|  6.06M|            value_label_t *vlabel = &value_labels[i];
  606|  6.06M|            if (vlabel->label)
  ------------------
  |  Branch (606:17): [True: 70.2k, False: 5.98M]
  ------------------
  607|  70.2k|                free(vlabel->label);
  608|  6.06M|        }
  609|  1.83k|        free(value_labels);
  610|  1.83k|    }
  611|       |    
  612|  18.4k|    return retval;
  613|  18.2k|}
readstat_sav_read.c:sav_tag_missing_double:
  149|  1.35M|static void sav_tag_missing_double(readstat_value_t *value, sav_ctx_t *ctx) {
  150|  1.35M|    double fp_value = value->v.double_value;
  151|  1.35M|    uint64_t long_value = 0;
  152|  1.35M|    memcpy(&long_value, &fp_value, 8);
  153|  1.35M|    if (long_value == ctx->missing_double)
  ------------------
  |  Branch (153:9): [True: 99.7k, False: 1.25M]
  ------------------
  154|  99.7k|        value->is_system_missing = 1;
  155|  1.35M|    if (long_value == ctx->lowest_double)
  ------------------
  |  Branch (155:9): [True: 411, False: 1.35M]
  ------------------
  156|    411|        value->is_system_missing = 1;
  157|  1.35M|    if (long_value == ctx->highest_double)
  ------------------
  |  Branch (157:9): [True: 426, False: 1.35M]
  ------------------
  158|    426|        value->is_system_missing = 1;
  159|  1.35M|    if (isnan(fp_value))
  160|  64.3k|        value->is_system_missing = 1;
  161|  1.35M|}
readstat_sav_read.c:sav_submit_value_labels:
  462|  18.2k|        readstat_type_t value_type, sav_ctx_t *ctx) {
  463|  18.2k|    char label_name_buf[256];
  464|  18.2k|    readstat_error_t retval = READSTAT_OK;
  465|  18.2k|    int32_t i;
  466|       |
  467|  18.2k|    snprintf(label_name_buf, sizeof(label_name_buf), SAV_LABEL_NAME_PREFIX "%d", ctx->value_labels_count);
  ------------------
  |  |  115|  18.2k|#define SAV_LABEL_NAME_PREFIX         "labels"
  ------------------
  468|       |
  469|  88.5k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (469:15): [True: 70.2k, False: 18.2k]
  ------------------
  470|  70.2k|        value_label_t *vlabel = &value_labels[i];
  471|  70.2k|        if (ctx->handle.value_label(label_name_buf, vlabel->final_value, vlabel->label, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (471:13): [True: 0, False: 70.2k]
  ------------------
  472|      0|            retval = READSTAT_ERROR_USER_ABORT;
  473|      0|            goto cleanup;
  474|      0|        }
  475|  70.2k|    }
  476|  18.2k|cleanup:
  477|  18.2k|    return retval;
  478|  18.2k|}
readstat_sav_read.c:sav_read_document_record:
  634|  1.06k|static readstat_error_t sav_read_document_record(sav_ctx_t *ctx) {
  635|  1.06k|    if (!ctx->handle.note)
  ------------------
  |  Branch (635:9): [True: 0, False: 1.06k]
  ------------------
  636|      0|        return sav_skip_document_record(ctx);
  637|       |
  638|  1.06k|    uint32_t n_lines;
  639|  1.06k|    readstat_error_t retval = READSTAT_OK;
  640|  1.06k|    readstat_io_t *io = ctx->io;
  641|  1.06k|    if (io->read(&n_lines, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (641:9): [True: 4, False: 1.05k]
  ------------------
  642|      4|        retval = READSTAT_ERROR_READ;
  643|      4|        goto cleanup;
  644|      4|    }
  645|  1.05k|    if (ctx->bswap)
  ------------------
  |  Branch (645:9): [True: 542, False: 516]
  ------------------
  646|    542|        n_lines = byteswap4(n_lines);
  647|       |
  648|  1.05k|    char raw_buffer[SPSS_DOC_LINE_SIZE];
  649|  1.05k|    char utf8_buffer[4*SPSS_DOC_LINE_SIZE+1];
  650|  1.05k|    int i;
  651|  1.45k|    for (i=0; i<n_lines; i++) {
  ------------------
  |  Branch (651:15): [True: 458, False: 996]
  ------------------
  652|    458|        if (io->read(raw_buffer, SPSS_DOC_LINE_SIZE, io->io_ctx) < SPSS_DOC_LINE_SIZE) {
  ------------------
  |  |   40|    458|#define SPSS_DOC_LINE_SIZE  80
  ------------------
                      if (io->read(raw_buffer, SPSS_DOC_LINE_SIZE, io->io_ctx) < SPSS_DOC_LINE_SIZE) {
  ------------------
  |  |   40|    458|#define SPSS_DOC_LINE_SIZE  80
  ------------------
  |  Branch (652:13): [True: 61, False: 397]
  ------------------
  653|     61|            retval = READSTAT_ERROR_READ;
  654|     61|            goto cleanup;
  655|     61|        }
  656|       |
  657|    397|        retval = readstat_convert(utf8_buffer, sizeof(utf8_buffer),
  658|    397|                raw_buffer, sizeof(raw_buffer), ctx->converter);
  659|    397|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (659:13): [True: 1, False: 396]
  ------------------
  660|      1|            goto cleanup;
  661|       |
  662|    396|        if (ctx->handle.note(i, utf8_buffer, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (662:13): [True: 0, False: 396]
  ------------------
  663|      0|            retval = READSTAT_ERROR_USER_ABORT;
  664|      0|            goto cleanup;
  665|      0|        }
  666|    396|    }
  667|       |
  668|  1.06k|cleanup:
  669|  1.06k|    return retval;
  670|  1.05k|}
readstat_sav_read.c:sav_read_dictionary_termination_record:
  672|  2.76k|static readstat_error_t sav_read_dictionary_termination_record(sav_ctx_t *ctx) {
  673|  2.76k|    int32_t filler;
  674|  2.76k|    readstat_error_t retval = READSTAT_OK;
  675|  2.76k|    readstat_io_t *io = ctx->io;
  676|  2.76k|    if (io->read(&filler, sizeof(int32_t), io->io_ctx) < sizeof(int32_t)) {
  ------------------
  |  Branch (676:9): [True: 1.16k, False: 1.60k]
  ------------------
  677|  1.16k|        retval = READSTAT_ERROR_READ;
  678|  1.16k|    }
  679|  2.76k|    return retval;
  680|  2.76k|}
readstat_sav_read.c:sav_parse_machine_floating_point_record:
  967|    457|static readstat_error_t sav_parse_machine_floating_point_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
  968|    457|    if (size != 8 || count != 3)
  ------------------
  |  Branch (968:9): [True: 19, False: 438]
  |  Branch (968:22): [True: 16, False: 422]
  ------------------
  969|     35|        return READSTAT_ERROR_PARSE;
  970|       |
  971|    422|    sav_machine_floating_point_info_record_t fp_info;
  972|    422|    memcpy(&fp_info, data, sizeof(sav_machine_floating_point_info_record_t));
  973|       |
  974|    422|    ctx->missing_double = ctx->bswap ? byteswap8(fp_info.sysmis) : fp_info.sysmis;
  ------------------
  |  Branch (974:27): [True: 201, False: 221]
  ------------------
  975|    422|    ctx->highest_double = ctx->bswap ? byteswap8(fp_info.highest) : fp_info.highest;
  ------------------
  |  Branch (975:27): [True: 201, False: 221]
  ------------------
  976|    422|    ctx->lowest_double = ctx->bswap ? byteswap8(fp_info.lowest) : fp_info.lowest;
  ------------------
  |  Branch (976:26): [True: 201, False: 221]
  ------------------
  977|       |
  978|    422|    return READSTAT_OK;
  979|    457|}
readstat_sav_read.c:sav_store_variable_display_parameter_record:
  983|    524|static readstat_error_t sav_store_variable_display_parameter_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
  984|    524|    if (size != 4)
  ------------------
  |  Branch (984:9): [True: 9, False: 515]
  ------------------
  985|      9|        return READSTAT_ERROR_PARSE;
  986|       |
  987|    515|    const uint32_t *data_ptr = data;
  988|    515|    int i;
  989|       |
  990|    515|    ctx->variable_display_values = readstat_realloc(ctx->variable_display_values, count * sizeof(uint32_t));
  991|    515|    if (count > 0 && ctx->variable_display_values == NULL)
  ------------------
  |  Branch (991:9): [True: 515, False: 0]
  |  Branch (991:22): [True: 0, False: 515]
  ------------------
  992|      0|        return READSTAT_ERROR_MALLOC;
  993|       |
  994|    515|    ctx->variable_display_values_count = count;
  995|  1.01M|    for (i=0; i<count; i++) {
  ------------------
  |  Branch (995:15): [True: 1.01M, False: 515]
  ------------------
  996|  1.01M|        ctx->variable_display_values[i] = ctx->bswap ? byteswap4(data_ptr[i]) : data_ptr[i];
  ------------------
  |  Branch (996:43): [True: 135k, False: 884k]
  ------------------
  997|  1.01M|    }
  998|    515|    return READSTAT_OK;
  999|    515|}
readstat_sav_read.c:sav_parse_long_string_value_labels_record:
 1061|    719|static readstat_error_t sav_parse_long_string_value_labels_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
 1062|    719|    if (!ctx->handle.value_label)
  ------------------
  |  Branch (1062:9): [True: 0, False: 719]
  ------------------
 1063|      0|        return READSTAT_OK;
 1064|    719|    if (size != 1)
  ------------------
  |  Branch (1064:9): [True: 14, False: 705]
  ------------------
 1065|     14|        return READSTAT_ERROR_PARSE;
 1066|       |
 1067|    705|    readstat_error_t retval = READSTAT_OK;
 1068|    705|    uint32_t label_count = 0;
 1069|    705|    uint32_t i = 0;
 1070|    705|    const char *data_ptr = data;
 1071|    705|    const char *data_end = data_ptr + count;
 1072|    705|    char var_name_buf[256+1]; // unconverted
 1073|    705|    char label_name_buf[256];
 1074|    705|    char *value_buffer = NULL;
 1075|    705|    char *label_buffer = NULL;
 1076|       |    
 1077|  2.31k|    while (data_ptr < data_end) {
  ------------------
  |  Branch (1077:12): [True: 1.85k, False: 464]
  ------------------
 1078|  1.85k|        memset(label_name_buf, '\0', sizeof(label_name_buf));
 1079|       |
 1080|  1.85k|        retval = sav_read_pascal_string(var_name_buf, sizeof(var_name_buf),
 1081|  1.85k|                &data_ptr, data_end - data_ptr, ctx);
 1082|  1.85k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1082:13): [True: 42, False: 1.81k]
  ------------------
 1083|     42|            goto cleanup;
 1084|       |
 1085|  19.5k|        for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1085:19): [True: 19.4k, False: 94]
  ------------------
 1086|  19.4k|            spss_varinfo_t *info = ctx->varinfo[i];
 1087|  19.4k|            if (strcmp(var_name_buf, info->longname) == 0) {
  ------------------
  |  Branch (1087:17): [True: 1.71k, False: 17.7k]
  ------------------
 1088|  1.71k|                info->labels_index = ctx->value_labels_count++;
 1089|  1.71k|                snprintf(label_name_buf, sizeof(label_name_buf),
 1090|  1.71k|                        SAV_LABEL_NAME_PREFIX "%d", info->labels_index);
  ------------------
  |  |  115|  1.71k|#define SAV_LABEL_NAME_PREFIX         "labels"
  ------------------
 1091|  1.71k|                break;
 1092|  1.71k|            }
 1093|  17.7k|            i += info->n_segments;
 1094|  17.7k|        }
 1095|       |
 1096|  1.81k|        if (label_name_buf[0] == '\0') {
  ------------------
  |  Branch (1096:13): [True: 94, False: 1.71k]
  ------------------
 1097|     94|            retval = READSTAT_ERROR_PARSE;
 1098|     94|            goto cleanup;
 1099|     94|        }
 1100|       |
 1101|  1.71k|        data_ptr += sizeof(uint32_t);
 1102|       |
 1103|  1.71k|        if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1103:13): [True: 13, False: 1.70k]
  ------------------
 1104|     13|            retval = READSTAT_ERROR_PARSE;
 1105|     13|            goto cleanup;
 1106|     13|        }
 1107|       |
 1108|  1.70k|        memcpy(&label_count, data_ptr, sizeof(uint32_t));
 1109|  1.70k|        if (ctx->bswap)
  ------------------
  |  Branch (1109:13): [True: 869, False: 835]
  ------------------
 1110|    869|            label_count = byteswap4(label_count);
 1111|       |
 1112|  1.70k|        data_ptr += sizeof(uint32_t);
 1113|       |
 1114|  2.94k|        for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (1114:19): [True: 1.33k, False: 1.61k]
  ------------------
 1115|  1.33k|            uint32_t value_len = 0, label_len = 0;
 1116|  1.33k|            uint32_t value_buffer_len = 0, label_buffer_len = 0;
 1117|       |
 1118|  1.33k|            if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1118:17): [True: 55, False: 1.27k]
  ------------------
 1119|     55|                retval = READSTAT_ERROR_PARSE;
 1120|     55|                goto cleanup;
 1121|     55|            }
 1122|       |
 1123|  1.27k|            memcpy(&value_len, data_ptr, sizeof(uint32_t));
 1124|  1.27k|            if (ctx->bswap)
  ------------------
  |  Branch (1124:17): [True: 745, False: 531]
  ------------------
 1125|    745|                value_len = byteswap4(value_len);
 1126|       |
 1127|  1.27k|            data_ptr += sizeof(uint32_t);
 1128|       |
 1129|  1.27k|            value_buffer_len = value_len*4+1;
 1130|  1.27k|            value_buffer = readstat_realloc(value_buffer, value_buffer_len);
 1131|  1.27k|            if (value_buffer == NULL) {
  ------------------
  |  Branch (1131:17): [True: 11, False: 1.26k]
  ------------------
 1132|     11|                retval = READSTAT_ERROR_MALLOC;
 1133|     11|                goto cleanup;
 1134|     11|            }
 1135|       |
 1136|  1.26k|            if (data_ptr + value_len > data_end) {
  ------------------
  |  Branch (1136:17): [True: 6, False: 1.25k]
  ------------------
 1137|      6|                retval = READSTAT_ERROR_PARSE;
 1138|      6|                goto cleanup;
 1139|      6|            }
 1140|       |
 1141|  1.25k|            retval = readstat_convert(value_buffer, value_buffer_len, data_ptr, value_len, ctx->converter);
 1142|  1.25k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (1142:17): [True: 1, False: 1.25k]
  ------------------
 1143|      1|                goto cleanup;
 1144|       |
 1145|  1.25k|            data_ptr += value_len;
 1146|       |
 1147|  1.25k|            if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1147:17): [True: 7, False: 1.25k]
  ------------------
 1148|      7|                retval = READSTAT_ERROR_PARSE;
 1149|      7|                goto cleanup;
 1150|      7|            }
 1151|       |
 1152|  1.25k|            memcpy(&label_len, data_ptr, sizeof(uint32_t));
 1153|  1.25k|            if (ctx->bswap)
  ------------------
  |  Branch (1153:17): [True: 738, False: 513]
  ------------------
 1154|    738|                label_len = byteswap4(label_len);
 1155|       |
 1156|  1.25k|            data_ptr += sizeof(uint32_t);
 1157|       |
 1158|  1.25k|            label_buffer_len = label_len*4+1;
 1159|  1.25k|            label_buffer = readstat_realloc(label_buffer, label_buffer_len);
 1160|  1.25k|            if (label_buffer == NULL) {
  ------------------
  |  Branch (1160:17): [True: 4, False: 1.24k]
  ------------------
 1161|      4|                retval = READSTAT_ERROR_MALLOC;
 1162|      4|                goto cleanup;
 1163|      4|            }
 1164|       |
 1165|  1.24k|            if (data_ptr + label_len > data_end) {
  ------------------
  |  Branch (1165:17): [True: 7, False: 1.24k]
  ------------------
 1166|      7|                retval = READSTAT_ERROR_PARSE;
 1167|      7|                goto cleanup;
 1168|      7|            }
 1169|       |
 1170|  1.24k|            retval = readstat_convert(label_buffer, label_buffer_len, data_ptr, label_len, ctx->converter);
 1171|  1.24k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (1171:17): [True: 1, False: 1.23k]
  ------------------
 1172|      1|                goto cleanup;
 1173|       |
 1174|  1.23k|            data_ptr += label_len;
 1175|       |
 1176|  1.23k|            readstat_value_t value = { .type = READSTAT_TYPE_STRING };
 1177|  1.23k|            value.v.string_value = value_buffer;
 1178|       |
 1179|  1.23k|            if (ctx->handle.value_label(label_name_buf, value, label_buffer, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (1179:17): [True: 0, False: 1.23k]
  ------------------
 1180|      0|                retval = READSTAT_ERROR_USER_ABORT;
 1181|      0|                goto cleanup;
 1182|      0|            }
 1183|  1.23k|        }
 1184|  1.70k|    }
 1185|       |
 1186|    464|    if (data_ptr != data_end) {
  ------------------
  |  Branch (1186:9): [True: 0, False: 464]
  ------------------
 1187|      0|        retval = READSTAT_ERROR_PARSE;
 1188|      0|    }
 1189|       |
 1190|    705|cleanup:
 1191|    705|    if (value_buffer)
  ------------------
  |  Branch (1191:9): [True: 280, False: 425]
  ------------------
 1192|    280|        free(value_buffer);
 1193|    705|    if (label_buffer)
  ------------------
  |  Branch (1193:9): [True: 279, False: 426]
  ------------------
 1194|    279|        free(label_buffer);
 1195|    705|    return retval;
 1196|    464|}
readstat_sav_read.c:sav_read_pascal_string:
 1027|  2.73k|        const char **inout_data_ptr, size_t data_ptr_len, sav_ctx_t *ctx) {
 1028|  2.73k|    const char *data_ptr = *inout_data_ptr;
 1029|  2.73k|    const char *data_end = data_ptr + data_ptr_len;
 1030|  2.73k|    readstat_error_t retval = READSTAT_OK;
 1031|  2.73k|    uint32_t var_name_len = 0;
 1032|       |
 1033|  2.73k|    if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1033:9): [True: 29, False: 2.70k]
  ------------------
 1034|     29|        retval = READSTAT_ERROR_PARSE;
 1035|     29|        goto cleanup;
 1036|     29|    }
 1037|       |
 1038|  2.70k|    memcpy(&var_name_len, data_ptr, sizeof(uint32_t));
 1039|  2.70k|    if (ctx->bswap)
  ------------------
  |  Branch (1039:9): [True: 1.31k, False: 1.39k]
  ------------------
 1040|  1.31k|        var_name_len = byteswap4(var_name_len);
 1041|       |
 1042|  2.70k|    data_ptr += sizeof(uint32_t);
 1043|       |
 1044|  2.70k|    if (data_ptr + var_name_len > data_end) {
  ------------------
  |  Branch (1044:9): [True: 33, False: 2.67k]
  ------------------
 1045|     33|        retval = READSTAT_ERROR_PARSE;
 1046|     33|        goto cleanup;
 1047|     33|    }
 1048|       |
 1049|  2.67k|    retval = readstat_convert(buf, buf_len, data_ptr, var_name_len, NULL);
 1050|  2.67k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (1050:9): [True: 17, False: 2.65k]
  ------------------
 1051|     17|        goto cleanup;
 1052|       |
 1053|  2.65k|    data_ptr += var_name_len;
 1054|       |
 1055|  2.73k|cleanup:
 1056|  2.73k|    *inout_data_ptr = data_ptr;
 1057|       |
 1058|  2.73k|    return retval;
 1059|  2.65k|}
readstat_sav_read.c:sav_parse_long_string_missing_values_record:
 1198|    470|static readstat_error_t sav_parse_long_string_missing_values_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
 1199|    470|    if (size != 1)
  ------------------
  |  Branch (1199:9): [True: 14, False: 456]
  ------------------
 1200|     14|        return READSTAT_ERROR_PARSE;
 1201|       |
 1202|    456|    readstat_error_t retval = READSTAT_OK;
 1203|    456|    uint32_t i = 0, j = 0;
 1204|    456|    const char *data_ptr = data;
 1205|    456|    const char *data_end = data_ptr + count;
 1206|    456|    char var_name_buf[256+1];
 1207|       |
 1208|  1.15k|    while (data_ptr < data_end) {
  ------------------
  |  Branch (1208:12): [True: 879, False: 271]
  ------------------
 1209|    879|        retval = sav_read_pascal_string(var_name_buf, sizeof(var_name_buf),
 1210|    879|                &data_ptr, data_end - data_ptr, ctx);
 1211|    879|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1211:13): [True: 37, False: 842]
  ------------------
 1212|     37|            goto cleanup;
 1213|       |
 1214|    842|        if (data_ptr == data_end) {
  ------------------
  |  Branch (1214:13): [True: 20, False: 822]
  ------------------
 1215|     20|            retval = READSTAT_ERROR_PARSE;
 1216|     20|            goto cleanup;
 1217|     20|        }
 1218|       |
 1219|    822|        char n_missing_values = *data_ptr++;
 1220|    822|        if (n_missing_values < 1 || n_missing_values > 3) {
  ------------------
  |  Branch (1220:13): [True: 15, False: 807]
  |  Branch (1220:37): [True: 14, False: 793]
  ------------------
 1221|     29|            retval = READSTAT_ERROR_PARSE;
 1222|     29|            goto cleanup;
 1223|     29|        }
 1224|       |
 1225|   118k|        for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1225:19): [True: 117k, False: 82]
  ------------------
 1226|   117k|            spss_varinfo_t *info = ctx->varinfo[i];
 1227|   117k|            if (strcmp(var_name_buf, info->longname) == 0) {
  ------------------
  |  Branch (1227:17): [True: 711, False: 117k]
  ------------------
 1228|    711|                info->n_missing_values = n_missing_values;
 1229|       |
 1230|    711|                uint32_t var_name_len = 0;
 1231|       |
 1232|    711|                if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1232:21): [True: 7, False: 704]
  ------------------
 1233|      7|                    retval = READSTAT_ERROR_PARSE;
 1234|      7|                    goto cleanup;
 1235|      7|                }
 1236|       |
 1237|    704|                memcpy(&var_name_len, data_ptr, sizeof(uint32_t));
 1238|    704|                if (ctx->bswap)
  ------------------
  |  Branch (1238:21): [True: 335, False: 369]
  ------------------
 1239|    335|                    var_name_len = byteswap4(var_name_len);
 1240|       |
 1241|    704|                data_ptr += sizeof(uint32_t);
 1242|       |
 1243|  2.57k|                for (j=0; j<n_missing_values; j++) {
  ------------------
  |  Branch (1243:27): [True: 1.87k, False: 694]
  ------------------
 1244|  1.87k|                    if (data_ptr + var_name_len > data_end) {
  ------------------
  |  Branch (1244:25): [True: 5, False: 1.87k]
  ------------------
 1245|      5|                        retval = READSTAT_ERROR_PARSE;
 1246|      5|                        goto cleanup;
 1247|      5|                    }
 1248|       |
 1249|  1.87k|                    retval = readstat_convert(info->missing_string_values[j],
 1250|  1.87k|                            sizeof(info->missing_string_values[0]),
 1251|  1.87k|                            data_ptr, var_name_len, ctx->converter);
 1252|  1.87k|                    if (retval != READSTAT_OK)
  ------------------
  |  Branch (1252:25): [True: 5, False: 1.86k]
  ------------------
 1253|      5|                        goto cleanup;
 1254|       |
 1255|  1.86k|                    data_ptr += var_name_len;
 1256|  1.86k|                }
 1257|    694|                break;
 1258|    704|            }
 1259|   117k|            i += info->n_segments;
 1260|   117k|        }
 1261|    776|        if (i == ctx->var_index) {
  ------------------
  |  Branch (1261:13): [True: 82, False: 694]
  ------------------
 1262|     82|            retval = READSTAT_ERROR_PARSE;
 1263|     82|            goto cleanup;
 1264|     82|        }
 1265|    776|    }
 1266|       |
 1267|    271|    if (data_ptr != data_end) {
  ------------------
  |  Branch (1267:9): [True: 0, False: 271]
  ------------------
 1268|      0|        retval = READSTAT_ERROR_PARSE;
 1269|      0|    }
 1270|       |
 1271|    456|cleanup:
 1272|    456|    return retval;
 1273|    271|}
readstat_sav_read.c:sav_set_n_segments_and_var_count:
 1477|  1.60k|static readstat_error_t sav_set_n_segments_and_var_count(sav_ctx_t *ctx) {
 1478|  1.60k|    int i;
 1479|  1.60k|    ctx->var_count = 0;
 1480|   167k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1480:15): [True: 166k, False: 1.57k]
  ------------------
 1481|   166k|        spss_varinfo_t *info = ctx->varinfo[i];
 1482|   166k|        if (info->string_length > VERY_LONG_STRING_MAX_LENGTH)
  ------------------
  |  |   28|   166k|#define VERY_LONG_STRING_MAX_LENGTH INT_MAX
  ------------------
  |  Branch (1482:13): [True: 32, False: 166k]
  ------------------
 1483|     32|            return READSTAT_ERROR_PARSE;
 1484|   166k|        if (info->string_length) {
  ------------------
  |  Branch (1484:13): [True: 413, False: 165k]
  ------------------
 1485|    413|            info->n_segments = (info->string_length + 251) / 252;
 1486|    413|        }
 1487|   166k|        info->index = ctx->var_count++;
 1488|   166k|        i += info->n_segments;
 1489|   166k|    }
 1490|  1.57k|    ctx->variables = readstat_calloc(ctx->var_count, sizeof(readstat_variable_t *));
 1491|  1.57k|    return READSTAT_OK;
 1492|  1.60k|}
readstat_sav_read.c:sav_parse_variable_display_parameter_record:
 1001|  1.56k|static readstat_error_t sav_parse_variable_display_parameter_record(sav_ctx_t *ctx) {
 1002|  1.56k|    if (!ctx->variable_display_values)
  ------------------
  |  Branch (1002:9): [True: 1.37k, False: 187]
  ------------------
 1003|  1.37k|        return READSTAT_OK;
 1004|       |
 1005|    187|    int i;
 1006|    187|    long count = ctx->variable_display_values_count;
 1007|    187|    if (count != 2 * ctx->var_index && count != 3 * ctx->var_index) {
  ------------------
  |  Branch (1007:9): [True: 52, False: 135]
  |  Branch (1007:40): [True: 36, False: 16]
  ------------------
 1008|     36|        return READSTAT_ERROR_PARSE;
 1009|     36|    }
 1010|    151|    int has_display_width = ctx->var_index > 0 && (count / ctx->var_index == 3);
  ------------------
  |  Branch (1010:29): [True: 151, False: 0]
  |  Branch (1010:51): [True: 16, False: 135]
  ------------------
 1011|    151|    int offset = 0;
 1012|  5.20k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1012:15): [True: 5.05k, False: 151]
  ------------------
 1013|  5.05k|        spss_varinfo_t *info = ctx->varinfo[i];
 1014|  5.05k|        offset = (2 + has_display_width)*i;
 1015|  5.05k|        info->measure = spss_measure_to_readstat_measure(ctx->variable_display_values[offset++]);
 1016|  5.05k|        if (has_display_width) {
  ------------------
  |  Branch (1016:13): [True: 730, False: 4.32k]
  ------------------
 1017|    730|            info->display_width = ctx->variable_display_values[offset++];
 1018|    730|        }
 1019|  5.05k|        info->alignment = spss_alignment_to_readstat_alignment(ctx->variable_display_values[offset++]);
 1020|       |
 1021|  5.05k|        i += info->n_segments;
 1022|  5.05k|    }
 1023|    151|    return READSTAT_OK;
 1024|    187|}
readstat_sav_read.c:sav_handle_variables:
 1494|  1.52k|static readstat_error_t sav_handle_variables(sav_ctx_t *ctx) {
 1495|  1.52k|    int i;
 1496|  1.52k|    int index_after_skipping = 0;
 1497|  1.52k|    readstat_error_t retval = READSTAT_OK;
 1498|       |
 1499|  1.52k|    if (!ctx->handle.variable)
  ------------------
  |  Branch (1499:9): [True: 0, False: 1.52k]
  ------------------
 1500|      0|        return retval;
 1501|       |
 1502|   167k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1502:15): [True: 165k, False: 1.52k]
  ------------------
 1503|   165k|        char label_name_buf[256];
 1504|   165k|        spss_varinfo_t *info = ctx->varinfo[i];
 1505|   165k|        ctx->variables[info->index] = spss_init_variable_for_info(info, index_after_skipping, ctx->converter);
 1506|       |
 1507|   165k|        snprintf(label_name_buf, sizeof(label_name_buf), SAV_LABEL_NAME_PREFIX "%d", info->labels_index);
  ------------------
  |  |  115|   165k|#define SAV_LABEL_NAME_PREFIX         "labels"
  ------------------
 1508|       |
 1509|   165k|        int cb_retval = ctx->handle.variable(info->index, ctx->variables[info->index],
 1510|   165k|                info->labels_index == -1 ? NULL : label_name_buf,
  ------------------
  |  Branch (1510:17): [True: 165k, False: 246]
  ------------------
 1511|   165k|                ctx->user_ctx);
 1512|       |
 1513|   165k|        if (cb_retval == READSTAT_HANDLER_ABORT) {
  ------------------
  |  Branch (1513:13): [True: 0, False: 165k]
  ------------------
 1514|      0|            retval = READSTAT_ERROR_USER_ABORT;
 1515|      0|            goto cleanup;
 1516|      0|        }
 1517|       |
 1518|   165k|        if (cb_retval == READSTAT_HANDLER_SKIP_VARIABLE) {
  ------------------
  |  Branch (1518:13): [True: 0, False: 165k]
  ------------------
 1519|      0|            ctx->variables[info->index]->skip = 1;
 1520|   165k|        } else {
 1521|   165k|            index_after_skipping++;
 1522|   165k|        }
 1523|       |
 1524|   165k|        i += info->n_segments;
 1525|   165k|    }
 1526|  1.52k|cleanup:
 1527|  1.52k|    return retval;
 1528|  1.52k|}
readstat_sav_read.c:sav_handle_fweight:
 1530|  1.52k|static readstat_error_t sav_handle_fweight(sav_ctx_t *ctx) {
 1531|  1.52k|    readstat_error_t retval = READSTAT_OK;
 1532|  1.52k|    int i;
 1533|  1.52k|    if (ctx->handle.fweight && ctx->fweight_index >= 0) {
  ------------------
  |  Branch (1533:9): [True: 1.52k, False: 0]
  |  Branch (1533:32): [True: 1.08k, False: 442]
  ------------------
 1534|   109k|        for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1534:19): [True: 108k, False: 1.06k]
  ------------------
 1535|   108k|            spss_varinfo_t *info = ctx->varinfo[i];
 1536|   108k|            if (info->offset == ctx->fweight_index - 1) {
  ------------------
  |  Branch (1536:17): [True: 18, False: 108k]
  ------------------
 1537|     18|                if (ctx->handle.fweight(ctx->variables[info->index], ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (1537:21): [True: 0, False: 18]
  ------------------
 1538|      0|                    retval = READSTAT_ERROR_USER_ABORT;
 1539|      0|                    goto cleanup;
 1540|      0|                }
 1541|     18|                break;
 1542|     18|            }
 1543|   108k|            i += info->n_segments;
 1544|   108k|        }
 1545|  1.08k|    }
 1546|  1.52k|cleanup:
 1547|  1.52k|    return retval;
 1548|  1.52k|}
readstat_sav_read.c:sav_read_data:
  766|  1.52k|static readstat_error_t sav_read_data(sav_ctx_t *ctx) {
  767|  1.52k|    readstat_error_t retval = READSTAT_OK;
  768|  1.52k|    size_t longest_string = 256;
  769|  1.52k|    int i;
  770|       |
  771|   167k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (771:15): [True: 165k, False: 1.52k]
  ------------------
  772|   165k|        spss_varinfo_t *info = ctx->varinfo[i];
  773|   165k|        if (info->string_length > longest_string) {
  ------------------
  |  Branch (773:13): [True: 165, False: 165k]
  ------------------
  774|    165|            longest_string = info->string_length;
  775|    165|        }
  776|   165k|        i += info->n_segments;
  777|   165k|    }
  778|       |
  779|  1.52k|    ctx->raw_string_len = longest_string + sizeof(SAV_EIGHT_SPACES)-2;
  ------------------
  |  |  138|  1.52k|#define SAV_EIGHT_SPACES              "        "
  ------------------
  780|  1.52k|    ctx->raw_string = readstat_malloc(ctx->raw_string_len);
  781|       |
  782|  1.52k|    ctx->utf8_string_len = 4*longest_string+1 + sizeof(SAV_EIGHT_SPACES)-2;
  ------------------
  |  |  138|  1.52k|#define SAV_EIGHT_SPACES              "        "
  ------------------
  783|  1.52k|    ctx->utf8_string = readstat_malloc(ctx->utf8_string_len);
  784|       |
  785|  1.52k|    if (ctx->raw_string == NULL || ctx->utf8_string == NULL) {
  ------------------
  |  Branch (785:9): [True: 22, False: 1.50k]
  |  Branch (785:36): [True: 13, False: 1.49k]
  ------------------
  786|     35|        retval = READSTAT_ERROR_MALLOC;
  787|     35|        goto done;
  788|     35|    }
  789|       |
  790|  1.49k|    if (ctx->compression == READSTAT_COMPRESS_ROWS) {
  ------------------
  |  Branch (790:9): [True: 416, False: 1.07k]
  ------------------
  791|    416|        retval = sav_read_compressed_data(ctx, &sav_process_row);
  792|  1.07k|    } else if (ctx->compression == READSTAT_COMPRESS_BINARY) {
  ------------------
  |  Branch (792:16): [True: 505, False: 569]
  ------------------
  793|    505|#if HAVE_ZLIB
  794|    505|        retval = zsav_read_compressed_data(ctx, &sav_process_row);
  795|       |#else
  796|       |        retval = READSTAT_ERROR_UNSUPPORTED_COMPRESSION;
  797|       |#endif
  798|    569|    } else {
  799|    569|        retval = sav_read_uncompressed_data(ctx, &sav_process_row);
  800|    569|    }
  801|  1.49k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (801:9): [True: 471, False: 1.01k]
  ------------------
  802|    471|        goto done;
  803|       |
  804|  1.01k|    if (ctx->record_count >= 0 && ctx->current_row != ctx->row_limit) {
  ------------------
  |  Branch (804:9): [True: 734, False: 285]
  |  Branch (804:35): [True: 674, False: 60]
  ------------------
  805|    674|        retval = READSTAT_ERROR_ROW_COUNT_MISMATCH;
  806|    674|    }
  807|       |
  808|  1.52k|done:
  809|  1.52k|    return retval;
  810|  1.01k|}
readstat_sav_read.c:sav_read_compressed_data:
  850|    416|        readstat_error_t (*row_handler)(unsigned char *, size_t, sav_ctx_t *)) {
  851|    416|    readstat_error_t retval = READSTAT_OK;
  852|    416|    readstat_io_t *io = ctx->io;
  853|    416|    readstat_off_t data_offset = 0;
  854|    416|    unsigned char buffer[DATA_BUFFER_SIZE];
  855|    416|    int buffer_used = 0;
  856|       |
  857|    416|    size_t uncompressed_row_len = ctx->var_offset * 8;
  858|    416|    readstat_off_t uncompressed_offset = 0;
  859|    416|    unsigned char *uncompressed_row = NULL;
  860|       |
  861|    416|    struct sav_row_stream_s state = { 
  862|    416|        .missing_value = ctx->missing_double,
  863|    416|        .bias = ctx->bias,
  864|    416|        .bswap = ctx->bswap };
  865|       |
  866|    416|    if (uncompressed_row_len && (uncompressed_row = readstat_malloc(uncompressed_row_len)) == NULL) {
  ------------------
  |  Branch (866:9): [True: 416, False: 0]
  |  Branch (866:33): [True: 0, False: 416]
  ------------------
  867|      0|        retval = READSTAT_ERROR_MALLOC;
  868|      0|        goto done;
  869|      0|    }
  870|       |
  871|    780|    while (1) {
  ------------------
  |  Branch (871:12): [Folded - Ignored]
  ------------------
  872|    780|        retval = sav_update_progress(ctx);
  873|    780|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (873:13): [True: 0, False: 780]
  ------------------
  874|      0|            goto done;
  875|       |
  876|    780|        buffer_used = io->read(buffer, sizeof(buffer), io->io_ctx);
  877|    780|        if (buffer_used == -1 || buffer_used == 0 || (buffer_used % 8) != 0)
  ------------------
  |  Branch (877:13): [True: 0, False: 780]
  |  Branch (877:34): [True: 336, False: 444]
  |  Branch (877:54): [True: 34, False: 410]
  ------------------
  878|    370|            goto done;
  879|       |
  880|    410|        state.status = SAV_ROW_STREAM_HAVE_DATA;
  881|    410|        data_offset = 0;
  882|       |
  883|  2.26M|        while (state.status != SAV_ROW_STREAM_NEED_DATA) {
  ------------------
  |  Branch (883:16): [True: 2.26M, False: 364]
  ------------------
  884|  2.26M|            state.next_in = &buffer[data_offset];
  885|  2.26M|            state.avail_in = buffer_used - data_offset;
  886|       |
  887|  2.26M|            state.next_out = &uncompressed_row[uncompressed_offset];
  888|  2.26M|            state.avail_out = uncompressed_row_len - uncompressed_offset;
  889|       |
  890|  2.26M|            sav_decompress_row(&state);
  891|       |
  892|  2.26M|            uncompressed_offset = uncompressed_row_len - state.avail_out;
  893|  2.26M|            data_offset = buffer_used - state.avail_in;
  894|       |
  895|  2.26M|            if (state.status == SAV_ROW_STREAM_FINISHED_ROW) {
  ------------------
  |  Branch (895:17): [True: 2.26M, False: 390]
  ------------------
  896|  2.26M|                retval = row_handler(uncompressed_row, uncompressed_row_len, ctx);
  897|  2.26M|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (897:21): [True: 10, False: 2.26M]
  ------------------
  898|     10|                    goto done;
  899|       |
  900|  2.26M|                uncompressed_offset = 0;
  901|  2.26M|            }
  902|       |
  903|  2.26M|            if (state.status == SAV_ROW_STREAM_FINISHED_ALL)
  ------------------
  |  Branch (903:17): [True: 26, False: 2.26M]
  ------------------
  904|     26|                goto done;
  905|  2.26M|            if (ctx->row_limit > 0 && ctx->current_row == ctx->row_limit)
  ------------------
  |  Branch (905:17): [True: 58.4k, False: 2.20M]
  |  Branch (905:39): [True: 10, False: 58.4k]
  ------------------
  906|     10|                goto done;
  907|  2.26M|        }
  908|    410|    }
  909|       |
  910|    416|done:
  911|    416|    if (uncompressed_row)
  ------------------
  |  Branch (911:9): [True: 416, False: 0]
  ------------------
  912|    416|        free(uncompressed_row);
  913|       |
  914|    416|    return retval;
  915|    416|}
readstat_sav_read.c:sav_process_row:
  682|  2.26M|static readstat_error_t sav_process_row(unsigned char *buffer, size_t buffer_len, sav_ctx_t *ctx) {
  683|  2.26M|    if (ctx->row_offset) {
  ------------------
  |  Branch (683:9): [True: 0, False: 2.26M]
  ------------------
  684|      0|        ctx->row_offset--;
  685|      0|        return READSTAT_OK;
  686|      0|    }
  687|       |
  688|  2.26M|    readstat_error_t retval = READSTAT_OK;
  689|  2.26M|    double fp_value;
  690|  2.26M|    int offset = 0;
  691|  2.26M|    readstat_off_t data_offset = 0;
  692|  2.26M|    size_t raw_str_used = 0;
  693|  2.26M|    int segment_offset = 0;
  694|  2.26M|    int var_index = 0, col = 0;
  695|  2.26M|    int raw_str_is_utf8 = ctx->input_encoding && !strcmp(ctx->input_encoding, "UTF-8");
  ------------------
  |  Branch (695:27): [True: 816, False: 2.26M]
  |  Branch (695:50): [True: 748, False: 68]
  ------------------
  696|       |
  697|  4.56M|    while (data_offset < buffer_len && col < ctx->var_index && var_index < ctx->var_index) {
  ------------------
  |  Branch (697:12): [True: 2.55M, False: 2.01M]
  |  Branch (697:40): [True: 2.29M, False: 252k]
  |  Branch (697:64): [True: 2.29M, False: 0]
  ------------------
  698|  2.29M|        spss_varinfo_t *col_info = ctx->varinfo[col];
  699|  2.29M|        spss_varinfo_t *var_info = ctx->varinfo[var_index];
  700|  2.29M|        readstat_value_t value = { .type = var_info->type };
  701|  2.29M|        if (offset > 31) {
  ------------------
  |  Branch (701:13): [True: 2, False: 2.29M]
  ------------------
  702|      2|            retval = READSTAT_ERROR_PARSE;
  703|      2|            goto done;
  704|      2|        }
  705|  2.29M|        if (var_info->type == READSTAT_TYPE_STRING) {
  ------------------
  |  Branch (705:13): [True: 963k, False: 1.33M]
  ------------------
  706|   963k|            if (raw_str_used + 8 <= ctx->raw_string_len) {
  ------------------
  |  Branch (706:17): [True: 963k, False: 253]
  ------------------
  707|   963k|                if (raw_str_is_utf8) {
  ------------------
  |  Branch (707:21): [True: 920, False: 962k]
  ------------------
  708|       |                    /* Skip null bytes, see https://github.com/tidyverse/haven/issues/560  */
  709|    920|                    char c;
  710|  8.28k|                    for (int i=0; i<8; i++)
  ------------------
  |  Branch (710:35): [True: 7.36k, False: 920]
  ------------------
  711|  7.36k|                        if ((c = buffer[data_offset+i]))
  ------------------
  |  Branch (711:29): [True: 3.93k, False: 3.42k]
  ------------------
  712|  3.93k|                            ctx->raw_string[raw_str_used++] = c;
  713|   962k|                } else {
  714|   962k|                    memcpy(ctx->raw_string + raw_str_used, &buffer[data_offset], 8);
  715|   962k|                    raw_str_used += 8;
  716|   962k|                }
  717|   963k|            }
  718|   963k|            if (++offset == col_info->width) {
  ------------------
  |  Branch (718:17): [True: 962k, False: 1.19k]
  ------------------
  719|   962k|                if (++segment_offset < var_info->n_segments) {
  ------------------
  |  Branch (719:21): [True: 2.97k, False: 959k]
  ------------------
  720|  2.97k|                    raw_str_used--;
  721|  2.97k|                }
  722|   962k|                offset = 0;
  723|   962k|                col++;
  724|   962k|            }
  725|   963k|            if (segment_offset == var_info->n_segments) {
  ------------------
  |  Branch (725:17): [True: 959k, False: 4.16k]
  ------------------
  726|   959k|                if (!ctx->variables[var_info->index]->skip) {
  ------------------
  |  Branch (726:21): [True: 959k, False: 0]
  ------------------
  727|   959k|                    retval = readstat_convert(ctx->utf8_string, ctx->utf8_string_len, 
  728|   959k|                            ctx->raw_string, raw_str_used, ctx->converter);
  729|   959k|                    if (retval != READSTAT_OK)
  ------------------
  |  Branch (729:25): [True: 15, False: 959k]
  ------------------
  730|     15|                        goto done;
  731|   959k|                    value.v.string_value = ctx->utf8_string;
  732|   959k|                    if (ctx->handle.value(ctx->current_row, ctx->variables[var_info->index],
  ------------------
  |  Branch (732:25): [True: 0, False: 959k]
  ------------------
  733|   959k|                                value, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  734|      0|                        retval = READSTAT_ERROR_USER_ABORT;
  735|      0|                        goto done;
  736|      0|                    }
  737|   959k|                }
  738|   959k|                raw_str_used = 0;
  739|   959k|                segment_offset = 0;
  740|   959k|                var_index += var_info->n_segments;
  741|   959k|            }
  742|  1.33M|        } else if (var_info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (742:20): [True: 1.33M, False: 0]
  ------------------
  743|  1.33M|            if (!ctx->variables[var_info->index]->skip) {
  ------------------
  |  Branch (743:17): [True: 1.33M, False: 0]
  ------------------
  744|  1.33M|                memcpy(&fp_value, &buffer[data_offset], 8);
  745|  1.33M|                if (ctx->bswap) {
  ------------------
  |  Branch (745:21): [True: 1.00M, False: 333k]
  ------------------
  746|  1.00M|                    fp_value = byteswap_double(fp_value);
  747|  1.00M|                }
  748|  1.33M|                value.v.double_value = fp_value;
  749|  1.33M|                sav_tag_missing_double(&value, ctx);
  750|  1.33M|                if (ctx->handle.value(ctx->current_row, ctx->variables[var_info->index],
  ------------------
  |  Branch (750:21): [True: 0, False: 1.33M]
  ------------------
  751|  1.33M|                            value, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  752|      0|                    retval = READSTAT_ERROR_USER_ABORT;
  753|      0|                    goto done;
  754|      0|                }
  755|  1.33M|            }
  756|  1.33M|            var_index += var_info->n_segments;
  757|  1.33M|            col++;
  758|  1.33M|        }
  759|  2.29M|        data_offset += 8;
  760|  2.29M|    }
  761|  2.26M|    ctx->current_row++;
  762|  2.26M|done:
  763|  2.26M|    return retval;
  764|  2.26M|}
readstat_sav_read.c:sav_read_uncompressed_data:
  813|    569|        readstat_error_t (*row_handler)(unsigned char *, size_t, sav_ctx_t *)) {
  814|    569|    readstat_error_t retval = READSTAT_OK;
  815|    569|    readstat_io_t *io = ctx->io;
  816|    569|    unsigned char *buffer = NULL;
  817|    569|    size_t bytes_read = 0;
  818|    569|    size_t buffer_len = ctx->var_offset * 8;
  819|       |
  820|    569|    buffer = readstat_malloc(buffer_len);
  821|       |
  822|    569|    if (ctx->row_offset) {
  ------------------
  |  Branch (822:9): [True: 0, False: 569]
  ------------------
  823|      0|        if (io->seek(buffer_len * ctx->row_offset, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (823:13): [True: 0, False: 0]
  ------------------
  824|      0|            retval = READSTAT_ERROR_SEEK;
  825|      0|            goto done;
  826|      0|        }
  827|      0|        ctx->row_offset = 0;
  828|      0|    }
  829|       |
  830|  1.23k|    while (ctx->row_limit == -1 || ctx->current_row < ctx->row_limit) {
  ------------------
  |  Branch (830:12): [True: 0, False: 1.23k]
  |  Branch (830:36): [True: 1.02k, False: 218]
  ------------------
  831|  1.02k|        retval = sav_update_progress(ctx);
  832|  1.02k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (832:13): [True: 0, False: 1.02k]
  ------------------
  833|      0|            goto done;
  834|       |
  835|  1.02k|        if ((bytes_read = io->read(buffer, buffer_len, io->io_ctx)) != buffer_len)
  ------------------
  |  Branch (835:13): [True: 346, False: 675]
  ------------------
  836|    346|            goto done;
  837|       |
  838|    675|        retval = row_handler(buffer, buffer_len, ctx);
  839|    675|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (839:13): [True: 5, False: 670]
  ------------------
  840|      5|            goto done;
  841|    675|    }
  842|    569|done:
  843|    569|    if (buffer)
  ------------------
  |  Branch (843:9): [True: 569, False: 0]
  ------------------
  844|    569|        free(buffer);
  845|       |
  846|    569|    return retval;
  847|    569|}

spss_format:
   51|   165k|int spss_format(char *buffer, size_t len, spss_format_t *format) {
   52|   165k|    if (format->type < 0 
  ------------------
  |  Branch (52:9): [True: 0, False: 165k]
  ------------------
   53|   165k|            || format->type >= sizeof(spss_type_strings)/sizeof(spss_type_strings[0])
  ------------------
  |  Branch (53:16): [True: 3.18k, False: 162k]
  ------------------
   54|   165k|            || spss_type_strings[format->type][0] == '\0') {
  ------------------
  |  Branch (54:16): [True: 17.4k, False: 145k]
  ------------------
   55|  20.6k|        return 0;
   56|  20.6k|    }
   57|   145k|    char *string = spss_type_strings[format->type];
   58|       |
   59|   145k|    if (format->decimal_places || format->type == SPSS_FORMAT_TYPE_F) {
  ------------------
  |  |    6|  97.8k|#define SPSS_FORMAT_TYPE_F        5
  ------------------
  |  Branch (59:9): [True: 47.3k, False: 97.8k]
  |  Branch (59:35): [True: 339, False: 97.4k]
  ------------------
   60|  47.7k|        snprintf(buffer, len, "%s%d.%d", string, format->width, format->decimal_places);
   61|  97.4k|    } else if (format->width) {
  ------------------
  |  Branch (61:16): [True: 58.6k, False: 38.8k]
  ------------------
   62|  58.6k|        snprintf(buffer, len, "%s%d", string, format->width);
   63|  58.6k|    } else {
   64|  38.8k|        snprintf(buffer, len, "%s", string);
   65|  38.8k|    }
   66|       |
   67|   145k|    return 1;
   68|   165k|}
spss_varinfo_compare:
   70|   568k|int spss_varinfo_compare(const void *elem1, const void *elem2) {
   71|   568k|    int offset = *(int *)elem1;
   72|   568k|    const spss_varinfo_t *v = *(const spss_varinfo_t **)elem2;
   73|   568k|    if (offset < v->offset)
  ------------------
  |  Branch (73:9): [True: 272k, False: 295k]
  ------------------
   74|   272k|        return -1;
   75|   295k|    return (offset > v->offset);
   76|   568k|}
spss_varinfo_free:
   78|   300k|void spss_varinfo_free(spss_varinfo_t *info) {
   79|   300k|    if (info) {
  ------------------
  |  Branch (79:9): [True: 300k, False: 9]
  ------------------
   80|   300k|        if (info->label)
  ------------------
  |  Branch (80:13): [True: 735, False: 299k]
  ------------------
   81|    735|            free(info->label);
   82|   300k|        free(info);
   83|   300k|    }
   84|   300k|}
spss_missingness_for_info:
  127|   165k|readstat_missingness_t spss_missingness_for_info(spss_varinfo_t *info) {
  128|   165k|    readstat_missingness_t missingness;
  129|   165k|    memset(&missingness, '\0', sizeof(readstat_missingness_t));
  130|       |
  131|   165k|    if (info->missing_range) {
  ------------------
  |  Branch (131:9): [True: 960, False: 164k]
  ------------------
  132|    960|        missingness.missing_ranges_count++;
  133|    960|        missingness.missing_ranges[0] = spss_boxed_missing_value(info, 0);
  134|    960|        missingness.missing_ranges[1] = spss_boxed_missing_value(info, 1);
  135|       |
  136|    960|        if (info->n_missing_values == 3) {
  ------------------
  |  Branch (136:13): [True: 509, False: 451]
  ------------------
  137|    509|            missingness.missing_ranges_count++;
  138|    509|            missingness.missing_ranges[2] = missingness.missing_ranges[3] = spss_boxed_missing_value(info, 2);
  139|    509|        }
  140|   164k|    } else if (info->n_missing_values > 0) {
  ------------------
  |  Branch (140:16): [True: 501, False: 164k]
  ------------------
  141|    501|        missingness.missing_ranges_count = info->n_missing_values;
  142|    501|        int i=0;
  143|  1.55k|        for (i=0; i<info->n_missing_values; i++) {
  ------------------
  |  Branch (143:19): [True: 1.05k, False: 501]
  ------------------
  144|  1.05k|            missingness.missing_ranges[2*i] = missingness.missing_ranges[2*i+1] = spss_boxed_missing_value(info, i);
  145|  1.05k|        }
  146|    501|    }
  147|   165k|    return missingness;
  148|   165k|}
spss_init_variable_for_info:
  151|   165k|        iconv_t converter) {
  152|   165k|    readstat_variable_t *variable = calloc(1, sizeof(readstat_variable_t));
  153|       |
  154|   165k|    variable->index = info->index;
  155|   165k|    variable->index_after_skipping = index_after_skipping;
  156|   165k|    variable->type = info->type;
  157|   165k|    if (info->string_length) {
  ------------------
  |  Branch (157:9): [True: 413, False: 165k]
  ------------------
  158|    413|        variable->storage_width = info->string_length;
  159|   165k|    } else {
  160|   165k|        variable->storage_width = 8 * info->width;
  161|   165k|    }
  162|       |
  163|   165k|    if (info->longname[0]) {
  ------------------
  |  Branch (163:9): [True: 162k, False: 2.90k]
  ------------------
  164|   162k|        readstat_convert(variable->name, sizeof(variable->name),
  165|   162k|                info->longname, sizeof(info->longname), converter);
  166|   162k|    } else {
  167|  2.90k|        readstat_convert(variable->name, sizeof(variable->name),
  168|  2.90k|                info->name, sizeof(info->name), converter);
  169|  2.90k|    }
  170|   165k|    if (info->label) {
  ------------------
  |  Branch (170:9): [True: 535, False: 165k]
  ------------------
  171|    535|        snprintf(variable->label, sizeof(variable->label), "%s", info->label);
  172|    535|    }
  173|       |
  174|   165k|    spss_format(variable->format, sizeof(variable->format), &info->print_format);
  175|       |
  176|   165k|    variable->missingness = spss_missingness_for_info(info);
  177|   165k|    variable->measure = info->measure;
  178|   165k|    if (info->display_width) {
  ------------------
  |  Branch (178:9): [True: 544, False: 165k]
  ------------------
  179|    544|        variable->display_width = info->display_width;
  180|   165k|    } else {
  181|   165k|        variable->display_width = info->print_format.width;
  182|   165k|    }
  183|       |
  184|   165k|    return variable;
  185|   165k|}
spss_measure_to_readstat_measure:
  199|  5.05k|readstat_measure_t spss_measure_to_readstat_measure(uint32_t sav_measure) {
  200|  5.05k|    if (sav_measure == SAV_MEASURE_NOMINAL)
  ------------------
  |  |   47|  5.05k|#define SAV_MEASURE_NOMINAL     1
  ------------------
  |  Branch (200:9): [True: 115, False: 4.94k]
  ------------------
  201|    115|        return READSTAT_MEASURE_NOMINAL;
  202|  4.94k|    if (sav_measure == SAV_MEASURE_ORDINAL)
  ------------------
  |  |   48|  4.94k|#define SAV_MEASURE_ORDINAL     2
  ------------------
  |  Branch (202:9): [True: 283, False: 4.65k]
  ------------------
  203|    283|        return READSTAT_MEASURE_ORDINAL;
  204|  4.65k|    if (sav_measure == SAV_MEASURE_SCALE)
  ------------------
  |  |   49|  4.65k|#define SAV_MEASURE_SCALE       3
  ------------------
  |  Branch (204:9): [True: 296, False: 4.36k]
  ------------------
  205|    296|        return READSTAT_MEASURE_SCALE;
  206|  4.36k|    return READSTAT_MEASURE_UNKNOWN;
  207|  4.65k|}
spss_alignment_to_readstat_alignment:
  221|  5.05k|readstat_alignment_t spss_alignment_to_readstat_alignment(uint32_t sav_alignment) {
  222|  5.05k|    if (sav_alignment == SAV_ALIGNMENT_LEFT)
  ------------------
  |  |   51|  5.05k|#define SAV_ALIGNMENT_LEFT      0
  ------------------
  |  Branch (222:9): [True: 1.70k, False: 3.35k]
  ------------------
  223|  1.70k|        return READSTAT_ALIGNMENT_LEFT;
  224|  3.35k|    if (sav_alignment == SAV_ALIGNMENT_CENTER)
  ------------------
  |  |   53|  3.35k|#define SAV_ALIGNMENT_CENTER    2
  ------------------
  |  Branch (224:9): [True: 312, False: 3.03k]
  ------------------
  225|    312|        return READSTAT_ALIGNMENT_CENTER;
  226|  3.03k|    if (sav_alignment == SAV_ALIGNMENT_RIGHT)
  ------------------
  |  |   52|  3.03k|#define SAV_ALIGNMENT_RIGHT     1
  ------------------
  |  Branch (226:9): [True: 98, False: 2.94k]
  ------------------
  227|     98|        return READSTAT_ALIGNMENT_RIGHT;
  228|  2.94k|    return READSTAT_ALIGNMENT_UNKNOWN;
  229|  3.03k|}
readstat_spss.c:spss_boxed_missing_value:
  120|  3.48k|static readstat_value_t spss_boxed_missing_value(spss_varinfo_t *info, int i) {
  121|  3.48k|    if (info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (121:9): [True: 1.53k, False: 1.95k]
  ------------------
  122|  1.53k|        return spss_boxed_double_value(info->missing_double_values[i]);
  123|  1.53k|    }
  124|  1.95k|    return spss_boxed_string_value(info->missing_string_values[i]);
  125|  3.48k|}
readstat_spss.c:spss_boxed_double_value:
  103|  1.53k|static readstat_value_t spss_boxed_double_value(double fp_value) {
  104|  1.53k|    readstat_value_t value = {
  105|  1.53k|        .type = READSTAT_TYPE_DOUBLE,
  106|  1.53k|        .v = { .double_value = fp_value },
  107|  1.53k|        .is_system_missing = isnan(fp_value)
  108|  1.53k|    };
  109|  1.53k|    return value;
  110|  1.53k|}
readstat_spss.c:spss_boxed_string_value:
  112|  1.95k|static readstat_value_t spss_boxed_string_value(const char *string) {
  113|  1.95k|    readstat_value_t value = {
  114|  1.95k|        .type = READSTAT_TYPE_STRING,
  115|  1.95k|        .v = { .string_value = string }
  116|  1.95k|    };
  117|  1.95k|    return value;
  118|  1.95k|}

zsav_read_compressed_data:
   32|    505|        readstat_error_t (*row_handler)(unsigned char *, size_t, sav_ctx_t *)) {
   33|    505|    readstat_error_t retval = READSTAT_OK;
   34|    505|    readstat_io_t *io = ctx->io;
   35|    505|    readstat_off_t data_offset = 0;
   36|       |
   37|    505|    size_t uncompressed_row_len = ctx->var_offset * 8;
   38|    505|    readstat_off_t uncompressed_offset = 0;
   39|    505|    unsigned char *uncompressed_row = NULL;
   40|       |
   41|    505|    uLongf uncompressed_block_len = 0;
   42|    505|    unsigned char *compressed_block = NULL, *uncompressed_block = NULL;
   43|       |
   44|    505|    struct sav_row_stream_s state = { 
   45|    505|        .missing_value = ctx->missing_double,
   46|    505|        .bias = ctx->bias,
   47|    505|        .bswap = ctx->bswap };
   48|       |
   49|    505|    struct zheader zheader;
   50|    505|    struct ztrailer ztrailer;
   51|    505|    struct ztrailer_entry *ztrailer_entries = NULL;
   52|       |
   53|    505|    int n_blocks = 0;
   54|    505|    int block_i = 0;
   55|    505|    int i;
   56|       |
   57|    505|    if (io->read(&zheader, sizeof(struct zheader), io->io_ctx) < sizeof(struct zheader)) {
  ------------------
  |  Branch (57:9): [True: 26, False: 479]
  ------------------
   58|     26|        retval = READSTAT_ERROR_READ;
   59|     26|        goto cleanup;
   60|     26|    }
   61|       |
   62|    479|    zheader.zheader_ofs = ctx->bswap ? byteswap8(zheader.zheader_ofs) : zheader.zheader_ofs;
  ------------------
  |  Branch (62:27): [True: 287, False: 192]
  ------------------
   63|    479|    zheader.ztrailer_ofs = ctx->bswap ? byteswap8(zheader.ztrailer_ofs) : zheader.ztrailer_ofs;
  ------------------
  |  Branch (63:28): [True: 287, False: 192]
  ------------------
   64|    479|    zheader.ztrailer_len = ctx->bswap ? byteswap8(zheader.ztrailer_len) : zheader.ztrailer_len;
  ------------------
  |  Branch (64:28): [True: 287, False: 192]
  ------------------
   65|       |
   66|    479|    if (zheader.zheader_ofs != io->seek(0, READSTAT_SEEK_CUR, io->io_ctx) - sizeof(struct zheader)) {
  ------------------
  |  Branch (66:9): [True: 105, False: 374]
  ------------------
   67|    105|        retval = READSTAT_ERROR_PARSE;
   68|    105|        goto cleanup;
   69|    105|    }
   70|       |
   71|    374|    n_blocks = (zheader.ztrailer_len - 24) / 24;
   72|       |
   73|    374|    if (io->seek(zheader.ztrailer_ofs, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (73:9): [True: 28, False: 346]
  ------------------
   74|     28|        retval = READSTAT_ERROR_SEEK;
   75|     28|        goto cleanup;
   76|     28|    }
   77|       |
   78|    346|    if (io->read(&ztrailer, sizeof(struct ztrailer), io->io_ctx) < sizeof(struct ztrailer)) {
  ------------------
  |  Branch (78:9): [True: 18, False: 328]
  ------------------
   79|     18|        retval = READSTAT_ERROR_READ;
   80|     18|        goto cleanup;
   81|     18|    }
   82|       |
   83|    328|    ztrailer.bias = ctx->bswap ? byteswap8(ztrailer.bias) : ztrailer.bias;
  ------------------
  |  Branch (83:21): [True: 194, False: 134]
  ------------------
   84|    328|    ztrailer.zero = ctx->bswap ? byteswap8(ztrailer.zero) : ztrailer.zero;
  ------------------
  |  Branch (84:21): [True: 194, False: 134]
  ------------------
   85|    328|    ztrailer.block_size = ctx->bswap ? byteswap4(ztrailer.block_size) : ztrailer.block_size;
  ------------------
  |  Branch (85:27): [True: 194, False: 134]
  ------------------
   86|    328|    ztrailer.n_blocks = ctx->bswap ? byteswap4(ztrailer.n_blocks) : ztrailer.n_blocks;
  ------------------
  |  Branch (86:25): [True: 194, False: 134]
  ------------------
   87|       |
   88|    328|    if (n_blocks != ztrailer.n_blocks) {
  ------------------
  |  Branch (88:9): [True: 46, False: 282]
  ------------------
   89|     46|        retval = READSTAT_ERROR_PARSE;
   90|     46|        goto cleanup;
   91|     46|    }
   92|       |
   93|    282|    if (n_blocks && (ztrailer_entries = readstat_malloc(n_blocks * sizeof(struct ztrailer_entry))) == NULL) {
  ------------------
  |  Branch (93:9): [True: 281, False: 1]
  |  Branch (93:21): [True: 50, False: 231]
  ------------------
   94|     50|        retval = READSTAT_ERROR_MALLOC;
   95|     50|        goto cleanup;
   96|     50|    }
   97|       |
   98|    232|    if (io->read(ztrailer_entries, n_blocks * sizeof(struct ztrailer_entry), io->io_ctx) < 
  ------------------
  |  Branch (98:9): [True: 33, False: 199]
  ------------------
   99|    232|            n_blocks * sizeof(struct ztrailer_entry)) {
  100|     33|        retval = READSTAT_ERROR_READ;
  101|     33|        goto cleanup;
  102|     33|    }
  103|       |
  104|  32.8k|    for (i=0; i<n_blocks; i++) {
  ------------------
  |  Branch (104:15): [True: 32.6k, False: 199]
  ------------------
  105|  32.6k|        struct ztrailer_entry *entry = &ztrailer_entries[i];
  106|       |
  107|  32.6k|        entry->uncompressed_ofs = ctx->bswap ? byteswap8(entry->uncompressed_ofs) : entry->uncompressed_ofs;
  ------------------
  |  Branch (107:35): [True: 11.4k, False: 21.2k]
  ------------------
  108|  32.6k|        entry->compressed_ofs = ctx->bswap ? byteswap8(entry->compressed_ofs) : entry->compressed_ofs;
  ------------------
  |  Branch (108:33): [True: 11.4k, False: 21.2k]
  ------------------
  109|  32.6k|        entry->uncompressed_size = ctx->bswap ? byteswap4(entry->uncompressed_size) : entry->uncompressed_size;
  ------------------
  |  Branch (109:36): [True: 11.4k, False: 21.2k]
  ------------------
  110|  32.6k|        entry->compressed_size = ctx->bswap ? byteswap4(entry->compressed_size) : entry->compressed_size;
  ------------------
  |  Branch (110:34): [True: 11.4k, False: 21.2k]
  ------------------
  111|  32.6k|    }
  112|       |
  113|    199|    if (uncompressed_row_len && (uncompressed_row = readstat_malloc(uncompressed_row_len)) == NULL) {
  ------------------
  |  Branch (113:9): [True: 199, False: 0]
  |  Branch (113:33): [True: 0, False: 199]
  ------------------
  114|      0|        retval = READSTAT_ERROR_MALLOC;
  115|      0|        goto cleanup;
  116|      0|    }
  117|       |
  118|    199|    while (1) {
  ------------------
  |  Branch (118:12): [Folded - Ignored]
  ------------------
  119|    199|        if (block_i == n_blocks)
  ------------------
  |  Branch (119:13): [True: 1, False: 198]
  ------------------
  120|      1|            goto cleanup;
  121|       |
  122|    198|        struct ztrailer_entry *entry = &ztrailer_entries[block_i];
  123|    198|        if (io->seek(entry->compressed_ofs, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (123:13): [True: 23, False: 175]
  ------------------
  124|     23|            retval = READSTAT_ERROR_SEEK;
  125|     23|            goto cleanup;
  126|     23|        }
  127|    175|        if ((compressed_block = readstat_realloc(compressed_block, entry->compressed_size)) == NULL) {
  ------------------
  |  Branch (127:13): [True: 46, False: 129]
  ------------------
  128|     46|            retval = READSTAT_ERROR_MALLOC;
  129|     46|            goto cleanup;
  130|     46|        }
  131|    129|        if (io->read(compressed_block, entry->compressed_size, io->io_ctx) != entry->compressed_size) {
  ------------------
  |  Branch (131:13): [True: 44, False: 85]
  ------------------
  132|     44|            retval = READSTAT_ERROR_READ;
  133|     44|            goto cleanup;
  134|     44|        }
  135|       |
  136|     85|        uncompressed_block_len = entry->uncompressed_size;
  137|     85|        if ((uncompressed_block = readstat_realloc(uncompressed_block, uncompressed_block_len)) == NULL) {
  ------------------
  |  Branch (137:13): [True: 10, False: 75]
  ------------------
  138|     10|            retval = READSTAT_ERROR_MALLOC;
  139|     10|            goto cleanup;
  140|     10|        }
  141|     75|        int status = uncompress(uncompressed_block, &uncompressed_block_len,
  142|     75|                compressed_block, entry->compressed_size);
  143|     75|        if (status != Z_OK || uncompressed_block_len != entry->uncompressed_size) {
  ------------------
  |  Branch (143:13): [True: 2, False: 73]
  |  Branch (143:31): [True: 23, False: 50]
  ------------------
  144|     25|            retval = READSTAT_ERROR_PARSE;
  145|     25|            goto cleanup;
  146|     25|        }
  147|       |
  148|     50|        block_i++;
  149|     50|        state.status = SAV_ROW_STREAM_HAVE_DATA;
  150|     50|        data_offset = 0;
  151|       |
  152|    166|        while (state.status != SAV_ROW_STREAM_NEED_DATA) {
  ------------------
  |  Branch (152:16): [True: 166, False: 0]
  ------------------
  153|    166|            state.next_in = &uncompressed_block[data_offset];
  154|    166|            state.avail_in = uncompressed_block_len - data_offset;
  155|       |
  156|    166|            state.next_out = &uncompressed_row[uncompressed_offset];
  157|    166|            state.avail_out = uncompressed_row_len - uncompressed_offset;
  158|       |
  159|    166|            sav_decompress_row(&state);
  160|       |
  161|    166|            uncompressed_offset = uncompressed_row_len - state.avail_out;
  162|    166|            data_offset = uncompressed_block_len - state.avail_in;
  163|       |
  164|    166|            if (state.status == SAV_ROW_STREAM_FINISHED_ROW) {
  ------------------
  |  Branch (164:17): [True: 122, False: 44]
  ------------------
  165|    122|                retval = row_handler(uncompressed_row, uncompressed_row_len, ctx);
  166|    122|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (166:21): [True: 2, False: 120]
  ------------------
  167|      2|                    goto cleanup;
  168|       |
  169|    120|                uncompressed_offset = 0;
  170|    120|            }
  171|       |
  172|    164|            if (state.status == SAV_ROW_STREAM_FINISHED_ALL)
  ------------------
  |  Branch (172:17): [True: 44, False: 120]
  ------------------
  173|     44|                goto cleanup;
  174|    120|            if (ctx->row_limit > 0 && ctx->current_row == ctx->row_limit)
  ------------------
  |  Branch (174:17): [True: 77, False: 43]
  |  Branch (174:39): [True: 4, False: 73]
  ------------------
  175|      4|                goto cleanup;
  176|    120|        }
  177|     50|    }
  178|       |
  179|    505|cleanup:
  180|    505|    if (uncompressed_row)
  ------------------
  |  Branch (180:9): [True: 199, False: 306]
  ------------------
  181|    199|        free(uncompressed_row);
  182|    505|    if (ztrailer_entries)
  ------------------
  |  Branch (182:9): [True: 231, False: 274]
  ------------------
  183|    231|        free(ztrailer_entries);
  184|    505|    if (compressed_block)
  ------------------
  |  Branch (184:9): [True: 129, False: 376]
  ------------------
  185|    129|        free(compressed_block);
  186|    505|    if (uncompressed_block)
  ------------------
  |  Branch (186:9): [True: 75, False: 430]
  ------------------
  187|     75|        free(uncompressed_block);
  188|       |
  189|    505|    return retval;
  190|    199|}

rt_open_handler:
    8|  5.31k|int rt_open_handler(const char *path, void *io_ctx) {
    9|  5.31k|    return 0;
   10|  5.31k|}
rt_close_handler:
   12|  5.31k|int rt_close_handler(void *io_ctx) {
   13|  5.31k|    return 0;
   14|  5.31k|}
rt_seek_handler:
   17|   479k|        readstat_io_flags_t whence, void *io_ctx) {
   18|   479k|    rt_buffer_ctx_t *buffer_ctx = (rt_buffer_ctx_t *)io_ctx;
   19|   479k|    readstat_off_t newpos = -1;
   20|   479k|    if (whence == READSTAT_SEEK_SET) {
  ------------------
  |  Branch (20:9): [True: 10.1k, False: 469k]
  ------------------
   21|  10.1k|        newpos = offset;
   22|   469k|    } else if (whence == READSTAT_SEEK_CUR) {
  ------------------
  |  Branch (22:16): [True: 464k, False: 5.31k]
  ------------------
   23|   464k|        newpos = buffer_ctx->pos + offset;
   24|   464k|    } else if (whence == READSTAT_SEEK_END) {
  ------------------
  |  Branch (24:16): [True: 5.31k, False: 0]
  ------------------
   25|  5.31k|        newpos = buffer_ctx->buffer->used + offset;
   26|  5.31k|    }
   27|       |
   28|   479k|    if (newpos < 0)
  ------------------
  |  Branch (28:9): [True: 75, False: 479k]
  ------------------
   29|     75|        return -1;
   30|       |
   31|   479k|    if (newpos > buffer_ctx->buffer->used)
  ------------------
  |  Branch (31:9): [True: 322, False: 479k]
  ------------------
   32|    322|        return -1;
   33|       |
   34|   479k|    buffer_ctx->pos = newpos;
   35|   479k|    return newpos;
   36|   479k|}
rt_read_handler:
   38|  1.86M|ssize_t rt_read_handler(void *buf, size_t nbytes, void *io_ctx) {
   39|  1.86M|    rt_buffer_ctx_t *buffer_ctx = (rt_buffer_ctx_t *)io_ctx;
   40|  1.86M|    ssize_t bytes_copied = 0;
   41|  1.86M|    ssize_t bytes_left = buffer_ctx->buffer->used - buffer_ctx->pos;
   42|  1.86M|    if (nbytes <= bytes_left) {
  ------------------
  |  Branch (42:9): [True: 1.86M, False: 3.04k]
  ------------------
   43|  1.86M|        memcpy(buf, buffer_ctx->buffer->bytes + buffer_ctx->pos, nbytes);
   44|  1.86M|        bytes_copied = nbytes;
   45|  1.86M|    } else if (bytes_left > 0) {
  ------------------
  |  Branch (45:16): [True: 746, False: 2.29k]
  ------------------
   46|    746|        memcpy(buf, buffer_ctx->buffer->bytes + buffer_ctx->pos, bytes_left);
   47|    746|        bytes_copied = bytes_left;
   48|    746|    }
   49|  1.86M|    buffer_ctx->pos += bytes_copied;
   50|  1.86M|    return bytes_copied;
   51|  1.86M|}
rt_update_handler:
   54|  6.07k|        void *user_ctx, void *io_ctx) {
   55|  6.07k|    if (!progress_handler)
  ------------------
  |  Branch (55:9): [True: 6.07k, False: 0]
  ------------------
   56|  6.07k|        return READSTAT_OK;
   57|       |
   58|      0|    rt_buffer_ctx_t *buffer_ctx = (rt_buffer_ctx_t *)io_ctx;
   59|       |
   60|      0|    if (progress_handler(1.0 * buffer_ctx->pos / buffer_ctx->buffer->used, user_ctx))
  ------------------
  |  Branch (60:9): [True: 0, False: 0]
  ------------------
   61|      0|        return READSTAT_ERROR_USER_ABORT;
   62|       |
   63|      0|    return READSTAT_OK;
   64|      0|}

