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

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

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

readstat_convert:
   39|   123k|readstat_error_t readstat_convert(char *dst, size_t dst_len, const char *src, size_t src_len, iconv_t converter) {
   40|   123k|    return readstat_convert_impl(dst, dst_len, src, src_len, converter, 1);
   41|   123k|}
readstat_convert_notrim:
   43|  2.87k|readstat_error_t readstat_convert_notrim(char *dst, size_t dst_len, const char *src, size_t src_len, iconv_t converter) {
   44|  2.87k|    return readstat_convert_impl(dst, dst_len, src, src_len, converter, 0);
   45|  2.87k|}
readstat_convert.c:readstat_convert_impl:
    8|   126k|        iconv_t converter, int trim_spaces) {
    9|       |    /* strip off spaces from the input because the programs use ASCII space
   10|       |     * padding even with non-ASCII encoding. */
   11|   142k|    while (src_len && ((trim_spaces && src[src_len-1] == ' ') || src[src_len-1] == '\0')) {
  ------------------
  |  Branch (11:12): [True: 93.7k, False: 49.1k]
  |  Branch (11:25): [True: 91.5k, False: 2.24k]
  |  Branch (11:40): [True: 11.8k, False: 79.6k]
  |  Branch (11:66): [True: 4.67k, False: 77.1k]
  ------------------
   12|  16.5k|        src_len--;
   13|  16.5k|    }
   14|   126k|    if (dst_len == 0) {
  ------------------
  |  Branch (14:9): [True: 0, False: 126k]
  ------------------
   15|      0|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   16|   126k|    } else if (converter) {
  ------------------
  |  Branch (16:16): [True: 123k, False: 2.40k]
  ------------------
   17|   123k|        size_t dst_left = dst_len - 1;
   18|   123k|        char *dst_end = dst;
   19|   123k|        size_t status = iconv(converter, (readstat_iconv_inbuf_t)&src, &src_len, &dst_end, &dst_left);
   20|   123k|        if (status == (size_t)-1) {
  ------------------
  |  Branch (20:13): [True: 894, False: 123k]
  ------------------
   21|    894|            if (errno == E2BIG) {
  ------------------
  |  Branch (21:17): [True: 0, False: 894]
  ------------------
   22|      0|                return READSTAT_ERROR_CONVERT_LONG_STRING;
   23|    894|            } else if (errno == EILSEQ) {
  ------------------
  |  Branch (23:24): [True: 894, False: 0]
  ------------------
   24|    894|                return READSTAT_ERROR_CONVERT_BAD_STRING;
   25|    894|            } else if (errno != EINVAL) { /* EINVAL indicates improper truncation; accept it */
  ------------------
  |  Branch (25:24): [True: 0, False: 0]
  ------------------
   26|      0|                return READSTAT_ERROR_CONVERT;
   27|      0|            }
   28|    894|        }
   29|   123k|        dst[dst_len - dst_left - 1] = '\0';
   30|   123k|    } else if (src_len + 1 > dst_len) {
  ------------------
  |  Branch (30:16): [True: 20, False: 2.38k]
  ------------------
   31|     20|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   32|  2.38k|    } else {
   33|  2.38k|        memcpy(dst, src, src_len);
   34|  2.38k|        dst[src_len] = '\0';
   35|  2.38k|    }
   36|   125k|    return READSTAT_OK;
   37|   126k|}

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

readstat_malloc:
   10|  13.7k|void *readstat_malloc(size_t len) {
   11|  13.7k|    if (len > MAX_MALLOC_SIZE || len == 0) {
  ------------------
  |  |    3|  27.5k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (11:9): [True: 0, False: 13.7k]
  |  Branch (11:34): [True: 0, False: 13.7k]
  ------------------
   12|      0|        return NULL;
   13|      0|    }
   14|  13.7k|    return malloc(len);
   15|  13.7k|}
readstat_realloc:
   27|  6.25k|void *readstat_realloc(void *ptr, size_t len) {
   28|  6.25k|    if (len > MAX_MALLOC_SIZE || len == 0) {
  ------------------
  |  |    3|  12.5k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (28:9): [True: 85, False: 6.16k]
  |  Branch (28:34): [True: 0, False: 6.16k]
  ------------------
   29|     85|        if (ptr)
  ------------------
  |  Branch (29:13): [True: 17, False: 68]
  ------------------
   30|     17|            free(ptr);
   31|     85|        return NULL;
   32|     85|    }
   33|  6.16k|    return realloc(ptr, len);
   34|  6.25k|}

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

dta_format_is_supported:
   19|  3.93k|int dta_format_is_supported(int ds_format) {
   20|  3.93k|    switch (ds_format) {
  ------------------
  |  Branch (20:13): [True: 3.92k, False: 10]
  ------------------
   21|  1.15k|        case 104: case 105: case 108: case 110: case 111:
  ------------------
  |  Branch (21:9): [True: 650, False: 3.28k]
  |  Branch (21:19): [True: 333, False: 3.59k]
  |  Branch (21:29): [True: 138, False: 3.79k]
  |  Branch (21:39): [True: 11, False: 3.92k]
  |  Branch (21:49): [True: 22, False: 3.91k]
  ------------------
   22|  3.92k|        case 113: case 114: case 115: case 117: case 118: case 119:
  ------------------
  |  Branch (22:9): [True: 460, False: 3.47k]
  |  Branch (22:19): [True: 100, False: 3.83k]
  |  Branch (22:29): [True: 31, False: 3.90k]
  |  Branch (22:39): [True: 1.71k, False: 2.21k]
  |  Branch (22:49): [True: 333, False: 3.59k]
  |  Branch (22:59): [True: 129, False: 3.80k]
  ------------------
   23|  3.92k|            return 1;
   24|  3.93k|    }
   25|     10|    return 0;
   26|  3.93k|}
dta_ctx_alloc:
   28|  4.40k|dta_ctx_t *dta_ctx_alloc(readstat_io_t *io) {
   29|  4.40k|    dta_ctx_t *ctx = calloc(1, sizeof(dta_ctx_t));
   30|  4.40k|    if (ctx == NULL) {
  ------------------
  |  Branch (30:9): [True: 0, False: 4.40k]
  ------------------
   31|      0|        return NULL;
   32|      0|    }
   33|       |
   34|  4.40k|    ctx->io = io;
   35|  4.40k|    ctx->initialized = 0;
   36|       |
   37|  4.40k|    return ctx;
   38|  4.40k|}
dta_ctx_init:
   42|  3.93k|        const char *input_encoding, const char *output_encoding) {
   43|  3.93k|    readstat_error_t retval = READSTAT_OK;
   44|  3.93k|    int machine_byteorder = DTA_HILO;
  ------------------
  |  |  129|  3.93k|#define DTA_HILO  0x01
  ------------------
   45|  3.93k|    if (!dta_format_is_supported(ds_format))
  ------------------
  |  Branch (45:9): [True: 10, False: 3.92k]
  ------------------
   46|     10|        return READSTAT_ERROR_UNSUPPORTED_FILE_FORMAT_VERSION;
   47|       |
   48|  3.92k|    if (machine_is_little_endian()) {
  ------------------
  |  Branch (48:9): [True: 3.92k, False: 0]
  ------------------
   49|  3.92k|        machine_byteorder = DTA_LOHI;
  ------------------
  |  |  130|  3.92k|#define DTA_LOHI  0x02
  ------------------
   50|  3.92k|    }
   51|       |
   52|  3.92k|    ctx->bswap = (byteorder != machine_byteorder);
   53|  3.92k|    ctx->ds_format = ds_format;
   54|  3.92k|    ctx->endianness = byteorder == DTA_LOHI ? READSTAT_ENDIAN_LITTLE : READSTAT_ENDIAN_BIG;
  ------------------
  |  |  130|  3.92k|#define DTA_LOHI  0x02
  ------------------
  |  Branch (54:23): [True: 1.69k, False: 2.22k]
  ------------------
   55|       |
   56|  3.92k|    ctx->nvar = nvar;
   57|  3.92k|    ctx->nobs = nobs;
   58|       |
   59|  3.92k|    if (ctx->nvar) {
  ------------------
  |  Branch (59:9): [True: 2.60k, False: 1.31k]
  ------------------
   60|  2.60k|        if ((ctx->variables = calloc(ctx->nvar, sizeof(readstat_variable_t *))) == NULL) {
  ------------------
  |  Branch (60:13): [True: 21, False: 2.58k]
  ------------------
   61|     21|            retval = READSTAT_ERROR_MALLOC;
   62|     21|            goto cleanup;
   63|     21|        }
   64|  2.60k|    }
   65|       |
   66|  3.90k|    ctx->machine_is_twos_complement = READSTAT_MACHINE_IS_TWOS_COMPLEMENT;
  ------------------
  |  |    8|  3.90k|#define READSTAT_MACHINE_IS_TWOS_COMPLEMENT 0
  ------------------
   67|       |
   68|  3.90k|    if (ds_format < 105) {
  ------------------
  |  Branch (68:9): [True: 650, False: 3.25k]
  ------------------
   69|    650|        ctx->fmtlist_entry_len = 7;
   70|  3.25k|    } else if (ds_format < 114) {
  ------------------
  |  Branch (70:16): [True: 964, False: 2.28k]
  ------------------
   71|    964|        ctx->fmtlist_entry_len = 12;
   72|  2.28k|    } else if (ds_format < 118) {
  ------------------
  |  Branch (72:16): [True: 1.84k, False: 441]
  ------------------
   73|  1.84k|        ctx->fmtlist_entry_len = 49;
   74|  1.84k|    } else {
   75|    441|        ctx->fmtlist_entry_len = 57;
   76|    441|    }
   77|       |    
   78|  3.90k|    if (ds_format >= 117) {
  ------------------
  |  Branch (78:9): [True: 2.15k, False: 1.74k]
  ------------------
   79|  2.15k|        ctx->typlist_version = 117;
   80|  2.15k|    } else if (ds_format >= 111) {
  ------------------
  |  Branch (80:16): [True: 613, False: 1.13k]
  ------------------
   81|    613|        ctx->typlist_version = 111;
   82|  1.13k|    } else {
   83|  1.13k|        ctx->typlist_version = 0;
   84|  1.13k|    }
   85|       |
   86|  3.90k|    if (ds_format >= 119) {
  ------------------
  |  Branch (86:9): [True: 108, False: 3.79k]
  ------------------
   87|       |        /* The 8-byte (v,o) field in the data is a 3-byte v and a 5-byte o */
   88|    108|        ctx->data_label_len_len = 2;
   89|    108|        ctx->strl_v_len = 3;
   90|    108|        ctx->strl_o_len = 5;
   91|  3.79k|    } else if (ds_format >= 118) {
  ------------------
  |  Branch (91:16): [True: 333, False: 3.46k]
  ------------------
   92|    333|        ctx->data_label_len_len = 2;
   93|    333|        ctx->strl_v_len = 2;
   94|    333|        ctx->strl_o_len = 6;
   95|  3.46k|    } else if (ds_format >= 117) {
  ------------------
  |  Branch (95:16): [True: 1.71k, False: 1.74k]
  ------------------
   96|  1.71k|        ctx->data_label_len_len = 1;
   97|  1.71k|        ctx->strl_v_len = 4;
   98|  1.71k|        ctx->strl_o_len = 4;
   99|  1.71k|    }
  100|       |
  101|  3.90k|    if (ds_format < 105) {
  ------------------
  |  Branch (101:9): [True: 650, False: 3.25k]
  ------------------
  102|    650|        ctx->expansion_len_len = 0;
  103|  3.25k|    } else if (ds_format < 110) {
  ------------------
  |  Branch (103:16): [True: 471, False: 2.78k]
  ------------------
  104|    471|        ctx->expansion_len_len = 2;
  105|  2.78k|    } else {
  106|  2.78k|        ctx->expansion_len_len = 4;
  107|  2.78k|    }
  108|       |    
  109|  3.90k|    if (ds_format < 110) {
  ------------------
  |  Branch (109:9): [True: 1.12k, False: 2.78k]
  ------------------
  110|  1.12k|        ctx->lbllist_entry_len = 9;
  111|  1.12k|        ctx->variable_name_len = 9;
  112|  1.12k|        ctx->ch_metadata_len = 9;
  113|  2.78k|    } else if (ds_format < 118) {
  ------------------
  |  Branch (113:16): [True: 2.33k, False: 441]
  ------------------
  114|  2.33k|        ctx->lbllist_entry_len = 33;
  115|  2.33k|        ctx->variable_name_len = 33;
  116|  2.33k|        ctx->ch_metadata_len = 33;
  117|  2.33k|    } else {
  118|    441|        ctx->lbllist_entry_len = 129;
  119|    441|        ctx->variable_name_len = 129;
  120|    441|        ctx->ch_metadata_len = 129;
  121|    441|    }
  122|       |
  123|  3.90k|    if (ds_format < 108) {
  ------------------
  |  Branch (123:9): [True: 983, False: 2.91k]
  ------------------
  124|    983|        ctx->variable_labels_entry_len = 32;
  125|    983|        ctx->data_label_len = 32;
  126|  2.91k|    } else if (ds_format < 118) {
  ------------------
  |  Branch (126:16): [True: 2.47k, False: 441]
  ------------------
  127|  2.47k|        ctx->variable_labels_entry_len = 81;
  128|  2.47k|        ctx->data_label_len = 81;
  129|  2.47k|    } else {
  130|    441|        ctx->variable_labels_entry_len = 321;
  131|    441|        ctx->data_label_len = 321;
  132|    441|    }
  133|       |
  134|  3.90k|    if (ds_format < 105) {
  ------------------
  |  Branch (134:9): [True: 650, False: 3.25k]
  ------------------
  135|    650|        ctx->timestamp_len = 0;
  136|  3.25k|    } else {
  137|  3.25k|        ctx->timestamp_len = 18;
  138|  3.25k|    }
  139|       |
  140|       |    /* Value label tables. Formats 105 and earlier use the "old" layout:
  141|       |     * n (int16), labname (9 bytes), 1 byte of padding, n int16 codes, then n
  142|       |     * 8-byte labels. Format 108 uses the modern layout but with a 9-byte
  143|       |     * label name; later formats widen the name with the variable name. */
  144|  3.90k|    if (ds_format < 108) {
  ------------------
  |  Branch (144:9): [True: 983, False: 2.91k]
  ------------------
  145|    983|        ctx->value_label_table_len_len = 2;
  146|    983|        ctx->value_label_table_labname_len = 9;
  147|    983|        ctx->value_label_table_padding_len = 1;
  148|  2.91k|    } else {
  149|  2.91k|        ctx->value_label_table_len_len = 4;
  150|  2.91k|        if (ds_format < 110) {
  ------------------
  |  Branch (150:13): [True: 138, False: 2.78k]
  ------------------
  151|    138|            ctx->value_label_table_labname_len = 9;
  152|  2.78k|        } else if (ds_format < 118) {
  ------------------
  |  Branch (152:20): [True: 2.33k, False: 441]
  ------------------
  153|  2.33k|            ctx->value_label_table_labname_len = 33;
  154|  2.33k|        } else {
  155|    441|            ctx->value_label_table_labname_len = 129;
  156|    441|        }
  157|  2.91k|        ctx->value_label_table_padding_len = 3;
  158|  2.91k|    }
  159|       |
  160|  3.90k|    if (ds_format < 117) {
  ------------------
  |  Branch (160:9): [True: 1.74k, False: 2.15k]
  ------------------
  161|  1.74k|        ctx->typlist_entry_len = 1;
  162|  1.74k|        ctx->file_is_xmlish = 0;
  163|  2.15k|    } else {
  164|  2.15k|        ctx->typlist_entry_len = 2;
  165|  2.15k|        ctx->file_is_xmlish = 1;
  166|  2.15k|    }
  167|       |
  168|  3.90k|    if (ds_format < 113) {
  ------------------
  |  Branch (168:9): [True: 1.15k, False: 2.74k]
  ------------------
  169|  1.15k|        ctx->max_int8 = DTA_OLD_MAX_INT8;
  ------------------
  |  |  132|  1.15k|#define DTA_OLD_MAX_INT8                     0x7e
  ------------------
  170|  1.15k|        ctx->max_int16 = DTA_OLD_MAX_INT16;
  ------------------
  |  |  133|  1.15k|#define DTA_OLD_MAX_INT16                  0x7ffe
  ------------------
  171|  1.15k|        ctx->max_int32 = DTA_OLD_MAX_INT32;
  ------------------
  |  |  134|  1.15k|#define DTA_OLD_MAX_INT32              0x7ffffffe
  ------------------
  172|  1.15k|        ctx->max_float = DTA_OLD_MAX_FLOAT;
  ------------------
  |  |  135|  1.15k|#define DTA_OLD_MAX_FLOAT              0x7effffff // +1.7e38f
  ------------------
  173|  1.15k|        ctx->max_double = DTA_OLD_MAX_DOUBLE;
  ------------------
  |  |  136|  1.15k|#define DTA_OLD_MAX_DOUBLE     0x7fdfffffffffffffL // +8.9e307
  ------------------
  174|  2.74k|    } else {
  175|  2.74k|        ctx->max_int8 = DTA_113_MAX_INT8;
  ------------------
  |  |  144|  2.74k|#define DTA_113_MAX_INT8                    0x64
  ------------------
  176|  2.74k|        ctx->max_int16 = DTA_113_MAX_INT16;
  ------------------
  |  |  145|  2.74k|#define DTA_113_MAX_INT16                 0x7fe4
  ------------------
  177|  2.74k|        ctx->max_int32 = DTA_113_MAX_INT32;
  ------------------
  |  |  146|  2.74k|#define DTA_113_MAX_INT32             0x7fffffe4
  ------------------
  178|  2.74k|        ctx->max_float = DTA_113_MAX_FLOAT;
  ------------------
  |  |  147|  2.74k|#define DTA_113_MAX_FLOAT             0x7effffff // +1.7e38f
  ------------------
  179|  2.74k|        ctx->max_double = DTA_113_MAX_DOUBLE;
  ------------------
  |  |  148|  2.74k|#define DTA_113_MAX_DOUBLE    0x7fdfffffffffffffL // +8.9e307
  ------------------
  180|       |
  181|  2.74k|        ctx->supports_tagged_missing = 1;
  182|  2.74k|    }
  183|       |
  184|  3.90k|    if (output_encoding) {
  ------------------
  |  Branch (184:9): [True: 3.90k, False: 0]
  ------------------
  185|  3.90k|        if (input_encoding) {
  ------------------
  |  Branch (185:13): [True: 0, False: 3.90k]
  ------------------
  186|      0|            ctx->converter = iconv_open(output_encoding, input_encoding);
  187|  3.90k|        } else if (ds_format < 118) {
  ------------------
  |  Branch (187:20): [True: 3.46k, False: 441]
  ------------------
  188|  3.46k|            ctx->converter = iconv_open(output_encoding, "WINDOWS-1252");
  189|  3.46k|        } else if (strcmp(output_encoding, "UTF-8") != 0) {
  ------------------
  |  Branch (189:20): [True: 0, False: 441]
  ------------------
  190|      0|            ctx->converter = iconv_open(output_encoding, "UTF-8");
  191|      0|        }
  192|  3.90k|        if (ctx->converter == (iconv_t)-1) {
  ------------------
  |  Branch (192:13): [True: 0, False: 3.90k]
  ------------------
  193|      0|            ctx->converter = NULL;
  194|      0|            retval = READSTAT_ERROR_UNSUPPORTED_CHARSET;
  195|      0|            goto cleanup;
  196|      0|        }
  197|  3.90k|    }
  198|       |
  199|  3.90k|    if (ds_format < 119) {
  ------------------
  |  Branch (199:9): [True: 3.79k, False: 108]
  ------------------
  200|  3.79k|        ctx->srtlist_len = (ctx->nvar + 1) * sizeof(int16_t);
  201|  3.79k|    } else {
  202|    108|        ctx->srtlist_len = (ctx->nvar + 1) * sizeof(int32_t);
  203|    108|    }
  204|       |
  205|  3.90k|    if ((ctx->srtlist = malloc(ctx->srtlist_len)) == NULL) {
  ------------------
  |  Branch (205:9): [True: 0, False: 3.90k]
  ------------------
  206|      0|        retval = READSTAT_ERROR_MALLOC;
  207|      0|        goto cleanup;
  208|      0|    }
  209|       |
  210|  3.90k|    if (ctx->nvar > 0) {
  ------------------
  |  Branch (210:9): [True: 2.58k, False: 1.31k]
  ------------------
  211|  2.58k|        if (ctx->file_size > 0) {
  ------------------
  |  Branch (211:13): [True: 2.58k, False: 0]
  ------------------
  212|       |            /* Every variable has a mandatory entry in each descriptor list, so
  213|       |             * a variable count whose descriptors alone exceed the file size
  214|       |             * cannot be read. Reject it here rather than allocating for it. */
  215|  2.58k|            size_t bytes_per_var = ctx->typlist_entry_len + ctx->variable_name_len
  216|  2.58k|                + ctx->fmtlist_entry_len + ctx->lbllist_entry_len + ctx->variable_labels_entry_len
  217|  2.58k|                + (ds_format < 119 ? sizeof(int16_t) : sizeof(int32_t));
  ------------------
  |  Branch (217:20): [True: 2.51k, False: 68]
  ------------------
  218|  2.58k|            if ((uint64_t)ctx->nvar * bytes_per_var > ctx->file_size) {
  ------------------
  |  Branch (218:17): [True: 70, False: 2.51k]
  ------------------
  219|     70|                retval = READSTAT_ERROR_PARSE;
  220|     70|                goto cleanup;
  221|     70|            }
  222|  2.58k|        }
  223|  2.51k|        ctx->typlist_len = ctx->nvar * sizeof(uint16_t);
  224|  2.51k|        ctx->varlist_len = ctx->variable_name_len * ctx->nvar * sizeof(char);
  225|  2.51k|        ctx->fmtlist_len = ctx->fmtlist_entry_len * ctx->nvar * sizeof(char);
  226|  2.51k|        ctx->lbllist_len = ctx->lbllist_entry_len * ctx->nvar * sizeof(char);
  227|  2.51k|        ctx->variable_labels_len = ctx->variable_labels_entry_len * ctx->nvar * sizeof(char);
  228|       |
  229|  2.51k|        if ((ctx->typlist = malloc(ctx->typlist_len)) == NULL) {
  ------------------
  |  Branch (229:13): [True: 0, False: 2.51k]
  ------------------
  230|      0|            retval = READSTAT_ERROR_MALLOC;
  231|      0|            goto cleanup;
  232|      0|        }
  233|  2.51k|        if ((ctx->varlist = malloc(ctx->varlist_len)) == NULL) {
  ------------------
  |  Branch (233:13): [True: 0, False: 2.51k]
  ------------------
  234|      0|            retval = READSTAT_ERROR_MALLOC;
  235|      0|            goto cleanup;
  236|      0|        }
  237|  2.51k|        if ((ctx->fmtlist = malloc(ctx->fmtlist_len)) == NULL) {
  ------------------
  |  Branch (237:13): [True: 0, False: 2.51k]
  ------------------
  238|      0|            retval = READSTAT_ERROR_MALLOC;
  239|      0|            goto cleanup;
  240|      0|        }
  241|  2.51k|        if ((ctx->lbllist = malloc(ctx->lbllist_len)) == NULL) {
  ------------------
  |  Branch (241:13): [True: 0, False: 2.51k]
  ------------------
  242|      0|            retval = READSTAT_ERROR_MALLOC;
  243|      0|            goto cleanup;
  244|      0|        }
  245|  2.51k|        if ((ctx->variable_labels = malloc(ctx->variable_labels_len)) == NULL) {
  ------------------
  |  Branch (245:13): [True: 0, False: 2.51k]
  ------------------
  246|      0|            retval = READSTAT_ERROR_MALLOC;
  247|      0|            goto cleanup;
  248|      0|        }
  249|  2.51k|    }
  250|       |
  251|  3.83k|    ctx->initialized = 1;
  252|       |
  253|  3.92k|cleanup:
  254|  3.92k|    return retval;
  255|  3.83k|}
