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

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

machine_is_little_endian:
   11|  7.86k|int machine_is_little_endian(void) {
   12|  7.86k|    int test_byte_order = 1;
   13|  7.86k|    return ((char *)&test_byte_order)[0];
   14|  7.86k|}
byteswap2:
   40|  74.6k|uint16_t byteswap2(uint16_t num) {
   41|  74.6k|    return ((num & 0xFF00) >> 8) | ((num & 0x00FF) << 8);
   42|  74.6k|}
byteswap4:
   44|   181k|uint32_t byteswap4(uint32_t num) {
   45|   181k|    num = ((num & 0xFFFF0000) >> 16) | ((num & 0x0000FFFF) << 16);
   46|   181k|    return ((num & 0xFF00FF00) >> 8) | ((num & 0x00FF00FF) << 8);
   47|   181k|}
byteswap8:
   49|  4.68k|uint64_t byteswap8(uint64_t num) {
   50|  4.68k|    num = ((num & 0xFFFFFFFF00000000) >> 32) | ((num & 0x00000000FFFFFFFF) << 32);
   51|  4.68k|    num = ((num & 0xFFFF0000FFFF0000) >> 16) | ((num & 0x0000FFFF0000FFFF) << 16);
   52|  4.68k|    return ((num & 0xFF00FF00FF00FF00) >> 8) | ((num & 0x00FF00FF00FF00FF) << 8);
   53|  4.68k|}

readstat_convert:
    7|   240k|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|   243k|    while (src_len && (src[src_len-1] == ' ' || src[src_len-1] == '\0')) {
  ------------------
  |  Branch (10:12): [True: 201k, False: 42.7k]
  |  Branch (10:24): [True: 2.28k, False: 198k]
  |  Branch (10:49): [True: 1.62k, False: 197k]
  ------------------
   11|  3.90k|        src_len--;
   12|  3.90k|    }
   13|   240k|    if (dst_len == 0) {
  ------------------
  |  Branch (13:9): [True: 0, False: 240k]
  ------------------
   14|      0|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   15|   240k|    } else if (converter) {
  ------------------
  |  Branch (15:16): [True: 237k, False: 2.04k]
  ------------------
   16|   237k|        size_t dst_left = dst_len - 1;
   17|   237k|        char *dst_end = dst;
   18|   237k|        size_t status = iconv(converter, (readstat_iconv_inbuf_t)&src, &src_len, &dst_end, &dst_left);
   19|   237k|        if (status == (size_t)-1) {
  ------------------
  |  Branch (19:13): [True: 1.90k, False: 236k]
  ------------------
   20|  1.90k|            if (errno == E2BIG) {
  ------------------
  |  Branch (20:17): [True: 1, False: 1.90k]
  ------------------
   21|      1|                return READSTAT_ERROR_CONVERT_LONG_STRING;
   22|  1.90k|            } else if (errno == EILSEQ) {
  ------------------
  |  Branch (22:24): [True: 1.90k, False: 0]
  ------------------
   23|  1.90k|                return READSTAT_ERROR_CONVERT_BAD_STRING;
   24|  1.90k|            } else if (errno != EINVAL) { /* EINVAL indicates improper truncation; accept it */
  ------------------
  |  Branch (24:24): [True: 0, False: 0]
  ------------------
   25|      0|                return READSTAT_ERROR_CONVERT;
   26|      0|            }
   27|  1.90k|        }
   28|   236k|        dst[dst_len - dst_left - 1] = '\0';
   29|   236k|    } else if (src_len + 1 > dst_len) {
  ------------------
  |  Branch (29:16): [True: 15, False: 2.03k]
  ------------------
   30|     15|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   31|  2.03k|    } else {
   32|  2.03k|        memcpy(dst, src, src_len);
   33|  2.03k|        dst[src_len] = '\0';
   34|  2.03k|    }
   35|   238k|    return READSTAT_OK;
   36|   240k|}

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

readstat_malloc:
   10|  93.3k|void *readstat_malloc(size_t len) {
   11|  93.3k|    if (len > MAX_MALLOC_SIZE || len == 0) {
  ------------------
  |  |    3|   186k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (11:9): [True: 38, False: 93.3k]
  |  Branch (11:34): [True: 0, False: 93.3k]
  ------------------
   12|     38|        return NULL;
   13|     38|    }
   14|  93.3k|    return malloc(len);
   15|  93.3k|}
readstat_calloc:
   17|  2.98k|void *readstat_calloc(size_t count, size_t size) {
   18|  2.98k|    if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|  5.97k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
                  if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|  5.92k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
                  if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|  2.93k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (18:9): [True: 54, False: 2.93k]
  |  Branch (18:36): [True: 0, False: 2.93k]
  |  Branch (18:62): [True: 19, False: 2.91k]
  ------------------
   19|     73|        return NULL;
   20|     73|    }
   21|  2.91k|    if (count == 0 || size == 0) {
  ------------------
  |  Branch (21:9): [True: 0, False: 2.91k]
  |  Branch (21:23): [True: 0, False: 2.91k]
  ------------------
   22|      0|        return NULL;
   23|      0|    }
   24|  2.91k|    return calloc(count, size);
   25|  2.91k|}
readstat_realloc:
   27|  6.63k|void *readstat_realloc(void *ptr, size_t len) {
   28|  6.63k|    if (len > MAX_MALLOC_SIZE || len == 0) {
  ------------------
  |  |    3|  13.2k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (28:9): [True: 42, False: 6.59k]
  |  Branch (28:34): [True: 8, False: 6.58k]
  ------------------
   29|     50|        if (ptr)
  ------------------
  |  Branch (29:13): [True: 7, False: 43]
  ------------------
   30|      7|            free(ptr);
   31|     50|        return NULL;
   32|     50|    }
   33|  6.58k|    return realloc(ptr, len);
   34|  6.63k|}

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

dta_ctx_alloc:
   17|  4.39k|dta_ctx_t *dta_ctx_alloc(readstat_io_t *io) {
   18|  4.39k|    dta_ctx_t *ctx = calloc(1, sizeof(dta_ctx_t));
   19|  4.39k|    if (ctx == NULL) {
  ------------------
  |  Branch (19:9): [True: 0, False: 4.39k]
  ------------------
   20|      0|        return NULL;
   21|      0|    }
   22|       |
   23|  4.39k|    ctx->io = io;
   24|  4.39k|    ctx->initialized = 0;
   25|       |
   26|  4.39k|    return ctx;
   27|  4.39k|}
dta_ctx_init:
   31|  3.92k|        const char *input_encoding, const char *output_encoding) {
   32|  3.92k|    readstat_error_t retval = READSTAT_OK;
   33|  3.92k|    int machine_byteorder = DTA_HILO;
  ------------------
  |  |  129|  3.92k|#define DTA_HILO  0x01
  ------------------
   34|  3.92k|    if (ds_format < DTA_MIN_VERSION || ds_format > DTA_MAX_VERSION)
  ------------------
  |  |   14|  7.84k|#define DTA_MIN_VERSION 104
  ------------------
                  if (ds_format < DTA_MIN_VERSION || ds_format > DTA_MAX_VERSION)
  ------------------
  |  |   15|  3.91k|#define DTA_MAX_VERSION 119
  ------------------
  |  Branch (34:9): [True: 6, False: 3.91k]
  |  Branch (34:40): [True: 5, False: 3.91k]
  ------------------
   35|     11|        return READSTAT_ERROR_UNSUPPORTED_FILE_FORMAT_VERSION;
   36|       |
   37|  3.91k|    if (machine_is_little_endian()) {
  ------------------
  |  Branch (37:9): [True: 3.91k, False: 0]
  ------------------
   38|  3.91k|        machine_byteorder = DTA_LOHI;
  ------------------
  |  |  130|  3.91k|#define DTA_LOHI  0x02
  ------------------
   39|  3.91k|    }
   40|       |
   41|  3.91k|    ctx->bswap = (byteorder != machine_byteorder);
   42|  3.91k|    ctx->ds_format = ds_format;
   43|  3.91k|    ctx->endianness = byteorder == DTA_LOHI ? READSTAT_ENDIAN_LITTLE : READSTAT_ENDIAN_BIG;
  ------------------
  |  |  130|  3.91k|#define DTA_LOHI  0x02
  ------------------
  |  Branch (43:23): [True: 1.33k, False: 2.57k]
  ------------------
   44|       |
   45|  3.91k|    ctx->nvar = nvar;
   46|  3.91k|    ctx->nobs = nobs;
   47|       |
   48|  3.91k|    if (ctx->nvar) {
  ------------------
  |  Branch (48:9): [True: 2.98k, False: 925]
  ------------------
   49|  2.98k|        if ((ctx->variables = readstat_calloc(ctx->nvar, sizeof(readstat_variable_t *))) == NULL) {
  ------------------
  |  Branch (49:13): [True: 73, False: 2.91k]
  ------------------
   50|     73|            retval = READSTAT_ERROR_MALLOC;
   51|     73|            goto cleanup;
   52|     73|        }
   53|  2.98k|    }
   54|       |
   55|  3.83k|    ctx->machine_is_twos_complement = READSTAT_MACHINE_IS_TWOS_COMPLEMENT;
  ------------------
  |  |    8|  3.83k|#define READSTAT_MACHINE_IS_TWOS_COMPLEMENT 0
  ------------------
   56|       |
   57|  3.83k|    if (ds_format < 105) {
  ------------------
  |  Branch (57:9): [True: 770, False: 3.06k]
  ------------------
   58|    770|        ctx->fmtlist_entry_len = 7;
   59|  3.06k|    } else if (ds_format < 114) {
  ------------------
  |  Branch (59:16): [True: 897, False: 2.17k]
  ------------------
   60|    897|        ctx->fmtlist_entry_len = 12;
   61|  2.17k|    } else if (ds_format < 118) {
  ------------------
  |  Branch (61:16): [True: 1.76k, False: 408]
  ------------------
   62|  1.76k|        ctx->fmtlist_entry_len = 49;
   63|  1.76k|    } else {
   64|    408|        ctx->fmtlist_entry_len = 57;
   65|    408|    }
   66|       |    
   67|  3.83k|    if (ds_format >= 117) {
  ------------------
  |  Branch (67:9): [True: 2.13k, False: 1.70k]
  ------------------
   68|  2.13k|        ctx->typlist_version = 117;
   69|  2.13k|    } else if (ds_format >= 111) {
  ------------------
  |  Branch (69:16): [True: 315, False: 1.38k]
  ------------------
   70|    315|        ctx->typlist_version = 111;
   71|  1.38k|    } else {
   72|  1.38k|        ctx->typlist_version = 0;
   73|  1.38k|    }
   74|       |
   75|  3.83k|    if (ds_format >= 118) {
  ------------------
  |  Branch (75:9): [True: 408, False: 3.43k]
  ------------------
   76|    408|        ctx->data_label_len_len = 2;
   77|    408|        ctx->strl_v_len = 2;
   78|    408|        ctx->strl_o_len = 6;
   79|  3.43k|    } else if (ds_format >= 117) {
  ------------------
  |  Branch (79:16): [True: 1.72k, False: 1.70k]
  ------------------
   80|  1.72k|        ctx->data_label_len_len = 1;
   81|  1.72k|        ctx->strl_v_len = 4;
   82|  1.72k|        ctx->strl_o_len = 4;
   83|  1.72k|    }
   84|       |
   85|  3.83k|    if (ds_format < 105) {
  ------------------
  |  Branch (85:9): [True: 770, False: 3.06k]
  ------------------
   86|    770|        ctx->expansion_len_len = 0;
   87|  3.06k|    } else if (ds_format < 110) {
  ------------------
  |  Branch (87:16): [True: 611, False: 2.45k]
  ------------------
   88|    611|        ctx->expansion_len_len = 2;
   89|  2.45k|    } else {
   90|  2.45k|        ctx->expansion_len_len = 4;
   91|  2.45k|    }
   92|       |    
   93|  3.83k|    if (ds_format < 110) {
  ------------------
  |  Branch (93:9): [True: 1.38k, False: 2.45k]
  ------------------
   94|  1.38k|        ctx->lbllist_entry_len = 9;
   95|  1.38k|        ctx->variable_name_len = 9;
   96|  1.38k|        ctx->ch_metadata_len = 9;
   97|  2.45k|    } else if (ds_format < 118) {
  ------------------
  |  Branch (97:16): [True: 2.05k, False: 408]
  ------------------
   98|  2.05k|        ctx->lbllist_entry_len = 33;
   99|  2.05k|        ctx->variable_name_len = 33;
  100|  2.05k|        ctx->ch_metadata_len = 33;
  101|  2.05k|    } else {
  102|    408|        ctx->lbllist_entry_len = 129;
  103|    408|        ctx->variable_name_len = 129;
  104|    408|        ctx->ch_metadata_len = 129;
  105|    408|    }
  106|       |
  107|  3.83k|    if (ds_format < 108) {
  ------------------
  |  Branch (107:9): [True: 1.37k, False: 2.46k]
  ------------------
  108|  1.37k|        ctx->variable_labels_entry_len = 32;
  109|  1.37k|        ctx->data_label_len = 32;
  110|  2.46k|    } else if (ds_format < 118) {
  ------------------
  |  Branch (110:16): [True: 2.05k, False: 408]
  ------------------
  111|  2.05k|        ctx->variable_labels_entry_len = 81;
  112|  2.05k|        ctx->data_label_len = 81;
  113|  2.05k|    } else {
  114|    408|        ctx->variable_labels_entry_len = 321;
  115|    408|        ctx->data_label_len = 321;
  116|    408|    }
  117|       |
  118|  3.83k|    if (ds_format < 105) {
  ------------------
  |  Branch (118:9): [True: 770, False: 3.06k]
  ------------------
  119|    770|        ctx->timestamp_len = 0;
  120|    770|        ctx->value_label_table_len_len = 2;
  121|    770|        ctx->value_label_table_labname_len = 12;
  122|    770|        ctx->value_label_table_padding_len = 2;
  123|  3.06k|    } else {
  124|  3.06k|        ctx->timestamp_len = 18;
  125|  3.06k|        ctx->value_label_table_len_len = 4;
  126|  3.06k|        if (ds_format < 118) {
  ------------------
  |  Branch (126:13): [True: 2.66k, False: 408]
  ------------------
  127|  2.66k|            ctx->value_label_table_labname_len = 33;
  128|  2.66k|        } else {
  129|    408|            ctx->value_label_table_labname_len = 129;
  130|    408|        }
  131|  3.06k|        ctx->value_label_table_padding_len = 3;
  132|  3.06k|    }
  133|       |
  134|  3.83k|    if (ds_format < 117) {
  ------------------
  |  Branch (134:9): [True: 1.70k, False: 2.13k]
  ------------------
  135|  1.70k|        ctx->typlist_entry_len = 1;
  136|  1.70k|        ctx->file_is_xmlish = 0;
  137|  2.13k|    } else {
  138|  2.13k|        ctx->typlist_entry_len = 2;
  139|  2.13k|        ctx->file_is_xmlish = 1;
  140|  2.13k|    }
  141|       |
  142|  3.83k|    if (ds_format < 113) {
  ------------------
  |  Branch (142:9): [True: 1.40k, False: 2.43k]
  ------------------
  143|  1.40k|        ctx->max_int8 = DTA_OLD_MAX_INT8;
  ------------------
  |  |  132|  1.40k|#define DTA_OLD_MAX_INT8                     0x7e
  ------------------
  144|  1.40k|        ctx->max_int16 = DTA_OLD_MAX_INT16;
  ------------------
  |  |  133|  1.40k|#define DTA_OLD_MAX_INT16                  0x7ffe
  ------------------
  145|  1.40k|        ctx->max_int32 = DTA_OLD_MAX_INT32;
  ------------------
  |  |  134|  1.40k|#define DTA_OLD_MAX_INT32              0x7ffffffe
  ------------------
  146|  1.40k|        ctx->max_float = DTA_OLD_MAX_FLOAT;
  ------------------
  |  |  135|  1.40k|#define DTA_OLD_MAX_FLOAT              0x7effffff // +1.7e38f
  ------------------
  147|  1.40k|        ctx->max_double = DTA_OLD_MAX_DOUBLE;
  ------------------
  |  |  136|  1.40k|#define DTA_OLD_MAX_DOUBLE     0x7fdfffffffffffffL // +8.9e307
  ------------------
  148|  2.43k|    } else {
  149|  2.43k|        ctx->max_int8 = DTA_113_MAX_INT8;
  ------------------
  |  |  144|  2.43k|#define DTA_113_MAX_INT8                    0x64
  ------------------
  150|  2.43k|        ctx->max_int16 = DTA_113_MAX_INT16;
  ------------------
  |  |  145|  2.43k|#define DTA_113_MAX_INT16                 0x7fe4
  ------------------
  151|  2.43k|        ctx->max_int32 = DTA_113_MAX_INT32;
  ------------------
  |  |  146|  2.43k|#define DTA_113_MAX_INT32             0x7fffffe4
  ------------------
  152|  2.43k|        ctx->max_float = DTA_113_MAX_FLOAT;
  ------------------
  |  |  147|  2.43k|#define DTA_113_MAX_FLOAT             0x7effffff // +1.7e38f
  ------------------
  153|  2.43k|        ctx->max_double = DTA_113_MAX_DOUBLE;
  ------------------
  |  |  148|  2.43k|#define DTA_113_MAX_DOUBLE    0x7fdfffffffffffffL // +8.9e307
  ------------------
  154|       |
  155|  2.43k|        ctx->supports_tagged_missing = 1;
  156|  2.43k|    }
  157|       |
  158|  3.83k|    if (output_encoding) {
  ------------------
  |  Branch (158:9): [True: 3.83k, False: 0]
  ------------------
  159|  3.83k|        if (input_encoding) {
  ------------------
  |  Branch (159:13): [True: 0, False: 3.83k]
  ------------------
  160|      0|            ctx->converter = iconv_open(output_encoding, input_encoding);
  161|  3.83k|        } else if (ds_format < 118) {
  ------------------
  |  Branch (161:20): [True: 3.43k, False: 408]
  ------------------
  162|  3.43k|            ctx->converter = iconv_open(output_encoding, "WINDOWS-1252");
  163|  3.43k|        } else if (strcmp(output_encoding, "UTF-8") != 0) {
  ------------------
  |  Branch (163:20): [True: 0, False: 408]
  ------------------
  164|      0|            ctx->converter = iconv_open(output_encoding, "UTF-8");
  165|      0|        }
  166|  3.83k|        if (ctx->converter == (iconv_t)-1) {
  ------------------
  |  Branch (166:13): [True: 0, False: 3.83k]
  ------------------
  167|      0|            ctx->converter = NULL;
  168|      0|            retval = READSTAT_ERROR_UNSUPPORTED_CHARSET;
  169|      0|            goto cleanup;
  170|      0|        }
  171|  3.83k|    }
  172|       |
  173|  3.83k|    if (ds_format < 119) {
  ------------------
  |  Branch (173:9): [True: 3.74k, False: 91]
  ------------------
  174|  3.74k|        ctx->srtlist_len = (ctx->nvar + 1) * sizeof(int16_t);
  175|  3.74k|    } else {
  176|     91|        ctx->srtlist_len = (ctx->nvar + 1) * sizeof(int32_t);
  177|     91|    }
  178|       |
  179|  3.83k|    if ((ctx->srtlist = readstat_malloc(ctx->srtlist_len)) == NULL) {
  ------------------
  |  Branch (179:9): [True: 0, False: 3.83k]
  ------------------
  180|      0|        retval = READSTAT_ERROR_MALLOC;
  181|      0|        goto cleanup;
  182|      0|    }
  183|       |
  184|  3.83k|    if (ctx->nvar > 0) {
  ------------------
  |  Branch (184:9): [True: 2.91k, False: 925]
  ------------------
  185|  2.91k|        ctx->typlist_len = ctx->nvar * sizeof(uint16_t);
  186|  2.91k|        ctx->varlist_len = ctx->variable_name_len * ctx->nvar * sizeof(char);
  187|  2.91k|        ctx->fmtlist_len = ctx->fmtlist_entry_len * ctx->nvar * sizeof(char);
  188|  2.91k|        ctx->lbllist_len = ctx->lbllist_entry_len * ctx->nvar * sizeof(char);
  189|  2.91k|        ctx->variable_labels_len = ctx->variable_labels_entry_len * ctx->nvar * sizeof(char);
  190|       |
  191|  2.91k|        if ((ctx->typlist = readstat_malloc(ctx->typlist_len)) == NULL) {
  ------------------
  |  Branch (191:13): [True: 0, False: 2.91k]
  ------------------
  192|      0|            retval = READSTAT_ERROR_MALLOC;
  193|      0|            goto cleanup;
  194|      0|        }
  195|  2.91k|        if ((ctx->varlist = readstat_malloc(ctx->varlist_len)) == NULL) {
  ------------------
  |  Branch (195:13): [True: 27, False: 2.88k]
  ------------------
  196|     27|            retval = READSTAT_ERROR_MALLOC;
  197|     27|            goto cleanup;
  198|     27|        }
  199|  2.88k|        if ((ctx->fmtlist = readstat_malloc(ctx->fmtlist_len)) == NULL) {
  ------------------
  |  Branch (199:13): [True: 0, False: 2.88k]
  ------------------
  200|      0|            retval = READSTAT_ERROR_MALLOC;
  201|      0|            goto cleanup;
  202|      0|        }
  203|  2.88k|        if ((ctx->lbllist = readstat_malloc(ctx->lbllist_len)) == NULL) {
  ------------------
  |  Branch (203:13): [True: 0, False: 2.88k]
  ------------------
  204|      0|            retval = READSTAT_ERROR_MALLOC;
  205|      0|            goto cleanup;
  206|      0|        }
  207|  2.88k|        if ((ctx->variable_labels = readstat_malloc(ctx->variable_labels_len)) == NULL) {
  ------------------
  |  Branch (207:13): [True: 4, False: 2.88k]
  ------------------
  208|      4|            retval = READSTAT_ERROR_MALLOC;
  209|      4|            goto cleanup;
  210|      4|        }
  211|  2.88k|    }
  212|       |
  213|  3.80k|    ctx->initialized = 1;
  214|       |
  215|  3.91k|cleanup:
  216|  3.91k|    return retval;
  217|  3.80k|}