dta_ctx_free:
  257|  4.40k|void dta_ctx_free(dta_ctx_t *ctx) {
  258|  4.40k|    if (ctx->typlist)
  ------------------
  |  Branch (258:9): [True: 2.51k, False: 1.89k]
  ------------------
  259|  2.51k|        free(ctx->typlist);
  260|  4.40k|    if (ctx->varlist)
  ------------------
  |  Branch (260:9): [True: 2.51k, False: 1.89k]
  ------------------
  261|  2.51k|        free(ctx->varlist);
  262|  4.40k|    if (ctx->srtlist)
  ------------------
  |  Branch (262:9): [True: 3.90k, False: 506]
  ------------------
  263|  3.90k|        free(ctx->srtlist);
  264|  4.40k|    if (ctx->fmtlist)
  ------------------
  |  Branch (264:9): [True: 2.51k, False: 1.89k]
  ------------------
  265|  2.51k|        free(ctx->fmtlist);
  266|  4.40k|    if (ctx->lbllist)
  ------------------
  |  Branch (266:9): [True: 2.51k, False: 1.89k]
  ------------------
  267|  2.51k|        free(ctx->lbllist);
  268|  4.40k|    if (ctx->variable_labels)
  ------------------
  |  Branch (268:9): [True: 2.51k, False: 1.89k]
  ------------------
  269|  2.51k|        free(ctx->variable_labels);
  270|  4.40k|    if (ctx->converter)
  ------------------
  |  Branch (270:9): [True: 3.46k, False: 947]
  ------------------
  271|  3.46k|        iconv_close(ctx->converter);
  272|  4.40k|    if (ctx->data_label)
  ------------------
  |  Branch (272:9): [True: 3.65k, False: 748]
  ------------------
  273|  3.65k|        free(ctx->data_label);
  274|  4.40k|    if (ctx->variables) {
  ------------------
  |  Branch (274:9): [True: 2.58k, False: 1.82k]
  ------------------
  275|  2.58k|        int i;
  276|  2.53G|        for (i=0; i<ctx->nvar; i++) {
  ------------------
  |  Branch (276:19): [True: 2.53G, False: 2.58k]
  ------------------
  277|  2.53G|            if (ctx->variables[i])
  ------------------
  |  Branch (277:17): [True: 23.8k, False: 2.53G]
  ------------------
  278|  23.8k|                free(ctx->variables[i]);
  279|  2.53G|        }
  280|  2.58k|        free(ctx->variables);
  281|  2.58k|    }
  282|  4.40k|    if (ctx->strls) {
  ------------------
  |  Branch (282:9): [True: 958, False: 3.44k]
  ------------------
  283|    958|        int i;
  284|   122k|        for (i=0; i<ctx->strls_count; i++) {
  ------------------
  |  Branch (284:19): [True: 121k, False: 958]
  ------------------
  285|   121k|            free(ctx->strls[i]);
  286|   121k|        }
  287|    958|        free(ctx->strls);
  288|    958|    }
  289|  4.40k|    free(ctx);
  290|  4.40k|}
dta_type_info:
  293|   222k|        size_t *max_len, readstat_type_t *out_type) {
  294|   222k|    readstat_error_t retval = READSTAT_OK;
  295|   222k|    size_t len = 0;
  296|   222k|    readstat_type_t type = READSTAT_TYPE_STRING;
  297|   222k|    if (ctx->typlist_version == 111) {
  ------------------
  |  Branch (297:9): [True: 150k, False: 71.6k]
  ------------------
  298|   150k|        switch (typecode) {
  299|    646|            case DTA_111_TYPE_CODE_INT8:
  ------------------
  |  |  172|    646|#define DTA_111_TYPE_CODE_INT8     0xFB
  ------------------
  |  Branch (299:13): [True: 646, False: 150k]
  ------------------
  300|    646|                len = 1; type = READSTAT_TYPE_INT8; break;
  301|    436|            case DTA_111_TYPE_CODE_INT16:
  ------------------
  |  |  173|    436|#define DTA_111_TYPE_CODE_INT16    0xFC
  ------------------
  |  Branch (301:13): [True: 436, False: 150k]
  ------------------
  302|    436|                len = 2; type = READSTAT_TYPE_INT16; break;
  303|  46.5k|            case DTA_111_TYPE_CODE_INT32:
  ------------------
  |  |  174|  46.5k|#define DTA_111_TYPE_CODE_INT32    0xFD
  ------------------
  |  Branch (303:13): [True: 46.5k, False: 104k]
  ------------------
  304|  46.5k|                len = 4; type = READSTAT_TYPE_INT32; break;
  305|  16.7k|            case DTA_111_TYPE_CODE_FLOAT:
  ------------------
  |  |  175|  16.7k|#define DTA_111_TYPE_CODE_FLOAT    0xFE
  ------------------
  |  Branch (305:13): [True: 16.7k, False: 134k]
  ------------------
  306|  16.7k|                len = 4; type = READSTAT_TYPE_FLOAT; break;
  307|  49.9k|            case DTA_111_TYPE_CODE_DOUBLE:
  ------------------
  |  |  176|  49.9k|#define DTA_111_TYPE_CODE_DOUBLE   0xFF
  ------------------
  |  Branch (307:13): [True: 49.9k, False: 100k]
  ------------------
  308|  49.9k|                len = 8; type = READSTAT_TYPE_DOUBLE; break;
  309|  36.6k|            default:
  ------------------
  |  Branch (309:13): [True: 36.6k, False: 114k]
  ------------------
  310|  36.6k|                len = typecode; type = READSTAT_TYPE_STRING; break;
  311|   150k|        }
  312|   150k|    } else if (ctx->typlist_version == 117) {
  ------------------
  |  Branch (312:16): [True: 36.5k, False: 35.0k]
  ------------------
  313|  36.5k|        switch (typecode) {
  314|  1.13k|            case DTA_117_TYPE_CODE_INT8:
  ------------------
  |  |  165|  1.13k|#define DTA_117_TYPE_CODE_INT8     0xFFFA
  ------------------
  |  Branch (314:13): [True: 1.13k, False: 35.3k]
  ------------------
  315|  1.13k|                len = 1; type = READSTAT_TYPE_INT8; break;
  316|  1.90k|            case DTA_117_TYPE_CODE_INT16:
  ------------------
  |  |  166|  1.90k|#define DTA_117_TYPE_CODE_INT16    0xFFF9
  ------------------
  |  Branch (316:13): [True: 1.90k, False: 34.6k]
  ------------------
  317|  1.90k|                len = 2; type = READSTAT_TYPE_INT16; break;
  318|  1.48k|            case DTA_117_TYPE_CODE_INT32:
  ------------------
  |  |  167|  1.48k|#define DTA_117_TYPE_CODE_INT32    0xFFF8
  ------------------
  |  Branch (318:13): [True: 1.48k, False: 35.0k]
  ------------------
  319|  1.48k|                len = 4; type = READSTAT_TYPE_INT32; break;
  320|    786|            case DTA_117_TYPE_CODE_FLOAT:
  ------------------
  |  |  168|    786|#define DTA_117_TYPE_CODE_FLOAT    0xFFF7
  ------------------
  |  Branch (320:13): [True: 786, False: 35.7k]
  ------------------
  321|    786|                len = 4; type = READSTAT_TYPE_FLOAT; break;
  322|    925|            case DTA_117_TYPE_CODE_DOUBLE:
  ------------------
  |  |  169|    925|#define DTA_117_TYPE_CODE_DOUBLE   0xFFF6
  ------------------
  |  Branch (322:13): [True: 925, False: 35.5k]
  ------------------
  323|    925|                len = 8; type = READSTAT_TYPE_DOUBLE; break;
  324|  27.3k|            case DTA_117_TYPE_CODE_STRL:
  ------------------
  |  |  170|  27.3k|#define DTA_117_TYPE_CODE_STRL     0x8000
  ------------------
  |  Branch (324:13): [True: 27.3k, False: 9.14k]
  ------------------
  325|  27.3k|                len = 8; type = READSTAT_TYPE_STRING_REF; break;
  326|  2.91k|            default:
  ------------------
  |  Branch (326:13): [True: 2.91k, False: 33.5k]
  ------------------
  327|  2.91k|                len = typecode; type = READSTAT_TYPE_STRING; break;
  328|  36.5k|        }
  329|  36.5k|    } else if (typecode < 0x7F) {
  ------------------
  |  Branch (329:16): [True: 26.1k, False: 8.89k]
  ------------------
  330|  26.1k|        switch (typecode) {
  331|  22.7k|            case DTA_OLD_TYPE_CODE_INT8:
  ------------------
  |  |  178|  22.7k|#define DTA_OLD_TYPE_CODE_INT8     'b'
  ------------------
  |  Branch (331:13): [True: 22.7k, False: 3.47k]
  ------------------
  332|  22.7k|                len = 1; type = READSTAT_TYPE_INT8; break;
  333|  1.25k|            case DTA_OLD_TYPE_CODE_INT16:
  ------------------
  |  |  179|  1.25k|#define DTA_OLD_TYPE_CODE_INT16    'i'
  ------------------
  |  Branch (333:13): [True: 1.25k, False: 24.9k]
  ------------------
  334|  1.25k|                len = 2; type = READSTAT_TYPE_INT16; break;
  335|    714|            case DTA_OLD_TYPE_CODE_INT32:
  ------------------
  |  |  180|    714|#define DTA_OLD_TYPE_CODE_INT32    'l'
  ------------------
  |  Branch (335:13): [True: 714, False: 25.4k]
  ------------------
  336|    714|                len = 4; type = READSTAT_TYPE_INT32; break;
  337|    490|            case DTA_OLD_TYPE_CODE_FLOAT:
  ------------------
  |  |  181|    490|#define DTA_OLD_TYPE_CODE_FLOAT    'f'
  ------------------
  |  Branch (337:13): [True: 490, False: 25.7k]
  ------------------
  338|    490|                len = 4; type = READSTAT_TYPE_FLOAT; break;
  339|  1.00k|            case DTA_OLD_TYPE_CODE_DOUBLE:
  ------------------
  |  |  182|  1.00k|#define DTA_OLD_TYPE_CODE_DOUBLE   'd'
  ------------------
  |  Branch (339:13): [True: 1.00k, False: 25.1k]
  ------------------
  340|  1.00k|                len = 8; type = READSTAT_TYPE_DOUBLE; break;
  341|     13|            default:
  ------------------
  |  Branch (341:13): [True: 13, False: 26.1k]
  ------------------
  342|     13|                retval = READSTAT_ERROR_PARSE; break;
  343|  26.1k|        }
  344|  26.1k|    } else {
  345|  8.89k|        len = typecode - 0x7F;
  346|  8.89k|        type = READSTAT_TYPE_STRING;
  347|  8.89k|    }
  348|       |    
  349|   222k|    if (max_len)
  ------------------
  |  Branch (349:9): [True: 222k, False: 0]
  ------------------
  350|   222k|        *max_len = len;
  351|   222k|    if (out_type)
  ------------------
  |  Branch (351:9): [True: 179k, False: 42.8k]
  ------------------
  352|   179k|        *out_type = type;
  353|       |
  354|   222k|    return retval;
  355|   222k|}

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

readstat_parse_dta:
 1244|  4.40k|readstat_error_t readstat_parse_dta(readstat_parser_t *parser, const char *path, void *user_ctx) {
 1245|  4.40k|    readstat_error_t retval = READSTAT_OK;
 1246|  4.40k|    readstat_io_t *io = parser->io;
 1247|  4.40k|    int i;
 1248|  4.40k|    dta_ctx_t    *ctx;
 1249|  4.40k|    size_t file_size = 0;
 1250|       |
 1251|  4.40k|    ctx = dta_ctx_alloc(io);
 1252|       |
 1253|  4.40k|    if (io->open(path, io->io_ctx) == -1) {
  ------------------
  |  Branch (1253:9): [True: 0, False: 4.40k]
  ------------------
 1254|      0|        retval = READSTAT_ERROR_OPEN;
 1255|      0|        goto cleanup;
 1256|      0|    }
 1257|       |
 1258|  4.40k|    char magic[4];
 1259|  4.40k|    if (io->read(magic, 4, io->io_ctx) != 4) {
  ------------------
  |  Branch (1259:9): [True: 2, False: 4.40k]
  ------------------
 1260|      2|        retval = READSTAT_ERROR_READ;
 1261|      2|        goto cleanup;
 1262|      2|    }
 1263|       |
 1264|  4.40k|    file_size = io->seek(0, READSTAT_SEEK_END, io->io_ctx);
 1265|  4.40k|    if (file_size == -1) {
  ------------------
  |  Branch (1265:9): [True: 0, False: 4.40k]
  ------------------
 1266|      0|        if (ctx->handle.error) {
  ------------------
  |  Branch (1266:13): [True: 0, False: 0]
  ------------------
 1267|      0|            snprintf(ctx->error_buf, sizeof(ctx->error_buf), "Failed to seek to end of file");
 1268|      0|            ctx->handle.error(ctx->error_buf, ctx->user_ctx);
 1269|      0|        }
 1270|      0|        retval = READSTAT_ERROR_SEEK;
 1271|      0|        goto cleanup;
 1272|      0|    }
 1273|       |
 1274|  4.40k|    if (io->seek(0, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (1274:9): [True: 0, False: 4.40k]
  ------------------
 1275|      0|        if (ctx->handle.error) {
  ------------------
  |  Branch (1275:13): [True: 0, False: 0]
  ------------------
 1276|      0|            snprintf(ctx->error_buf, sizeof(ctx->error_buf), "Failed to seek to start of file");
 1277|      0|            ctx->handle.error(ctx->error_buf, ctx->user_ctx);
 1278|      0|        }
 1279|      0|        retval = READSTAT_ERROR_SEEK;
 1280|      0|        goto cleanup;
 1281|      0|    }
 1282|       |
 1283|  4.40k|    ctx->file_size = file_size;
 1284|       |
 1285|  4.40k|    if (strncmp(magic, "<sta", 4) == 0) {
  ------------------
  |  Branch (1285:9): [True: 1.13k, False: 3.27k]
  ------------------
 1286|  1.13k|        dta_header64_t header;
 1287|  1.13k|        if ((retval = dta_read_xmlish_header(ctx, &header)) != READSTAT_OK) {
  ------------------
  |  Branch (1287:13): [True: 435, False: 700]
  ------------------
 1288|    435|            goto cleanup;
 1289|    435|        }
 1290|    700|        retval = dta_ctx_init(ctx, header.nvar, header.nobs, header.byteorder, header.ds_format,
 1291|    700|                parser->input_encoding, parser->output_encoding);
 1292|  3.27k|    } else {
 1293|  3.27k|        dta_header_t header;
 1294|  3.27k|        if ((retval = dta_read_header(ctx, &header)) != READSTAT_OK) {
  ------------------
  |  Branch (1294:13): [True: 38, False: 3.23k]
  ------------------
 1295|     38|            goto cleanup;
 1296|     38|        }
 1297|  3.23k|        retval = dta_ctx_init(ctx, header.nvar, header.nobs, header.byteorder, header.ds_format,
 1298|  3.23k|                parser->input_encoding, parser->output_encoding);
 1299|  3.23k|    }
 1300|  3.93k|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (1300:9): [True: 101, False: 3.83k]
  ------------------
 1301|    101|        goto cleanup;
 1302|    101|    }
 1303|       |
 1304|  3.83k|    ctx->user_ctx = user_ctx;
 1305|  3.83k|    ctx->handle = parser->handlers;
 1306|  3.83k|    if (parser->row_offset > 0)
  ------------------
  |  Branch (1306:9): [True: 0, False: 3.83k]
  ------------------
 1307|      0|        ctx->row_offset = parser->row_offset;
 1308|  3.83k|    int64_t nobs_after_skipping = ctx->nobs - ctx->row_offset;
 1309|  3.83k|    if (nobs_after_skipping < 0) {
  ------------------
  |  Branch (1309:9): [True: 167, False: 3.66k]
  ------------------
 1310|    167|        nobs_after_skipping = 0;
 1311|    167|        ctx->row_offset = ctx->nobs;
 1312|    167|    }
 1313|  3.83k|    ctx->row_limit = nobs_after_skipping;
 1314|  3.83k|    if (parser->row_limit > 0 && parser->row_limit < nobs_after_skipping)
  ------------------
  |  Branch (1314:9): [True: 0, False: 3.83k]
  |  Branch (1314:34): [True: 0, False: 0]
  ------------------
 1315|      0|        ctx->row_limit = parser->row_limit;
 1316|       |
 1317|  3.83k|    retval = dta_update_progress(ctx);
 1318|  3.83k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (1318:9): [True: 0, False: 3.83k]
  ------------------
 1319|      0|        goto cleanup;
 1320|       |    
 1321|  3.83k|    if ((retval = dta_read_label_and_timestamp(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1321:9): [True: 462, False: 3.36k]
  ------------------
 1322|    462|        goto cleanup;
 1323|       |
 1324|  3.36k|    if ((retval = dta_read_tag(ctx, "</header>")) != READSTAT_OK) {
  ------------------
  |  Branch (1324:9): [True: 9, False: 3.36k]
  ------------------
 1325|      9|        goto cleanup;
 1326|      9|    }
 1327|       |
 1328|  3.36k|    if (ctx->handle.metadata) {
  ------------------
  |  Branch (1328:9): [True: 3.36k, False: 0]
  ------------------
 1329|  3.36k|        readstat_metadata_t metadata = {
 1330|  3.36k|            .row_count = ctx->row_limit,
 1331|  3.36k|            .var_count = ctx->nvar,
 1332|  3.36k|            .file_label = ctx->data_label,
 1333|  3.36k|            .creation_time = ctx->timestamp,
 1334|  3.36k|            .modified_time = ctx->timestamp,
 1335|  3.36k|            .file_format_version = ctx->ds_format,
 1336|  3.36k|            .is64bit = ctx->ds_format >= 118,
 1337|  3.36k|            .endianness = ctx->endianness
 1338|  3.36k|        };
 1339|  3.36k|        if (ctx->handle.metadata(&metadata, user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|  3.36k|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (1339:13): [True: 0, False: 3.36k]
  ------------------
 1340|      0|            retval = READSTAT_ERROR_USER_ABORT;
 1341|      0|            goto cleanup;
 1342|      0|        }
 1343|  3.36k|    }
 1344|       |
 1345|  3.36k|    if ((retval = dta_read_map(ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (1345:9): [True: 13, False: 3.34k]
  ------------------
 1346|     13|        retval = READSTAT_ERROR_READ;
 1347|     13|        goto cleanup;
 1348|     13|    }
 1349|       |
 1350|  3.34k|    if ((retval = dta_read_descriptors(ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (1350:9): [True: 176, False: 3.17k]
  ------------------
 1351|    176|        goto cleanup;
 1352|    176|    }
 1353|       |
 1354|  46.0k|    for (i=0; i<ctx->nvar; i++) {
  ------------------
  |  Branch (1354:15): [True: 42.8k, False: 3.15k]
  ------------------
 1355|  42.8k|        size_t      max_len;
 1356|  42.8k|        if ((retval = dta_type_info(ctx->typlist[i], ctx, &max_len, NULL)) != READSTAT_OK)
  ------------------
  |  Branch (1356:13): [True: 13, False: 42.8k]
  ------------------
 1357|     13|            goto cleanup;
 1358|       |
 1359|  42.8k|        ctx->record_len += max_len;
 1360|  42.8k|    }
 1361|       |
 1362|  3.15k|    if (ctx->nvar > 0 && ctx->record_len == 0) {
  ------------------
  |  Branch (1362:9): [True: 2.30k, False: 853]
  |  Branch (1362:26): [True: 3, False: 2.30k]
  ------------------
 1363|      3|        retval = READSTAT_ERROR_PARSE;
 1364|      3|        goto cleanup;
 1365|      3|    }
 1366|       |
 1367|  3.15k|    if ((retval = dta_handle_variables(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1367:9): [True: 14, False: 3.14k]
  ------------------
 1368|     14|        goto cleanup;
 1369|       |
 1370|  3.14k|    if ((retval = dta_read_expansion_fields(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1370:9): [True: 720, False: 2.42k]
  ------------------
 1371|    720|        goto cleanup;
 1372|       |
 1373|  2.42k|    if (!ctx->file_is_xmlish) {
  ------------------
  |  Branch (1373:9): [True: 1.28k, False: 1.13k]
  ------------------
 1374|  1.28k|        ctx->data_offset = io->seek(0, READSTAT_SEEK_CUR, io->io_ctx);
 1375|  1.28k|        if (ctx->data_offset == -1) {
  ------------------
  |  Branch (1375:13): [True: 0, False: 1.28k]
  ------------------
 1376|      0|            retval = READSTAT_ERROR_SEEK;
 1377|      0|            goto cleanup;
 1378|      0|        }
 1379|  1.28k|        ctx->value_labels_offset = ctx->data_offset + ctx->record_len * ctx->nobs;
 1380|  1.28k|    }
 1381|       |
 1382|  2.42k|    if ((retval = dta_read_strls(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1382:9): [True: 428, False: 1.99k]
  ------------------
 1383|    428|        goto cleanup;
 1384|       |
 1385|  1.99k|    if ((retval = dta_read_data(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1385:9): [True: 1.16k, False: 830]
  ------------------
 1386|  1.16k|        goto cleanup;
 1387|       |
 1388|    830|    if ((retval = dta_handle_value_labels(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1388:9): [True: 341, False: 489]
  ------------------
 1389|    341|        goto cleanup;
 1390|       |
 1391|  4.40k|cleanup:
 1392|  4.40k|    io->close(io->io_ctx);
 1393|  4.40k|    if (ctx)
  ------------------
  |  Branch (1393:9): [True: 4.40k, False: 0]
  ------------------
 1394|  4.40k|        dta_ctx_free(ctx);
 1395|       |
 1396|  4.40k|    return retval;
 1397|    830|}
readstat_dta_read.c:dta_read_xmlish_header:
  838|  1.13k|static readstat_error_t dta_read_xmlish_header(dta_ctx_t *ctx, dta_header64_t *header) {
  839|  1.13k|    readstat_error_t retval = READSTAT_OK;
  840|       |    
  841|  1.13k|    if ((retval = dta_read_tag(ctx, "<stata_dta>")) != READSTAT_OK) {
  ------------------
  |  Branch (841:9): [True: 69, False: 1.06k]
  ------------------
  842|     69|        goto cleanup;
  843|     69|    }
  844|  1.06k|    if ((retval = dta_read_tag(ctx, "<header>")) != READSTAT_OK) {
  ------------------
  |  Branch (844:9): [True: 76, False: 990]
  ------------------
  845|     76|        goto cleanup;
  846|     76|    }
  847|       |
  848|    990|    char ds_format[3];
  849|    990|    if ((retval = dta_read_chunk(ctx, "<release>", ds_format,
  ------------------
  |  Branch (849:9): [True: 166, False: 824]
  ------------------
  850|    990|                    sizeof(ds_format), "</release>")) != READSTAT_OK) {
  851|    166|        goto cleanup;
  852|    166|    }
  853|       |
  854|    824|    header->ds_format = 100 * (ds_format[0] - '0') + 10 * (ds_format[1] - '0') + (ds_format[2] - '0');
  855|       |
  856|    824|    char byteorder[3];
  857|    824|    int byteswap = 0;
  858|    824|    if ((retval = dta_read_chunk(ctx, "<byteorder>", byteorder, 
  ------------------
  |  Branch (858:9): [True: 49, False: 775]
  ------------------
  859|    824|                    sizeof(byteorder), "</byteorder>")) != READSTAT_OK) {
  860|     49|        goto cleanup;
  861|     49|    }
  862|    775|    if (strncmp(byteorder, "MSF", 3) == 0) {
  ------------------
  |  Branch (862:9): [True: 42, False: 733]
  ------------------
  863|     42|        header->byteorder = DTA_HILO;
  ------------------
  |  |  129|     42|#define DTA_HILO  0x01
  ------------------
  864|    733|    } else if (strncmp(byteorder, "LSF", 3) == 0) {
  ------------------
  |  Branch (864:16): [True: 691, False: 42]
  ------------------
  865|    691|        header->byteorder = DTA_LOHI;
  ------------------
  |  |  130|    691|#define DTA_LOHI  0x02
  ------------------
  866|    691|    } else {
  867|     42|        retval = READSTAT_ERROR_PARSE;
  868|     42|        goto cleanup;
  869|     42|    }
  870|    733|    byteswap = (header->byteorder == DTA_LOHI) ^ machine_is_little_endian();
  ------------------
  |  |  130|    733|#define DTA_LOHI  0x02
  ------------------
  871|       |
  872|    733|    if (header->ds_format >= 119) {
  ------------------
  |  Branch (872:9): [True: 84, False: 649]
  ------------------
  873|     84|        uint32_t nvar;
  874|     84|        if ((retval = dta_read_chunk(ctx, "<K>", &nvar, 
  ------------------
  |  Branch (874:13): [True: 6, False: 78]
  ------------------
  875|     84|                        sizeof(uint32_t), "</K>")) != READSTAT_OK) {
  876|      6|            goto cleanup;
  877|      6|        }
  878|     78|        header->nvar = byteswap ? byteswap4(nvar) : nvar;
  ------------------
  |  Branch (878:24): [True: 29, False: 49]
  ------------------
  879|    649|    } else {
  880|    649|        uint16_t nvar;
  881|    649|        if ((retval = dta_read_chunk(ctx, "<K>", &nvar, 
  ------------------
  |  Branch (881:13): [True: 11, False: 638]
  ------------------
  882|    649|                        sizeof(uint16_t), "</K>")) != READSTAT_OK) {
  883|     11|            goto cleanup;
  884|     11|        }
  885|    638|        header->nvar = byteswap ? byteswap2(nvar) : nvar;
  ------------------
  |  Branch (885:24): [True: 5, False: 633]
  ------------------
  886|    638|    }
  887|       |
  888|    716|    if (header->ds_format >= 118) {
  ------------------
  |  Branch (888:9): [True: 405, False: 311]
  ------------------
  889|    405|        uint64_t nobs;
  890|    405|        if ((retval = dta_read_chunk(ctx, "<N>", &nobs, 
  ------------------
  |  Branch (890:13): [True: 4, False: 401]
  ------------------
  891|    405|                        sizeof(uint64_t), "</N>")) != READSTAT_OK) {
  892|      4|            goto cleanup;
  893|      4|        }
  894|    401|        header->nobs = byteswap ? byteswap8(nobs) : nobs;
  ------------------
  |  Branch (894:24): [True: 28, False: 373]
  ------------------
  895|    401|    } else {
  896|    311|        uint32_t nobs;
  897|    311|        if ((retval = dta_read_chunk(ctx, "<N>", &nobs, 
  ------------------
  |  Branch (897:13): [True: 12, False: 299]
  ------------------
  898|    311|                        sizeof(uint32_t), "</N>")) != READSTAT_OK) {
  899|     12|            goto cleanup;
  900|     12|        }
  901|    299|        header->nobs = byteswap ? byteswap4(nobs) : nobs;
  ------------------
  |  Branch (901:24): [True: 1, False: 298]
  ------------------
  902|    299|    }
  903|       |
  904|  1.13k|cleanup:
  905|  1.13k|    return retval;
  906|    716|}
readstat_dta_read.c:dta_read_chunk:
   92|  24.3k|        const char *end_tag) {
   93|  24.3k|    char *dst_buffer = (char *)dst;
   94|  24.3k|    readstat_io_t *io = ctx->io;
   95|  24.3k|    readstat_error_t retval = READSTAT_OK;
   96|       |
   97|  24.3k|    if ((retval = dta_read_tag(ctx, start_tag)) != READSTAT_OK)
  ------------------
  |  Branch (97:9): [True: 197, False: 24.2k]
  ------------------
   98|    197|        goto cleanup;
   99|       |
  100|  24.2k|    if (io->read(dst_buffer, dst_len, io->io_ctx) != dst_len) {
  ------------------
  |  Branch (100:9): [True: 76, False: 24.1k]
  ------------------
  101|     76|        retval = READSTAT_ERROR_READ;
  102|     76|        goto cleanup;
  103|     76|    }
  104|       |
  105|  24.1k|    if ((retval = dta_read_tag(ctx, end_tag)) != READSTAT_OK)
  ------------------
  |  Branch (105:9): [True: 164, False: 23.9k]
  ------------------
  106|    164|        goto cleanup;
  107|       |
  108|  24.3k|cleanup:
  109|       |
  110|  24.3k|    return retval;
  111|  24.1k|}
readstat_dta_read.c:dta_read_header:
  821|  3.27k|static readstat_error_t dta_read_header(dta_ctx_t *ctx, dta_header_t *header) {
  822|  3.27k|    readstat_error_t retval = READSTAT_OK;
  823|  3.27k|    readstat_io_t *io = ctx->io;
  824|  3.27k|    int bswap = 0;
  825|       |
  826|  3.27k|    if (io->read(header, sizeof(dta_header_t), io->io_ctx) != sizeof(dta_header_t)) {
  ------------------
  |  Branch (826:9): [True: 38, False: 3.23k]
  ------------------
  827|     38|        retval = READSTAT_ERROR_READ;
  828|     38|        goto cleanup;
  829|     38|    }
  830|  3.23k|    bswap = (header->byteorder == DTA_LOHI) ^ machine_is_little_endian();
  ------------------
  |  |  130|  3.23k|#define DTA_LOHI  0x02
  ------------------
  831|  3.23k|    header->nvar = bswap ? byteswap2(header->nvar) : header->nvar;
  ------------------
  |  Branch (831:20): [True: 2.20k, False: 1.02k]
  ------------------
  832|  3.23k|    header->nobs = bswap ? byteswap4(header->nobs) : header->nobs;
  ------------------
  |  Branch (832:20): [True: 2.20k, False: 1.02k]
  ------------------
  833|       |
  834|  3.27k|cleanup:
  835|  3.27k|    return retval;
  836|  3.23k|}
readstat_dta_read.c:dta_update_progress:
   29|   578M|static readstat_error_t dta_update_progress(dta_ctx_t *ctx) {
   30|   578M|    double progress = 0.0;
   31|   578M|    if (ctx->row_limit > 0)
  ------------------
  |  Branch (31:9): [True: 578M, False: 1.47k]
  ------------------
   32|   578M|        progress = 1.0 * ctx->current_row / ctx->row_limit;
   33|   578M|    if (ctx->handle.progress && ctx->handle.progress(progress, ctx->user_ctx) != READSTAT_HANDLER_OK)
  ------------------
  |  |   22|      0|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (33:9): [True: 0, False: 578M]
  |  Branch (33:33): [True: 0, False: 0]
  ------------------
   34|      0|        return READSTAT_ERROR_USER_ABORT;
   35|   578M|    return READSTAT_OK;
   36|   578M|}
readstat_dta_read.c:dta_read_label_and_timestamp:
  908|  3.83k|static readstat_error_t dta_read_label_and_timestamp(dta_ctx_t *ctx) {
  909|  3.83k|    readstat_io_t *io = ctx->io;
  910|  3.83k|    readstat_error_t retval = READSTAT_OK;
  911|  3.83k|    char *data_label_buffer = NULL;
  912|  3.83k|    char *timestamp_buffer = NULL;
  913|  3.83k|    uint16_t label_len = 0;
  914|  3.83k|    unsigned char timestamp_len = 0;
  915|  3.83k|    char last_data_label_char = 0;
  916|  3.83k|    struct tm timestamp = { .tm_isdst = -1 };
  917|       |
  918|  3.83k|    if (ctx->file_is_xmlish) {
  ------------------
  |  Branch (918:9): [True: 2.11k, False: 1.71k]
  ------------------
  919|  2.11k|        if ((retval = dta_read_tag(ctx, "<label>")) != READSTAT_OK) {
  ------------------
  |  Branch (919:13): [True: 122, False: 1.99k]
  ------------------
  920|    122|            goto cleanup;
  921|    122|        }
  922|       |        
  923|  1.99k|        if (ctx->data_label_len_len == 2) {
  ------------------
  |  Branch (923:13): [True: 360, False: 1.63k]
  ------------------
  924|    360|            if (io->read(&label_len, sizeof(uint16_t), io->io_ctx) != sizeof(uint16_t)) {
  ------------------
  |  Branch (924:17): [True: 2, False: 358]
  ------------------
  925|      2|                retval = READSTAT_ERROR_READ;
  926|      2|                goto cleanup;
  927|      2|            }
  928|    358|            label_len = ctx->bswap ? byteswap2(label_len) : label_len;
  ------------------
  |  Branch (928:25): [True: 39, False: 319]
  ------------------
  929|  1.63k|        } else if (ctx->data_label_len_len == 1) {
  ------------------
  |  Branch (929:20): [True: 1.63k, False: 0]
  ------------------
  930|  1.63k|            unsigned char label_len_char;
  931|  1.63k|            if (io->read(&label_len_char, sizeof(unsigned char), io->io_ctx) != sizeof(unsigned char)) {
  ------------------
  |  Branch (931:17): [True: 1, False: 1.63k]
  ------------------
  932|      1|                retval = READSTAT_ERROR_READ;
  933|      1|                goto cleanup;
  934|      1|            }
  935|  1.63k|            label_len = label_len_char;
  936|  1.63k|        }
  937|  1.99k|    } else {
  938|  1.71k|        label_len = ctx->data_label_len;
  939|  1.71k|    }
  940|       |
  941|  3.70k|    if ((data_label_buffer = readstat_malloc(label_len+1)) == NULL) {
  ------------------
  |  Branch (941:9): [True: 0, False: 3.70k]
  ------------------
  942|      0|        retval = READSTAT_ERROR_MALLOC;
  943|      0|        goto cleanup;
  944|      0|    }
  945|       |
  946|  3.70k|    if (io->read(data_label_buffer, label_len, io->io_ctx) != label_len) {
  ------------------
  |  Branch (946:9): [True: 47, False: 3.65k]
  ------------------
  947|     47|        retval = READSTAT_ERROR_READ;
  948|     47|        goto cleanup;
  949|     47|    }
  950|       |
  951|  3.65k|    if (!ctx->file_is_xmlish) {
  ------------------
  |  Branch (951:9): [True: 1.69k, False: 1.96k]
  ------------------
  952|  1.69k|        last_data_label_char = data_label_buffer[label_len-1];
  953|  1.69k|        data_label_buffer[label_len] = '\0';
  954|  1.69k|        label_len = strlen(data_label_buffer);
  955|  1.69k|    }
  956|       |
  957|  3.65k|    if ((ctx->data_label = readstat_malloc(4*label_len+1)) == NULL) {
  ------------------
  |  Branch (957:9): [True: 0, False: 3.65k]
  ------------------
  958|      0|        retval = READSTAT_ERROR_MALLOC;
  959|      0|        goto cleanup;
  960|      0|    }
  961|       |
  962|  3.65k|    if ((retval = readstat_convert(ctx->data_label, 4*label_len+1,
  ------------------
  |  Branch (962:9): [True: 3, False: 3.65k]
  ------------------
  963|  3.65k|                    data_label_buffer, label_len, ctx->converter)) != READSTAT_OK)
  964|      3|        goto cleanup;
  965|       |
  966|  3.65k|    if (ctx->file_is_xmlish) {
  ------------------
  |  Branch (966:9): [True: 1.95k, False: 1.69k]
  ------------------
  967|  1.95k|        if ((retval = dta_read_tag(ctx, "</label>")) != READSTAT_OK) {
  ------------------
  |  Branch (967:13): [True: 122, False: 1.83k]
  ------------------
  968|    122|            goto cleanup;
  969|    122|        }
  970|       |        
  971|  1.83k|        if ((retval = dta_read_tag(ctx, "<timestamp>")) != READSTAT_OK) {
  ------------------
  |  Branch (971:13): [True: 87, False: 1.74k]
  ------------------
  972|     87|            goto cleanup;
  973|     87|        }
  974|       |        
  975|  1.74k|        if (io->read(&timestamp_len, 1, io->io_ctx) != 1) {
  ------------------
  |  Branch (975:13): [True: 1, False: 1.74k]
  ------------------
  976|      1|            retval = READSTAT_ERROR_READ;
  977|      1|            goto cleanup;
  978|      1|        }
  979|  1.74k|    } else {
  980|  1.69k|        timestamp_len = ctx->timestamp_len;
  981|  1.69k|    }
  982|       |
  983|  3.44k|    if (timestamp_len) {
  ------------------
  |  Branch (983:9): [True: 1.68k, False: 1.75k]
  ------------------
  984|  1.68k|        if ((timestamp_buffer = readstat_malloc(timestamp_len)) == NULL) {
  ------------------
  |  Branch (984:13): [True: 0, False: 1.68k]
  ------------------
  985|      0|            retval = READSTAT_ERROR_MALLOC;
  986|      0|            goto cleanup;
  987|      0|        }
  988|       |
  989|  1.68k|        if (io->read(timestamp_buffer, timestamp_len, io->io_ctx) != timestamp_len) {
  ------------------
  |  Branch (989:13): [True: 13, False: 1.67k]
  ------------------
  990|     13|            retval = READSTAT_ERROR_READ;
  991|     13|            goto cleanup;
  992|     13|        }
  993|       |
  994|  1.67k|        if (!ctx->file_is_xmlish)
  ------------------
  |  Branch (994:13): [True: 1.06k, False: 613]
  ------------------
  995|  1.06k|            timestamp_len--;
  996|       |
  997|  1.67k|        if (timestamp_buffer[0]) {
  ------------------
  |  Branch (997:13): [True: 1.27k, False: 404]
  ------------------
  998|  1.27k|            if (timestamp_buffer[timestamp_len-1] == '\0' && last_data_label_char != '\0') {
  ------------------
  |  Branch (998:17): [True: 207, False: 1.06k]
  |  Branch (998:62): [True: 146, False: 61]
  ------------------
  999|       |                /* Stupid hack for miswritten files with off-by-one timestamp, DTA 114 era? */
 1000|    146|                memmove(timestamp_buffer+1, timestamp_buffer, timestamp_len-1);
 1001|    146|                timestamp_buffer[0] = last_data_label_char;
 1002|    146|            }
 1003|  1.27k|            if (dta_parse_timestamp(timestamp_buffer, timestamp_len,
  ------------------
  |  Branch (1003:17): [True: 117, False: 1.15k]
  ------------------
 1004|  1.27k|                        &timestamp, ctx->handle.error, ctx->user_ctx) == READSTAT_OK) {
 1005|    117|                ctx->timestamp = mktime(&timestamp);
 1006|    117|            }
 1007|  1.27k|        }
 1008|  1.67k|    }
 1009|       |
 1010|  3.43k|    if ((retval = dta_read_tag(ctx, "</timestamp>")) != READSTAT_OK) {
  ------------------
  |  Branch (1010:9): [True: 64, False: 3.36k]
  ------------------
 1011|     64|        goto cleanup;
 1012|     64|    }
 1013|       |
 1014|  3.83k|cleanup:
 1015|  3.83k|    if (data_label_buffer)
  ------------------
  |  Branch (1015:9): [True: 3.70k, False: 125]
  ------------------
 1016|  3.70k|        free(data_label_buffer);
 1017|  3.83k|    if (timestamp_buffer)
  ------------------
  |  Branch (1017:9): [True: 1.68k, False: 2.14k]
  ------------------
 1018|  1.68k|        free(timestamp_buffer);
 1019|       |
 1020|  3.83k|    return retval;
 1021|  3.43k|}
readstat_dta_read.c:dta_read_tag:
  317|   103k|static readstat_error_t dta_read_tag(dta_ctx_t *ctx, const char *tag) {
  318|   103k|    readstat_error_t retval = READSTAT_OK;
  319|   103k|    if (ctx->initialized && !ctx->file_is_xmlish)
  ------------------
  |  Branch (319:9): [True: 94.4k, False: 8.59k]
  |  Branch (319:29): [True: 54.6k, False: 39.8k]
  ------------------
  320|  54.6k|        return retval;
  321|       |
  322|  48.4k|    char buffer[256];
  323|  48.4k|    size_t len = strlen(tag);
  324|  48.4k|    if (ctx->io->read(buffer, len, ctx->io->io_ctx) != len) {
  ------------------
  |  Branch (324:9): [True: 298, False: 48.1k]
  ------------------
  325|    298|        retval = READSTAT_ERROR_READ;
  326|    298|        goto cleanup;
  327|    298|    }
  328|  48.1k|    if (strncmp(buffer, tag, len) != 0) {
  ------------------
  |  Branch (328:9): [True: 1.45k, False: 46.7k]
  ------------------
  329|  1.45k|        retval = READSTAT_ERROR_PARSE;
  330|  1.45k|        goto cleanup;
  331|  1.45k|    }
  332|  48.4k|cleanup:
  333|  48.4k|    return retval;
  334|  48.1k|}
readstat_dta_read.c:dta_read_map:
  113|  3.36k|static readstat_error_t dta_read_map(dta_ctx_t *ctx) {
  114|  3.36k|    if (!ctx->file_is_xmlish)
  ------------------
  |  Branch (114:9): [True: 1.69k, False: 1.66k]
  ------------------
  115|  1.69k|        return READSTAT_OK;
  116|       |
  117|  1.66k|    readstat_error_t retval = READSTAT_OK;
  118|  1.66k|    uint64_t map_buffer[14];
  119|       |
  120|  1.66k|    if ((retval = dta_read_chunk(ctx, "<map>", map_buffer, 
  ------------------
  |  Branch (120:9): [True: 13, False: 1.65k]
  ------------------
  121|  1.66k|                    sizeof(map_buffer), "</map>")) != READSTAT_OK) {
  122|     13|        goto cleanup;
  123|     13|    }
  124|       |
  125|  1.65k|    ctx->data_offset = ctx->bswap ? byteswap8(map_buffer[9]) : map_buffer[9];
  ------------------
  |  Branch (125:24): [True: 1.08k, False: 574]
  ------------------
  126|  1.65k|    ctx->strls_offset = ctx->bswap ? byteswap8(map_buffer[10]) : map_buffer[10];
  ------------------
  |  Branch (126:25): [True: 1.08k, False: 574]
  ------------------
  127|  1.65k|    ctx->value_labels_offset = ctx->bswap ? byteswap8(map_buffer[11]) : map_buffer[11];
  ------------------
  |  Branch (127:32): [True: 1.08k, False: 574]
  ------------------
  128|       |
  129|  1.66k|cleanup:
  130|  1.66k|    return retval;
  131|  1.65k|}
readstat_dta_read.c:dta_read_descriptors:
  133|  3.34k|static readstat_error_t dta_read_descriptors(dta_ctx_t *ctx) {
  134|  3.34k|    readstat_error_t retval = READSTAT_OK;
  135|  3.34k|    size_t buffer_len = ctx->nvar * ctx->typlist_entry_len;
  136|  3.34k|    unsigned char *buffer = NULL;
  137|  3.34k|    int i;
  138|       |
  139|  3.34k|    if (ctx->nvar && (buffer = readstat_malloc(buffer_len)) == NULL) {
  ------------------
  |  Branch (139:9): [True: 2.43k, False: 913]
  |  Branch (139:22): [True: 0, False: 2.43k]
  ------------------
  140|      0|        retval = READSTAT_ERROR_MALLOC;
  141|      0|        goto cleanup;
  142|      0|    }
  143|       |
  144|  3.34k|    if ((retval = dta_read_chunk(ctx, "<variable_types>", buffer, 
  ------------------
  |  Branch (144:9): [True: 89, False: 3.25k]
  ------------------
  145|  3.34k|                    buffer_len, "</variable_types>")) != READSTAT_OK)
  146|     89|        goto cleanup;
  147|       |
  148|  3.25k|    if (ctx->typlist_entry_len == 1) {
  ------------------
  |  Branch (148:9): [True: 1.69k, False: 1.56k]
  ------------------
  149|  92.4k|        for (i=0; i<ctx->nvar; i++) {
  ------------------
  |  Branch (149:19): [True: 90.8k, False: 1.69k]
  ------------------
  150|  90.8k|            ctx->typlist[i] = buffer[i];
  151|  90.8k|        }
  152|  1.69k|    } else if (ctx->typlist_entry_len == 2) {
  ------------------
  |  Branch (152:16): [True: 1.56k, False: 0]
  ------------------
  153|  1.56k|        memcpy(ctx->typlist, buffer, buffer_len);
  154|  1.56k|        if (ctx->bswap) {
  ------------------
  |  Branch (154:13): [True: 1.01k, False: 554]
  ------------------
  155|  2.08k|            for (i=0; i<ctx->nvar; i++) {
  ------------------
  |  Branch (155:23): [True: 1.07k, False: 1.01k]
  ------------------
  156|  1.07k|                ctx->typlist[i] = byteswap2(ctx->typlist[i]);
  157|  1.07k|            }
  158|  1.01k|        }
  159|  1.56k|    }
  160|       |
  161|  3.25k|    if ((retval = dta_read_chunk(ctx, "<varnames>", ctx->varlist, 
  ------------------
  |  Branch (161:9): [True: 12, False: 3.24k]
  ------------------
  162|  3.25k|                    ctx->varlist_len, "</varnames>")) != READSTAT_OK)
  163|     12|        goto cleanup;
  164|       |
  165|  3.24k|    if ((retval = dta_read_chunk(ctx, "<sortlist>", ctx->srtlist, 
  ------------------
  |  Branch (165:9): [True: 35, False: 3.21k]
  ------------------
  166|  3.24k|                    ctx->srtlist_len, "</sortlist>")) != READSTAT_OK)
  167|     35|        goto cleanup;
  168|       |
  169|  3.21k|    if ((retval = dta_read_chunk(ctx, "<formats>", ctx->fmtlist, 
  ------------------
  |  Branch (169:9): [True: 7, False: 3.20k]
  ------------------
  170|  3.21k|                    ctx->fmtlist_len, "</formats>")) != READSTAT_OK)
  171|      7|        goto cleanup;
  172|       |
  173|  3.20k|    if ((retval = dta_read_chunk(ctx, "<value_label_names>", ctx->lbllist, 
  ------------------
  |  Branch (173:9): [True: 4, False: 3.20k]
  ------------------
  174|  3.20k|                    ctx->lbllist_len, "</value_label_names>")) != READSTAT_OK)
  175|      4|        goto cleanup;
  176|       |
  177|  3.20k|    if ((retval = dta_read_chunk(ctx, "<variable_labels>", ctx->variable_labels, 
  ------------------
  |  Branch (177:9): [True: 29, False: 3.17k]
  ------------------
  178|  3.20k|                    ctx->variable_labels_len, "</variable_labels>")) != READSTAT_OK)
  179|     29|        goto cleanup;
  180|       |
  181|  3.34k|cleanup:
  182|  3.34k|    if (buffer)
  ------------------
  |  Branch (182:9): [True: 2.43k, False: 913]
  ------------------
  183|  2.43k|        free(buffer);
  184|       |
  185|  3.34k|    return retval;
  186|  3.20k|}
readstat_dta_read.c:dta_handle_variables:
 1023|  3.15k|static readstat_error_t dta_handle_variables(dta_ctx_t *ctx) {
 1024|  3.15k|    readstat_error_t retval = READSTAT_OK;
 1025|  3.15k|    int i;
 1026|  3.15k|    int index_after_skipping = 0;
 1027|  3.15k|    char label_set_name[4*129+1];
 1028|       |
 1029|  26.9k|    for (i=0; i<ctx->nvar; i++) {
  ------------------
  |  Branch (1029:15): [True: 23.8k, False: 3.14k]
  ------------------
 1030|  23.8k|        size_t      max_len;
 1031|  23.8k|        readstat_type_t type;
 1032|  23.8k|        retval = dta_type_info(ctx->typlist[i], ctx, &max_len, &type);
 1033|  23.8k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1033:13): [True: 0, False: 23.8k]
  ------------------
 1034|      0|            goto cleanup;
 1035|       |
 1036|  23.8k|        if (type == READSTAT_TYPE_STRING)
  ------------------
  |  Branch (1036:13): [True: 15.9k, False: 7.89k]
  ------------------
 1037|  15.9k|            max_len++; /* might append NULL */
 1038|  23.8k|        if (type == READSTAT_TYPE_STRING_REF) {
  ------------------
  |  Branch (1038:13): [True: 326, False: 23.5k]
  ------------------
 1039|    326|            type = READSTAT_TYPE_STRING;
 1040|    326|            max_len = 0;
 1041|    326|        }
 1042|       |
 1043|  23.8k|        ctx->variables[i] = dta_init_variable(ctx, i, index_after_skipping, type, max_len, &retval);
 1044|  23.8k|        if (ctx->variables[i] == NULL)
  ------------------
  |  Branch (1044:13): [True: 0, False: 23.8k]
  ------------------
 1045|      0|            goto cleanup;
 1046|       |
 1047|  23.8k|        const char *value_labels = NULL;
 1048|  23.8k|        const char *lbllist_entry = &ctx->lbllist[ctx->lbllist_entry_len*i];
 1049|       |
 1050|  23.8k|        if (lbllist_entry[0]) {
  ------------------
  |  Branch (1050:13): [True: 17.4k, False: 6.39k]
  ------------------
 1051|  17.4k|            retval = readstat_convert(label_set_name, sizeof(label_set_name),
 1052|  17.4k|                    lbllist_entry, strnlen(lbllist_entry, ctx->lbllist_entry_len), ctx->converter);
 1053|  17.4k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (1053:17): [True: 14, False: 17.4k]
  ------------------
 1054|     14|                goto cleanup;
 1055|  17.4k|            value_labels = label_set_name;
 1056|  17.4k|        }
 1057|       |
 1058|  23.8k|        int cb_retval = READSTAT_HANDLER_OK;
  ------------------
  |  |   22|  23.8k|#define READSTAT_HANDLER_OK             0
  ------------------
 1059|  23.8k|        if (ctx->handle.variable)
  ------------------
  |  Branch (1059:13): [True: 23.8k, False: 0]
  ------------------
 1060|  23.8k|            cb_retval = ctx->handle.variable(i, ctx->variables[i], value_labels, ctx->user_ctx);
 1061|       |
 1062|  23.8k|        if (cb_retval == READSTAT_HANDLER_ABORT) {
  ------------------
  |  |   23|  23.8k|#define READSTAT_HANDLER_ABORT          1
  ------------------
  |  Branch (1062:13): [True: 0, False: 23.8k]
  ------------------
 1063|      0|            retval = READSTAT_ERROR_USER_ABORT;
 1064|      0|            goto cleanup;
 1065|      0|        }
 1066|       |
 1067|  23.8k|        if (cb_retval == READSTAT_HANDLER_SKIP_VARIABLE) {
  ------------------
  |  |   24|  23.8k|#define READSTAT_HANDLER_SKIP_VARIABLE  2
  ------------------
  |  Branch (1067:13): [True: 0, False: 23.8k]
  ------------------
 1068|      0|            ctx->variables[i]->skip = 1;
 1069|  23.8k|        } else {
 1070|  23.8k|            index_after_skipping++;
 1071|  23.8k|        }
 1072|  23.8k|    }
 1073|  3.15k|cleanup:
 1074|  3.15k|    return retval;
 1075|  3.15k|}
readstat_dta_read.c:dta_init_variable:
   39|  23.8k|        readstat_type_t type, size_t max_len, readstat_error_t *out_retval) {
   40|  23.8k|    readstat_variable_t *variable = calloc(1, sizeof(readstat_variable_t));
   41|       |
   42|  23.8k|    if (variable == NULL) {
  ------------------
  |  Branch (42:9): [True: 0, False: 23.8k]
  ------------------
   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|  23.8k|    variable->type = type;
   48|  23.8k|    variable->index = i;
   49|  23.8k|    variable->index_after_skipping = index_after_skipping;
   50|  23.8k|    variable->storage_width = max_len;
   51|       |
   52|  23.8k|    readstat_convert(variable->name, sizeof(variable->name), 
   53|  23.8k|            &ctx->varlist[ctx->variable_name_len*i],
   54|  23.8k|            strnlen(&ctx->varlist[ctx->variable_name_len*i], ctx->variable_name_len),
   55|  23.8k|            ctx->converter);
   56|       |
   57|  23.8k|    if (ctx->variable_labels[ctx->variable_labels_entry_len*i]) {
  ------------------
  |  Branch (57:9): [True: 8.30k, False: 15.5k]
  ------------------
   58|  8.30k|        readstat_convert(variable->label, sizeof(variable->label),
   59|  8.30k|                &ctx->variable_labels[ctx->variable_labels_entry_len*i],
   60|  8.30k|                strnlen(&ctx->variable_labels[ctx->variable_labels_entry_len*i], ctx->variable_labels_entry_len),
   61|  8.30k|                ctx->converter);
   62|  8.30k|    }
   63|       |
   64|  23.8k|    if (ctx->fmtlist[ctx->fmtlist_entry_len*i]) {
  ------------------
  |  Branch (64:9): [True: 10.8k, False: 13.0k]
  ------------------
   65|  10.8k|        readstat_convert(variable->format, sizeof(variable->format),
   66|  10.8k|                &ctx->fmtlist[ctx->fmtlist_entry_len*i],
   67|  10.8k|                strnlen(&ctx->fmtlist[ctx->fmtlist_entry_len*i], ctx->fmtlist_entry_len),
   68|  10.8k|                ctx->converter);
   69|  10.8k|        if (variable->format[0] == '%') {
  ------------------
  |  Branch (69:13): [True: 3.01k, False: 7.80k]
  ------------------
   70|  3.01k|            if (variable->format[1] == '-') {
  ------------------
  |  Branch (70:17): [True: 981, False: 2.03k]
  ------------------
   71|    981|                variable->alignment = READSTAT_ALIGNMENT_LEFT;
   72|  2.03k|            } else if (variable->format[1] == '~') {
  ------------------
  |  Branch (72:24): [True: 267, False: 1.76k]
  ------------------
   73|    267|                variable->alignment = READSTAT_ALIGNMENT_CENTER;
   74|  1.76k|            } else {
   75|  1.76k|                variable->alignment = READSTAT_ALIGNMENT_RIGHT;
   76|  1.76k|            }
   77|  3.01k|        }
   78|  10.8k|        int display_width;
   79|  10.8k|        if (sscanf(variable->format, "%%%ds", &display_width) == 1 ||
  ------------------
  |  Branch (79:13): [True: 1.18k, False: 9.63k]
  ------------------
   80|  9.63k|                sscanf(variable->format, "%%-%ds", &display_width) == 1) {
  ------------------
  |  Branch (80:17): [True: 493, False: 9.14k]
  ------------------
   81|  1.68k|            variable->display_width = display_width;
   82|  1.68k|        }
   83|  10.8k|    }
   84|       |
   85|  23.8k|    return variable;
   86|  23.8k|}
readstat_dta_read.c:dta_read_expansion_fields:
  188|  3.14k|static readstat_error_t dta_read_expansion_fields(dta_ctx_t *ctx) {
  189|  3.14k|    readstat_error_t retval = READSTAT_OK;
  190|  3.14k|    readstat_io_t *io = ctx->io;
  191|  3.14k|    char *buffer = NULL;
  192|  3.14k|    char *note_buffer = NULL;
  193|       |
  194|  3.14k|    if (ctx->expansion_len_len == 0)
  ------------------
  |  Branch (194:9): [True: 576, False: 2.56k]
  ------------------
  195|    576|        return READSTAT_OK;
  196|       |
  197|  2.56k|    if (ctx->file_is_xmlish && !ctx->handle.note) {
  ------------------
  |  Branch (197:9): [True: 1.54k, False: 1.02k]
  |  Branch (197:32): [True: 0, False: 1.54k]
  ------------------
  198|      0|        if (io->seek(ctx->data_offset, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (198:13): [True: 0, False: 0]
  ------------------
  199|      0|            if (ctx->handle.error) {
  ------------------
  |  Branch (199:17): [True: 0, False: 0]
  ------------------
  200|      0|                snprintf(ctx->error_buf, sizeof(ctx->error_buf),
  201|      0|                        "Failed to seek to data section (offset=%" PRId64 ")",
  202|      0|                        ctx->data_offset);
  203|      0|                ctx->handle.error(ctx->error_buf, ctx->user_ctx);
  204|      0|            }
  205|      0|            return READSTAT_ERROR_SEEK;
  206|      0|        }
  207|      0|        return READSTAT_OK;
  208|      0|    }
  209|       |
  210|  2.56k|    retval = dta_read_tag(ctx, "<characteristics>");
  211|  2.56k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (211:9): [True: 189, False: 2.37k]
  ------------------
  212|    189|        goto cleanup;
  213|       |
  214|  28.1k|    while (1) {
  ------------------
  |  Branch (214:12): [True: 28.1k, Folded]
  ------------------
  215|  28.1k|        size_t len;
  216|  28.1k|        char data_type;
  217|       |
  218|  28.1k|        if (ctx->file_is_xmlish) {
  ------------------
  |  Branch (218:13): [True: 1.85k, False: 26.2k]
  ------------------
  219|  1.85k|            char start[4];
  220|  1.85k|            if (io->read(start, sizeof(start), io->io_ctx) != sizeof(start)) {
  ------------------
  |  Branch (220:17): [True: 11, False: 1.84k]
  ------------------
  221|     11|                retval = READSTAT_ERROR_READ;
  222|     11|                goto cleanup;
  223|     11|            }
  224|  1.84k|            if (memcmp(start, "</ch", sizeof(start)) == 0) {
  ------------------
  |  Branch (224:17): [True: 1.26k, False: 586]
  ------------------
  225|  1.26k|                retval = dta_read_tag(ctx, "aracteristics>");
  226|  1.26k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (226:21): [True: 125, False: 1.13k]
  ------------------
  227|    125|                    goto cleanup;
  228|       |
  229|  1.13k|                break;
  230|  1.26k|            } else if (memcmp(start, "<ch>", sizeof(start)) != 0) {
  ------------------
  |  Branch (230:24): [True: 23, False: 563]
  ------------------
  231|     23|                retval = READSTAT_ERROR_PARSE;
  232|     23|                goto cleanup;
  233|     23|            }
  234|    563|            data_type = 1;
  235|  26.2k|        } else {
  236|  26.2k|            if (io->read(&data_type, 1, io->io_ctx) != 1) {
  ------------------
  |  Branch (236:17): [True: 74, False: 26.1k]
  ------------------
  237|     74|                retval = READSTAT_ERROR_READ;
  238|     74|                goto cleanup;
  239|     74|            }
  240|  26.2k|        }
  241|       |
  242|  26.7k|        if (ctx->expansion_len_len == 2) {
  ------------------
  |  Branch (242:13): [True: 24.6k, False: 2.06k]
  ------------------
  243|  24.6k|            uint16_t len16;
  244|  24.6k|            if (io->read(&len16, sizeof(uint16_t), io->io_ctx) != sizeof(uint16_t)) {
  ------------------
  |  Branch (244:17): [True: 16, False: 24.6k]
  ------------------
  245|     16|                retval = READSTAT_ERROR_READ;
  246|     16|                goto cleanup;
  247|     16|            }
  248|  24.6k|            len = ctx->bswap ? byteswap2(len16) : len16;
  ------------------
  |  Branch (248:19): [True: 1.77k, False: 22.8k]
  ------------------
  249|  24.6k|        } else {
  250|  2.06k|            uint32_t len32;
  251|  2.06k|            if (io->read(&len32, sizeof(uint32_t), io->io_ctx) != sizeof(uint32_t)) {
  ------------------
  |  Branch (251:17): [True: 14, False: 2.04k]
  ------------------
  252|     14|                retval = READSTAT_ERROR_READ;
  253|     14|                goto cleanup;
  254|     14|            }
  255|  2.04k|            len = ctx->bswap ? byteswap4(len32) : len32;
  ------------------
  |  Branch (255:19): [True: 991, False: 1.05k]
  ------------------
  256|  2.04k|        }
  257|       |
  258|  26.7k|        if (data_type == 0 && len == 0)
  ------------------
  |  Branch (258:13): [True: 1.03k, False: 25.6k]
  |  Branch (258:31): [True: 708, False: 327]
  ------------------
  259|    708|            break;
  260|       |        
  261|  25.9k|        if (len > (1<<20)) {
  ------------------
  |  Branch (261:13): [True: 26, False: 25.9k]
  ------------------
  262|     26|            retval = READSTAT_ERROR_NOTE_IS_TOO_LONG;
  263|     26|            goto cleanup;
  264|     26|        }
  265|       |
  266|  25.9k|        if (data_type == 1 && ctx->handle.note && len >= 2 * ctx->ch_metadata_len) {
  ------------------
  |  Branch (266:13): [True: 25.4k, False: 508]
  |  Branch (266:31): [True: 25.4k, False: 0]
  |  Branch (266:51): [True: 2.28k, False: 23.1k]
  ------------------
  267|  2.28k|            if ((buffer = readstat_realloc(buffer, len + 1)) == NULL) {
  ------------------
  |  Branch (267:17): [True: 0, False: 2.28k]
  ------------------
  268|      0|                retval = READSTAT_ERROR_MALLOC;
  269|      0|                goto cleanup;
  270|      0|            }
  271|  2.28k|            buffer[len] = '\0';
  272|       |
  273|  2.28k|            if (io->read(buffer, len, io->io_ctx) != len) {
  ------------------
  |  Branch (273:17): [True: 58, False: 2.22k]
  ------------------
  274|     58|                retval = READSTAT_ERROR_READ;
  275|     58|                goto cleanup;
  276|     58|            }
  277|  2.22k|            int index = 0;
  278|       |            /* _dta[note0] holds the number of notes, not a note */
  279|  2.22k|            if (strcmp(&buffer[0], "_dta") == 0 &&
  ------------------
  |  Branch (279:17): [True: 485, False: 1.73k]
  ------------------
  280|    485|                    sscanf(&buffer[ctx->ch_metadata_len], "note%d", &index) == 1 && index > 0) {
  ------------------
  |  Branch (280:21): [True: 363, False: 122]
  |  Branch (280:85): [True: 292, False: 71]
  ------------------
  281|    292|                const char *note = &buffer[2*ctx->ch_metadata_len];
  282|    292|                size_t note_len = strlen(note);
  283|    292|                if ((note_buffer = readstat_realloc(note_buffer, 4*note_len+1)) == NULL) {
  ------------------
  |  Branch (283:21): [True: 0, False: 292]
  ------------------
  284|      0|                    retval = READSTAT_ERROR_MALLOC;
  285|      0|                    goto cleanup;
  286|      0|                }
  287|    292|                retval = readstat_convert(note_buffer, 4*note_len+1, note, note_len, ctx->converter);
  288|    292|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (288:21): [True: 2, False: 290]
  ------------------
  289|      2|                    goto cleanup;
  290|       |
  291|    290|                if (ctx->handle.note(index, note_buffer, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|    290|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (291:21): [True: 0, False: 290]
  ------------------
  292|      0|                    retval = READSTAT_ERROR_USER_ABORT;
  293|      0|                    goto cleanup;
  294|      0|                }
  295|    290|            }
  296|  23.6k|        } else {
  297|  23.6k|            if (io->seek(len, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (297:17): [True: 132, False: 23.5k]
  ------------------
  298|    132|                retval = READSTAT_ERROR_SEEK;
  299|    132|                goto cleanup;
  300|    132|            }
  301|  23.6k|        }
  302|       |
  303|  25.7k|        retval = dta_read_tag(ctx, "</ch>");
  304|  25.7k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (304:13): [True: 50, False: 25.7k]
  ------------------
  305|     50|            goto cleanup;
  306|  25.7k|    }
  307|       |
  308|  2.56k|cleanup:
  309|  2.56k|    if (buffer)
  ------------------
  |  Branch (309:9): [True: 197, False: 2.36k]
  ------------------
  310|    197|        free(buffer);
  311|  2.56k|    if (note_buffer)
  ------------------
  |  Branch (311:9): [True: 37, False: 2.52k]
  ------------------
  312|     37|        free(note_buffer);
  313|       |
  314|  2.56k|    return retval;
  315|  2.37k|}
readstat_dta_read.c:dta_read_strls:
  441|  2.42k|static readstat_error_t dta_read_strls(dta_ctx_t *ctx) {
  442|  2.42k|    if (!ctx->file_is_xmlish)
  ------------------
  |  Branch (442:9): [True: 1.28k, False: 1.13k]
  ------------------
  443|  1.28k|        return READSTAT_OK;
  444|       |
  445|  1.13k|    readstat_error_t retval = READSTAT_OK;
  446|  1.13k|    readstat_io_t *io = ctx->io;
  447|       |
  448|  1.13k|    if (io->seek(ctx->strls_offset, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (448:9): [True: 102, False: 1.03k]
  ------------------
  449|    102|        if (ctx->handle.error) {
  ------------------
  |  Branch (449:13): [True: 0, False: 102]
  ------------------
  450|      0|            snprintf(ctx->error_buf, sizeof(ctx->error_buf), "Failed to seek to strls section (offset=%" PRId64 ")",
  451|      0|                    ctx->strls_offset);
  452|      0|            ctx->handle.error(ctx->error_buf, ctx->user_ctx);
  453|      0|        }
  454|    102|        retval = READSTAT_ERROR_SEEK;
  455|    102|        goto cleanup;
  456|    102|    }
  457|       |
  458|  1.03k|    retval = dta_read_tag(ctx, "<strls>");
  459|  1.03k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (459:9): [True: 77, False: 958]
  ------------------
  460|     77|        goto cleanup;
  461|       |
  462|    958|    ctx->strls_capacity = 100;
  463|    958|    if ((ctx->strls = readstat_malloc(ctx->strls_capacity * sizeof(dta_strl_t *))) == NULL) {
  ------------------
  |  Branch (463:9): [True: 0, False: 958]
  ------------------
  464|      0|        retval = READSTAT_ERROR_MALLOC;
  465|      0|        goto cleanup;
  466|      0|    }
  467|       |
  468|   122k|    while (1) {
  ------------------
  |  Branch (468:12): [True: 122k, Folded]
  ------------------
  469|   122k|        char tag[3];
  470|   122k|        if (io->read(tag, sizeof(tag), io->io_ctx) != sizeof(tag)) {
  ------------------
  |  Branch (470:13): [True: 19, False: 122k]
  ------------------
  471|     19|            retval = READSTAT_ERROR_READ;
  472|     19|            goto cleanup;
  473|     19|        }
  474|       |
  475|   122k|        if (memcmp(tag, "GSO", sizeof(tag)) == 0) {
  ------------------
  |  Branch (475:13): [True: 121k, False: 843]
  ------------------
  476|   121k|            dta_strl_t strl;
  477|   121k|            retval = dta_read_strl(ctx, &strl);
  478|   121k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (478:17): [True: 27, False: 121k]
  ------------------
  479|     27|                goto cleanup;
  480|       |
  481|   121k|            readstat_off_t pos = io->seek(0, READSTAT_SEEK_CUR, io->io_ctx);
  482|   121k|            if (pos == -1) {
  ------------------
  |  Branch (482:17): [True: 0, False: 121k]
  ------------------
  483|      0|                retval = READSTAT_ERROR_SEEK;
  484|      0|                goto cleanup;
  485|      0|            }
  486|   121k|            if (strl.len > ctx->file_size - pos) {
  ------------------
  |  Branch (486:17): [True: 69, False: 121k]
  ------------------
  487|     69|                if (ctx->handle.error) {
  ------------------
  |  Branch (487:21): [True: 0, False: 69]
  ------------------
  488|      0|                    snprintf(ctx->error_buf, sizeof(ctx->error_buf),
  489|      0|                            "strL length (%zu) exceeds remaining file size (%" PRId64 ")",
  490|      0|                            strl.len, (int64_t)(ctx->file_size - pos));
  491|      0|                    ctx->handle.error(ctx->error_buf, ctx->user_ctx);
  492|      0|                }
  493|     69|                retval = READSTAT_ERROR_PARSE;
  494|     69|                goto cleanup;
  495|     69|            }
  496|       |
  497|   121k|            if (strl.type != DTA_GSO_TYPE_ASCII && strl.type != DTA_GSO_TYPE_BINARY) {
  ------------------
  |  |  163|   243k|#define DTA_GSO_TYPE_ASCII         0x82
  ------------------
                          if (strl.type != DTA_GSO_TYPE_ASCII && strl.type != DTA_GSO_TYPE_BINARY) {
  ------------------
  |  |  162|    171|#define DTA_GSO_TYPE_BINARY        0x81
  ------------------
  |  Branch (497:17): [True: 171, False: 121k]
  |  Branch (497:52): [True: 153, False: 18]
  ------------------
  498|       |                /* Unknown record type: skip its contents */
  499|    153|                if (io->seek(strl.len, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (499:21): [True: 0, False: 153]
  ------------------
  500|      0|                    retval = READSTAT_ERROR_SEEK;
  501|      0|                    goto cleanup;
  502|      0|                }
  503|    153|                continue;
  504|    153|            }
  505|       |
  506|   121k|            if (ctx->strls_count == ctx->strls_capacity) {
  ------------------
  |  Branch (506:17): [True: 165, False: 121k]
  ------------------
  507|       |                /* Every entry corresponds to a GSO record already read from the
  508|       |                 * file, so the pointer array is bounded by the file size. Use
  509|       |                 * plain realloc rather than the capped readstat_realloc, which
  510|       |                 * fails at around 1.6 million strLs. */
  511|    165|                dta_strl_t **new_strls = realloc(ctx->strls, sizeof(dta_strl_t *) * ctx->strls_capacity * 2);
  512|    165|                if (new_strls == NULL) {
  ------------------
  |  Branch (512:21): [True: 0, False: 165]
  ------------------
  513|      0|                    retval = READSTAT_ERROR_MALLOC;
  514|      0|                    goto cleanup;
  515|      0|                }
  516|    165|                ctx->strls = new_strls;
  517|    165|                ctx->strls_capacity *= 2;
  518|    165|            }
  519|       |
  520|       |            /* The record's own length is bounded by the file size above, so
  521|       |             * a plain malloc is safe; Stata allows strLs up to 2 GB. Binary
  522|       |             * strLs (type 129) are kept too and delivered up to their first
  523|       |             * NUL, since the value API only carries C strings. */
  524|   121k|            dta_strl_t *strl_ptr = malloc(sizeof(dta_strl_t) + strl.len + 1);
  525|   121k|            if (strl_ptr == NULL) {
  ------------------
  |  Branch (525:17): [True: 0, False: 121k]
  ------------------
  526|      0|                retval = READSTAT_ERROR_MALLOC;
  527|      0|                goto cleanup;
  528|      0|            }
  529|   121k|            memcpy(strl_ptr, &strl, sizeof(dta_strl_t));
  530|       |
  531|   121k|            ctx->strls[ctx->strls_count++] = strl_ptr;
  532|       |
  533|   121k|            if (io->read(&strl_ptr->data[0], strl_ptr->len, io->io_ctx) != strl_ptr->len) {
  ------------------
  |  Branch (533:17): [True: 0, False: 121k]
  ------------------
  534|      0|                retval = READSTAT_ERROR_READ;
  535|      0|                goto cleanup;
  536|      0|            }
  537|       |            /* Type 130 records must already end in NUL, but don't trust it */
  538|   121k|            strl_ptr->data[strl_ptr->len] = '\0';
  539|   121k|        } else if (memcmp(tag, "</s", sizeof(tag)) == 0) {
  ------------------
  |  Branch (539:20): [True: 756, False: 87]
  ------------------
  540|    756|            retval = dta_read_tag(ctx, "trls>");
  541|    756|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (541:17): [True: 47, False: 709]
  ------------------
  542|     47|                goto cleanup;
  543|       |            /* Stata writes the records in (o,v) order, which the lookup
  544|       |             * relies on; sort in case another writer did not */
  545|    709|            qsort(ctx->strls, ctx->strls_count, sizeof(dta_strl_t *), &dta_compare_strl_ptrs);
  546|    709|            break;
  547|    756|        } else {
  548|     87|            retval = READSTAT_ERROR_PARSE;
  549|     87|            goto cleanup;
  550|     87|        }
  551|   122k|    }
  552|       |
  553|  1.13k|cleanup:
  554|  1.13k|    return retval;
  555|    958|}
readstat_dta_read.c:dta_read_strl:
  434|   121k|static readstat_error_t dta_read_strl(dta_ctx_t *ctx, dta_strl_t *strl) {
  435|   121k|    if (ctx->strl_o_len > 4) {
  ------------------
  |  Branch (435:9): [True: 89, False: 121k]
  ------------------
  436|     89|        return dta_118_read_strl(ctx, strl);
  437|     89|    }
  438|   121k|    return dta_117_read_strl(ctx, strl);
  439|   121k|}
readstat_dta_read.c:dta_118_read_strl:
  415|     89|static readstat_error_t dta_118_read_strl(dta_ctx_t *ctx, dta_strl_t *strl) {
  416|     89|    readstat_error_t retval = READSTAT_OK;
  417|     89|    readstat_io_t *io = ctx->io;
  418|     89|    dta_118_strl_header_t header;
  419|       |
  420|     89|    if (io->read(&header, SIZEOF_DTA_118_STRL_HEADER_T, io->io_ctx) != SIZEOF_DTA_118_STRL_HEADER_T) {
  ------------------
  |  |   43|     89|#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|     89|#define SIZEOF_DTA_118_STRL_HEADER_T 17
  ------------------
  |  Branch (420:9): [True: 4, False: 85]
  ------------------
  421|      4|        retval = READSTAT_ERROR_READ;
  422|      4|        goto cleanup;
  423|      4|    }
  424|       |
  425|     85|    strl->v = ctx->bswap ? byteswap4(header.v) : header.v;
  ------------------
  |  Branch (425:15): [True: 0, False: 85]
  ------------------
  426|     85|    strl->o = ctx->bswap ? byteswap8(header.o) : header.o;
  ------------------
  |  Branch (426:15): [True: 0, False: 85]
  ------------------
  427|     85|    strl->type = header.type;
  428|     85|    strl->len = ctx->bswap ? byteswap4(header.len) : header.len;
  ------------------
  |  Branch (428:17): [True: 0, False: 85]
  ------------------
  429|       |
  430|     89|cleanup:
  431|     89|    return retval;
  432|     85|}
readstat_dta_read.c:dta_117_read_strl:
  396|   121k|static readstat_error_t dta_117_read_strl(dta_ctx_t *ctx, dta_strl_t *strl) {
  397|   121k|    readstat_error_t retval = READSTAT_OK;
  398|   121k|    readstat_io_t *io = ctx->io;
  399|   121k|    dta_117_strl_header_t header;
  400|       |
  401|   121k|    if (io->read(&header, SIZEOF_DTA_117_STRL_HEADER_T, io->io_ctx) != SIZEOF_DTA_117_STRL_HEADER_T) {
  ------------------
  |  |   34|   121k|#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|   121k|#define SIZEOF_DTA_117_STRL_HEADER_T 13
  ------------------
  |  Branch (401:9): [True: 23, False: 121k]
  ------------------
  402|     23|        retval = READSTAT_ERROR_READ;
  403|     23|        goto cleanup;
  404|     23|    }
  405|       |
  406|   121k|    strl->v = ctx->bswap ? byteswap4(header.v) : header.v;
  ------------------
  |  Branch (406:15): [True: 1.11k, False: 120k]
  ------------------
  407|   121k|    strl->o = ctx->bswap ? byteswap4(header.o) : header.o;
  ------------------
  |  Branch (407:15): [True: 1.11k, False: 120k]
  ------------------
  408|   121k|    strl->type = header.type;
  409|   121k|    strl->len = ctx->bswap ? byteswap4(header.len) : header.len;
  ------------------
  |  Branch (409:17): [True: 1.11k, False: 120k]
  ------------------
  410|       |
  411|   121k|cleanup:
  412|   121k|    return retval;
  413|   121k|}
readstat_dta_read.c:dta_compare_strl_ptrs:
  345|  44.0k|static int dta_compare_strl_ptrs(const void *elem1, const void *elem2) {
  346|  44.0k|    const dta_strl_t *key = *(const dta_strl_t **)elem1;
  347|  44.0k|    return dta_compare_strls(key, elem2);
  348|  44.0k|}
readstat_dta_read.c:dta_compare_strls:
  336|   214k|static int dta_compare_strls(const void *elem1, const void *elem2) {
  337|   214k|    const dta_strl_t *key = (const dta_strl_t *)elem1;
  338|   214k|    const dta_strl_t *target = *(const dta_strl_t **)elem2;
  339|   214k|    if (key->o != target->o)
  ------------------
  |  Branch (339:9): [True: 170k, False: 43.8k]
  ------------------
  340|   170k|        return (key->o > target->o) - (key->o < target->o);
  341|  43.8k|    return (key->v > target->v) - (key->v < target->v);
  342|   214k|}
readstat_dta_read.c:dta_read_data:
  787|  1.99k|static readstat_error_t dta_read_data(dta_ctx_t *ctx) {
  788|  1.99k|    readstat_error_t retval = READSTAT_OK;
  789|  1.99k|    readstat_io_t *io = ctx->io;
  790|       |
  791|  1.99k|    if (!ctx->handle.value) {
  ------------------
  |  Branch (791:9): [True: 0, False: 1.99k]
  ------------------
  792|      0|        return READSTAT_OK;
  793|      0|    }
  794|       |
  795|  1.99k|    if (io->seek(ctx->data_offset, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (795:9): [True: 29, False: 1.96k]
  ------------------
  796|     29|        if (ctx->handle.error) {
  ------------------
  |  Branch (796:13): [True: 0, False: 29]
  ------------------
  797|      0|            snprintf(ctx->error_buf, sizeof(ctx->error_buf), "Failed to seek to data section (offset=%" PRId64 ")",
  798|      0|                    ctx->data_offset);
  799|      0|            ctx->handle.error(ctx->error_buf, ctx->user_ctx);
  800|      0|        }
  801|     29|        retval = READSTAT_ERROR_SEEK;
  802|     29|        goto cleanup;
  803|     29|    }
  804|       |
  805|  1.96k|    if ((retval = dta_read_tag(ctx, "<data>")) != READSTAT_OK)
  ------------------
  |  Branch (805:9): [True: 59, False: 1.90k]
  ------------------
  806|     59|        goto cleanup;
  807|       |
  808|  1.90k|    if ((retval = dta_update_progress(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (808:9): [True: 0, False: 1.90k]
  ------------------
  809|      0|        goto cleanup;
  810|       |
  811|  1.90k|    if ((retval = dta_handle_rows(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (811:9): [True: 978, False: 927]
  ------------------
  812|    978|        goto cleanup;
  813|       |
  814|    927|    if ((retval = dta_read_tag(ctx, "</data>")) != READSTAT_OK)
  ------------------
  |  Branch (814:9): [True: 97, False: 830]
  ------------------
  815|     97|        goto cleanup;
  816|       |
  817|  1.99k|cleanup:
  818|  1.99k|    return retval;
  819|    927|}
readstat_dta_read.c:dta_handle_rows:
  743|  1.90k|static readstat_error_t dta_handle_rows(dta_ctx_t *ctx) {
  744|  1.90k|    readstat_io_t *io = ctx->io;
  745|  1.90k|    unsigned char *buf = NULL;
  746|  1.90k|    int64_t i;
  747|  1.90k|    readstat_error_t retval = READSTAT_OK;
  748|       |
  749|  1.90k|    if (ctx->record_len && (buf = readstat_malloc(ctx->record_len)) == NULL) {
  ------------------
  |  Branch (749:9): [True: 1.31k, False: 589]
  |  Branch (749:28): [True: 0, False: 1.31k]
  ------------------
  750|      0|        retval = READSTAT_ERROR_MALLOC;
  751|      0|        goto cleanup;
  752|      0|    }
  753|       |
  754|  1.90k|    if (ctx->row_offset) {
  ------------------
  |  Branch (754:9): [True: 95, False: 1.81k]
  ------------------
  755|     95|        if (io->seek(ctx->record_len * ctx->row_offset, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (755:13): [True: 81, False: 14]
  ------------------
  756|     81|            retval = READSTAT_ERROR_SEEK;
  757|     81|            goto cleanup;
  758|     81|        }
  759|     95|    }
  760|       |
  761|   578M|    for (i=0; i<ctx->row_limit; i++) {
  ------------------
  |  Branch (761:15): [True: 578M, False: 927]
  ------------------
  762|   578M|        if (io->read(buf, ctx->record_len, io->io_ctx) != ctx->record_len) {
  ------------------
  |  Branch (762:13): [True: 869, False: 578M]
  ------------------
  763|    869|            retval = READSTAT_ERROR_READ;
  764|    869|            goto cleanup;
  765|    869|        }
  766|   578M|        if ((retval = dta_handle_row(buf, ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (766:13): [True: 28, False: 578M]
  ------------------
  767|     28|            goto cleanup;
  768|     28|        }
  769|   578M|        ctx->current_row++;
  770|   578M|        if ((retval = dta_update_progress(ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (770:13): [True: 0, False: 578M]
  ------------------
  771|      0|            goto cleanup;
  772|      0|        }
  773|   578M|    }
  774|       |
  775|    927|    if (ctx->row_limit < ctx->nobs - ctx->row_offset) {
  ------------------
  |  Branch (775:9): [True: 0, False: 927]
  ------------------
  776|      0|        if (io->seek(ctx->record_len * (ctx->nobs - ctx->row_offset - ctx->row_limit), READSTAT_SEEK_CUR, io->io_ctx) == -1)
  ------------------
  |  Branch (776:13): [True: 0, False: 0]
  ------------------
  777|      0|            retval = READSTAT_ERROR_SEEK;
  778|      0|    }
  779|       |
  780|  1.90k|cleanup:
  781|  1.90k|    if (buf)
  ------------------
  |  Branch (781:9): [True: 1.31k, False: 589]
  ------------------
  782|  1.31k|        free(buf);
  783|       |
  784|  1.90k|    return retval;
  785|    927|}
readstat_dta_read.c:dta_handle_row:
  675|   578M|static readstat_error_t dta_handle_row(const unsigned char *buf, dta_ctx_t *ctx) {
  676|   578M|    char  str_buf[4*2045+1]; /* str2045 in a legacy code page, converted to UTF-8 */
  677|   578M|    int j;
  678|   578M|    readstat_off_t offset = 0;
  679|   578M|    readstat_error_t retval = READSTAT_OK;
  680|   578M|    for (j=0; j<ctx->nvar; j++) {
  ------------------
  |  Branch (680:15): [True: 155k, False: 578M]
  ------------------
  681|   155k|        size_t max_len;
  682|   155k|        readstat_value_t value = { { 0 } };
  683|       |
  684|   155k|        retval = dta_type_info(ctx->typlist[j], ctx, &max_len, &value.type);
  685|   155k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (685:13): [True: 0, False: 155k]
  ------------------
  686|      0|            goto cleanup;
  687|       |
  688|   155k|        if (ctx->variables[j]->skip) {
  ------------------
  |  Branch (688:13): [True: 0, False: 155k]
  ------------------
  689|      0|            offset += max_len;
  690|      0|            continue;
  691|      0|        }
  692|       |
  693|   155k|        if (offset + max_len > ctx->record_len) {
  ------------------
  |  Branch (693:13): [True: 0, False: 155k]
  ------------------
  694|      0|            retval = READSTAT_ERROR_PARSE;
  695|      0|            goto cleanup;
  696|      0|        }
  697|       |
  698|   155k|        if (value.type == READSTAT_TYPE_STRING) {
  ------------------
  |  Branch (698:13): [True: 2.87k, False: 152k]
  ------------------
  699|  2.87k|            if (max_len == 0) {
  ------------------
  |  Branch (699:17): [True: 2, False: 2.87k]
  ------------------
  700|      2|                retval = READSTAT_ERROR_PARSE;
  701|      2|                goto cleanup;
  702|      2|            }
  703|  2.87k|            size_t str_len = strnlen((const char *)&buf[offset], max_len);
  704|       |            /* Leading and trailing blanks are significant in Stata */
  705|  2.87k|            retval = readstat_convert_notrim(str_buf, sizeof(str_buf),
  706|  2.87k|                    (const char *)&buf[offset], str_len, ctx->converter);
  707|  2.87k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (707:17): [True: 26, False: 2.84k]
  ------------------
  708|     26|                goto cleanup;
  709|  2.84k|            value.v.string_value = str_buf;
  710|   152k|        } else if (value.type == READSTAT_TYPE_STRING_REF) {
  ------------------
  |  Branch (710:20): [True: 26.7k, False: 126k]
  ------------------
  711|  26.7k|            dta_strl_t key = dta_interpret_strl_vo_bytes(ctx, &buf[offset]);
  712|  26.7k|            dta_strl_t **found = bsearch(&key, ctx->strls, ctx->strls_count, sizeof(dta_strl_t *), &dta_compare_strls);
  713|       |
  714|  26.7k|            if (found) {
  ------------------
  |  Branch (714:17): [True: 327, False: 26.3k]
  ------------------
  715|    327|                value.v.string_value = (*found)->data;
  716|  26.3k|            } else if (key.v == 0 && key.o == 0) {
  ------------------
  |  Branch (716:24): [True: 2.35k, False: 24.0k]
  |  Branch (716:38): [True: 1.30k, False: 1.05k]
  ------------------
  717|  1.30k|                value.v.string_value = ""; /* the predefined empty strL */
  718|  1.30k|            }
  719|  26.7k|            value.type = READSTAT_TYPE_STRING;
  720|   126k|        } else if (value.type == READSTAT_TYPE_INT8) {
  ------------------
  |  Branch (720:20): [True: 6.41k, False: 119k]
  ------------------
  721|  6.41k|            value = dta_interpret_int8_bytes(ctx, &buf[offset]);
  722|   119k|        } else if (value.type == READSTAT_TYPE_INT16) {
  ------------------
  |  Branch (722:20): [True: 3.02k, False: 116k]
  ------------------
  723|  3.02k|            value = dta_interpret_int16_bytes(ctx, &buf[offset]);
  724|   116k|        } else if (value.type == READSTAT_TYPE_INT32) {
  ------------------
  |  Branch (724:20): [True: 48.0k, False: 68.7k]
  ------------------
  725|  48.0k|            value = dta_interpret_int32_bytes(ctx, &buf[offset]);
  726|  68.7k|        } else if (value.type == READSTAT_TYPE_FLOAT) {
  ------------------
  |  Branch (726:20): [True: 17.7k, False: 51.0k]
  ------------------
  727|  17.7k|            value = dta_interpret_float_bytes(ctx, &buf[offset]);
  728|  51.0k|        } else if (value.type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (728:20): [True: 51.0k, False: 0]
  ------------------
  729|  51.0k|            value = dta_interpret_double_bytes(ctx, &buf[offset]);
  730|  51.0k|        }
  731|       |
  732|   155k|        if (ctx->handle.value(ctx->current_row, ctx->variables[j], value, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|   155k|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (732:13): [True: 0, False: 155k]
  ------------------
  733|      0|            retval = READSTAT_ERROR_USER_ABORT;
  734|      0|            goto cleanup;
  735|      0|        }
  736|       |
  737|   155k|        offset += max_len;
  738|   155k|    }
  739|   578M|cleanup:
  740|   578M|    return retval;
  741|   578M|}
readstat_dta_read.c:dta_interpret_strl_vo_bytes:
  350|  26.7k|static dta_strl_t dta_interpret_strl_vo_bytes(dta_ctx_t *ctx, const unsigned char *vo_bytes) {
  351|  26.7k|    dta_strl_t strl = {0};
  352|       |
  353|  26.7k|    if (ctx->strl_v_len == 2) {
  ------------------
  |  Branch (353:9): [True: 1.90k, False: 24.8k]
  ------------------
  354|  1.90k|        if (ctx->endianness == READSTAT_ENDIAN_BIG) {
  ------------------
  |  Branch (354:13): [True: 0, False: 1.90k]
  ------------------
  355|      0|            strl.v = (vo_bytes[0] << 8) + vo_bytes[1];
  356|      0|            strl.o = (((uint64_t)vo_bytes[2] << 40)
  357|      0|                    + ((uint64_t)vo_bytes[3] << 32)
  358|      0|                    + ((uint64_t)vo_bytes[4] << 24)
  359|      0|                    + (vo_bytes[5] << 16)
  360|      0|                    + (vo_bytes[6] << 8)
  361|      0|                    + vo_bytes[7]);
  362|  1.90k|        } else {
  363|  1.90k|            strl.v = vo_bytes[0] + (vo_bytes[1] << 8);
  364|  1.90k|            strl.o = (vo_bytes[2] + (vo_bytes[3] << 8)
  365|  1.90k|                    + (vo_bytes[4] << 16)
  366|  1.90k|                    + ((uint64_t)vo_bytes[5] << 24)
  367|  1.90k|                    + ((uint64_t)vo_bytes[6] << 32)
  368|  1.90k|                    + ((uint64_t)vo_bytes[7] << 40));
  369|  1.90k|        }
  370|  24.8k|    } else if (ctx->strl_v_len == 3) {
  ------------------
  |  Branch (370:16): [True: 1.00k, False: 23.8k]
  ------------------
  371|       |        /* Format 119 and later: 3-byte v followed by 5-byte o */
  372|  1.00k|        int i;
  373|  1.00k|        if (ctx->endianness == READSTAT_ENDIAN_BIG) {
  ------------------
  |  Branch (373:13): [True: 0, False: 1.00k]
  ------------------
  374|      0|            strl.v = ((uint32_t)vo_bytes[0] << 16) + ((uint32_t)vo_bytes[1] << 8) + vo_bytes[2];
  375|      0|            for (i=3; i<8; i++) {
  ------------------
  |  Branch (375:23): [True: 0, False: 0]
  ------------------
  376|      0|                strl.o = (strl.o << 8) + vo_bytes[i];
  377|      0|            }
  378|  1.00k|        } else {
  379|  1.00k|            strl.v = vo_bytes[0] + ((uint32_t)vo_bytes[1] << 8) + ((uint32_t)vo_bytes[2] << 16);
  380|  6.02k|            for (i=7; i>=3; i--) {
  ------------------
  |  Branch (380:23): [True: 5.02k, False: 1.00k]
  ------------------
  381|  5.02k|                strl.o = (strl.o << 8) + vo_bytes[i];
  382|  5.02k|            }
  383|  1.00k|        }
  384|  23.8k|    } else if (ctx->strl_v_len == 4) {
  ------------------
  |  Branch (384:16): [True: 23.8k, False: 0]
  ------------------
  385|  23.8k|        uint32_t v, o;
  386|       |
  387|  23.8k|        memcpy(&v, &vo_bytes[0], sizeof(uint32_t));
  388|  23.8k|        memcpy(&o, &vo_bytes[4], sizeof(uint32_t));
  389|       |
  390|  23.8k|        strl.v = ctx->bswap ? byteswap4(v) : v;
  ------------------
  |  Branch (390:18): [True: 2.29k, False: 21.5k]
  ------------------
  391|  23.8k|        strl.o = ctx->bswap ? byteswap4(o) : o;
  ------------------
  |  Branch (391:18): [True: 2.29k, False: 21.5k]
  ------------------
  392|  23.8k|    }
  393|  26.7k|    return strl;
  394|  26.7k|}
readstat_dta_read.c:dta_interpret_int8_bytes:
  557|  6.41k|static readstat_value_t dta_interpret_int8_bytes(dta_ctx_t *ctx, const void *buf) {
  558|  6.41k|    readstat_value_t value = { .type = READSTAT_TYPE_INT8 };
  559|  6.41k|    int8_t byte = 0;
  560|  6.41k|    memcpy(&byte, buf, sizeof(int8_t));
  561|  6.41k|    if (ctx->machine_is_twos_complement) {
  ------------------
  |  Branch (561:9): [True: 0, False: 6.41k]
  ------------------
  562|      0|        byte = ones_to_twos_complement1(byte);
  563|      0|    }
  564|  6.41k|    if (byte > ctx->max_int8) {
  ------------------
  |  Branch (564:9): [True: 947, False: 5.47k]
  ------------------
  565|    947|        if (ctx->supports_tagged_missing && byte > DTA_113_MISSING_INT8) {
  ------------------
  |  |  150|    697|#define DTA_113_MISSING_INT8                 0x65
  ------------------
  |  Branch (565:13): [True: 697, False: 250]
  |  Branch (565:45): [True: 466, False: 231]
  ------------------
  566|    466|            value.tag = 'a' + (byte - DTA_113_MISSING_INT8_A);
  ------------------
  |  |  156|    466|#define DTA_113_MISSING_INT8_A    (DTA_113_MISSING_INT8+1)
  |  |  ------------------
  |  |  |  |  150|    466|#define DTA_113_MISSING_INT8                 0x65
  |  |  ------------------
  ------------------
  567|    466|            value.is_tagged_missing = 1;
  568|    481|        } else {
  569|    481|            value.is_system_missing = 1;
  570|    481|        }
  571|    947|    }
  572|  6.41k|    value.v.i8_value = byte;
  573|       |
  574|  6.41k|    return value;
  575|  6.41k|}
readstat_dta_read.c:dta_interpret_int16_bytes:
  577|  3.02k|static readstat_value_t dta_interpret_int16_bytes(dta_ctx_t *ctx, const void *buf) {
  578|  3.02k|    readstat_value_t value = { .type = READSTAT_TYPE_INT16 };
  579|  3.02k|    int16_t num = 0;
  580|  3.02k|    memcpy(&num, buf, sizeof(int16_t));
  581|  3.02k|    if (ctx->bswap) {
  ------------------
  |  Branch (581:9): [True: 2.33k, False: 697]
  ------------------
  582|  2.33k|        num = byteswap2(num);
  583|  2.33k|    }
  584|  3.02k|    if (ctx->machine_is_twos_complement) {
  ------------------
  |  Branch (584:9): [True: 0, False: 3.02k]
  ------------------
  585|      0|        num = ones_to_twos_complement2(num);
  586|      0|    }
  587|  3.02k|    if (num > ctx->max_int16) {
  ------------------
  |  Branch (587:9): [True: 609, False: 2.41k]
  ------------------
  588|    609|        if (ctx->supports_tagged_missing && num > DTA_113_MISSING_INT16) {
  ------------------
  |  |  151|    397|#define DTA_113_MISSING_INT16              0x7FE5
  ------------------
  |  Branch (588:13): [True: 397, False: 212]
  |  Branch (588:45): [True: 200, False: 197]
  ------------------
  589|    200|            value.tag = 'a' + (num - DTA_113_MISSING_INT16_A);
  ------------------
  |  |  157|    200|#define DTA_113_MISSING_INT16_A   (DTA_113_MISSING_INT16+1)
  |  |  ------------------
  |  |  |  |  151|    200|#define DTA_113_MISSING_INT16              0x7FE5
  |  |  ------------------
  ------------------
  590|    200|            value.is_tagged_missing = 1;
  591|    409|        } else {
  592|    409|            value.is_system_missing = 1;
  593|    409|        }
  594|    609|    }
  595|  3.02k|    value.v.i16_value = num;
  596|       |
  597|  3.02k|    return value;
  598|  3.02k|}
readstat_dta_read.c:dta_interpret_int32_bytes:
  600|  50.7k|static readstat_value_t dta_interpret_int32_bytes(dta_ctx_t *ctx, const void *buf) {
  601|  50.7k|    readstat_value_t value = { .type = READSTAT_TYPE_INT32 };
  602|  50.7k|    int32_t num = 0;
  603|  50.7k|    memcpy(&num, buf, sizeof(int32_t));
  604|  50.7k|    if (ctx->bswap) {
  ------------------
  |  Branch (604:9): [True: 2.18k, False: 48.5k]
  ------------------
  605|  2.18k|        num = byteswap4(num);
  606|  2.18k|    }
  607|  50.7k|    if (ctx->machine_is_twos_complement) {
  ------------------
  |  Branch (607:9): [True: 0, False: 50.7k]
  ------------------
  608|      0|        num = ones_to_twos_complement4(num);
  609|      0|    }
  610|  50.7k|    if (num > ctx->max_int32) {
  ------------------
  |  Branch (610:9): [True: 1.99k, False: 48.7k]
  ------------------
  611|  1.99k|        if (ctx->supports_tagged_missing && num > DTA_113_MISSING_INT32) {
  ------------------
  |  |  152|  1.70k|#define DTA_113_MISSING_INT32          0x7FFFFFE5
  ------------------
  |  Branch (611:13): [True: 1.70k, False: 296]
  |  Branch (611:45): [True: 572, False: 1.13k]
  ------------------
  612|    572|            value.tag = 'a' + (num - DTA_113_MISSING_INT32_A);
  ------------------
  |  |  158|    572|#define DTA_113_MISSING_INT32_A   (DTA_113_MISSING_INT32+1)
  |  |  ------------------
  |  |  |  |  152|    572|#define DTA_113_MISSING_INT32          0x7FFFFFE5
  |  |  ------------------
  ------------------
  613|    572|            value.is_tagged_missing = 1;
  614|  1.42k|        } else {
  615|  1.42k|            value.is_system_missing = 1;
  616|  1.42k|        }
  617|  1.99k|    }
  618|  50.7k|    value.v.i32_value = num;
  619|       |
  620|  50.7k|    return value;
  621|  50.7k|}
readstat_dta_read.c:dta_interpret_float_bytes:
  623|  17.7k|static readstat_value_t dta_interpret_float_bytes(dta_ctx_t *ctx, const void *buf) {
  624|  17.7k|    readstat_value_t value = { .type = READSTAT_TYPE_FLOAT };
  625|  17.7k|    float f_num = NAN;
  626|  17.7k|    int32_t num = 0;
  627|  17.7k|    memcpy(&num, buf, sizeof(int32_t));
  628|  17.7k|    if (ctx->bswap) {
  ------------------
  |  Branch (628:9): [True: 929, False: 16.7k]
  ------------------
  629|    929|        num = byteswap4(num);
  630|    929|    }
  631|  17.7k|    if (num > ctx->max_float) {
  ------------------
  |  Branch (631:9): [True: 4.52k, False: 13.1k]
  ------------------
  632|  4.52k|        int32_t tag_index = (num - DTA_113_MISSING_FLOAT_A) >> 11;
  ------------------
  |  |  159|  4.52k|#define DTA_113_MISSING_FLOAT_A   (DTA_113_MISSING_FLOAT+0x0800)
  |  |  ------------------
  |  |  |  |  153|  4.52k|#define DTA_113_MISSING_FLOAT          0x7F000000
  |  |  ------------------
  ------------------
  633|  4.52k|        if (ctx->supports_tagged_missing && num >= DTA_113_MISSING_FLOAT_A && tag_index <= 25) {
  ------------------
  |  |  159|  8.82k|#define DTA_113_MISSING_FLOAT_A   (DTA_113_MISSING_FLOAT+0x0800)
  |  |  ------------------
  |  |  |  |  153|  4.30k|#define DTA_113_MISSING_FLOAT          0x7F000000
  |  |  ------------------
  ------------------
  |  Branch (633:13): [True: 4.30k, False: 221]
  |  Branch (633:45): [True: 511, False: 3.79k]
  |  Branch (633:79): [True: 201, False: 310]
  ------------------
  634|    201|            value.tag = 'a' + tag_index;
  635|    201|            value.is_tagged_missing = 1;
  636|  4.32k|        } else {
  637|  4.32k|            value.is_system_missing = 1;
  638|  4.32k|        }
  639|  13.1k|    } else {
  640|  13.1k|        memcpy(&f_num, &num, sizeof(int32_t));
  641|  13.1k|        if (isnan(f_num)) /* negative NaN: not a Stata value */
  ------------------
  |  Branch (641:13): [True: 894, False: 12.2k]
  ------------------
  642|    894|            value.is_system_missing = 1;
  643|  13.1k|    }
  644|  17.7k|    value.v.float_value = f_num;
  645|       |
  646|  17.7k|    return value;
  647|  17.7k|}
readstat_dta_read.c:dta_interpret_double_bytes:
  649|  51.0k|static readstat_value_t dta_interpret_double_bytes(dta_ctx_t *ctx, const void *buf) {
  650|  51.0k|    readstat_value_t value = { .type = READSTAT_TYPE_DOUBLE };
  651|  51.0k|    double d_num = NAN;
  652|  51.0k|    int64_t num = 0;
  653|  51.0k|    memcpy(&num, buf, sizeof(int64_t));
  654|  51.0k|    if (ctx->bswap) {
  ------------------
  |  Branch (654:9): [True: 1.26k, False: 49.7k]
  ------------------
  655|  1.26k|        num = byteswap8(num);
  656|  1.26k|    }
  657|  51.0k|    if (num > ctx->max_double) {
  ------------------
  |  Branch (657:9): [True: 6.13k, False: 44.8k]
  ------------------
  658|  6.13k|        int64_t tag_index = (num - DTA_113_MISSING_DOUBLE_A) >> 40;
  ------------------
  |  |  160|  6.13k|#define DTA_113_MISSING_DOUBLE_A  (DTA_113_MISSING_DOUBLE+0x010000000000)
  |  |  ------------------
  |  |  |  |  154|  6.13k|#define DTA_113_MISSING_DOUBLE 0x7FE0000000000000L
  |  |  ------------------
  ------------------
  659|  6.13k|        if (ctx->supports_tagged_missing && num >= DTA_113_MISSING_DOUBLE_A && tag_index <= 25) {
  ------------------
  |  |  160|  12.0k|#define DTA_113_MISSING_DOUBLE_A  (DTA_113_MISSING_DOUBLE+0x010000000000)
  |  |  ------------------
  |  |  |  |  154|  5.89k|#define DTA_113_MISSING_DOUBLE 0x7FE0000000000000L
  |  |  ------------------
  ------------------
  |  Branch (659:13): [True: 5.89k, False: 244]
  |  Branch (659:45): [True: 566, False: 5.32k]
  |  Branch (659:80): [True: 220, False: 346]
  ------------------
  660|    220|            value.tag = 'a' + tag_index;
  661|    220|            value.is_tagged_missing = 1;
  662|  5.91k|        } else {
  663|  5.91k|            value.is_system_missing = 1;
  664|  5.91k|        }
  665|  44.8k|    } else {
  666|  44.8k|        memcpy(&d_num, &num, sizeof(int64_t));
  667|  44.8k|        if (isnan(d_num)) /* negative NaN: not a Stata value */
  ------------------
  |  Branch (667:13): [True: 1.63k, False: 43.2k]
  ------------------
  668|  1.63k|            value.is_system_missing = 1;
  669|  44.8k|    }
  670|  51.0k|    value.v.double_value = d_num;
  671|       |
  672|  51.0k|    return value;
  673|  51.0k|}
readstat_dta_read.c:dta_handle_value_labels:
 1077|    830|static readstat_error_t dta_handle_value_labels(dta_ctx_t *ctx) {
 1078|    830|    readstat_io_t *io = ctx->io;
 1079|    830|    readstat_error_t retval = READSTAT_OK;
 1080|    830|    char *table_buffer = NULL;
 1081|    830|    char *utf8_buffer = NULL;
 1082|       |
 1083|    830|    if (io->seek(ctx->value_labels_offset, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (1083:9): [True: 4, False: 826]
  ------------------
 1084|      4|        if (ctx->handle.error) {
  ------------------
  |  Branch (1084:13): [True: 0, False: 4]
  ------------------
 1085|      0|            snprintf(ctx->error_buf, sizeof(ctx->error_buf), "Failed to seek to value labels section (offset=%" PRId64 ")",
 1086|      0|                    ctx->value_labels_offset);
 1087|      0|            ctx->handle.error(ctx->error_buf, ctx->user_ctx);
 1088|      0|        }
 1089|      4|        retval = READSTAT_ERROR_SEEK;
 1090|      4|        goto cleanup;
 1091|      4|    }
 1092|    826|    if ((retval = dta_read_tag(ctx, "<value_labels>")) != READSTAT_OK) {
  ------------------
  |  Branch (1092:9): [True: 121, False: 705]
  ------------------
 1093|    121|        goto cleanup;
 1094|    121|    }
 1095|       |
 1096|    705|    if (!ctx->handle.value_label) {
  ------------------
  |  Branch (1096:9): [True: 0, False: 705]
  ------------------
 1097|      0|        return READSTAT_OK;
 1098|      0|    }
 1099|       |
 1100|  10.6k|    while (1) {
  ------------------
  |  Branch (1100:12): [True: 10.6k, Folded]
  ------------------
 1101|  10.6k|        size_t len = 0;
 1102|  10.6k|        char raw_labname[129+1];
 1103|  10.6k|        char labname[4*129+1];
 1104|  10.6k|        uint32_t i = 0, n = 0;
 1105|       |
 1106|  10.6k|        if (ctx->value_label_table_len_len == 2) {
  ------------------
  |  Branch (1106:13): [True: 7.58k, False: 3.03k]
  ------------------
 1107|       |            /* Formats 105 and earlier: n (int16), labname, 1 byte of padding,
 1108|       |             * n int16 codes, then n 8-byte labels */
 1109|  7.58k|            uint16_t n16;
 1110|  7.58k|            if (io->read(&n16, sizeof(uint16_t), io->io_ctx) < sizeof(uint16_t))
  ------------------
  |  Branch (1110:17): [True: 80, False: 7.50k]
  ------------------
 1111|     80|                break;
 1112|       |
 1113|  7.50k|            n = ctx->bswap ? byteswap2(n16) : n16;
  ------------------
  |  Branch (1113:17): [True: 1.95k, False: 5.55k]
  ------------------
 1114|  7.50k|            len = 10 * n;
 1115|  7.50k|        } else {
 1116|  3.03k|            if (dta_read_tag(ctx, "<lbl>") != READSTAT_OK) {
  ------------------
  |  Branch (1116:17): [True: 68, False: 2.96k]
  ------------------
 1117|     68|                break;
 1118|     68|            }
 1119|       |
 1120|  2.96k|            int32_t table_header_len;
 1121|  2.96k|            if (io->read(&table_header_len, sizeof(int32_t), io->io_ctx) < sizeof(int32_t))
  ------------------
  |  Branch (1121:17): [True: 63, False: 2.90k]
  ------------------
 1122|     63|                break;
 1123|       |
 1124|  2.90k|            len = table_header_len;
 1125|       |
 1126|  2.90k|            if (ctx->bswap)
  ------------------
  |  Branch (1126:17): [True: 642, False: 2.26k]
  ------------------
 1127|    642|                len = byteswap4(table_header_len);
 1128|  2.90k|        }
 1129|       |
 1130|  10.4k|        if (io->read(raw_labname, ctx->value_label_table_labname_len, io->io_ctx) < ctx->value_label_table_labname_len)
  ------------------
  |  Branch (1130:13): [True: 95, False: 10.3k]
  ------------------
 1131|     95|            break;
 1132|  10.3k|        retval = readstat_convert(labname, sizeof(labname), raw_labname,
 1133|  10.3k|                strnlen(raw_labname, ctx->value_label_table_labname_len), ctx->converter);
 1134|  10.3k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1134:13): [True: 2, False: 10.3k]
  ------------------
 1135|      2|            goto cleanup;
 1136|       |
 1137|  10.3k|        if (io->seek(ctx->value_label_table_padding_len, READSTAT_SEEK_CUR, io->io_ctx) == -1)
  ------------------
  |  Branch (1137:13): [True: 11, False: 10.2k]
  ------------------
 1138|     11|            break;
 1139|       |
 1140|  10.2k|        if (len == 0)
  ------------------
  |  Branch (1140:13): [True: 8.03k, False: 2.26k]
  ------------------
 1141|  8.03k|            continue;
 1142|       |
 1143|  2.26k|        if ((table_buffer = readstat_realloc(table_buffer, len)) == NULL) {
  ------------------
  |  Branch (1143:13): [True: 85, False: 2.17k]
  ------------------
 1144|     85|            retval = READSTAT_ERROR_MALLOC;
 1145|     85|            goto cleanup;
 1146|     85|        }
 1147|       |
 1148|  2.17k|        if (io->read(table_buffer, len, io->io_ctx) < len) {
  ------------------
  |  Branch (1148:13): [True: 94, False: 2.08k]
  ------------------
 1149|     94|            break;
 1150|     94|        }
 1151|       |
 1152|  2.08k|        if (ctx->value_label_table_len_len == 2) {
  ------------------
  |  Branch (1152:13): [True: 321, False: 1.76k]
  ------------------
 1153|  46.4k|            for (i=0; i<n; i++) {
  ------------------
  |  Branch (1153:23): [True: 46.1k, False: 310]
  ------------------
 1154|  46.1k|                int16_t code = 0;
 1155|  46.1k|                char label_buf[4*8+1];
 1156|  46.1k|                const char *label_bytes = &table_buffer[2*n + 8*i];
 1157|       |
 1158|  46.1k|                memcpy(&code, &table_buffer[2*i], sizeof(int16_t));
 1159|  46.1k|                if (ctx->bswap)
  ------------------
  |  Branch (1159:21): [True: 4.60k, False: 41.5k]
  ------------------
 1160|  4.60k|                    code = byteswap2(code);
 1161|       |
 1162|  46.1k|                readstat_value_t value = { .v = { .i32_value = code }, .type = READSTAT_TYPE_INT32 };
 1163|       |
 1164|  46.1k|                retval = readstat_convert(label_buf, sizeof(label_buf),
 1165|  46.1k|                        label_bytes, strnlen(label_bytes, 8), ctx->converter);
 1166|  46.1k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1166:21): [True: 11, False: 46.1k]
  ------------------
 1167|     11|                    goto cleanup;
 1168|       |
 1169|  46.1k|                if (label_buf[0] && ctx->handle.value_label(labname, value, label_buf, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|  17.5k|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (1169:21): [True: 17.5k, False: 28.5k]
  |  Branch (1169:37): [True: 0, False: 17.5k]
  ------------------
 1170|      0|                    retval = READSTAT_ERROR_USER_ABORT;
 1171|      0|                    goto cleanup;
 1172|      0|                }
 1173|  46.1k|            }
 1174|  1.76k|        } else if (len >= 8) {
  ------------------
  |  Branch (1174:20): [True: 1.50k, False: 264]
  ------------------
 1175|  1.50k|            if ((retval = dta_read_tag(ctx, "</lbl>")) != READSTAT_OK) {
  ------------------
  |  Branch (1175:17): [True: 8, False: 1.49k]
  ------------------
 1176|      8|                goto cleanup;
 1177|      8|            }
 1178|       |
 1179|  1.49k|            n = *(uint32_t *)table_buffer;
 1180|       |
 1181|  1.49k|            uint32_t txtlen = *((uint32_t *)table_buffer+1);
 1182|  1.49k|            if (ctx->bswap) {
  ------------------
  |  Branch (1182:17): [True: 322, False: 1.17k]
  ------------------
 1183|    322|                n = byteswap4(n);
 1184|    322|                txtlen = byteswap4(txtlen);
 1185|    322|            }
 1186|       |
 1187|  1.49k|            if (txtlen > len - 8 || n > (len - 8 - txtlen) / 8) {
  ------------------
  |  Branch (1187:17): [True: 38, False: 1.45k]
  |  Branch (1187:37): [True: 40, False: 1.41k]
  ------------------
 1188|     78|                break;
 1189|     78|            }
 1190|       |
 1191|  1.41k|            uint32_t *off = (uint32_t *)table_buffer+2;
 1192|  1.41k|            uint32_t *val = (uint32_t *)table_buffer+2+n;
 1193|  1.41k|            char *txt = &table_buffer[8LL*n+8];
 1194|  1.41k|            size_t utf8_buffer_len = 4*txtlen+1;
 1195|  1.41k|            if (txtlen > MAX_VALUE_LABEL_LEN+1)
  ------------------
  |  |   21|  1.41k|#define MAX_VALUE_LABEL_LEN 32000
  ------------------
  |  Branch (1195:17): [True: 12, False: 1.40k]
  ------------------
 1196|     12|                utf8_buffer_len = 4*MAX_VALUE_LABEL_LEN+1;
  ------------------
  |  |   21|     12|#define MAX_VALUE_LABEL_LEN 32000
  ------------------
 1197|       |
 1198|  1.41k|            utf8_buffer = readstat_realloc(utf8_buffer, utf8_buffer_len);
 1199|       |            /* Much bigger than we need but whatever */
 1200|  1.41k|            if (utf8_buffer == NULL) {
  ------------------
  |  Branch (1200:17): [True: 0, False: 1.41k]
  ------------------
 1201|      0|                retval = READSTAT_ERROR_MALLOC;
 1202|      0|                goto cleanup;
 1203|      0|            }
 1204|       |
 1205|  1.41k|            if (ctx->bswap) {
  ------------------
  |  Branch (1205:17): [True: 275, False: 1.13k]
  ------------------
 1206|  3.55k|                for (i=0; i<n; i++) {
  ------------------
  |  Branch (1206:27): [True: 3.27k, False: 275]
  ------------------
 1207|  3.27k|                    off[i] = byteswap4(off[i]);
 1208|  3.27k|                }
 1209|    275|            }
 1210|       |
 1211|  4.07k|            for (i=0; i<n; i++) {
  ------------------
  |  Branch (1211:23): [True: 2.76k, False: 1.30k]
  ------------------
 1212|  2.76k|                if (off[i] >= txtlen) {
  ------------------
  |  Branch (1212:21): [True: 106, False: 2.66k]
  ------------------
 1213|    106|                    retval = READSTAT_ERROR_PARSE;
 1214|    106|                    goto cleanup;
 1215|    106|                }
 1216|       |
 1217|  2.66k|                readstat_value_t value = dta_interpret_int32_bytes(ctx, &val[i]);
 1218|  2.66k|                size_t max_label_len = txtlen - off[i];
 1219|  2.66k|                if (max_label_len > MAX_VALUE_LABEL_LEN)
  ------------------
  |  |   21|  2.66k|#define MAX_VALUE_LABEL_LEN 32000
  ------------------
  |  Branch (1219:21): [True: 682, False: 1.97k]
  ------------------
 1220|    682|                    max_label_len = MAX_VALUE_LABEL_LEN;
  ------------------
  |  |   21|    682|#define MAX_VALUE_LABEL_LEN 32000
  ------------------
 1221|  2.66k|                size_t label_len = strnlen(&txt[off[i]], max_label_len);
 1222|       |
 1223|  2.66k|                retval = readstat_convert(utf8_buffer, utf8_buffer_len, &txt[off[i]], label_len, ctx->converter);
 1224|  2.66k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1224:21): [True: 4, False: 2.65k]
  ------------------
 1225|      4|                    goto cleanup;
 1226|       |
 1227|  2.65k|                if (ctx->handle.value_label(labname, value, utf8_buffer, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|  2.65k|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (1227:21): [True: 0, False: 2.65k]
  ------------------
 1228|      0|                    retval = READSTAT_ERROR_USER_ABORT;
 1229|      0|                    goto cleanup;
 1230|      0|                }
 1231|  2.65k|            }
 1232|  1.41k|        }
 1233|  2.08k|    }
 1234|       |
 1235|    830|cleanup:
 1236|    830|    if (table_buffer)
  ------------------
  |  Branch (1236:9): [True: 453, False: 377]
  ------------------
 1237|    453|        free(table_buffer);
 1238|    830|    if (utf8_buffer)
  ------------------
  |  Branch (1238:9): [True: 239, False: 591]
  ------------------
 1239|    239|        free(utf8_buffer);
 1240|       |
 1241|    830|    return retval;
 1242|    705|}

rt_open_handler:
    8|  4.40k|int rt_open_handler(const char *path, void *io_ctx) {
    9|  4.40k|    return 0;
   10|  4.40k|}
rt_close_handler:
   12|  4.40k|int rt_close_handler(void *io_ctx) {
   13|  4.40k|    return 0;
   14|  4.40k|}
rt_seek_handler:
   17|   170k|        readstat_io_flags_t whence, void *io_ctx) {
   18|   170k|    rt_buffer_ctx_t *buffer_ctx = (rt_buffer_ctx_t *)io_ctx;
   19|   170k|    readstat_off_t newpos = -1;
   20|   170k|    if (whence == READSTAT_SEEK_SET) {
  ------------------
  |  Branch (20:9): [True: 8.36k, False: 161k]
  ------------------
   21|  8.36k|        newpos = offset;
   22|   161k|    } else if (whence == READSTAT_SEEK_CUR) {
  ------------------
  |  Branch (22:16): [True: 157k, False: 4.40k]
  ------------------
   23|   157k|        newpos = buffer_ctx->pos + offset;
   24|   157k|    } else if (whence == READSTAT_SEEK_END) {
  ------------------
  |  Branch (24:16): [True: 4.40k, False: 0]
  ------------------
   25|  4.40k|        newpos = buffer_ctx->buffer->used + offset;
   26|  4.40k|    }
   27|       |
   28|   170k|    if (newpos < 0)
  ------------------
  |  Branch (28:9): [True: 118, False: 170k]
  ------------------
   29|    118|        return -1;
   30|       |
   31|   170k|    if (newpos > buffer_ctx->buffer->used)
  ------------------
  |  Branch (31:9): [True: 241, False: 169k]
  ------------------
   32|    241|        return -1;
   33|       |
   34|   169k|    buffer_ctx->pos = newpos;
   35|   169k|    return newpos;
   36|   170k|}
rt_read_handler:
   38|   578M|ssize_t rt_read_handler(void *buf, size_t nbytes, void *io_ctx) {
   39|   578M|    rt_buffer_ctx_t *buffer_ctx = (rt_buffer_ctx_t *)io_ctx;
   40|   578M|    ssize_t bytes_copied = 0;
   41|   578M|    ssize_t bytes_left = buffer_ctx->buffer->used - buffer_ctx->pos;
   42|   578M|    if (nbytes <= bytes_left) {
  ------------------
  |  Branch (42:9): [True: 578M, False: 1.89k]
  ------------------
   43|   578M|        memcpy(buf, buffer_ctx->buffer->bytes + buffer_ctx->pos, nbytes);
   44|   578M|        bytes_copied = nbytes;
   45|   578M|    } else if (bytes_left > 0) {
  ------------------
  |  Branch (45:16): [True: 791, False: 1.10k]
  ------------------
   46|    791|        memcpy(buf, buffer_ctx->buffer->bytes + buffer_ctx->pos, bytes_left);
   47|    791|        bytes_copied = bytes_left;
   48|    791|    }
   49|   578M|    buffer_ctx->pos += bytes_copied;
   50|   578M|    return bytes_copied;
   51|   578M|}