dta_ctx_free:
  219|  4.39k|void dta_ctx_free(dta_ctx_t *ctx) {
  220|  4.39k|    if (ctx->typlist)
  ------------------
  |  Branch (220:9): [True: 2.91k, False: 1.48k]
  ------------------
  221|  2.91k|        free(ctx->typlist);
  222|  4.39k|    if (ctx->varlist)
  ------------------
  |  Branch (222:9): [True: 2.88k, False: 1.51k]
  ------------------
  223|  2.88k|        free(ctx->varlist);
  224|  4.39k|    if (ctx->srtlist)
  ------------------
  |  Branch (224:9): [True: 3.83k, False: 559]
  ------------------
  225|  3.83k|        free(ctx->srtlist);
  226|  4.39k|    if (ctx->fmtlist)
  ------------------
  |  Branch (226:9): [True: 2.88k, False: 1.51k]
  ------------------
  227|  2.88k|        free(ctx->fmtlist);
  228|  4.39k|    if (ctx->lbllist)
  ------------------
  |  Branch (228:9): [True: 2.88k, False: 1.51k]
  ------------------
  229|  2.88k|        free(ctx->lbllist);
  230|  4.39k|    if (ctx->variable_labels)
  ------------------
  |  Branch (230:9): [True: 2.88k, False: 1.51k]
  ------------------
  231|  2.88k|        free(ctx->variable_labels);
  232|  4.39k|    if (ctx->converter)
  ------------------
  |  Branch (232:9): [True: 3.43k, False: 967]
  ------------------
  233|  3.43k|        iconv_close(ctx->converter);
  234|  4.39k|    if (ctx->data_label)
  ------------------
  |  Branch (234:9): [True: 3.56k, False: 834]
  ------------------
  235|  3.56k|        free(ctx->data_label);
  236|  4.39k|    if (ctx->variables) {
  ------------------
  |  Branch (236:9): [True: 2.91k, False: 1.48k]
  ------------------
  237|  2.91k|        int i;
  238|  59.1M|        for (i=0; i<ctx->nvar; i++) {
  ------------------
  |  Branch (238:19): [True: 59.1M, False: 2.91k]
  ------------------
  239|  59.1M|            if (ctx->variables[i])
  ------------------
  |  Branch (239:17): [True: 57.0k, False: 59.0M]
  ------------------
  240|  57.0k|                free(ctx->variables[i]);
  241|  59.1M|        }
  242|  2.91k|        free(ctx->variables);
  243|  2.91k|    }
  244|  4.39k|    if (ctx->strls) {
  ------------------
  |  Branch (244:9): [True: 834, False: 3.56k]
  ------------------
  245|    834|        int i;
  246|  62.9k|        for (i=0; i<ctx->strls_count; i++) {
  ------------------
  |  Branch (246:19): [True: 62.1k, False: 834]
  ------------------
  247|  62.1k|            free(ctx->strls[i]);
  248|  62.1k|        }
  249|    834|        free(ctx->strls);
  250|    834|    }
  251|  4.39k|    free(ctx);
  252|  4.39k|}
dta_type_info:
  255|   210k|        size_t *max_len, readstat_type_t *out_type) {
  256|   210k|    readstat_error_t retval = READSTAT_OK;
  257|   210k|    size_t len = 0;
  258|   210k|    readstat_type_t type = READSTAT_TYPE_STRING;
  259|   210k|    if (ctx->typlist_version == 111) {
  ------------------
  |  Branch (259:9): [True: 95.4k, False: 115k]
  ------------------
  260|  95.4k|        switch (typecode) {
  261|    880|            case DTA_111_TYPE_CODE_INT8:
  ------------------
  |  |  172|    880|#define DTA_111_TYPE_CODE_INT8     0xFB
  ------------------
  |  Branch (261:13): [True: 880, False: 94.5k]
  ------------------
  262|    880|                len = 1; type = READSTAT_TYPE_INT8; break;
  263|    422|            case DTA_111_TYPE_CODE_INT16:
  ------------------
  |  |  173|    422|#define DTA_111_TYPE_CODE_INT16    0xFC
  ------------------
  |  Branch (263:13): [True: 422, False: 95.0k]
  ------------------
  264|    422|                len = 2; type = READSTAT_TYPE_INT16; break;
  265|  23.4k|            case DTA_111_TYPE_CODE_INT32:
  ------------------
  |  |  174|  23.4k|#define DTA_111_TYPE_CODE_INT32    0xFD
  ------------------
  |  Branch (265:13): [True: 23.4k, False: 71.9k]
  ------------------
  266|  23.4k|                len = 4; type = READSTAT_TYPE_INT32; break;
  267|    488|            case DTA_111_TYPE_CODE_FLOAT:
  ------------------
  |  |  175|    488|#define DTA_111_TYPE_CODE_FLOAT    0xFE
  ------------------
  |  Branch (267:13): [True: 488, False: 94.9k]
  ------------------
  268|    488|                len = 4; type = READSTAT_TYPE_FLOAT; break;
  269|  1.13k|            case DTA_111_TYPE_CODE_DOUBLE:
  ------------------
  |  |  176|  1.13k|#define DTA_111_TYPE_CODE_DOUBLE   0xFF
  ------------------
  |  Branch (269:13): [True: 1.13k, False: 94.2k]
  ------------------
  270|  1.13k|                len = 8; type = READSTAT_TYPE_DOUBLE; break;
  271|  68.9k|            default:
  ------------------
  |  Branch (271:13): [True: 68.9k, False: 26.4k]
  ------------------
  272|  68.9k|                len = typecode; type = READSTAT_TYPE_STRING; break;
  273|  95.4k|        }
  274|   115k|    } else if (ctx->typlist_version == 117) {
  ------------------
  |  Branch (274:16): [True: 58.2k, False: 56.9k]
  ------------------
  275|  58.2k|        switch (typecode) {
  276|    962|            case DTA_117_TYPE_CODE_INT8:
  ------------------
  |  |  165|    962|#define DTA_117_TYPE_CODE_INT8     0xFFFA
  ------------------
  |  Branch (276:13): [True: 962, False: 57.2k]
  ------------------
  277|    962|                len = 1; type = READSTAT_TYPE_INT8; break;
  278|    704|            case DTA_117_TYPE_CODE_INT16:
  ------------------
  |  |  166|    704|#define DTA_117_TYPE_CODE_INT16    0xFFF9
  ------------------
  |  Branch (278:13): [True: 704, False: 57.5k]
  ------------------
  279|    704|                len = 2; type = READSTAT_TYPE_INT16; break;
  280|  1.65k|            case DTA_117_TYPE_CODE_INT32:
  ------------------
  |  |  167|  1.65k|#define DTA_117_TYPE_CODE_INT32    0xFFF8
  ------------------
  |  Branch (280:13): [True: 1.65k, False: 56.6k]
  ------------------
  281|  1.65k|                len = 4; type = READSTAT_TYPE_INT32; break;
  282|    779|            case DTA_117_TYPE_CODE_FLOAT:
  ------------------
  |  |  168|    779|#define DTA_117_TYPE_CODE_FLOAT    0xFFF7
  ------------------
  |  Branch (282:13): [True: 779, False: 57.4k]
  ------------------
  283|    779|                len = 4; type = READSTAT_TYPE_FLOAT; break;
  284|    763|            case DTA_117_TYPE_CODE_DOUBLE:
  ------------------
  |  |  169|    763|#define DTA_117_TYPE_CODE_DOUBLE   0xFFF6
  ------------------
  |  Branch (284:13): [True: 763, False: 57.4k]
  ------------------
  285|    763|                len = 8; type = READSTAT_TYPE_DOUBLE; break;
  286|  49.8k|            case DTA_117_TYPE_CODE_STRL:
  ------------------
  |  |  170|  49.8k|#define DTA_117_TYPE_CODE_STRL     0x8000
  ------------------
  |  Branch (286:13): [True: 49.8k, False: 8.44k]
  ------------------
  287|  49.8k|                len = 8; type = READSTAT_TYPE_STRING_REF; break;
  288|  3.57k|            default:
  ------------------
  |  Branch (288:13): [True: 3.57k, False: 54.6k]
  ------------------
  289|  3.57k|                len = typecode; type = READSTAT_TYPE_STRING; break;
  290|  58.2k|        }
  291|  58.2k|    } else if (typecode < 0x7F) {
  ------------------
  |  Branch (291:16): [True: 42.3k, False: 14.5k]
  ------------------
  292|  42.3k|        switch (typecode) {
  293|  38.7k|            case DTA_OLD_TYPE_CODE_INT8:
  ------------------
  |  |  178|  38.7k|#define DTA_OLD_TYPE_CODE_INT8     'b'
  ------------------
  |  Branch (293:13): [True: 38.7k, False: 3.60k]
  ------------------
  294|  38.7k|                len = 1; type = READSTAT_TYPE_INT8; break;
  295|  1.19k|            case DTA_OLD_TYPE_CODE_INT16:
  ------------------
  |  |  179|  1.19k|#define DTA_OLD_TYPE_CODE_INT16    'i'
  ------------------
  |  Branch (295:13): [True: 1.19k, False: 41.1k]
  ------------------
  296|  1.19k|                len = 2; type = READSTAT_TYPE_INT16; break;
  297|    857|            case DTA_OLD_TYPE_CODE_INT32:
  ------------------
  |  |  180|    857|#define DTA_OLD_TYPE_CODE_INT32    'l'
  ------------------
  |  Branch (297:13): [True: 857, False: 41.5k]
  ------------------
  298|    857|                len = 4; type = READSTAT_TYPE_INT32; break;
  299|    762|            case DTA_OLD_TYPE_CODE_FLOAT:
  ------------------
  |  |  181|    762|#define DTA_OLD_TYPE_CODE_FLOAT    'f'
  ------------------
  |  Branch (299:13): [True: 762, False: 41.6k]
  ------------------
  300|    762|                len = 4; type = READSTAT_TYPE_FLOAT; break;
  301|    770|            case DTA_OLD_TYPE_CODE_DOUBLE:
  ------------------
  |  |  182|    770|#define DTA_OLD_TYPE_CODE_DOUBLE   'd'
  ------------------
  |  Branch (301:13): [True: 770, False: 41.6k]
  ------------------
  302|    770|                len = 8; type = READSTAT_TYPE_DOUBLE; break;
  303|     15|            default:
  ------------------
  |  Branch (303:13): [True: 15, False: 42.3k]
  ------------------
  304|     15|                retval = READSTAT_ERROR_PARSE; break;
  305|  42.3k|        }
  306|  42.3k|    } else {
  307|  14.5k|        len = typecode - 0x7F;
  308|  14.5k|        type = READSTAT_TYPE_STRING;
  309|  14.5k|    }
  310|       |    
  311|   210k|    if (max_len)
  ------------------
  |  Branch (311:9): [True: 210k, False: 0]
  ------------------
  312|   210k|        *max_len = len;
  313|   210k|    if (out_type)
  ------------------
  |  Branch (313:9): [True: 153k, False: 57.1k]
  ------------------
  314|   153k|        *out_type = type;
  315|       |
  316|   210k|    return retval;
  317|   210k|}

dta_parse_timestamp:
  145|    896|readstat_error_handler error_handler, void *user_ctx) {
  146|    896|	readstat_error_t retval = READSTAT_OK;
  147|    896|	const char *p = data;
  148|    896|	const char *pe = p + len;
  149|    896|	const char *eof = pe;
  150|    896|	int cs;
  151|    896|	unsigned int temp_val = 0;
  152|       |	
  153|    896|#line 154 "src/stata/readstat_dta_parse_timestamp.c"
  154|    896|	{
  155|    896|		cs = (int)dta_timestamp_parse_start;
  156|    896|	}
  157|       |	
  158|    896|#line 159 "src/stata/readstat_dta_parse_timestamp.c"
  159|    896|	{
  160|    896|		int _klen;
  161|    896|		unsigned int _trans = 0;
  162|    896|		const char * _keys;
  163|    896|		const signed char * _acts;
  164|    896|		unsigned int _nacts;
  165|  3.17k|		_resume: {}
  166|  3.17k|		if ( p == pe && p != eof )
  ------------------
  |  Branch (166:8): [True: 81, False: 3.09k]
  |  Branch (166:19): [True: 0, False: 81]
  ------------------
  167|      0|			goto _out;
  168|  3.17k|		if ( p == eof ) {
  ------------------
  |  Branch (168:8): [True: 81, False: 3.09k]
  ------------------
  169|     81|			if ( _dta_timestamp_parse_eof_trans[cs] > 0 ) {
  ------------------
  |  Branch (169:9): [True: 81, False: 0]
  ------------------
  170|     81|				_trans = (unsigned int)_dta_timestamp_parse_eof_trans[cs] - 1;
  171|     81|			}
  172|     81|		}
  173|  3.09k|		else {
  174|  3.09k|			_keys = ( _dta_timestamp_parse_trans_keys + (_dta_timestamp_parse_key_offsets[cs]));
  175|  3.09k|			_trans = (unsigned int)_dta_timestamp_parse_index_offsets[cs];
  176|       |			
  177|  3.09k|			_klen = (int)_dta_timestamp_parse_single_lengths[cs];
  178|  3.09k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (178:9): [True: 2.77k, False: 315]
  ------------------
  179|  2.77k|				const char *_lower = _keys;
  180|  2.77k|				const char *_upper = _keys + _klen - 1;
  181|  2.77k|				const char *_mid;
  182|  5.33k|				while ( 1 ) {
  ------------------
  |  Branch (182:13): [True: 5.33k, Folded]
  ------------------
  183|  5.33k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (183:11): [True: 1.99k, False: 3.33k]
  ------------------
  184|  1.99k|						_keys += _klen;
  185|  1.99k|						_trans += (unsigned int)_klen;
  186|  1.99k|						break;
  187|  1.99k|					}
  188|       |					
  189|  3.33k|					_mid = _lower + ((_upper-_lower) >> 1);
  190|  3.33k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (190:11): [True: 821, False: 2.51k]
  ------------------
  191|    821|						_upper = _mid - 1;
  192|  2.51k|					else if ( ( (*( p))) > (*( _mid)) )
  ------------------
  |  Branch (192:16): [True: 1.73k, False: 781]
  ------------------
  193|  1.73k|						_lower = _mid + 1;
  194|    781|					else {
  195|    781|						_trans += (unsigned int)(_mid - _keys);
  196|    781|						goto _match;
  197|    781|					}
  198|  3.33k|				}
  199|  2.77k|			}
  200|       |			
  201|  2.31k|			_klen = (int)_dta_timestamp_parse_range_lengths[cs];
  202|  2.31k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (202:9): [True: 2.29k, False: 20]
  ------------------
  203|  2.29k|				const char *_lower = _keys;
  204|  2.29k|				const char *_upper = _keys + (_klen<<1) - 2;
  205|  2.29k|				const char *_mid;
  206|  3.08k|				while ( 1 ) {
  ------------------
  |  Branch (206:13): [True: 3.08k, Folded]
  ------------------
  207|  3.08k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (207:11): [True: 795, False: 2.29k]
  ------------------
  208|    795|						_trans += (unsigned int)_klen;
  209|    795|						break;
  210|    795|					}
  211|       |					
  212|  2.29k|					_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  213|  2.29k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (213:11): [True: 449, False: 1.84k]
  ------------------
  214|    449|						_upper = _mid - 2;
  215|  1.84k|					else if ( ( (*( p))) > (*( _mid + 1)) )
  ------------------
  |  Branch (215:16): [True: 346, False: 1.49k]
  ------------------
  216|    346|						_lower = _mid + 2;
  217|  1.49k|					else {
  218|  1.49k|						_trans += (unsigned int)((_mid - _keys)>>1);
  219|  1.49k|						break;
  220|  1.49k|					}
  221|  2.29k|				}
  222|  2.29k|			}
  223|       |			
  224|  3.09k|			_match: {}
  225|  3.09k|		}
  226|  3.17k|		cs = (int)_dta_timestamp_parse_cond_targs[_trans];
  227|       |		
  228|  3.17k|		if ( _dta_timestamp_parse_cond_actions[_trans] != 0 ) {
  ------------------
  |  Branch (228:8): [True: 1.82k, False: 1.35k]
  ------------------
  229|       |			
  230|  1.82k|			_acts = ( _dta_timestamp_parse_actions + (_dta_timestamp_parse_cond_actions[_trans]));
  231|  1.82k|			_nacts = (unsigned int)(*( _acts));
  232|  1.82k|			_acts += 1;
  233|  4.11k|			while ( _nacts > 0 ) {
  ------------------
  |  Branch (233:12): [True: 2.29k, False: 1.82k]
  ------------------
  234|  2.29k|				switch ( (*( _acts)) )
  ------------------
  |  Branch (234:14): [True: 2.29k, False: 0]
  ------------------
  235|  2.29k|				{
  236|  1.49k|					case 0:  {
  ------------------
  |  Branch (236:6): [True: 1.49k, False: 794]
  ------------------
  237|  1.49k|						{
  238|  1.49k|#line 20 "src/stata/readstat_dta_parse_timestamp.rl"
  239|       |							
  240|  1.49k|							temp_val = 10 * temp_val + ((( (*( p)))) - '0');
  241|  1.49k|						}
  242|       |						
  243|  1.49k|#line 244 "src/stata/readstat_dta_parse_timestamp.c"
  244|       |						
  245|  1.49k|						break; 
  246|      0|					}
  247|    469|					case 1:  {
  ------------------
  |  Branch (247:6): [True: 469, False: 1.82k]
  ------------------
  248|    469|						{
  249|    469|#line 24 "src/stata/readstat_dta_parse_timestamp.rl"
  250|    469|							temp_val = 0; }
  251|       |						
  252|    469|#line 253 "src/stata/readstat_dta_parse_timestamp.c"
  253|       |						
  254|    469|						break; 
  255|      0|					}
  256|    120|					case 2:  {
  ------------------
  |  Branch (256:6): [True: 120, False: 2.17k]
  ------------------
  257|    120|						{
  258|    120|#line 26 "src/stata/readstat_dta_parse_timestamp.rl"
  259|    120|							timestamp->tm_mday = temp_val; }
  260|       |						
  261|    120|#line 262 "src/stata/readstat_dta_parse_timestamp.c"
  262|       |						
  263|    120|						break; 
  264|      0|					}
  265|     16|					case 3:  {
  ------------------
  |  Branch (265:6): [True: 16, False: 2.27k]
  ------------------
  266|     16|						{
  267|     16|#line 29 "src/stata/readstat_dta_parse_timestamp.rl"
  268|     16|							timestamp->tm_mon = 0; }
  269|       |						
  270|     16|#line 271 "src/stata/readstat_dta_parse_timestamp.c"
  271|       |						
  272|     16|						break; 
  273|      0|					}
  274|      3|					case 4:  {
  ------------------
  |  Branch (274:6): [True: 3, False: 2.28k]
  ------------------
  275|      3|						{
  276|      3|#line 30 "src/stata/readstat_dta_parse_timestamp.rl"
  277|      3|							timestamp->tm_mon = 1; }
  278|       |						
  279|      3|#line 280 "src/stata/readstat_dta_parse_timestamp.c"
  280|       |						
  281|      3|						break; 
  282|      0|					}
  283|      3|					case 5:  {
  ------------------
  |  Branch (283:6): [True: 3, False: 2.28k]
  ------------------
  284|      3|						{
  285|      3|#line 31 "src/stata/readstat_dta_parse_timestamp.rl"
  286|      3|							timestamp->tm_mon = 2; }
  287|       |						
  288|      3|#line 289 "src/stata/readstat_dta_parse_timestamp.c"
  289|       |						
  290|      3|						break; 
  291|      0|					}
  292|     19|					case 6:  {
  ------------------
  |  Branch (292:6): [True: 19, False: 2.27k]
  ------------------
  293|     19|						{
  294|     19|#line 32 "src/stata/readstat_dta_parse_timestamp.rl"
  295|     19|							timestamp->tm_mon = 3; }
  296|       |						
  297|     19|#line 298 "src/stata/readstat_dta_parse_timestamp.c"
  298|       |						
  299|     19|						break; 
  300|      0|					}
  301|     15|					case 7:  {
  ------------------
  |  Branch (301:6): [True: 15, False: 2.27k]
  ------------------
  302|     15|						{
  303|     15|#line 33 "src/stata/readstat_dta_parse_timestamp.rl"
  304|     15|							timestamp->tm_mon = 4; }
  305|       |						
  306|     15|#line 307 "src/stata/readstat_dta_parse_timestamp.c"
  307|       |						
  308|     15|						break; 
  309|      0|					}
  310|     15|					case 8:  {
  ------------------
  |  Branch (310:6): [True: 15, False: 2.27k]
  ------------------
  311|     15|						{
  312|     15|#line 34 "src/stata/readstat_dta_parse_timestamp.rl"
  313|     15|							timestamp->tm_mon = 5; }
  314|       |						
  315|     15|#line 316 "src/stata/readstat_dta_parse_timestamp.c"
  316|       |						
  317|     15|						break; 
  318|      0|					}
  319|      1|					case 9:  {
  ------------------
  |  Branch (319:6): [True: 1, False: 2.29k]
  ------------------
  320|      1|						{
  321|      1|#line 35 "src/stata/readstat_dta_parse_timestamp.rl"
  322|      1|							timestamp->tm_mon = 6; }
  323|       |						
  324|      1|#line 325 "src/stata/readstat_dta_parse_timestamp.c"
  325|       |						
  326|      1|						break; 
  327|      0|					}
  328|      2|					case 10:  {
  ------------------
  |  Branch (328:6): [True: 2, False: 2.29k]
  ------------------
  329|      2|						{
  330|      2|#line 36 "src/stata/readstat_dta_parse_timestamp.rl"
  331|      2|							timestamp->tm_mon = 7; }
  332|       |						
  333|      2|#line 334 "src/stata/readstat_dta_parse_timestamp.c"
  334|       |						
  335|      2|						break; 
  336|      0|					}
  337|      3|					case 11:  {
  ------------------
  |  Branch (337:6): [True: 3, False: 2.28k]
  ------------------
  338|      3|						{
  339|      3|#line 37 "src/stata/readstat_dta_parse_timestamp.rl"
  340|      3|							timestamp->tm_mon = 8; }
  341|       |						
  342|      3|#line 343 "src/stata/readstat_dta_parse_timestamp.c"
  343|       |						
  344|      3|						break; 
  345|      0|					}
  346|      6|					case 12:  {
  ------------------
  |  Branch (346:6): [True: 6, False: 2.28k]
  ------------------
  347|      6|						{
  348|      6|#line 38 "src/stata/readstat_dta_parse_timestamp.rl"
  349|      6|							timestamp->tm_mon = 9; }
  350|       |						
  351|      6|#line 352 "src/stata/readstat_dta_parse_timestamp.c"
  352|       |						
  353|      6|						break; 
  354|      0|					}
  355|      1|					case 13:  {
  ------------------
  |  Branch (355:6): [True: 1, False: 2.29k]
  ------------------
  356|      1|						{
  357|      1|#line 39 "src/stata/readstat_dta_parse_timestamp.rl"
  358|      1|							timestamp->tm_mon = 10; }
  359|       |						
  360|      1|#line 361 "src/stata/readstat_dta_parse_timestamp.c"
  361|       |						
  362|      1|						break; 
  363|      0|					}
  364|      1|					case 14:  {
  ------------------
  |  Branch (364:6): [True: 1, False: 2.29k]
  ------------------
  365|      1|						{
  366|      1|#line 40 "src/stata/readstat_dta_parse_timestamp.rl"
  367|      1|							timestamp->tm_mon = 11; }
  368|       |						
  369|      1|#line 370 "src/stata/readstat_dta_parse_timestamp.c"
  370|       |						
  371|      1|						break; 
  372|      0|					}
  373|     61|					case 15:  {
  ------------------
  |  Branch (373:6): [True: 61, False: 2.23k]
  ------------------
  374|     61|						{
  375|     61|#line 42 "src/stata/readstat_dta_parse_timestamp.rl"
  376|     61|							timestamp->tm_year = temp_val - 1900; }
  377|       |						
  378|     61|#line 379 "src/stata/readstat_dta_parse_timestamp.c"
  379|       |						
  380|     61|						break; 
  381|      0|					}
  382|     31|					case 16:  {
  ------------------
  |  Branch (382:6): [True: 31, False: 2.26k]
  ------------------
  383|     31|						{
  384|     31|#line 44 "src/stata/readstat_dta_parse_timestamp.rl"
  385|     31|							timestamp->tm_hour = temp_val; }
  386|       |						
  387|     31|#line 388 "src/stata/readstat_dta_parse_timestamp.c"
  388|       |						
  389|     31|						break; 
  390|      0|					}
  391|     28|					case 17:  {
  ------------------
  |  Branch (391:6): [True: 28, False: 2.26k]
  ------------------
  392|     28|						{
  393|     28|#line 46 "src/stata/readstat_dta_parse_timestamp.rl"
  394|     28|							timestamp->tm_min = temp_val; }
  395|       |						
  396|     28|#line 397 "src/stata/readstat_dta_parse_timestamp.c"
  397|       |						
  398|     28|						break; 
  399|      0|					}
  400|  2.29k|				}
  401|  2.29k|				_nacts -= 1;
  402|  2.29k|				_acts += 1;
  403|  2.29k|			}
  404|       |			
  405|  1.82k|		}
  406|       |		
  407|  3.17k|		if ( p == eof ) {
  ------------------
  |  Branch (407:8): [True: 81, False: 3.09k]
  ------------------
  408|     81|			if ( cs >= 44 )
  ------------------
  |  Branch (408:9): [True: 28, False: 53]
  ------------------
  409|     28|				goto _out;
  410|     81|		}
  411|  3.09k|		else {
  412|  3.09k|			if ( cs != 0 ) {
  ------------------
  |  Branch (412:9): [True: 2.27k, False: 815]
  ------------------
  413|  2.27k|				p += 1;
  414|  2.27k|				goto _resume;
  415|  2.27k|			}
  416|  3.09k|		}
  417|    896|		_out: {}
  418|    896|	}
  419|       |	
  420|      0|#line 52 "src/stata/readstat_dta_parse_timestamp.rl"
  421|       |	
  422|       |	
  423|    896|	if (cs < 
  ------------------
  |  Branch (423:6): [True: 868, False: 28]
  ------------------
  424|    896|#line 425 "src/stata/readstat_dta_parse_timestamp.c"
  425|    896|	44
  426|     28|#line 54 "src/stata/readstat_dta_parse_timestamp.rl"
  427|    868|	|| p != pe) {
  ------------------
  |  Branch (427:5): [True: 0, False: 28]
  ------------------
  428|    868|		char error_buf[1024];
  429|    868|		if (error_handler) {
  ------------------
  |  Branch (429:7): [True: 0, False: 868]
  ------------------
  430|      0|			snprintf(error_buf, sizeof(error_buf), "Invalid timestamp string (length=%d): %.*s", (int)len, (int)len, data);
  431|      0|			error_handler(error_buf, user_ctx);
  432|      0|		}
  433|    868|		retval = READSTAT_ERROR_BAD_TIMESTAMP_STRING;
  434|    868|	}
  435|       |	
  436|    896|	(void)dta_timestamp_parse_en_main;
  437|       |	
  438|    896|	return retval;
  439|  3.17k|}

readstat_parse_dta:
 1139|  4.39k|readstat_error_t readstat_parse_dta(readstat_parser_t *parser, const char *path, void *user_ctx) {
 1140|  4.39k|    readstat_error_t retval = READSTAT_OK;
 1141|  4.39k|    readstat_io_t *io = parser->io;
 1142|  4.39k|    int i;
 1143|  4.39k|    dta_ctx_t    *ctx;
 1144|  4.39k|    size_t file_size = 0;
 1145|       |
 1146|  4.39k|    ctx = dta_ctx_alloc(io);
 1147|       |
 1148|  4.39k|    if (io->open(path, io->io_ctx) == -1) {
  ------------------
  |  Branch (1148:9): [True: 0, False: 4.39k]
  ------------------
 1149|      0|        retval = READSTAT_ERROR_OPEN;
 1150|      0|        goto cleanup;
 1151|      0|    }
 1152|       |
 1153|  4.39k|    char magic[4];
 1154|  4.39k|    if (io->read(magic, 4, io->io_ctx) != 4) {
  ------------------
  |  Branch (1154:9): [True: 2, False: 4.39k]
  ------------------
 1155|      2|        retval = READSTAT_ERROR_READ;
 1156|      2|        goto cleanup;
 1157|      2|    }
 1158|       |
 1159|  4.39k|    file_size = io->seek(0, READSTAT_SEEK_END, io->io_ctx);
 1160|  4.39k|    if (file_size == -1) {
  ------------------
  |  Branch (1160:9): [True: 0, False: 4.39k]
  ------------------
 1161|      0|        if (ctx->handle.error) {
  ------------------
  |  Branch (1161:13): [True: 0, False: 0]
  ------------------
 1162|      0|            snprintf(ctx->error_buf, sizeof(ctx->error_buf), "Failed to seek to end of file");
 1163|      0|            ctx->handle.error(ctx->error_buf, ctx->user_ctx);
 1164|      0|        }
 1165|      0|        retval = READSTAT_ERROR_SEEK;
 1166|      0|        goto cleanup;
 1167|      0|    }
 1168|       |
 1169|  4.39k|    if (io->seek(0, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (1169:9): [True: 0, False: 4.39k]
  ------------------
 1170|      0|        if (ctx->handle.error) {
  ------------------
  |  Branch (1170:13): [True: 0, False: 0]
  ------------------
 1171|      0|            snprintf(ctx->error_buf, sizeof(ctx->error_buf), "Failed to seek to start of file");
 1172|      0|            ctx->handle.error(ctx->error_buf, ctx->user_ctx);
 1173|      0|        }
 1174|      0|        retval = READSTAT_ERROR_SEEK;
 1175|      0|        goto cleanup;
 1176|      0|    }
 1177|       |
 1178|  4.39k|    if (strncmp(magic, "<sta", 4) == 0) {
  ------------------
  |  Branch (1178:9): [True: 942, False: 3.45k]
  ------------------
 1179|    942|        dta_header64_t header;
 1180|    942|        if ((retval = dta_read_xmlish_header(ctx, &header)) != READSTAT_OK) {
  ------------------
  |  Branch (1180:13): [True: 434, False: 508]
  ------------------
 1181|    434|            goto cleanup;
 1182|    434|        }
 1183|    508|        retval = dta_ctx_init(ctx, header.nvar, header.nobs, header.byteorder, header.ds_format,
 1184|    508|                parser->input_encoding, parser->output_encoding);
 1185|  3.45k|    } else {
 1186|  3.45k|        dta_header_t header;
 1187|  3.45k|        if ((retval = dta_read_header(ctx, &header)) != READSTAT_OK) {
  ------------------
  |  Branch (1187:13): [True: 39, False: 3.41k]
  ------------------
 1188|     39|            goto cleanup;
 1189|     39|        }
 1190|  3.41k|        retval = dta_ctx_init(ctx, header.nvar, header.nobs, header.byteorder, header.ds_format,
 1191|  3.41k|                parser->input_encoding, parser->output_encoding);
 1192|  3.41k|    }
 1193|  3.92k|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (1193:9): [True: 115, False: 3.80k]
  ------------------
 1194|    115|        goto cleanup;
 1195|    115|    }
 1196|       |
 1197|  3.80k|    ctx->user_ctx = user_ctx;
 1198|  3.80k|    ctx->file_size = file_size;
 1199|  3.80k|    ctx->handle = parser->handlers;
 1200|  3.80k|    if (parser->row_offset > 0)
  ------------------
  |  Branch (1200:9): [True: 0, False: 3.80k]
  ------------------
 1201|      0|        ctx->row_offset = parser->row_offset;
 1202|  3.80k|    int64_t nobs_after_skipping = ctx->nobs - ctx->row_offset;
 1203|  3.80k|    if (nobs_after_skipping < 0) {
  ------------------
  |  Branch (1203:9): [True: 182, False: 3.62k]
  ------------------
 1204|    182|        nobs_after_skipping = 0;
 1205|    182|        ctx->row_offset = ctx->nobs;
 1206|    182|    }
 1207|  3.80k|    ctx->row_limit = nobs_after_skipping;
 1208|  3.80k|    if (parser->row_limit > 0 && parser->row_limit < nobs_after_skipping)
  ------------------
  |  Branch (1208:9): [True: 0, False: 3.80k]
  |  Branch (1208:34): [True: 0, False: 0]
  ------------------
 1209|      0|        ctx->row_limit = parser->row_limit;
 1210|       |
 1211|  3.80k|    retval = dta_update_progress(ctx);
 1212|  3.80k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (1212:9): [True: 0, False: 3.80k]
  ------------------
 1213|      0|        goto cleanup;
 1214|       |    
 1215|  3.80k|    if ((retval = dta_read_label_and_timestamp(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1215:9): [True: 570, False: 3.23k]
  ------------------
 1216|    570|        goto cleanup;
 1217|       |
 1218|  3.23k|    if ((retval = dta_read_tag(ctx, "</header>")) != READSTAT_OK) {
  ------------------
  |  Branch (1218:9): [True: 1, False: 3.23k]
  ------------------
 1219|      1|        goto cleanup;
 1220|      1|    }
 1221|       |
 1222|  3.23k|    if (ctx->handle.metadata) {
  ------------------
  |  Branch (1222:9): [True: 3.23k, False: 0]
  ------------------
 1223|  3.23k|        readstat_metadata_t metadata = {
 1224|  3.23k|            .row_count = ctx->row_limit,
 1225|  3.23k|            .var_count = ctx->nvar,
 1226|  3.23k|            .file_label = ctx->data_label,
 1227|  3.23k|            .creation_time = ctx->timestamp,
 1228|  3.23k|            .modified_time = ctx->timestamp,
 1229|  3.23k|            .file_format_version = ctx->ds_format,
 1230|  3.23k|            .is64bit = ctx->ds_format >= 118,
 1231|  3.23k|            .endianness = ctx->endianness
 1232|  3.23k|        };
 1233|  3.23k|        if (ctx->handle.metadata(&metadata, user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (1233:13): [True: 0, False: 3.23k]
  ------------------
 1234|      0|            retval = READSTAT_ERROR_USER_ABORT;
 1235|      0|            goto cleanup;
 1236|      0|        }
 1237|  3.23k|    }
 1238|       |
 1239|  3.23k|    if ((retval = dta_read_map(ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (1239:9): [True: 4, False: 3.23k]
  ------------------
 1240|      4|        retval = READSTAT_ERROR_READ;
 1241|      4|        goto cleanup;
 1242|      4|    }
 1243|       |
 1244|  3.23k|    if ((retval = dta_read_descriptors(ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (1244:9): [True: 171, False: 3.06k]
  ------------------
 1245|    171|        goto cleanup;
 1246|    171|    }
 1247|       |
 1248|  60.1k|    for (i=0; i<ctx->nvar; i++) {
  ------------------
  |  Branch (1248:15): [True: 57.1k, False: 3.04k]
  ------------------
 1249|  57.1k|        size_t      max_len;
 1250|  57.1k|        if ((retval = dta_type_info(ctx->typlist[i], ctx, &max_len, NULL)) != READSTAT_OK)
  ------------------
  |  Branch (1250:13): [True: 15, False: 57.1k]
  ------------------
 1251|     15|            goto cleanup;
 1252|       |
 1253|  57.1k|        ctx->record_len += max_len;
 1254|  57.1k|    }
 1255|       |
 1256|  3.04k|    if ((ctx->nvar > 0 || ctx->nobs > 0) && ctx->record_len == 0) {
  ------------------
  |  Branch (1256:10): [True: 2.19k, False: 857]
  |  Branch (1256:27): [True: 33, False: 824]
  |  Branch (1256:45): [True: 36, False: 2.18k]
  ------------------
 1257|     36|        retval = READSTAT_ERROR_PARSE;
 1258|     36|        goto cleanup;
 1259|     36|    }
 1260|       |
 1261|  3.01k|    if ((retval = dta_handle_variables(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1261:9): [True: 0, False: 3.01k]
  ------------------
 1262|      0|        goto cleanup;
 1263|       |
 1264|  3.01k|    if ((retval = dta_read_expansion_fields(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1264:9): [True: 656, False: 2.35k]
  ------------------
 1265|    656|        goto cleanup;
 1266|       |
 1267|  2.35k|    if (!ctx->file_is_xmlish) {
  ------------------
  |  Branch (1267:9): [True: 1.31k, False: 1.03k]
  ------------------
 1268|  1.31k|        ctx->data_offset = io->seek(0, READSTAT_SEEK_CUR, io->io_ctx);
 1269|  1.31k|        if (ctx->data_offset == -1) {
  ------------------
  |  Branch (1269:13): [True: 0, False: 1.31k]
  ------------------
 1270|      0|            retval = READSTAT_ERROR_SEEK;
 1271|      0|            goto cleanup;
 1272|      0|        }
 1273|  1.31k|        ctx->value_labels_offset = ctx->data_offset + ctx->record_len * ctx->nobs;
 1274|  1.31k|    }
 1275|       |
 1276|  2.35k|    if ((retval = dta_read_strls(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1276:9): [True: 421, False: 1.93k]
  ------------------
 1277|    421|        goto cleanup;
 1278|       |
 1279|  1.93k|    if ((retval = dta_read_data(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1279:9): [True: 1.13k, False: 801]
  ------------------
 1280|  1.13k|        goto cleanup;
 1281|       |
 1282|    801|    if ((retval = dta_handle_value_labels(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1282:9): [True: 307, False: 494]
  ------------------
 1283|    307|        goto cleanup;
 1284|       |
 1285|  4.39k|cleanup:
 1286|  4.39k|    io->close(io->io_ctx);
 1287|  4.39k|    if (ctx)
  ------------------
  |  Branch (1287:9): [True: 4.39k, False: 0]
  ------------------
 1288|  4.39k|        dta_ctx_free(ctx);
 1289|       |
 1290|  4.39k|    return retval;
 1291|    801|}
readstat_dta_read.c:dta_read_xmlish_header:
  755|    942|static readstat_error_t dta_read_xmlish_header(dta_ctx_t *ctx, dta_header64_t *header) {
  756|    942|    readstat_error_t retval = READSTAT_OK;
  757|       |    
  758|    942|    if ((retval = dta_read_tag(ctx, "<stata_dta>")) != READSTAT_OK) {
  ------------------
  |  Branch (758:9): [True: 68, False: 874]
  ------------------
  759|     68|        goto cleanup;
  760|     68|    }
  761|    874|    if ((retval = dta_read_tag(ctx, "<header>")) != READSTAT_OK) {
  ------------------
  |  Branch (761:9): [True: 77, False: 797]
  ------------------
  762|     77|        goto cleanup;
  763|     77|    }
  764|       |
  765|    797|    char ds_format[3];
  766|    797|    if ((retval = dta_read_chunk(ctx, "<release>", ds_format,
  ------------------
  |  Branch (766:9): [True: 176, False: 621]
  ------------------
  767|    797|                    sizeof(ds_format), "</release>")) != READSTAT_OK) {
  768|    176|        goto cleanup;
  769|    176|    }
  770|       |
  771|    621|    header->ds_format = 100 * (ds_format[0] - '0') + 10 * (ds_format[1] - '0') + (ds_format[2] - '0');
  772|       |
  773|    621|    char byteorder[3];
  774|    621|    int byteswap = 0;
  775|    621|    if ((retval = dta_read_chunk(ctx, "<byteorder>", byteorder, 
  ------------------
  |  Branch (775:9): [True: 39, False: 582]
  ------------------
  776|    621|                    sizeof(byteorder), "</byteorder>")) != READSTAT_OK) {
  777|     39|        goto cleanup;
  778|     39|    }
  779|    582|    if (strncmp(byteorder, "MSF", 3) == 0) {
  ------------------
  |  Branch (779:9): [True: 87, False: 495]
  ------------------
  780|     87|        header->byteorder = DTA_HILO;
  ------------------
  |  |  129|     87|#define DTA_HILO  0x01
  ------------------
  781|    495|    } else if (strncmp(byteorder, "LSF", 3) == 0) {
  ------------------
  |  Branch (781:16): [True: 452, False: 43]
  ------------------
  782|    452|        header->byteorder = DTA_LOHI;
  ------------------
  |  |  130|    452|#define DTA_LOHI  0x02
  ------------------
  783|    452|    } else {
  784|     43|        retval = READSTAT_ERROR_PARSE;
  785|     43|        goto cleanup;
  786|     43|    }
  787|    539|    byteswap = (header->byteorder == DTA_LOHI) ^ machine_is_little_endian();
  ------------------
  |  |  130|    539|#define DTA_LOHI  0x02
  ------------------
  788|       |
  789|    539|    if (header->ds_format >= 119) {
  ------------------
  |  Branch (789:9): [True: 110, False: 429]
  ------------------
  790|    110|        uint32_t nvar;
  791|    110|        if ((retval = dta_read_chunk(ctx, "<K>", &nvar, 
  ------------------
  |  Branch (791:13): [True: 6, False: 104]
  ------------------
  792|    110|                        sizeof(uint32_t), "</K>")) != READSTAT_OK) {
  793|      6|            goto cleanup;
  794|      6|        }
  795|    104|        header->nvar = byteswap ? byteswap4(nvar) : nvar;
  ------------------
  |  Branch (795:24): [True: 35, False: 69]
  ------------------
  796|    429|    } else {
  797|    429|        uint16_t nvar;
  798|    429|        if ((retval = dta_read_chunk(ctx, "<K>", &nvar, 
  ------------------
  |  Branch (798:13): [True: 12, False: 417]
  ------------------
  799|    429|                        sizeof(uint16_t), "</K>")) != READSTAT_OK) {
  800|     12|            goto cleanup;
  801|     12|        }
  802|    417|        header->nvar = byteswap ? byteswap2(nvar) : nvar;
  ------------------
  |  Branch (802:24): [True: 47, False: 370]
  ------------------
  803|    417|    }
  804|       |
  805|    521|    if (header->ds_format >= 118) {
  ------------------
  |  Branch (805:9): [True: 411, False: 110]
  ------------------
  806|    411|        uint64_t nobs;
  807|    411|        if ((retval = dta_read_chunk(ctx, "<N>", &nobs, 
  ------------------
  |  Branch (807:13): [True: 5, False: 406]
  ------------------
  808|    411|                        sizeof(uint64_t), "</N>")) != READSTAT_OK) {
  809|      5|            goto cleanup;
  810|      5|        }
  811|    406|        header->nobs = byteswap ? byteswap8(nobs) : nobs;
  ------------------
  |  Branch (811:24): [True: 75, False: 331]
  ------------------
  812|    406|    } else {
  813|    110|        uint32_t nobs;
  814|    110|        if ((retval = dta_read_chunk(ctx, "<N>", &nobs, 
  ------------------
  |  Branch (814:13): [True: 8, False: 102]
  ------------------
  815|    110|                        sizeof(uint32_t), "</N>")) != READSTAT_OK) {
  816|      8|            goto cleanup;
  817|      8|        }
  818|    102|        header->nobs = byteswap ? byteswap4(nobs) : nobs;
  ------------------
  |  Branch (818:24): [True: 2, False: 100]
  ------------------
  819|    102|    }
  820|       |
  821|    942|cleanup:
  822|    942|    return retval;
  823|    521|}
readstat_dta_read.c:dta_read_chunk:
   92|  22.6k|        const char *end_tag) {
   93|  22.6k|    char *dst_buffer = (char *)dst;
   94|  22.6k|    readstat_io_t *io = ctx->io;
   95|  22.6k|    readstat_error_t retval = READSTAT_OK;
   96|       |
   97|  22.6k|    if ((retval = dta_read_tag(ctx, start_tag)) != READSTAT_OK)
  ------------------
  |  Branch (97:9): [True: 204, False: 22.4k]
  ------------------
   98|    204|        goto cleanup;
   99|       |
  100|  22.4k|    if (io->read(dst_buffer, dst_len, io->io_ctx) != dst_len) {
  ------------------
  |  Branch (100:9): [True: 62, False: 22.4k]
  ------------------
  101|     62|        retval = READSTAT_ERROR_READ;
  102|     62|        goto cleanup;
  103|     62|    }
  104|       |
  105|  22.4k|    if ((retval = dta_read_tag(ctx, end_tag)) != READSTAT_OK)
  ------------------
  |  Branch (105:9): [True: 155, False: 22.2k]
  ------------------
  106|    155|        goto cleanup;
  107|       |
  108|  22.6k|cleanup:
  109|       |
  110|  22.6k|    return retval;
  111|  22.4k|}
readstat_dta_read.c:dta_read_header:
  738|  3.45k|static readstat_error_t dta_read_header(dta_ctx_t *ctx, dta_header_t *header) {
  739|  3.45k|    readstat_error_t retval = READSTAT_OK;
  740|  3.45k|    readstat_io_t *io = ctx->io;
  741|  3.45k|    int bswap = 0;
  742|       |
  743|  3.45k|    if (io->read(header, sizeof(dta_header_t), io->io_ctx) != sizeof(dta_header_t)) {
  ------------------
  |  Branch (743:9): [True: 39, False: 3.41k]
  ------------------
  744|     39|        retval = READSTAT_ERROR_READ;
  745|     39|        goto cleanup;
  746|     39|    }
  747|  3.41k|    bswap = (header->byteorder == DTA_LOHI) ^ machine_is_little_endian();
  ------------------
  |  |  130|  3.41k|#define DTA_LOHI  0x02
  ------------------
  748|  3.41k|    header->nvar = bswap ? byteswap2(header->nvar) : header->nvar;
  ------------------
  |  Branch (748:20): [True: 2.51k, False: 905]
  ------------------
  749|  3.41k|    header->nobs = bswap ? byteswap4(header->nobs) : header->nobs;
  ------------------
  |  Branch (749:20): [True: 2.51k, False: 905]
  ------------------
  750|       |
  751|  3.45k|cleanup:
  752|  3.45k|    return retval;
  753|  3.41k|}
readstat_dta_read.c:dta_update_progress:
   29|  98.5k|static readstat_error_t dta_update_progress(dta_ctx_t *ctx) {
   30|  98.5k|    double progress = 0.0;
   31|  98.5k|    if (ctx->row_limit > 0)
  ------------------
  |  Branch (31:9): [True: 96.6k, False: 1.81k]
  ------------------
   32|  96.6k|        progress = 1.0 * ctx->current_row / ctx->row_limit;
   33|  98.5k|    if (ctx->handle.progress && ctx->handle.progress(progress, ctx->user_ctx) != READSTAT_HANDLER_OK)
  ------------------
  |  Branch (33:9): [True: 0, False: 98.5k]
  |  Branch (33:33): [True: 0, False: 0]
  ------------------
   34|      0|        return READSTAT_ERROR_USER_ABORT;
   35|  98.5k|    return READSTAT_OK;
   36|  98.5k|}
readstat_dta_read.c:dta_read_label_and_timestamp:
  825|  3.80k|static readstat_error_t dta_read_label_and_timestamp(dta_ctx_t *ctx) {
  826|  3.80k|    readstat_io_t *io = ctx->io;
  827|  3.80k|    readstat_error_t retval = READSTAT_OK;
  828|  3.80k|    char *data_label_buffer = NULL;
  829|  3.80k|    char *timestamp_buffer = NULL;
  830|  3.80k|    uint16_t label_len = 0;
  831|  3.80k|    unsigned char timestamp_len = 0;
  832|  3.80k|    char last_data_label_char = 0;
  833|  3.80k|    struct tm timestamp = { .tm_isdst = -1 };
  834|       |
  835|  3.80k|    if (ctx->file_is_xmlish) {
  ------------------
  |  Branch (835:9): [True: 2.10k, False: 1.70k]
  ------------------
  836|  2.10k|        if ((retval = dta_read_tag(ctx, "<label>")) != READSTAT_OK) {
  ------------------
  |  Branch (836:13): [True: 189, False: 1.91k]
  ------------------
  837|    189|            goto cleanup;
  838|    189|        }
  839|       |        
  840|  1.91k|        if (ctx->data_label_len_len == 2) {
  ------------------
  |  Branch (840:13): [True: 255, False: 1.66k]
  ------------------
  841|    255|            if (io->read(&label_len, sizeof(uint16_t), io->io_ctx) != sizeof(uint16_t)) {
  ------------------
  |  Branch (841:17): [True: 2, False: 253]
  ------------------
  842|      2|                retval = READSTAT_ERROR_READ;
  843|      2|                goto cleanup;
  844|      2|            }
  845|    253|            label_len = ctx->bswap ? byteswap2(label_len) : label_len;
  ------------------
  |  Branch (845:25): [True: 40, False: 213]
  ------------------
  846|  1.66k|        } else if (ctx->data_label_len_len == 1) {
  ------------------
  |  Branch (846:20): [True: 1.66k, False: 0]
  ------------------
  847|  1.66k|            unsigned char label_len_char;
  848|  1.66k|            if (io->read(&label_len_char, sizeof(unsigned char), io->io_ctx) != sizeof(unsigned char)) {
  ------------------
  |  Branch (848:17): [True: 1, False: 1.66k]
  ------------------
  849|      1|                retval = READSTAT_ERROR_READ;
  850|      1|                goto cleanup;
  851|      1|            }
  852|  1.66k|            label_len = label_len_char;
  853|  1.66k|        }
  854|  1.91k|    } else {
  855|  1.70k|        label_len = ctx->data_label_len;
  856|  1.70k|    }
  857|       |
  858|  3.61k|    if ((data_label_buffer = readstat_malloc(label_len+1)) == NULL) {
  ------------------
  |  Branch (858:9): [True: 0, False: 3.61k]
  ------------------
  859|      0|        retval = READSTAT_ERROR_MALLOC;
  860|      0|        goto cleanup;
  861|      0|    }
  862|       |
  863|  3.61k|    if (io->read(data_label_buffer, label_len, io->io_ctx) != label_len) {
  ------------------
  |  Branch (863:9): [True: 52, False: 3.56k]
  ------------------
  864|     52|        retval = READSTAT_ERROR_READ;
  865|     52|        goto cleanup;
  866|     52|    }
  867|       |
  868|  3.56k|    if (!ctx->file_is_xmlish) {
  ------------------
  |  Branch (868:9): [True: 1.67k, False: 1.89k]
  ------------------
  869|  1.67k|        last_data_label_char = data_label_buffer[label_len-1];
  870|  1.67k|        data_label_buffer[label_len] = '\0';
  871|  1.67k|        label_len = strlen(data_label_buffer);
  872|  1.67k|    }
  873|       |
  874|  3.56k|    if ((ctx->data_label = readstat_malloc(4*label_len+1)) == NULL) {
  ------------------
  |  Branch (874:9): [True: 0, False: 3.56k]
  ------------------
  875|      0|        retval = READSTAT_ERROR_MALLOC;
  876|      0|        goto cleanup;
  877|      0|    }
  878|       |
  879|  3.56k|    if ((retval = readstat_convert(ctx->data_label, 4*label_len+1,
  ------------------
  |  Branch (879:9): [True: 4, False: 3.56k]
  ------------------
  880|  3.56k|                    data_label_buffer, label_len, ctx->converter)) != READSTAT_OK)
  881|      4|        goto cleanup;
  882|       |
  883|  3.56k|    if (ctx->file_is_xmlish) {
  ------------------
  |  Branch (883:9): [True: 1.89k, False: 1.67k]
  ------------------
  884|  1.89k|        if ((retval = dta_read_tag(ctx, "</label>")) != READSTAT_OK) {
  ------------------
  |  Branch (884:13): [True: 126, False: 1.76k]
  ------------------
  885|    126|            goto cleanup;
  886|    126|        }
  887|       |        
  888|  1.76k|        if ((retval = dta_read_tag(ctx, "<timestamp>")) != READSTAT_OK) {
  ------------------
  |  Branch (888:13): [True: 98, False: 1.66k]
  ------------------
  889|     98|            goto cleanup;
  890|     98|        }
  891|       |        
  892|  1.66k|        if (io->read(&timestamp_len, 1, io->io_ctx) != 1) {
  ------------------
  |  Branch (892:13): [True: 1, False: 1.66k]
  ------------------
  893|      1|            retval = READSTAT_ERROR_READ;
  894|      1|            goto cleanup;
  895|      1|        }
  896|  1.67k|    } else {
  897|  1.67k|        timestamp_len = ctx->timestamp_len;
  898|  1.67k|    }
  899|       |
  900|  3.33k|    if (timestamp_len) {
  ------------------
  |  Branch (900:9): [True: 1.30k, False: 2.03k]
  ------------------
  901|  1.30k|        timestamp_buffer = readstat_malloc(timestamp_len);
  902|       |        
  903|  1.30k|        if (io->read(timestamp_buffer, timestamp_len, io->io_ctx) != timestamp_len) {
  ------------------
  |  Branch (903:13): [True: 10, False: 1.29k]
  ------------------
  904|     10|            retval = READSTAT_ERROR_READ;
  905|     10|            goto cleanup;
  906|     10|        }
  907|       |
  908|  1.29k|        if (!ctx->file_is_xmlish)
  ------------------
  |  Branch (908:13): [True: 907, False: 384]
  ------------------
  909|    907|            timestamp_len--;
  910|       |
  911|  1.29k|        if (timestamp_buffer[0]) {
  ------------------
  |  Branch (911:13): [True: 896, False: 395]
  ------------------
  912|    896|            if (timestamp_buffer[timestamp_len-1] == '\0' && last_data_label_char != '\0') {
  ------------------
  |  Branch (912:17): [True: 198, False: 698]
  |  Branch (912:62): [True: 126, False: 72]
  ------------------
  913|       |                /* Stupid hack for miswritten files with off-by-one timestamp, DTA 114 era? */
  914|    126|                memmove(timestamp_buffer+1, timestamp_buffer, timestamp_len-1);
  915|    126|                timestamp_buffer[0] = last_data_label_char;
  916|    126|            }
  917|    896|            if (dta_parse_timestamp(timestamp_buffer, timestamp_len,
  ------------------
  |  Branch (917:17): [True: 28, False: 868]
  ------------------
  918|    896|                        &timestamp, ctx->handle.error, ctx->user_ctx) == READSTAT_OK) {
  919|     28|                ctx->timestamp = mktime(&timestamp);
  920|     28|            }
  921|    896|        }
  922|  1.29k|    }
  923|       |
  924|  3.32k|    if ((retval = dta_read_tag(ctx, "</timestamp>")) != READSTAT_OK) {
  ------------------
  |  Branch (924:9): [True: 87, False: 3.23k]
  ------------------
  925|     87|        goto cleanup;
  926|     87|    }
  927|       |
  928|  3.80k|cleanup:
  929|  3.80k|    if (data_label_buffer)
  ------------------
  |  Branch (929:9): [True: 3.61k, False: 192]
  ------------------
  930|  3.61k|        free(data_label_buffer);
  931|  3.80k|    if (timestamp_buffer)
  ------------------
  |  Branch (931:9): [True: 1.30k, False: 2.50k]
  ------------------
  932|  1.30k|        free(timestamp_buffer);
  933|       |
  934|  3.80k|    return retval;
  935|  3.32k|}
readstat_dta_read.c:dta_read_tag:
  303|  78.9k|static readstat_error_t dta_read_tag(dta_ctx_t *ctx, const char *tag) {
  304|  78.9k|    readstat_error_t retval = READSTAT_OK;
  305|  78.9k|    if (ctx->initialized && !ctx->file_is_xmlish)
  ------------------
  |  Branch (305:9): [True: 72.3k, False: 6.63k]
  |  Branch (305:29): [True: 34.7k, False: 37.5k]
  ------------------
  306|  34.7k|        return retval;
  307|       |
  308|  44.2k|    char buffer[256];
  309|  44.2k|    size_t len = strlen(tag);
  310|  44.2k|    if (ctx->io->read(buffer, len, ctx->io->io_ctx) != len) {
  ------------------
  |  Branch (310:9): [True: 465, False: 43.7k]
  ------------------
  311|    465|        retval = READSTAT_ERROR_READ;
  312|    465|        goto cleanup;
  313|    465|    }
  314|  43.7k|    if (strncmp(buffer, tag, len) != 0) {
  ------------------
  |  Branch (314:9): [True: 1.37k, False: 42.3k]
  ------------------
  315|  1.37k|        retval = READSTAT_ERROR_PARSE;
  316|  1.37k|        goto cleanup;
  317|  1.37k|    }
  318|  44.2k|cleanup:
  319|  44.2k|    return retval;
  320|  43.7k|}
readstat_dta_read.c:dta_read_map:
  113|  3.23k|static readstat_error_t dta_read_map(dta_ctx_t *ctx) {
  114|  3.23k|    if (!ctx->file_is_xmlish)
  ------------------
  |  Branch (114:9): [True: 1.66k, False: 1.56k]
  ------------------
  115|  1.66k|        return READSTAT_OK;
  116|       |
  117|  1.56k|    readstat_error_t retval = READSTAT_OK;
  118|  1.56k|    uint64_t map_buffer[14];
  119|       |
  120|  1.56k|    if ((retval = dta_read_chunk(ctx, "<map>", map_buffer, 
  ------------------
  |  Branch (120:9): [True: 4, False: 1.56k]
  ------------------
  121|  1.56k|                    sizeof(map_buffer), "</map>")) != READSTAT_OK) {
  122|      4|        goto cleanup;
  123|      4|    }
  124|       |
  125|  1.56k|    ctx->data_offset = ctx->bswap ? byteswap8(map_buffer[9]) : map_buffer[9];
  ------------------
  |  Branch (125:24): [True: 1.25k, False: 315]
  ------------------
  126|  1.56k|    ctx->strls_offset = ctx->bswap ? byteswap8(map_buffer[10]) : map_buffer[10];
  ------------------
  |  Branch (126:25): [True: 1.25k, False: 315]
  ------------------
  127|  1.56k|    ctx->value_labels_offset = ctx->bswap ? byteswap8(map_buffer[11]) : map_buffer[11];
  ------------------
  |  Branch (127:32): [True: 1.25k, False: 315]
  ------------------
  128|       |
  129|  1.56k|cleanup:
  130|  1.56k|    return retval;
  131|  1.56k|}
readstat_dta_read.c:dta_read_descriptors:
  133|  3.23k|static readstat_error_t dta_read_descriptors(dta_ctx_t *ctx) {
  134|  3.23k|    readstat_error_t retval = READSTAT_OK;
  135|  3.23k|    size_t buffer_len = ctx->nvar * ctx->typlist_entry_len;
  136|  3.23k|    unsigned char *buffer = NULL;
  137|  3.23k|    int i;
  138|       |
  139|  3.23k|    if (ctx->nvar && (buffer = readstat_malloc(buffer_len)) == NULL) {
  ------------------
  |  Branch (139:9): [True: 2.34k, False: 884]
  |  Branch (139:22): [True: 0, False: 2.34k]
  ------------------
  140|      0|        retval = READSTAT_ERROR_MALLOC;
  141|      0|        goto cleanup;
  142|      0|    }
  143|       |
  144|  3.23k|    if ((retval = dta_read_chunk(ctx, "<variable_types>", buffer, 
  ------------------
  |  Branch (144:9): [True: 115, False: 3.11k]
  ------------------
  145|  3.23k|                    buffer_len, "</variable_types>")) != READSTAT_OK)
  146|    115|        goto cleanup;
  147|       |
  148|  3.11k|    if (ctx->typlist_entry_len == 1) {
  ------------------
  |  Branch (148:9): [True: 1.64k, False: 1.47k]
  ------------------
  149|   247k|        for (i=0; i<ctx->nvar; i++) {
  ------------------
  |  Branch (149:19): [True: 245k, False: 1.64k]
  ------------------
  150|   245k|            ctx->typlist[i] = buffer[i];
  151|   245k|        }
  152|  1.64k|    } else if (ctx->typlist_entry_len == 2) {
  ------------------
  |  Branch (152:16): [True: 1.47k, False: 0]
  ------------------
  153|  1.47k|        memcpy(ctx->typlist, buffer, buffer_len);
  154|  1.47k|        if (ctx->bswap) {
  ------------------
  |  Branch (154:13): [True: 1.17k, False: 307]
  ------------------
  155|  68.4k|            for (i=0; i<ctx->nvar; i++) {
  ------------------
  |  Branch (155:23): [True: 67.2k, False: 1.17k]
  ------------------
  156|  67.2k|                ctx->typlist[i] = byteswap2(ctx->typlist[i]);
  157|  67.2k|            }
  158|  1.17k|        }
  159|  1.47k|    }
  160|       |
  161|  3.11k|    if ((retval = dta_read_chunk(ctx, "<varnames>", ctx->varlist, 
  ------------------
  |  Branch (161:9): [True: 37, False: 3.08k]
  ------------------
  162|  3.11k|                    ctx->varlist_len, "</varnames>")) != READSTAT_OK)
  163|     37|        goto cleanup;
  164|       |
  165|  3.08k|    if ((retval = dta_read_chunk(ctx, "<sortlist>", ctx->srtlist, 
  ------------------
  |  Branch (165:9): [True: 12, False: 3.06k]
  ------------------
  166|  3.08k|                    ctx->srtlist_len, "</sortlist>")) != READSTAT_OK)
  167|     12|        goto cleanup;
  168|       |
  169|  3.06k|    if ((retval = dta_read_chunk(ctx, "<formats>", ctx->fmtlist, 
  ------------------
  |  Branch (169:9): [True: 3, False: 3.06k]
  ------------------
  170|  3.06k|                    ctx->fmtlist_len, "</formats>")) != READSTAT_OK)
  171|      3|        goto cleanup;
  172|       |
  173|  3.06k|    if ((retval = dta_read_chunk(ctx, "<value_label_names>", ctx->lbllist, 
  ------------------
  |  Branch (173:9): [True: 4, False: 3.06k]
  ------------------
  174|  3.06k|                    ctx->lbllist_len, "</value_label_names>")) != READSTAT_OK)
  175|      4|        goto cleanup;
  176|       |
  177|  3.06k|    if ((retval = dta_read_chunk(ctx, "<variable_labels>", ctx->variable_labels, 
  ------------------
  |  Branch (177:9): [True: 0, False: 3.06k]
  ------------------
  178|  3.06k|                    ctx->variable_labels_len, "</variable_labels>")) != READSTAT_OK)
  179|      0|        goto cleanup;
  180|       |
  181|  3.23k|cleanup:
  182|  3.23k|    if (buffer)
  ------------------
  |  Branch (182:9): [True: 2.34k, False: 884]
  ------------------
  183|  2.34k|        free(buffer);
  184|       |
  185|  3.23k|    return retval;
  186|  3.06k|}
readstat_dta_read.c:dta_handle_variables:
  937|  3.01k|static readstat_error_t dta_handle_variables(dta_ctx_t *ctx) {
  938|  3.01k|    if (!ctx->handle.variable)
  ------------------
  |  Branch (938:9): [True: 0, False: 3.01k]
  ------------------
  939|      0|        return READSTAT_OK;
  940|       |
  941|  3.01k|    readstat_error_t retval = READSTAT_OK;
  942|  3.01k|    int i;
  943|  3.01k|    int index_after_skipping = 0;
  944|       |
  945|  60.1k|    for (i=0; i<ctx->nvar; i++) {
  ------------------
  |  Branch (945:15): [True: 57.0k, False: 3.01k]
  ------------------
  946|  57.0k|        size_t      max_len;
  947|  57.0k|        readstat_type_t type;
  948|  57.0k|        retval = dta_type_info(ctx->typlist[i], ctx, &max_len, &type);
  949|  57.0k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (949:13): [True: 0, False: 57.0k]
  ------------------
  950|      0|            goto cleanup;
  951|       |
  952|  57.0k|        if (type == READSTAT_TYPE_STRING)
  ------------------
  |  Branch (952:13): [True: 41.9k, False: 15.0k]
  ------------------
  953|  41.9k|            max_len++; /* might append NULL */
  954|  57.0k|        if (type == READSTAT_TYPE_STRING_REF) {
  ------------------
  |  Branch (954:13): [True: 191, False: 56.9k]
  ------------------
  955|    191|            type = READSTAT_TYPE_STRING;
  956|    191|            max_len = 0;
  957|    191|        }
  958|       |
  959|  57.0k|        ctx->variables[i] = dta_init_variable(ctx, i, index_after_skipping, type, max_len, &retval);
  960|  57.0k|        if (ctx->variables[i] == NULL)
  ------------------
  |  Branch (960:13): [True: 0, False: 57.0k]
  ------------------
  961|      0|            goto cleanup;
  962|       |
  963|  57.0k|        const char *value_labels = NULL;
  964|       |
  965|  57.0k|        if (ctx->lbllist[ctx->lbllist_entry_len*i])
  ------------------
  |  Branch (965:13): [True: 21.2k, False: 35.8k]
  ------------------
  966|  21.2k|            value_labels = &ctx->lbllist[ctx->lbllist_entry_len*i];
  967|       |
  968|  57.0k|        int cb_retval = ctx->handle.variable(i, ctx->variables[i], value_labels, ctx->user_ctx);
  969|       |
  970|  57.0k|        if (cb_retval == READSTAT_HANDLER_ABORT) {
  ------------------
  |  Branch (970:13): [True: 0, False: 57.0k]
  ------------------
  971|      0|            retval = READSTAT_ERROR_USER_ABORT;
  972|      0|            goto cleanup;
  973|      0|        }
  974|       |
  975|  57.0k|        if (cb_retval == READSTAT_HANDLER_SKIP_VARIABLE) {
  ------------------
  |  Branch (975:13): [True: 0, False: 57.0k]
  ------------------
  976|      0|            ctx->variables[i]->skip = 1;
  977|  57.0k|        } else {
  978|  57.0k|            index_after_skipping++;
  979|  57.0k|        }
  980|  57.0k|    }
  981|  3.01k|cleanup:
  982|  3.01k|    return retval;
  983|  3.01k|}
readstat_dta_read.c:dta_init_variable:
   39|  57.0k|        readstat_type_t type, size_t max_len, readstat_error_t *out_retval) {
   40|  57.0k|    readstat_variable_t *variable = calloc(1, sizeof(readstat_variable_t));
   41|       |
   42|  57.0k|    if (variable == NULL) {
  ------------------
  |  Branch (42:9): [True: 0, False: 57.0k]
  ------------------
   43|      0|        if (out_retval) *out_retval = READSTAT_ERROR_MALLOC;
  ------------------
  |  Branch (43:13): [True: 0, False: 0]
  ------------------
   44|      0|        return NULL;
   45|      0|    }
   46|       |
   47|  57.0k|    variable->type = type;
   48|  57.0k|    variable->index = i;
   49|  57.0k|    variable->index_after_skipping = index_after_skipping;
   50|  57.0k|    variable->storage_width = max_len;
   51|       |
   52|  57.0k|    readstat_convert(variable->name, sizeof(variable->name), 
   53|  57.0k|            &ctx->varlist[ctx->variable_name_len*i],
   54|  57.0k|            strnlen(&ctx->varlist[ctx->variable_name_len*i], ctx->variable_name_len),
   55|  57.0k|            ctx->converter);
   56|       |
   57|  57.0k|    if (ctx->variable_labels[ctx->variable_labels_entry_len*i]) {
  ------------------
  |  Branch (57:9): [True: 20.2k, False: 36.8k]
  ------------------
   58|  20.2k|        readstat_convert(variable->label, sizeof(variable->label),
   59|  20.2k|                &ctx->variable_labels[ctx->variable_labels_entry_len*i],
   60|  20.2k|                strnlen(&ctx->variable_labels[ctx->variable_labels_entry_len*i], ctx->variable_labels_entry_len),
   61|  20.2k|                ctx->converter);
   62|  20.2k|    }
   63|       |
   64|  57.0k|    if (ctx->fmtlist[ctx->fmtlist_entry_len*i]) {
  ------------------
  |  Branch (64:9): [True: 21.3k, False: 35.7k]
  ------------------
   65|  21.3k|        readstat_convert(variable->format, sizeof(variable->format),
   66|  21.3k|                &ctx->fmtlist[ctx->fmtlist_entry_len*i],
   67|  21.3k|                strnlen(&ctx->fmtlist[ctx->fmtlist_entry_len*i], ctx->fmtlist_entry_len),
   68|  21.3k|                ctx->converter);
   69|  21.3k|        if (variable->format[0] == '%') {
  ------------------
  |  Branch (69:13): [True: 3.98k, False: 17.3k]
  ------------------
   70|  3.98k|            if (variable->format[1] == '-') {
  ------------------
  |  Branch (70:17): [True: 990, False: 2.99k]
  ------------------
   71|    990|                variable->alignment = READSTAT_ALIGNMENT_LEFT;
   72|  2.99k|            } else if (variable->format[1] == '~') {
  ------------------
  |  Branch (72:24): [True: 284, False: 2.71k]
  ------------------
   73|    284|                variable->alignment = READSTAT_ALIGNMENT_CENTER;
   74|  2.71k|            } else {
   75|  2.71k|                variable->alignment = READSTAT_ALIGNMENT_RIGHT;
   76|  2.71k|            }
   77|  3.98k|        }
   78|  21.3k|        int display_width;
   79|  21.3k|        if (sscanf(variable->format, "%%%ds", &display_width) == 1 ||
  ------------------
  |  Branch (79:13): [True: 1.07k, False: 20.2k]
  ------------------
   80|  20.2k|                sscanf(variable->format, "%%-%ds", &display_width) == 1) {
  ------------------
  |  Branch (80:17): [True: 496, False: 19.7k]
  ------------------
   81|  1.57k|            variable->display_width = display_width;
   82|  1.57k|        }
   83|  21.3k|    }
   84|       |
   85|  57.0k|    return variable;
   86|  57.0k|}
readstat_dta_read.c:dta_read_expansion_fields:
  188|  3.01k|static readstat_error_t dta_read_expansion_fields(dta_ctx_t *ctx) {
  189|  3.01k|    readstat_error_t retval = READSTAT_OK;
  190|  3.01k|    readstat_io_t *io = ctx->io;
  191|  3.01k|    char *buffer = NULL;
  192|       |
  193|  3.01k|    if (ctx->expansion_len_len == 0)
  ------------------
  |  Branch (193:9): [True: 677, False: 2.33k]
  ------------------
  194|    677|        return READSTAT_OK;
  195|       |
  196|  2.33k|    if (ctx->file_is_xmlish && !ctx->handle.note) {
  ------------------
  |  Branch (196:9): [True: 1.44k, False: 887]
  |  Branch (196:32): [True: 0, False: 1.44k]
  ------------------
  197|      0|        if (io->seek(ctx->data_offset, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (197:13): [True: 0, False: 0]
  ------------------
  198|      0|            if (ctx->handle.error) {
  ------------------
  |  Branch (198:17): [True: 0, False: 0]
  ------------------
  199|      0|                snprintf(ctx->error_buf, sizeof(ctx->error_buf),
  200|      0|                        "Failed to seek to data section (offset=%" PRId64 ")",
  201|      0|                        ctx->data_offset);
  202|      0|                ctx->handle.error(ctx->error_buf, ctx->user_ctx);
  203|      0|            }
  204|      0|            return READSTAT_ERROR_SEEK;
  205|      0|        }
  206|      0|        return READSTAT_OK;
  207|      0|    }
  208|       |
  209|  2.33k|    retval = dta_read_tag(ctx, "<characteristics>");
  210|  2.33k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (210:9): [True: 191, False: 2.14k]
  ------------------
  211|    191|        goto cleanup;
  212|       |
  213|  7.30k|    while (1) {
  ------------------
  |  Branch (213:12): [True: 7.30k, Folded]
  ------------------
  214|  7.30k|        size_t len;
  215|  7.30k|        char data_type;
  216|       |
  217|  7.30k|        if (ctx->file_is_xmlish) {
  ------------------
  |  Branch (217:13): [True: 1.80k, False: 5.49k]
  ------------------
  218|  1.80k|            char start[4];
  219|  1.80k|            if (io->read(start, sizeof(start), io->io_ctx) != sizeof(start)) {
  ------------------
  |  Branch (219:17): [True: 11, False: 1.79k]
  ------------------
  220|     11|                retval = READSTAT_ERROR_READ;
  221|     11|                goto cleanup;
  222|     11|            }
  223|  1.79k|            if (memcmp(start, "</ch", sizeof(start)) == 0) {
  ------------------
  |  Branch (223:17): [True: 1.16k, False: 626]
  ------------------
  224|  1.16k|                retval = dta_read_tag(ctx, "aracteristics>");
  225|  1.16k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (225:21): [True: 130, False: 1.03k]
  ------------------
  226|    130|                    goto cleanup;
  227|       |
  228|  1.03k|                break;
  229|  1.16k|            } else if (memcmp(start, "<ch>", sizeof(start)) != 0) {
  ------------------
  |  Branch (229:24): [True: 16, False: 610]
  ------------------
  230|     16|                retval = READSTAT_ERROR_PARSE;
  231|     16|                goto cleanup;
  232|     16|            }
  233|    610|            data_type = 1;
  234|  5.49k|        } else {
  235|  5.49k|            if (io->read(&data_type, 1, io->io_ctx) != 1) {
  ------------------
  |  Branch (235:17): [True: 97, False: 5.39k]
  ------------------
  236|     97|                retval = READSTAT_ERROR_READ;
  237|     97|                goto cleanup;
  238|     97|            }
  239|  5.49k|        }
  240|       |
  241|  6.00k|        if (ctx->expansion_len_len == 2) {
  ------------------
  |  Branch (241:13): [True: 4.58k, False: 1.42k]
  ------------------
  242|  4.58k|            uint16_t len16;
  243|  4.58k|            if (io->read(&len16, sizeof(uint16_t), io->io_ctx) != sizeof(uint16_t)) {
  ------------------
  |  Branch (243:17): [True: 15, False: 4.56k]
  ------------------
  244|     15|                retval = READSTAT_ERROR_READ;
  245|     15|                goto cleanup;
  246|     15|            }
  247|  4.56k|            len = ctx->bswap ? byteswap2(len16) : len16;
  ------------------
  |  Branch (247:19): [True: 1.87k, False: 2.68k]
  ------------------
  248|  4.56k|        } else {
  249|  1.42k|            uint32_t len32;
  250|  1.42k|            if (io->read(&len32, sizeof(uint32_t), io->io_ctx) != sizeof(uint32_t)) {
  ------------------
  |  Branch (250:17): [True: 14, False: 1.41k]
  ------------------
  251|     14|                retval = READSTAT_ERROR_READ;
  252|     14|                goto cleanup;
  253|     14|            }
  254|  1.41k|            len = ctx->bswap ? byteswap4(len32) : len32;
  ------------------
  |  Branch (254:19): [True: 930, False: 484]
  ------------------
  255|  1.41k|        }
  256|       |
  257|  5.98k|        if (data_type == 0 && len == 0)
  ------------------
  |  Branch (257:13): [True: 674, False: 5.30k]
  |  Branch (257:31): [True: 639, False: 35]
  ------------------
  258|    639|            break;
  259|       |        
  260|  5.34k|        if (data_type != 1 || len > (1<<20)) {
  ------------------
  |  Branch (260:13): [True: 51, False: 5.29k]
  |  Branch (260:31): [True: 13, False: 5.27k]
  ------------------
  261|     64|            retval = READSTAT_ERROR_NOTE_IS_TOO_LONG;
  262|     64|            goto cleanup;
  263|     64|        }
  264|       |
  265|  5.27k|        if (ctx->handle.note && len >= 2 * ctx->ch_metadata_len) {
  ------------------
  |  Branch (265:13): [True: 5.27k, False: 0]
  |  Branch (265:33): [True: 1.48k, False: 3.79k]
  ------------------
  266|  1.48k|            if ((buffer = readstat_realloc(buffer, len + 1)) == NULL) {
  ------------------
  |  Branch (266:17): [True: 0, False: 1.48k]
  ------------------
  267|      0|                retval = READSTAT_ERROR_MALLOC;
  268|      0|                goto cleanup;
  269|      0|            }
  270|  1.48k|            buffer[len] = '\0';
  271|       |
  272|  1.48k|            if (io->read(buffer, len, io->io_ctx) != len) {
  ------------------
  |  Branch (272:17): [True: 56, False: 1.42k]
  ------------------
  273|     56|                retval = READSTAT_ERROR_READ;
  274|     56|                goto cleanup;
  275|     56|            }
  276|  1.42k|            int index = 0;
  277|  1.42k|            if (strncmp(&buffer[0], "_dta", 4) == 0 &&
  ------------------
  |  Branch (277:17): [True: 393, False: 1.03k]
  ------------------
  278|    393|                    sscanf(&buffer[ctx->ch_metadata_len], "note%d", &index) == 1) {
  ------------------
  |  Branch (278:21): [True: 194, False: 199]
  ------------------
  279|    194|                if (ctx->handle.note(index, &buffer[2*ctx->ch_metadata_len], ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (279:21): [True: 0, False: 194]
  ------------------
  280|      0|                    retval = READSTAT_ERROR_USER_ABORT;
  281|      0|                    goto cleanup;
  282|      0|                }
  283|    194|            }
  284|  3.79k|        } else {
  285|  3.79k|            if (io->seek(len, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (285:17): [True: 10, False: 3.78k]
  ------------------
  286|     10|                retval = READSTAT_ERROR_SEEK;
  287|     10|                goto cleanup;
  288|     10|            }
  289|  3.79k|        }
  290|       |
  291|  5.21k|        retval = dta_read_tag(ctx, "</ch>");
  292|  5.21k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (292:13): [True: 52, False: 5.15k]
  ------------------
  293|     52|            goto cleanup;
  294|  5.21k|    }
  295|       |
  296|  2.33k|cleanup:
  297|  2.33k|    if (buffer)
  ------------------
  |  Branch (297:9): [True: 143, False: 2.19k]
  ------------------
  298|    143|        free(buffer);
  299|       |
  300|  2.33k|    return retval;
  301|  2.14k|}
readstat_dta_read.c:dta_read_strls:
  407|  2.35k|static readstat_error_t dta_read_strls(dta_ctx_t *ctx) {
  408|  2.35k|    if (!ctx->file_is_xmlish)
  ------------------
  |  Branch (408:9): [True: 1.31k, False: 1.03k]
  ------------------
  409|  1.31k|        return READSTAT_OK;
  410|       |
  411|  1.03k|    readstat_error_t retval = READSTAT_OK;
  412|  1.03k|    readstat_io_t *io = ctx->io;
  413|       |
  414|  1.03k|    if (io->seek(ctx->strls_offset, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (414:9): [True: 135, False: 904]
  ------------------
  415|    135|        if (ctx->handle.error) {
  ------------------
  |  Branch (415:13): [True: 0, False: 135]
  ------------------
  416|      0|            snprintf(ctx->error_buf, sizeof(ctx->error_buf), "Failed to seek to strls section (offset=%" PRId64 ")",
  417|      0|                    ctx->strls_offset);
  418|      0|            ctx->handle.error(ctx->error_buf, ctx->user_ctx);
  419|      0|        }
  420|    135|        retval = READSTAT_ERROR_SEEK;
  421|    135|        goto cleanup;
  422|    135|    }
  423|       |
  424|    904|    retval = dta_read_tag(ctx, "<strls>");
  425|    904|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (425:9): [True: 70, False: 834]
  ------------------
  426|     70|        goto cleanup;
  427|       |
  428|    834|    ctx->strls_capacity = 100;
  429|    834|    ctx->strls = readstat_malloc(ctx->strls_capacity * sizeof(dta_strl_t *));
  430|       |
  431|  63.7k|    while (1) {
  ------------------
  |  Branch (431:12): [True: 63.7k, Folded]
  ------------------
  432|  63.7k|        char tag[3];
  433|  63.7k|        if (io->read(tag, sizeof(tag), io->io_ctx) != sizeof(tag)) {
  ------------------
  |  Branch (433:13): [True: 40, False: 63.6k]
  ------------------
  434|     40|            retval = READSTAT_ERROR_READ;
  435|     40|            goto cleanup;
  436|     40|        }
  437|       |
  438|  63.6k|        if (memcmp(tag, "GSO", sizeof(tag)) == 0) {
  ------------------
  |  Branch (438:13): [True: 62.9k, False: 733]
  ------------------
  439|  62.9k|            dta_strl_t strl;
  440|  62.9k|            retval = dta_read_strl(ctx, &strl);
  441|  62.9k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (441:17): [True: 19, False: 62.9k]
  ------------------
  442|     19|                goto cleanup;
  443|       |
  444|  62.9k|            if (strl.type != DTA_GSO_TYPE_ASCII)
  ------------------
  |  |  163|  62.9k|#define DTA_GSO_TYPE_ASCII         0x82
  ------------------
  |  Branch (444:17): [True: 778, False: 62.1k]
  ------------------
  445|    778|                continue;
  446|       |
  447|  62.1k|            if (ctx->strls_count == ctx->strls_capacity) {
  ------------------
  |  Branch (447:17): [True: 85, False: 62.0k]
  ------------------
  448|     85|                ctx->strls_capacity *= 2;
  449|     85|                if ((ctx->strls = readstat_realloc(ctx->strls, sizeof(dta_strl_t *) * ctx->strls_capacity)) == NULL) {
  ------------------
  |  Branch (449:21): [True: 0, False: 85]
  ------------------
  450|      0|                    retval = READSTAT_ERROR_MALLOC;
  451|      0|                    goto cleanup;
  452|      0|                }
  453|     85|            }
  454|       |
  455|  62.1k|            dta_strl_t *strl_ptr = readstat_malloc(sizeof(dta_strl_t) + strl.len);
  456|  62.1k|            if (strl_ptr == NULL) {
  ------------------
  |  Branch (456:17): [True: 7, False: 62.1k]
  ------------------
  457|      7|                retval = READSTAT_ERROR_MALLOC;
  458|      7|                goto cleanup;
  459|      7|            }
  460|  62.1k|            memcpy(strl_ptr, &strl, sizeof(dta_strl_t));
  461|       |
  462|  62.1k|            ctx->strls[ctx->strls_count++] = strl_ptr;
  463|       |
  464|  62.1k|            if (io->read(&strl_ptr->data[0], strl_ptr->len, io->io_ctx) != strl_ptr->len) {
  ------------------
  |  Branch (464:17): [True: 35, False: 62.0k]
  ------------------
  465|     35|                retval = READSTAT_ERROR_READ;
  466|     35|                goto cleanup;
  467|     35|            }
  468|  62.1k|        } else if (memcmp(tag, "</s", sizeof(tag)) == 0) {
  ------------------
  |  Branch (468:20): [True: 665, False: 68]
  ------------------
  469|    665|            retval = dta_read_tag(ctx, "trls>");
  470|    665|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (470:17): [True: 47, False: 618]
  ------------------
  471|     47|                goto cleanup;
  472|    618|            break;
  473|    665|        } else {
  474|     68|            retval = READSTAT_ERROR_PARSE;
  475|     68|            goto cleanup;
  476|     68|        }
  477|  63.6k|    }
  478|       |
  479|  1.03k|cleanup:
  480|  1.03k|    return retval;
  481|    834|}
readstat_dta_read.c:dta_read_strl:
  400|  62.9k|static readstat_error_t dta_read_strl(dta_ctx_t *ctx, dta_strl_t *strl) {
  401|  62.9k|    if (ctx->strl_o_len > 4) {
  ------------------
  |  Branch (401:9): [True: 222, False: 62.7k]
  ------------------
  402|    222|        return dta_118_read_strl(ctx, strl);
  403|    222|    }
  404|  62.7k|    return dta_117_read_strl(ctx, strl);
  405|  62.9k|}
readstat_dta_read.c:dta_118_read_strl:
  381|    222|static readstat_error_t dta_118_read_strl(dta_ctx_t *ctx, dta_strl_t *strl) {
  382|    222|    readstat_error_t retval = READSTAT_OK;
  383|    222|    readstat_io_t *io = ctx->io;
  384|    222|    dta_118_strl_header_t header;
  385|       |
  386|    222|    if (io->read(&header, SIZEOF_DTA_118_STRL_HEADER_T, io->io_ctx) != SIZEOF_DTA_118_STRL_HEADER_T) {
  ------------------
  |  |   43|    222|#define SIZEOF_DTA_118_STRL_HEADER_T 17
  ------------------
                  if (io->read(&header, SIZEOF_DTA_118_STRL_HEADER_T, io->io_ctx) != SIZEOF_DTA_118_STRL_HEADER_T) {
  ------------------
  |  |   43|    222|#define SIZEOF_DTA_118_STRL_HEADER_T 17
  ------------------
  |  Branch (386:9): [True: 6, False: 216]
  ------------------
  387|      6|        retval = READSTAT_ERROR_READ;
  388|      6|        goto cleanup;
  389|      6|    }
  390|       |
  391|    216|    strl->v = ctx->bswap ? byteswap4(header.v) : header.v;
  ------------------
  |  Branch (391:15): [True: 0, False: 216]
  ------------------
  392|    216|    strl->o = ctx->bswap ? byteswap8(header.o) : header.o;
  ------------------
  |  Branch (392:15): [True: 0, False: 216]
  ------------------
  393|    216|    strl->type = header.type;
  394|    216|    strl->len = ctx->bswap ? byteswap4(header.len) : header.len;
  ------------------
  |  Branch (394:17): [True: 0, False: 216]
  ------------------
  395|       |
  396|    222|cleanup:
  397|    222|    return retval;
  398|    216|}
readstat_dta_read.c:dta_117_read_strl:
  362|  62.7k|static readstat_error_t dta_117_read_strl(dta_ctx_t *ctx, dta_strl_t *strl) {
  363|  62.7k|    readstat_error_t retval = READSTAT_OK;
  364|  62.7k|    readstat_io_t *io = ctx->io;
  365|  62.7k|    dta_117_strl_header_t header;
  366|       |
  367|  62.7k|    if (io->read(&header, SIZEOF_DTA_117_STRL_HEADER_T, io->io_ctx) != SIZEOF_DTA_117_STRL_HEADER_T) {
  ------------------
  |  |   34|  62.7k|#define SIZEOF_DTA_117_STRL_HEADER_T 13
  ------------------
                  if (io->read(&header, SIZEOF_DTA_117_STRL_HEADER_T, io->io_ctx) != SIZEOF_DTA_117_STRL_HEADER_T) {
  ------------------
  |  |   34|  62.7k|#define SIZEOF_DTA_117_STRL_HEADER_T 13
  ------------------
  |  Branch (367:9): [True: 13, False: 62.6k]
  ------------------
  368|     13|        retval = READSTAT_ERROR_READ;
  369|     13|        goto cleanup;
  370|     13|    }
  371|       |
  372|  62.6k|    strl->v = ctx->bswap ? byteswap4(header.v) : header.v;
  ------------------
  |  Branch (372:15): [True: 2.60k, False: 60.0k]
  ------------------
  373|  62.6k|    strl->o = ctx->bswap ? byteswap4(header.o) : header.o;
  ------------------
  |  Branch (373:15): [True: 2.60k, False: 60.0k]
  ------------------
  374|  62.6k|    strl->type = header.type;
  375|  62.6k|    strl->len = ctx->bswap ? byteswap4(header.len) : header.len;
  ------------------
  |  Branch (375:17): [True: 2.60k, False: 60.0k]
  ------------------
  376|       |
  377|  62.7k|cleanup:
  378|  62.7k|    return retval;
  379|  62.6k|}
readstat_dta_read.c:dta_read_data:
  704|  1.93k|static readstat_error_t dta_read_data(dta_ctx_t *ctx) {
  705|  1.93k|    readstat_error_t retval = READSTAT_OK;
  706|  1.93k|    readstat_io_t *io = ctx->io;
  707|       |
  708|  1.93k|    if (!ctx->handle.value) {
  ------------------
  |  Branch (708:9): [True: 0, False: 1.93k]
  ------------------
  709|      0|        return READSTAT_OK;
  710|      0|    }
  711|       |
  712|  1.93k|    if (io->seek(ctx->data_offset, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (712:9): [True: 27, False: 1.90k]
  ------------------
  713|     27|        if (ctx->handle.error) {
  ------------------
  |  Branch (713:13): [True: 0, False: 27]
  ------------------
  714|      0|            snprintf(ctx->error_buf, sizeof(ctx->error_buf), "Failed to seek to data section (offset=%" PRId64 ")",
  715|      0|                    ctx->data_offset);
  716|      0|            ctx->handle.error(ctx->error_buf, ctx->user_ctx);
  717|      0|        }
  718|     27|        retval = READSTAT_ERROR_SEEK;
  719|     27|        goto cleanup;
  720|     27|    }
  721|       |
  722|  1.90k|    if ((retval = dta_read_tag(ctx, "<data>")) != READSTAT_OK)
  ------------------
  |  Branch (722:9): [True: 55, False: 1.85k]
  ------------------
  723|     55|        goto cleanup;
  724|       |
  725|  1.85k|    if ((retval = dta_update_progress(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (725:9): [True: 0, False: 1.85k]
  ------------------
  726|      0|        goto cleanup;
  727|       |
  728|  1.85k|    if ((retval = dta_handle_rows(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (728:9): [True: 940, False: 912]
  ------------------
  729|    940|        goto cleanup;
  730|       |
  731|    912|    if ((retval = dta_read_tag(ctx, "</data>")) != READSTAT_OK)
  ------------------
  |  Branch (731:9): [True: 111, False: 801]
  ------------------
  732|    111|        goto cleanup;
  733|       |
  734|  1.93k|cleanup:
  735|  1.93k|    return retval;
  736|    912|}
readstat_dta_read.c:dta_handle_rows:
  660|  1.85k|static readstat_error_t dta_handle_rows(dta_ctx_t *ctx) {
  661|  1.85k|    readstat_io_t *io = ctx->io;
  662|  1.85k|    unsigned char *buf = NULL;
  663|  1.85k|    int i;
  664|  1.85k|    readstat_error_t retval = READSTAT_OK;
  665|       |
  666|  1.85k|    if (ctx->record_len && (buf = readstat_malloc(ctx->record_len)) == NULL) {
  ------------------
  |  Branch (666:9): [True: 1.26k, False: 591]
  |  Branch (666:28): [True: 0, False: 1.26k]
  ------------------
  667|      0|        retval = READSTAT_ERROR_MALLOC;
  668|      0|        goto cleanup;
  669|      0|    }
  670|       |
  671|  1.85k|    if (ctx->row_offset) {
  ------------------
  |  Branch (671:9): [True: 107, False: 1.74k]
  ------------------
  672|    107|        if (io->seek(ctx->record_len * ctx->row_offset, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (672:13): [True: 92, False: 15]
  ------------------
  673|     92|            retval = READSTAT_ERROR_SEEK;
  674|     92|            goto cleanup;
  675|     92|        }
  676|    107|    }
  677|       |
  678|  94.6k|    for (i=0; i<ctx->row_limit; i++) {
  ------------------
  |  Branch (678:15): [True: 93.7k, False: 912]
  ------------------
  679|  93.7k|        if (io->read(buf, ctx->record_len, io->io_ctx) != ctx->record_len) {
  ------------------
  |  Branch (679:13): [True: 818, False: 92.8k]
  ------------------
  680|    818|            retval = READSTAT_ERROR_READ;
  681|    818|            goto cleanup;
  682|    818|        }
  683|  92.8k|        if ((retval = dta_handle_row(buf, ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (683:13): [True: 30, False: 92.8k]
  ------------------
  684|     30|            goto cleanup;
  685|     30|        }
  686|  92.8k|        ctx->current_row++;
  687|  92.8k|        if ((retval = dta_update_progress(ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (687:13): [True: 0, False: 92.8k]
  ------------------
  688|      0|            goto cleanup;
  689|      0|        }
  690|  92.8k|    }
  691|       |
  692|    912|    if (ctx->row_limit < ctx->nobs - ctx->row_offset) {
  ------------------
  |  Branch (692:9): [True: 0, False: 912]
  ------------------
  693|      0|        if (io->seek(ctx->record_len * (ctx->nobs - ctx->row_offset - ctx->row_limit), READSTAT_SEEK_CUR, io->io_ctx) == -1)
  ------------------
  |  Branch (693:13): [True: 0, False: 0]
  ------------------
  694|      0|            retval = READSTAT_ERROR_SEEK;
  695|      0|    }
  696|       |
  697|  1.85k|cleanup:
  698|  1.85k|    if (buf)
  ------------------
  |  Branch (698:9): [True: 1.26k, False: 591]
  ------------------
  699|  1.26k|        free(buf);
  700|       |
  701|  1.85k|    return retval;
  702|    912|}
readstat_dta_read.c:dta_handle_row:
  595|  92.8k|static readstat_error_t dta_handle_row(const unsigned char *buf, dta_ctx_t *ctx) {
  596|  92.8k|    char  str_buf[2048];
  597|  92.8k|    int j;
  598|  92.8k|    readstat_off_t offset = 0;
  599|  92.8k|    readstat_error_t retval = READSTAT_OK;
  600|   189k|    for (j=0; j<ctx->nvar; j++) {
  ------------------
  |  Branch (600:15): [True: 96.4k, False: 92.8k]
  ------------------
  601|  96.4k|        size_t max_len;
  602|  96.4k|        readstat_value_t value = { { 0 } };
  603|       |
  604|  96.4k|        retval = dta_type_info(ctx->typlist[j], ctx, &max_len, &value.type);
  605|  96.4k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (605:13): [True: 0, False: 96.4k]
  ------------------
  606|      0|            goto cleanup;
  607|       |
  608|  96.4k|        if (ctx->variables[j]->skip) {
  ------------------
  |  Branch (608:13): [True: 0, False: 96.4k]
  ------------------
  609|      0|            offset += max_len;
  610|      0|            continue;
  611|      0|        }
  612|       |
  613|  96.4k|        if (offset + max_len > ctx->record_len) {
  ------------------
  |  Branch (613:13): [True: 0, False: 96.4k]
  ------------------
  614|      0|            retval = READSTAT_ERROR_PARSE;
  615|      0|            goto cleanup;
  616|      0|        }
  617|       |
  618|  96.4k|        if (value.type == READSTAT_TYPE_STRING) {
  ------------------
  |  Branch (618:13): [True: 3.14k, False: 93.2k]
  ------------------
  619|  3.14k|            if (max_len == 0) {
  ------------------
  |  Branch (619:17): [True: 4, False: 3.14k]
  ------------------
  620|      4|                retval = READSTAT_ERROR_PARSE;
  621|      4|                goto cleanup;
  622|      4|            }
  623|  3.14k|            size_t str_len = strnlen((const char *)&buf[offset], max_len);
  624|  3.14k|            retval = readstat_convert(str_buf, sizeof(str_buf),
  625|  3.14k|                    (const char *)&buf[offset], str_len, ctx->converter);
  626|  3.14k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (626:17): [True: 26, False: 3.11k]
  ------------------
  627|     26|                goto cleanup;
  628|  3.11k|            value.v.string_value = str_buf;
  629|  93.2k|        } else if (value.type == READSTAT_TYPE_STRING_REF) {
  ------------------
  |  Branch (629:20): [True: 49.4k, False: 43.8k]
  ------------------
  630|  49.4k|            dta_strl_t key = dta_interpret_strl_vo_bytes(ctx, &buf[offset]);
  631|  49.4k|            dta_strl_t **found = bsearch(&key, ctx->strls, ctx->strls_count, sizeof(dta_strl_t *), &dta_compare_strls);
  632|       |
  633|  49.4k|            if (found) {
  ------------------
  |  Branch (633:17): [True: 211, False: 49.2k]
  ------------------
  634|    211|                value.v.string_value = (*found)->data;
  635|    211|            }
  636|  49.4k|            value.type = READSTAT_TYPE_STRING;
  637|  49.4k|        } else if (value.type == READSTAT_TYPE_INT8) {
  ------------------
  |  Branch (637:20): [True: 13.3k, False: 30.4k]
  ------------------
  638|  13.3k|            value = dta_interpret_int8_bytes(ctx, &buf[offset]);
  639|  30.4k|        } else if (value.type == READSTAT_TYPE_INT16) {
  ------------------
  |  Branch (639:20): [True: 1.77k, False: 28.7k]
  ------------------
  640|  1.77k|            value = dta_interpret_int16_bytes(ctx, &buf[offset]);
  641|  28.7k|        } else if (value.type == READSTAT_TYPE_INT32) {
  ------------------
  |  Branch (641:20): [True: 25.1k, False: 3.58k]
  ------------------
  642|  25.1k|            value = dta_interpret_int32_bytes(ctx, &buf[offset]);
  643|  25.1k|        } else if (value.type == READSTAT_TYPE_FLOAT) {
  ------------------
  |  Branch (643:20): [True: 1.64k, False: 1.94k]
  ------------------
  644|  1.64k|            value = dta_interpret_float_bytes(ctx, &buf[offset]);
  645|  1.94k|        } else if (value.type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (645:20): [True: 1.94k, False: 0]
  ------------------
  646|  1.94k|            value = dta_interpret_double_bytes(ctx, &buf[offset]);
  647|  1.94k|        }
  648|       |
  649|  96.3k|        if (ctx->handle.value(ctx->current_row, ctx->variables[j], value, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (649:13): [True: 0, False: 96.3k]
  ------------------
  650|      0|            retval = READSTAT_ERROR_USER_ABORT;
  651|      0|            goto cleanup;
  652|      0|        }
  653|       |
  654|  96.3k|        offset += max_len;
  655|  96.3k|    }
  656|  92.8k|cleanup:
  657|  92.8k|    return retval;
  658|  92.8k|}
readstat_dta_read.c:dta_interpret_strl_vo_bytes:
  330|  49.4k|static dta_strl_t dta_interpret_strl_vo_bytes(dta_ctx_t *ctx, const unsigned char *vo_bytes) {
  331|  49.4k|    dta_strl_t strl = {0};
  332|       |
  333|  49.4k|    if (ctx->strl_v_len == 2) {
  ------------------
  |  Branch (333:9): [True: 1.15k, False: 48.2k]
  ------------------
  334|  1.15k|        if (ctx->endianness == READSTAT_ENDIAN_BIG) {
  ------------------
  |  Branch (334:13): [True: 0, False: 1.15k]
  ------------------
  335|      0|            strl.v = (vo_bytes[0] << 8) + vo_bytes[1];
  336|      0|            strl.o = (((uint64_t)vo_bytes[2] << 40)
  337|      0|                    + ((uint64_t)vo_bytes[3] << 32)
  338|      0|                    + ((uint64_t)vo_bytes[4] << 24)
  339|      0|                    + (vo_bytes[5] << 16)
  340|      0|                    + (vo_bytes[6] << 8)
  341|      0|                    + vo_bytes[7]);
  342|  1.15k|        } else {
  343|  1.15k|            strl.v = vo_bytes[0] + (vo_bytes[1] << 8);
  344|  1.15k|            strl.o = (vo_bytes[2] + (vo_bytes[3] << 8)
  345|  1.15k|                    + (vo_bytes[4] << 16)
  346|  1.15k|                    + ((uint64_t)vo_bytes[5] << 24)
  347|  1.15k|                    + ((uint64_t)vo_bytes[6] << 32)
  348|  1.15k|                    + ((uint64_t)vo_bytes[7] << 40));
  349|  1.15k|        }
  350|  48.2k|    } else if (ctx->strl_v_len == 4) {
  ------------------
  |  Branch (350:16): [True: 48.2k, False: 0]
  ------------------
  351|  48.2k|        uint32_t v, o;
  352|       |
  353|  48.2k|        memcpy(&v, &vo_bytes[0], sizeof(uint32_t));
  354|  48.2k|        memcpy(&o, &vo_bytes[4], sizeof(uint32_t));
  355|       |
  356|  48.2k|        strl.v = ctx->bswap ? byteswap4(v) : v;
  ------------------
  |  Branch (356:18): [True: 674, False: 47.6k]
  ------------------
  357|  48.2k|        strl.o = ctx->bswap ? byteswap4(o) : o;
  ------------------
  |  Branch (357:18): [True: 674, False: 47.6k]
  ------------------
  358|  48.2k|    }
  359|  49.4k|    return strl;
  360|  49.4k|}
readstat_dta_read.c:dta_compare_strls:
  322|   551k|static int dta_compare_strls(const void *elem1, const void *elem2) {
  323|   551k|    const dta_strl_t *key = (const dta_strl_t *)elem1;
  324|   551k|    const dta_strl_t *target = *(const dta_strl_t **)elem2;
  325|   551k|    if (key->o != target->o)
  ------------------
  |  Branch (325:9): [True: 550k, False: 577]
  ------------------
  326|   550k|        return (key->o > target->o) - (key->o < target->o);
  327|    577|    return (key->v > target->v) - (key->v < target->v);
  328|   551k|}
readstat_dta_read.c:dta_interpret_int8_bytes:
  483|  13.3k|static readstat_value_t dta_interpret_int8_bytes(dta_ctx_t *ctx, const void *buf) {
  484|  13.3k|    readstat_value_t value = { .type = READSTAT_TYPE_INT8 };
  485|  13.3k|    int8_t byte = 0;
  486|  13.3k|    memcpy(&byte, buf, sizeof(int8_t));
  487|  13.3k|    if (ctx->machine_is_twos_complement) {
  ------------------
  |  Branch (487:9): [True: 0, False: 13.3k]
  ------------------
  488|      0|        byte = ones_to_twos_complement1(byte);
  489|      0|    }
  490|  13.3k|    if (byte > ctx->max_int8) {
  ------------------
  |  Branch (490:9): [True: 1.02k, False: 12.3k]
  ------------------
  491|  1.02k|        if (ctx->supports_tagged_missing && byte > DTA_113_MISSING_INT8) {
  ------------------
  |  |  150|    760|#define DTA_113_MISSING_INT8                 0x65
  ------------------
  |  Branch (491:13): [True: 760, False: 266]
  |  Branch (491:45): [True: 524, False: 236]
  ------------------
  492|    524|            value.tag = 'a' + (byte - DTA_113_MISSING_INT8_A);
  ------------------
  |  |  156|    524|#define DTA_113_MISSING_INT8_A    (DTA_113_MISSING_INT8+1)
  |  |  ------------------
  |  |  |  |  150|    524|#define DTA_113_MISSING_INT8                 0x65
  |  |  ------------------
  ------------------
  493|    524|            value.is_tagged_missing = 1;
  494|    524|        } else {
  495|    502|            value.is_system_missing = 1;
  496|    502|        }
  497|  1.02k|    }
  498|  13.3k|    value.v.i8_value = byte;
  499|       |
  500|  13.3k|    return value;
  501|  13.3k|}
readstat_dta_read.c:dta_interpret_int16_bytes:
  503|  1.77k|static readstat_value_t dta_interpret_int16_bytes(dta_ctx_t *ctx, const void *buf) {
  504|  1.77k|    readstat_value_t value = { .type = READSTAT_TYPE_INT16 };
  505|  1.77k|    int16_t num = 0;
  506|  1.77k|    memcpy(&num, buf, sizeof(int16_t));
  507|  1.77k|    if (ctx->bswap) {
  ------------------
  |  Branch (507:9): [True: 1.33k, False: 432]
  ------------------
  508|  1.33k|        num = byteswap2(num);
  509|  1.33k|    }
  510|  1.77k|    if (ctx->machine_is_twos_complement) {
  ------------------
  |  Branch (510:9): [True: 0, False: 1.77k]
  ------------------
  511|      0|        num = ones_to_twos_complement2(num);
  512|      0|    }
  513|  1.77k|    if (num > ctx->max_int16) {
  ------------------
  |  Branch (513:9): [True: 585, False: 1.18k]
  ------------------
  514|    585|        if (ctx->supports_tagged_missing && num > DTA_113_MISSING_INT16) {
  ------------------
  |  |  151|    388|#define DTA_113_MISSING_INT16              0x7FE5
  ------------------
  |  Branch (514:13): [True: 388, False: 197]
  |  Branch (514:45): [True: 194, False: 194]
  ------------------
  515|    194|            value.tag = 'a' + (num - DTA_113_MISSING_INT16_A);
  ------------------
  |  |  157|    194|#define DTA_113_MISSING_INT16_A   (DTA_113_MISSING_INT16+1)
  |  |  ------------------
  |  |  |  |  151|    194|#define DTA_113_MISSING_INT16              0x7FE5
  |  |  ------------------
  ------------------
  516|    194|            value.is_tagged_missing = 1;
  517|    391|        } else {
  518|    391|            value.is_system_missing = 1;
  519|    391|        }
  520|    585|    }
  521|  1.77k|    value.v.i16_value = num;
  522|       |
  523|  1.77k|    return value;
  524|  1.77k|}
readstat_dta_read.c:dta_interpret_int32_bytes:
  526|  27.1k|static readstat_value_t dta_interpret_int32_bytes(dta_ctx_t *ctx, const void *buf) {
  527|  27.1k|    readstat_value_t value = { .type = READSTAT_TYPE_INT32 };
  528|  27.1k|    int32_t num = 0;
  529|  27.1k|    memcpy(&num, buf, sizeof(int32_t));
  530|  27.1k|    if (ctx->bswap) {
  ------------------
  |  Branch (530:9): [True: 2.58k, False: 24.5k]
  ------------------
  531|  2.58k|        num = byteswap4(num);
  532|  2.58k|    }
  533|  27.1k|    if (ctx->machine_is_twos_complement) {
  ------------------
  |  Branch (533:9): [True: 0, False: 27.1k]
  ------------------
  534|      0|        num = ones_to_twos_complement4(num);
  535|      0|    }
  536|  27.1k|    if (num > ctx->max_int32) {
  ------------------
  |  Branch (536:9): [True: 1.23k, False: 25.9k]
  ------------------
  537|  1.23k|        if (ctx->supports_tagged_missing && num > DTA_113_MISSING_INT32) {
  ------------------
  |  |  152|    803|#define DTA_113_MISSING_INT32          0x7FFFFFE5
  ------------------
  |  Branch (537:13): [True: 803, False: 436]
  |  Branch (537:45): [True: 407, False: 396]
  ------------------
  538|    407|            value.tag = 'a' + (num - DTA_113_MISSING_INT32_A);
  ------------------
  |  |  158|    407|#define DTA_113_MISSING_INT32_A   (DTA_113_MISSING_INT32+1)
  |  |  ------------------
  |  |  |  |  152|    407|#define DTA_113_MISSING_INT32          0x7FFFFFE5
  |  |  ------------------
  ------------------
  539|    407|            value.is_tagged_missing = 1;
  540|    832|        } else {
  541|    832|            value.is_system_missing = 1;
  542|    832|        }
  543|  1.23k|    }
  544|  27.1k|    value.v.i32_value = num;
  545|       |
  546|  27.1k|    return value;
  547|  27.1k|}
readstat_dta_read.c:dta_interpret_float_bytes:
  549|  1.64k|static readstat_value_t dta_interpret_float_bytes(dta_ctx_t *ctx, const void *buf) {
  550|  1.64k|    readstat_value_t value = { .type = READSTAT_TYPE_FLOAT };
  551|  1.64k|    float f_num = NAN;
  552|  1.64k|    int32_t num = 0;
  553|  1.64k|    memcpy(&num, buf, sizeof(int32_t));
  554|  1.64k|    if (ctx->bswap) {
  ------------------
  |  Branch (554:9): [True: 859, False: 782]
  ------------------
  555|    859|        num = byteswap4(num);
  556|    859|    }
  557|  1.64k|    if (num > ctx->max_float) {
  ------------------
  |  Branch (557:9): [True: 716, False: 925]
  ------------------
  558|    716|        if (ctx->supports_tagged_missing && num > DTA_113_MISSING_FLOAT) {
  ------------------
  |  |  153|    485|#define DTA_113_MISSING_FLOAT          0x7F000000
  ------------------
  |  Branch (558:13): [True: 485, False: 231]
  |  Branch (558:45): [True: 291, False: 194]
  ------------------
  559|    291|            value.tag = 'a' + ((num - DTA_113_MISSING_FLOAT_A) >> 11);
  ------------------
  |  |  159|    291|#define DTA_113_MISSING_FLOAT_A   (DTA_113_MISSING_FLOAT+0x0800)
  |  |  ------------------
  |  |  |  |  153|    291|#define DTA_113_MISSING_FLOAT          0x7F000000
  |  |  ------------------
  ------------------
  560|    291|            value.is_tagged_missing = 1;
  561|    425|        } else {
  562|    425|            value.is_system_missing = 1;
  563|    425|        }
  564|    925|    } else {
  565|    925|        memcpy(&f_num, &num, sizeof(int32_t));
  566|    925|    }
  567|  1.64k|    value.v.float_value = f_num;
  568|       |
  569|  1.64k|    return value;
  570|  1.64k|}
readstat_dta_read.c:dta_interpret_double_bytes:
  572|  1.94k|static readstat_value_t dta_interpret_double_bytes(dta_ctx_t *ctx, const void *buf) {
  573|  1.94k|    readstat_value_t value = { .type = READSTAT_TYPE_DOUBLE };
  574|  1.94k|    double d_num = NAN;
  575|  1.94k|    int64_t num = 0;
  576|  1.94k|    memcpy(&num, buf, sizeof(int64_t));
  577|  1.94k|    if (ctx->bswap) {
  ------------------
  |  Branch (577:9): [True: 856, False: 1.08k]
  ------------------
  578|    856|        num = byteswap8(num);
  579|    856|    }
  580|  1.94k|    if (num > ctx->max_double) {
  ------------------
  |  Branch (580:9): [True: 704, False: 1.24k]
  ------------------
  581|    704|        if (ctx->supports_tagged_missing && num > DTA_113_MISSING_DOUBLE) {
  ------------------
  |  |  154|    440|#define DTA_113_MISSING_DOUBLE 0x7FE0000000000000L
  ------------------
  |  Branch (581:13): [True: 440, False: 264]
  |  Branch (581:45): [True: 246, False: 194]
  ------------------
  582|    246|            value.tag = 'a' + ((num - DTA_113_MISSING_DOUBLE_A) >> 40);
  ------------------
  |  |  160|    246|#define DTA_113_MISSING_DOUBLE_A  (DTA_113_MISSING_DOUBLE+0x010000000000)
  |  |  ------------------
  |  |  |  |  154|    246|#define DTA_113_MISSING_DOUBLE 0x7FE0000000000000L
  |  |  ------------------
  ------------------
  583|    246|            value.is_tagged_missing = 1;
  584|    458|        } else {
  585|    458|            value.is_system_missing = 1;
  586|    458|        }
  587|  1.24k|    } else {
  588|  1.24k|        memcpy(&d_num, &num, sizeof(int64_t));
  589|  1.24k|    }
  590|  1.94k|    value.v.double_value = d_num;
  591|       |
  592|  1.94k|    return value;
  593|  1.94k|}
readstat_dta_read.c:dta_handle_value_labels:
  985|    801|static readstat_error_t dta_handle_value_labels(dta_ctx_t *ctx) {
  986|    801|    readstat_io_t *io = ctx->io;
  987|    801|    readstat_error_t retval = READSTAT_OK;
  988|    801|    char *table_buffer = NULL;
  989|    801|    char *utf8_buffer = NULL;
  990|       |
  991|    801|    if (io->seek(ctx->value_labels_offset, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (991:9): [True: 3, False: 798]
  ------------------
  992|      3|        if (ctx->handle.error) {
  ------------------
  |  Branch (992:13): [True: 0, False: 3]
  ------------------
  993|      0|            snprintf(ctx->error_buf, sizeof(ctx->error_buf), "Failed to seek to value labels section (offset=%" PRId64 ")",
  994|      0|                    ctx->value_labels_offset);
  995|      0|            ctx->handle.error(ctx->error_buf, ctx->user_ctx);
  996|      0|        }
  997|      3|        retval = READSTAT_ERROR_SEEK;
  998|      3|        goto cleanup;
  999|      3|    }
 1000|    798|    if ((retval = dta_read_tag(ctx, "<value_labels>")) != READSTAT_OK) {
  ------------------
  |  Branch (1000:9): [True: 126, False: 672]
  ------------------
 1001|    126|        goto cleanup;
 1002|    126|    }
 1003|       |
 1004|    672|    if (!ctx->handle.value_label) {
  ------------------
  |  Branch (1004:9): [True: 0, False: 672]
  ------------------
 1005|      0|        return READSTAT_OK;
 1006|      0|    }
 1007|       |
 1008|  5.41k|    while (1) {
  ------------------
  |  Branch (1008:12): [True: 5.41k, Folded]
  ------------------
 1009|  5.41k|        size_t len = 0;
 1010|  5.41k|        char labname[129];
 1011|  5.41k|        uint32_t i = 0, n = 0;
 1012|       |
 1013|  5.41k|        if (ctx->value_label_table_len_len == 2) {
  ------------------
  |  Branch (1013:13): [True: 1.99k, False: 3.41k]
  ------------------
 1014|  1.99k|            int16_t table_header_len;
 1015|  1.99k|            if (io->read(&table_header_len, sizeof(int16_t), io->io_ctx) < sizeof(int16_t))
  ------------------
  |  Branch (1015:17): [True: 60, False: 1.93k]
  ------------------
 1016|     60|                break;
 1017|       |
 1018|  1.93k|            len = table_header_len;
 1019|       |
 1020|  1.93k|            if (ctx->bswap)
  ------------------
  |  Branch (1020:17): [True: 1.58k, False: 347]
  ------------------
 1021|  1.58k|                len = byteswap2(table_header_len);
 1022|       |
 1023|  1.93k|            n = len / 8;
 1024|  3.41k|        } else {
 1025|  3.41k|            if (dta_read_tag(ctx, "<lbl>") != READSTAT_OK) {
  ------------------
  |  Branch (1025:17): [True: 47, False: 3.36k]
  ------------------
 1026|     47|                break;
 1027|     47|            }
 1028|       |
 1029|  3.36k|            int32_t table_header_len;
 1030|  3.36k|            if (io->read(&table_header_len, sizeof(int32_t), io->io_ctx) < sizeof(int32_t))
  ------------------
  |  Branch (1030:17): [True: 191, False: 3.17k]
  ------------------
 1031|    191|                break;
 1032|       |
 1033|  3.17k|            len = table_header_len;
 1034|       |
 1035|  3.17k|            if (ctx->bswap)
  ------------------
  |  Branch (1035:17): [True: 1.82k, False: 1.35k]
  ------------------
 1036|  1.82k|                len = byteswap4(table_header_len);
 1037|  3.17k|        }
 1038|       |
 1039|  5.11k|        if (io->read(labname, ctx->value_label_table_labname_len, io->io_ctx) < ctx->value_label_table_labname_len)
  ------------------
  |  Branch (1039:13): [True: 43, False: 5.07k]
  ------------------
 1040|     43|            break;
 1041|       |
 1042|  5.07k|        if (io->seek(ctx->value_label_table_padding_len, READSTAT_SEEK_CUR, io->io_ctx) == -1)
  ------------------
  |  Branch (1042:13): [True: 2, False: 5.06k]
  ------------------
 1043|      2|            break;
 1044|       |
 1045|  5.06k|        if ((table_buffer = readstat_realloc(table_buffer, len)) == NULL) {
  ------------------
  |  Branch (1045:13): [True: 50, False: 5.01k]
  ------------------
 1046|     50|            retval = READSTAT_ERROR_MALLOC;
 1047|     50|            goto cleanup;
 1048|     50|        }
 1049|       |
 1050|  5.01k|        if (io->read(table_buffer, len, io->io_ctx) < len) {
  ------------------
  |  Branch (1050:13): [True: 76, False: 4.94k]
  ------------------
 1051|     76|            break;
 1052|     76|        }
 1053|       |
 1054|  4.94k|        if (ctx->value_label_table_len_len == 2) {
  ------------------
  |  Branch (1054:13): [True: 1.85k, False: 3.08k]
  ------------------
 1055|   134k|            for (i=0; i<n; i++) {
  ------------------
  |  Branch (1055:23): [True: 132k, False: 1.85k]
  ------------------
 1056|   132k|                readstat_value_t value = { .v = { .i32_value = i }, .type = READSTAT_TYPE_INT32 };
 1057|   132k|                char label_buf[4*8+1];
 1058|       |
 1059|   132k|                retval = readstat_convert(label_buf, sizeof(label_buf),
 1060|   132k|                        &table_buffer[8*i], strnlen(&table_buffer[8*i], 8), ctx->converter);
 1061|   132k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1061:21): [True: 8, False: 132k]
  ------------------
 1062|      8|                    goto cleanup;
 1063|       |
 1064|   132k|                if (label_buf[0] && ctx->handle.value_label(labname, value, label_buf, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (1064:21): [True: 128k, False: 3.77k]
  |  Branch (1064:37): [True: 0, False: 128k]
  ------------------
 1065|      0|                    retval = READSTAT_ERROR_USER_ABORT;
 1066|      0|                    goto cleanup;
 1067|      0|                }
 1068|   132k|            }
 1069|  3.08k|        } else if (len >= 8) {
  ------------------
  |  Branch (1069:20): [True: 2.45k, False: 626]
  ------------------
 1070|  2.45k|            if ((retval = dta_read_tag(ctx, "</lbl>")) != READSTAT_OK) {
  ------------------
  |  Branch (1070:17): [True: 5, False: 2.45k]
  ------------------
 1071|      5|                goto cleanup;
 1072|      5|            }
 1073|       |
 1074|  2.45k|            n = *(uint32_t *)table_buffer;
 1075|       |
 1076|  2.45k|            uint32_t txtlen = *((uint32_t *)table_buffer+1);
 1077|  2.45k|            if (ctx->bswap) {
  ------------------
  |  Branch (1077:17): [True: 1.30k, False: 1.15k]
  ------------------
 1078|  1.30k|                n = byteswap4(n);
 1079|  1.30k|                txtlen = byteswap4(txtlen);
 1080|  1.30k|            }
 1081|       |
 1082|  2.45k|            if (txtlen > len - 8 || n > (len - 8 - txtlen) / 8) {
  ------------------
  |  Branch (1082:17): [True: 40, False: 2.41k]
  |  Branch (1082:37): [True: 35, False: 2.37k]
  ------------------
 1083|     75|                break;
 1084|     75|            }
 1085|       |
 1086|  2.37k|            uint32_t *off = (uint32_t *)table_buffer+2;
 1087|  2.37k|            uint32_t *val = (uint32_t *)table_buffer+2+n;
 1088|  2.37k|            char *txt = &table_buffer[8LL*n+8];
 1089|  2.37k|            size_t utf8_buffer_len = 4*txtlen+1;
 1090|  2.37k|            if (txtlen > MAX_VALUE_LABEL_LEN+1)
  ------------------
  |  |   21|  2.37k|#define MAX_VALUE_LABEL_LEN 32000
  ------------------
  |  Branch (1090:17): [True: 17, False: 2.36k]
  ------------------
 1091|     17|                utf8_buffer_len = 4*MAX_VALUE_LABEL_LEN+1;
  ------------------
  |  |   21|     17|#define MAX_VALUE_LABEL_LEN 32000
  ------------------
 1092|       |
 1093|  2.37k|            utf8_buffer = realloc(utf8_buffer, utf8_buffer_len);
 1094|       |            /* Much bigger than we need but whatever */
 1095|  2.37k|            if (utf8_buffer == NULL) {
  ------------------
  |  Branch (1095:17): [True: 0, False: 2.37k]
  ------------------
 1096|      0|                retval = READSTAT_ERROR_MALLOC;
 1097|      0|                goto cleanup;
 1098|      0|            }
 1099|       |
 1100|  2.37k|            if (ctx->bswap) {
  ------------------
  |  Branch (1100:17): [True: 1.25k, False: 1.12k]
  ------------------
 1101|   162k|                for (i=0; i<n; i++) {
  ------------------
  |  Branch (1101:27): [True: 160k, False: 1.25k]
  ------------------
 1102|   160k|                    off[i] = byteswap4(off[i]);
 1103|   160k|                }
 1104|  1.25k|            }
 1105|       |
 1106|  4.38k|            for (i=0; i<n; i++) {
  ------------------
  |  Branch (1106:23): [True: 2.12k, False: 2.26k]
  ------------------
 1107|  2.12k|                if (off[i] >= txtlen) {
  ------------------
  |  Branch (1107:21): [True: 97, False: 2.02k]
  ------------------
 1108|     97|                    retval = READSTAT_ERROR_PARSE;
 1109|     97|                    goto cleanup;
 1110|     97|                }
 1111|       |
 1112|  2.02k|                readstat_value_t value = dta_interpret_int32_bytes(ctx, &val[i]);
 1113|  2.02k|                size_t max_label_len = txtlen - off[i];
 1114|  2.02k|                if (max_label_len > MAX_VALUE_LABEL_LEN)
  ------------------
  |  |   21|  2.02k|#define MAX_VALUE_LABEL_LEN 32000
  ------------------
  |  Branch (1114:21): [True: 224, False: 1.80k]
  ------------------
 1115|    224|                    max_label_len = MAX_VALUE_LABEL_LEN;
  ------------------
  |  |   21|    224|#define MAX_VALUE_LABEL_LEN 32000
  ------------------
 1116|  2.02k|                size_t label_len = strnlen(&txt[off[i]], max_label_len);
 1117|       |
 1118|  2.02k|                retval = readstat_convert(utf8_buffer, utf8_buffer_len, &txt[off[i]], label_len, ctx->converter);
 1119|  2.02k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1119:21): [True: 18, False: 2.01k]
  ------------------
 1120|     18|                    goto cleanup;
 1121|       |
 1122|  2.01k|                if (ctx->handle.value_label(labname, value, utf8_buffer, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (1122:21): [True: 0, False: 2.01k]
  ------------------
 1123|      0|                    retval = READSTAT_ERROR_USER_ABORT;
 1124|      0|                    goto cleanup;
 1125|      0|                }
 1126|  2.01k|            }
 1127|  2.37k|        }
 1128|  4.94k|    }
 1129|       |
 1130|    801|cleanup:
 1131|    801|    if (table_buffer)
  ------------------
  |  Branch (1131:9): [True: 534, False: 267]
  ------------------
 1132|    534|        free(table_buffer);
 1133|    801|    if (utf8_buffer)
  ------------------
  |  Branch (1133:9): [True: 285, False: 516]
  ------------------
 1134|    285|        free(utf8_buffer);
 1135|       |
 1136|    801|    return retval;
 1137|    672|}

rt_open_handler:
    8|  4.39k|int rt_open_handler(const char *path, void *io_ctx) {
    9|  4.39k|    return 0;
   10|  4.39k|}
rt_close_handler:
   12|  4.39k|int rt_close_handler(void *io_ctx) {
   13|  4.39k|    return 0;
   14|  4.39k|}
rt_seek_handler:
   17|  22.8k|        readstat_io_flags_t whence, void *io_ctx) {
   18|  22.8k|    rt_buffer_ctx_t *buffer_ctx = (rt_buffer_ctx_t *)io_ctx;
   19|  22.8k|    readstat_off_t newpos = -1;
   20|  22.8k|    if (whence == READSTAT_SEEK_SET) {
  ------------------
  |  Branch (20:9): [True: 8.17k, False: 14.6k]
  ------------------
   21|  8.17k|        newpos = offset;
   22|  14.6k|    } else if (whence == READSTAT_SEEK_CUR) {
  ------------------
  |  Branch (22:16): [True: 10.2k, False: 4.39k]
  ------------------
   23|  10.2k|        newpos = buffer_ctx->pos + offset;
   24|  10.2k|    } else if (whence == READSTAT_SEEK_END) {
  ------------------
  |  Branch (24:16): [True: 4.39k, False: 0]
  ------------------
   25|  4.39k|        newpos = buffer_ctx->buffer->used + offset;
   26|  4.39k|    }
   27|       |
   28|  22.8k|    if (newpos < 0)
  ------------------
  |  Branch (28:9): [True: 141, False: 22.7k]
  ------------------
   29|    141|        return -1;
   30|       |
   31|  22.7k|    if (newpos > buffer_ctx->buffer->used)
  ------------------
  |  Branch (31:9): [True: 128, False: 22.5k]
  ------------------
   32|    128|        return -1;
   33|       |
   34|  22.5k|    buffer_ctx->pos = newpos;
   35|  22.5k|    return newpos;
   36|  22.7k|}
rt_read_handler:
   38|   395k|ssize_t rt_read_handler(void *buf, size_t nbytes, void *io_ctx) {
   39|   395k|    rt_buffer_ctx_t *buffer_ctx = (rt_buffer_ctx_t *)io_ctx;
   40|   395k|    ssize_t bytes_copied = 0;
   41|   395k|    ssize_t bytes_left = buffer_ctx->buffer->used - buffer_ctx->pos;
   42|   395k|    if (nbytes <= bytes_left) {
  ------------------
  |  Branch (42:9): [True: 393k, False: 2.10k]
  ------------------
   43|   393k|        memcpy(buf, buffer_ctx->buffer->bytes + buffer_ctx->pos, nbytes);
   44|   393k|        bytes_copied = nbytes;
   45|   393k|    } else if (bytes_left > 0) {
  ------------------
  |  Branch (45:16): [True: 336, False: 1.77k]
  ------------------
   46|    336|        memcpy(buf, buffer_ctx->buffer->bytes + buffer_ctx->pos, bytes_left);
   47|    336|        bytes_copied = bytes_left;
   48|    336|    }
   49|   395k|    buffer_ctx->pos += bytes_copied;
   50|   395k|    return bytes_copied;
   51|   395k|}

