ck_str_hash_lookup:
  146|  25.2k|const void *ck_str_hash_lookup(const char *key, ck_hash_table_t *table) {
  147|  25.2k|    size_t keylen = strlen(key);
  148|  25.2k|    return ck_str_n_hash_lookup(key, keylen, table);
  149|  25.2k|}
ck_str_n_hash_lookup:
  152|  25.2k|{
  153|  25.2k|	if (table->count == 0)
  ------------------
  |  Branch (153:6): [True: 461, False: 24.8k]
  ------------------
  154|    461|		return NULL;
  155|       |    	
  156|  24.8k|	if (keylen == 0)
  ------------------
  |  Branch (156:6): [True: 218, False: 24.5k]
  ------------------
  157|    218|		return NULL;
  158|       |	
  159|  24.5k|    uint64_t hash_key = ck_hash_str(key, keylen);
  160|  24.5k|	hash_key %= table->capacity;
  161|  24.5k|    uint64_t end = hash_key;
  162|  29.5k|    do {
  163|  29.5k|        char *this_key = &table->keys[table->entries[hash_key].key_offset];
  164|  29.5k|        size_t this_keylen = table->entries[hash_key].key_length;
  165|  29.5k|        if (this_keylen == 0)
  ------------------
  |  Branch (165:13): [True: 24.2k, False: 5.26k]
  ------------------
  166|  24.2k|            return NULL;
  167|  5.26k|        if (this_keylen == keylen && memcmp(this_key, key, keylen) == 0) {
  ------------------
  |  Branch (167:13): [True: 3.16k, False: 2.09k]
  |  Branch (167:38): [True: 295, False: 2.86k]
  ------------------
  168|    295|			return table->entries[hash_key].value;
  169|    295|		}
  170|  4.96k|		hash_key++;
  171|  4.96k|		hash_key %= table->capacity;
  172|  4.96k|    } while (hash_key != end);
  ------------------
  |  Branch (172:14): [True: 4.96k, False: 0]
  ------------------
  173|      0|	return NULL;
  174|  24.5k|}
ck_str_hash_insert:
  177|   457k|{
  178|   457k|    size_t keylen = strlen(key);
  179|   457k|    return ck_str_n_hash_insert(key, keylen, value, table);
  180|   457k|}
ck_str_n_hash_insert:
  210|   457k|{    
  211|   457k|	if (table->capacity == 0)
  ------------------
  |  Branch (211:6): [True: 0, False: 457k]
  ------------------
  212|      0|		return 0;
  213|       |    	
  214|   457k|	if (keylen == 0)
  ------------------
  |  Branch (214:6): [True: 0, False: 457k]
  ------------------
  215|      0|		return 0;
  216|       |    
  217|   457k|    if (table->count >= 0.75 * table->capacity) {
  ------------------
  |  Branch (217:9): [True: 0, False: 457k]
  ------------------
  218|      0|        if (ck_hash_table_grow(table) == -1) {
  ------------------
  |  Branch (218:13): [True: 0, False: 0]
  ------------------
  219|      0|            return 0;
  220|      0|        }
  221|      0|    }
  222|       |	
  223|   457k|    uint64_t hash_key = ck_hash_str(key, keylen);
  224|   457k|	hash_key %= table->capacity;
  225|   457k|    uint64_t end = hash_key;
  226|   458k|    do {
  227|   458k|        ck_hash_entry_t *entry = &table->entries[hash_key];
  228|   458k|        char *this_key = &table->keys[entry->key_offset];
  229|   458k|        if (entry->key_length == 0) {
  ------------------
  |  Branch (229:13): [True: 8.08k, False: 450k]
  ------------------
  230|  8.08k|            table->count++;
  231|  8.08k|            while (table->keys_used + keylen > table->keys_capacity) {
  ------------------
  |  Branch (231:20): [True: 0, False: 8.08k]
  ------------------
  232|      0|                table->keys_capacity *= 2;
  233|      0|                table->keys = realloc(table->keys, table->keys_capacity);
  234|      0|            }
  235|  8.08k|            memcpy(table->keys + table->keys_used, key, keylen);
  236|  8.08k|            entry->key_offset = table->keys_used;
  237|  8.08k|            entry->key_length = keylen;
  238|  8.08k|            table->keys_used += keylen;
  239|  8.08k|            entry->value = value;
  240|  8.08k|            return 1;
  241|   450k|        } else if (entry->key_length == keylen &&
  ------------------
  |  Branch (241:20): [True: 449k, False: 875]
  ------------------
  242|   449k|                   memcmp(this_key, key, keylen) == 0) {
  ------------------
  |  Branch (242:20): [True: 449k, False: 531]
  ------------------
  243|   449k|			table->entries[hash_key].value = value;
  244|   449k|			return 1;
  245|   449k|		}
  246|  1.40k|		hash_key++;
  247|  1.40k|		hash_key %= table->capacity;
  248|  1.40k|    } while (hash_key != end);
  ------------------
  |  Branch (248:14): [True: 1.40k, False: 0]
  ------------------
  249|      0|	return 0;
  250|   457k|}
ck_hash_table_init:
  253|  1.92k|{
  254|  1.92k|	ck_hash_table_t *table;
  255|  1.92k|	if ((table = malloc(sizeof(ck_hash_table_t))) == NULL)
  ------------------
  |  Branch (255:6): [True: 0, False: 1.92k]
  ------------------
  256|      0|		return NULL;
  257|       |    
  258|  1.92k|    if ((table->keys = malloc(num_entries * mean_key_length)) == NULL) {
  ------------------
  |  Branch (258:9): [True: 0, False: 1.92k]
  ------------------
  259|      0|        free(table);
  260|      0|        return NULL;
  261|      0|    }
  262|  1.92k|    table->keys_capacity = num_entries * mean_key_length;
  263|       |    
  264|  1.92k|    num_entries *= 2;
  265|       |    
  266|  1.92k|    if ((table->entries = malloc(num_entries * sizeof(ck_hash_entry_t))) == NULL) {
  ------------------
  |  Branch (266:9): [True: 0, False: 1.92k]
  ------------------
  267|      0|        free(table->keys);
  268|      0|        free(table);
  269|      0|        return NULL;
  270|      0|    }
  271|  1.92k|	table->capacity = num_entries;
  272|  1.92k|    ck_hash_table_wipe(table);
  273|  1.92k|	return table;
  274|  1.92k|}
ck_hash_table_free:
  276|  1.92k|void ck_hash_table_free(ck_hash_table_t *table) {
  277|  1.92k|    free(table->entries);
  278|  1.92k|    if (table->keys)
  ------------------
  |  Branch (278:9): [True: 1.92k, False: 0]
  ------------------
  279|  1.92k|        free(table->keys);
  280|  1.92k|    free(table);
  281|  1.92k|}
ck_hash_table_wipe:
  283|  1.92k|void ck_hash_table_wipe(ck_hash_table_t *table) {
  284|  1.92k|    table->keys_used = 0;
  285|  1.92k|    table->count = 0;
  286|  1.92k|    memset(table->entries, 0, table->capacity * sizeof(ck_hash_entry_t));
  287|  1.92k|}
CKHashTable.c:ck_hash_str:
  121|   482k|{
  122|   482k|    uint64_t hash;
  123|   482k|    unsigned char k[16] = { 0 };
  124|   482k|    siphash((unsigned char *)&hash, (const unsigned char *)str, keylen, k);
  125|   482k|    return hash;
  126|   482k|}
CKHashTable.c:siphash:
   57|   482k|{
   58|       |    /* "somepseudorandomlygeneratedbytes" */
   59|   482k|    u64 v0 = 0x736f6d6570736575ULL;
   60|   482k|    u64 v1 = 0x646f72616e646f6dULL;
   61|   482k|    u64 v2 = 0x6c7967656e657261ULL;
   62|   482k|    u64 v3 = 0x7465646279746573ULL;
   63|   482k|    u64 b;
   64|   482k|    u64 k0 = U8TO64_LE( k );
  ------------------
  |  |   37|   482k|#define U8TO64_LE(p) \
  |  |   38|   482k|(((u64)((p)[0])      ) | \
  |  |   39|   482k|((u64)((p)[1]) <<  8) | \
  |  |   40|   482k|((u64)((p)[2]) << 16) | \
  |  |   41|   482k|((u64)((p)[3]) << 24) | \
  |  |   42|   482k|((u64)((p)[4]) << 32) | \
  |  |   43|   482k|((u64)((p)[5]) << 40) | \
  |  |   44|   482k|((u64)((p)[6]) << 48) | \
  |  |   45|   482k|((u64)((p)[7]) << 56))
  ------------------
   65|   482k|    u64 k1 = U8TO64_LE( k + 8 );
  ------------------
  |  |   37|   482k|#define U8TO64_LE(p) \
  |  |   38|   482k|(((u64)((p)[0])      ) | \
  |  |   39|   482k|((u64)((p)[1]) <<  8) | \
  |  |   40|   482k|((u64)((p)[2]) << 16) | \
  |  |   41|   482k|((u64)((p)[3]) << 24) | \
  |  |   42|   482k|((u64)((p)[4]) << 32) | \
  |  |   43|   482k|((u64)((p)[5]) << 40) | \
  |  |   44|   482k|((u64)((p)[6]) << 48) | \
  |  |   45|   482k|((u64)((p)[7]) << 56))
  ------------------
   66|   482k|    u64 m;
   67|   482k|    const u8 *end = in + inlen - ( inlen % sizeof( u64 ) );
   68|   482k|    const int left = inlen & 7;
   69|   482k|    b = ( ( u64 )inlen ) << 56;
   70|   482k|    v3 ^= k1;
   71|   482k|    v2 ^= k0;
   72|   482k|    v1 ^= k1;
   73|   482k|    v0 ^= k0;
   74|       |    
   75|   605k|    for ( ; in != end; in += 8 )
  ------------------
  |  Branch (75:13): [True: 123k, False: 482k]
  ------------------
   76|   123k|    {
   77|   123k|        m = U8TO64_LE( in );
  ------------------
  |  |   37|   123k|#define U8TO64_LE(p) \
  |  |   38|   123k|(((u64)((p)[0])      ) | \
  |  |   39|   123k|((u64)((p)[1]) <<  8) | \
  |  |   40|   123k|((u64)((p)[2]) << 16) | \
  |  |   41|   123k|((u64)((p)[3]) << 24) | \
  |  |   42|   123k|((u64)((p)[4]) << 32) | \
  |  |   43|   123k|((u64)((p)[5]) << 40) | \
  |  |   44|   123k|((u64)((p)[6]) << 48) | \
  |  |   45|   123k|((u64)((p)[7]) << 56))
  ------------------
   78|       |        
   79|   123k|        v3 ^= m;
   80|       |        
   81|   123k|        SIPROUND;
  ------------------
  |  |   47|   123k|#define SIPROUND            \
  |  |   48|   123k|do {              \
  |  |   49|   123k|v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   123k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   123k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   50|   123k|v2 += v3; v3=ROTL(v3,16); v3 ^= v2;     \
  |  |  ------------------
  |  |  |  |   27|   123k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   51|   123k|v0 += v3; v3=ROTL(v3,21); v3 ^= v0;     \
  |  |  ------------------
  |  |  |  |   27|   123k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   52|   123k|v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   123k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   123k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   53|   123k|} while(0)
  |  |  ------------------
  |  |  |  Branch (53:9): [Folded, False: 123k]
  |  |  ------------------
  ------------------
   82|       |        
   83|   123k|        v0 ^= m;
   84|   123k|    }
   85|       |    
   86|   482k|    switch( left )
  ------------------
  |  Branch (86:13): [True: 482k, False: 0]
  ------------------
   87|   482k|    {
   88|  27.0k|        case 7: b |= ( ( u64 )in[ 6] )  << 48;
  ------------------
  |  Branch (88:9): [True: 27.0k, False: 455k]
  ------------------
   89|       |            
   90|  47.1k|        case 6: b |= ( ( u64 )in[ 5] )  << 40;
  ------------------
  |  Branch (90:9): [True: 20.0k, False: 462k]
  ------------------
   91|       |            
   92|  81.8k|        case 5: b |= ( ( u64 )in[ 4] )  << 32;
  ------------------
  |  Branch (92:9): [True: 34.7k, False: 447k]
  ------------------
   93|       |            
   94|  92.5k|        case 4: b |= ( ( u64 )in[ 3] )  << 24;
  ------------------
  |  Branch (94:9): [True: 10.6k, False: 471k]
  ------------------
   95|       |            
   96|  94.9k|        case 3: b |= ( ( u64 )in[ 2] )  << 16;
  ------------------
  |  Branch (96:9): [True: 2.48k, False: 479k]
  ------------------
   97|       |            
   98|   307k|        case 2: b |= ( ( u64 )in[ 1] )  <<  8;
  ------------------
  |  Branch (98:9): [True: 212k, False: 269k]
  ------------------
   99|       |            
  100|   397k|        case 1: b |= ( ( u64 )in[ 0] ); break;
  ------------------
  |  Branch (100:9): [True: 90.1k, False: 391k]
  ------------------
  101|       |            
  102|  84.4k|        case 0: break;
  ------------------
  |  Branch (102:9): [True: 84.4k, False: 397k]
  ------------------
  103|   482k|    }
  104|       |
  105|   482k|    v3 ^= b;
  106|       |    
  107|   482k|    SIPROUND;
  ------------------
  |  |   47|   482k|#define SIPROUND            \
  |  |   48|   482k|do {              \
  |  |   49|   482k|v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   50|   482k|v2 += v3; v3=ROTL(v3,16); v3 ^= v2;     \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   51|   482k|v0 += v3; v3=ROTL(v3,21); v3 ^= v0;     \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   52|   482k|v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   53|   482k|} while(0)
  |  |  ------------------
  |  |  |  Branch (53:9): [Folded, False: 482k]
  |  |  ------------------
  ------------------
  108|       |    
  109|   482k|    v0 ^= b;
  110|   482k|    v2 ^= 0xff;
  111|       |    
  112|   482k|    SIPROUND;
  ------------------
  |  |   47|   482k|#define SIPROUND            \
  |  |   48|   482k|do {              \
  |  |   49|   482k|v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   50|   482k|v2 += v3; v3=ROTL(v3,16); v3 ^= v2;     \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   51|   482k|v0 += v3; v3=ROTL(v3,21); v3 ^= v0;     \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   52|   482k|v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   53|   482k|} while(0)
  |  |  ------------------
  |  |  |  Branch (53:9): [Folded, False: 482k]
  |  |  ------------------
  ------------------
  113|   482k|    SIPROUND;
  ------------------
  |  |   47|   482k|#define SIPROUND            \
  |  |   48|   482k|do {              \
  |  |   49|   482k|v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   50|   482k|v2 += v3; v3=ROTL(v3,16); v3 ^= v2;     \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   51|   482k|v0 += v3; v3=ROTL(v3,21); v3 ^= v0;     \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   52|   482k|v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   482k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   53|   482k|} while(0)
  |  |  ------------------
  |  |  |  Branch (53:9): [Folded, False: 482k]
  |  |  ------------------
  ------------------
  114|       |    
  115|   482k|    b = v0 ^ v1 ^ v2  ^ v3;
  116|   482k|    U64TO8_LE( out, b );
  ------------------
  |  |   33|   482k|#define U64TO8_LE(p, v)         \
  |  |  ------------------
  |  |  |  |   29|   482k|#define U32TO8_LE(p, v)         \
  |  |  |  |   30|   482k|(p)[0] = (u8)((v)      ); (p)[1] = (u8)((v) >>  8); \
  |  |  |  |   31|   482k|(p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24);
  |  |  ------------------
  |  |   34|   482k|U32TO8_LE((p),     (u32)((v)      ));   \
  |  |  ------------------
  |  |  |  |   29|   482k|#define U32TO8_LE(p, v)         \
  |  |  |  |   30|   482k|(p)[0] = (u8)((v)      ); (p)[1] = (u8)((v) >>  8); \
  |  |  |  |   31|   482k|(p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24);
  |  |  ------------------
  |  |   35|   482k|U32TO8_LE((p) + 4, (u32)((v) >> 32));
  ------------------
  117|   482k|    return 0;
  118|   482k|}

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

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

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

readstat_convert:
   39|  1.18M|readstat_error_t readstat_convert(char *dst, size_t dst_len, const char *src, size_t src_len, iconv_t converter) {
   40|  1.18M|    return readstat_convert_impl(dst, dst_len, src, src_len, converter, 1);
   41|  1.18M|}
readstat_convert.c:readstat_convert_impl:
    8|  1.18M|        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|  7.53M|    while (src_len && ((trim_spaces && src[src_len-1] == ' ') || src[src_len-1] == '\0')) {
  ------------------
  |  Branch (11:12): [True: 7.47M, False: 67.2k]
  |  Branch (11:25): [True: 7.47M, False: 0]
  |  Branch (11:40): [True: 2.94M, False: 4.52M]
  |  Branch (11:66): [True: 3.40M, False: 1.11M]
  ------------------
   12|  6.35M|        src_len--;
   13|  6.35M|    }
   14|  1.18M|    if (dst_len == 0) {
  ------------------
  |  Branch (14:9): [True: 0, False: 1.18M]
  ------------------
   15|      0|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   16|  1.18M|    } else if (converter) {
  ------------------
  |  Branch (16:16): [True: 10.8k, False: 1.17M]
  ------------------
   17|  10.8k|        size_t dst_left = dst_len - 1;
   18|  10.8k|        char *dst_end = dst;
   19|  10.8k|        size_t status = iconv(converter, (readstat_iconv_inbuf_t)&src, &src_len, &dst_end, &dst_left);
   20|  10.8k|        if (status == (size_t)-1) {
  ------------------
  |  Branch (20:13): [True: 2.66k, False: 8.23k]
  ------------------
   21|  2.66k|            if (errno == E2BIG) {
  ------------------
  |  Branch (21:17): [True: 66, False: 2.59k]
  ------------------
   22|     66|                return READSTAT_ERROR_CONVERT_LONG_STRING;
   23|  2.59k|            } else if (errno == EILSEQ) {
  ------------------
  |  Branch (23:24): [True: 1.59k, False: 1.00k]
  ------------------
   24|  1.59k|                return READSTAT_ERROR_CONVERT_BAD_STRING;
   25|  1.59k|            } else if (errno != EINVAL) { /* EINVAL indicates improper truncation; accept it */
  ------------------
  |  Branch (25:24): [True: 0, False: 1.00k]
  ------------------
   26|      0|                return READSTAT_ERROR_CONVERT;
   27|      0|            }
   28|  2.66k|        }
   29|  9.23k|        dst[dst_len - dst_left - 1] = '\0';
   30|  1.17M|    } else if (src_len + 1 > dst_len) {
  ------------------
  |  Branch (30:16): [True: 14, False: 1.17M]
  ------------------
   31|     14|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   32|  1.17M|    } else {
   33|  1.17M|        memcpy(dst, src, src_len);
   34|  1.17M|        dst[src_len] = '\0';
   35|  1.17M|    }
   36|  1.18M|    return READSTAT_OK;
   37|  1.18M|}

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

readstat_malloc:
   10|   226k|void *readstat_malloc(size_t len) {
   11|   226k|    if (len > MAX_MALLOC_SIZE || len == 0) {
  ------------------
  |  |    3|   452k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (11:9): [True: 653, False: 225k]
  |  Branch (11:34): [True: 984, False: 224k]
  ------------------
   12|  1.63k|        return NULL;
   13|  1.63k|    }
   14|   224k|    return malloc(len);
   15|   226k|}
readstat_calloc:
   17|   491k|void *readstat_calloc(size_t count, size_t size) {
   18|   491k|    if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|   982k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
                  if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|   982k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
                  if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|   491k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (18:9): [True: 0, False: 491k]
  |  Branch (18:36): [True: 0, False: 491k]
  |  Branch (18:62): [True: 0, False: 491k]
  ------------------
   19|      0|        return NULL;
   20|      0|    }
   21|   491k|    if (count == 0 || size == 0) {
  ------------------
  |  Branch (21:9): [True: 90, False: 491k]
  |  Branch (21:23): [True: 0, False: 491k]
  ------------------
   22|     90|        return NULL;
   23|     90|    }
   24|   491k|    return calloc(count, size);
   25|   491k|}
readstat_realloc:
   27|  86.6k|void *readstat_realloc(void *ptr, size_t len) {
   28|  86.6k|    if (len > MAX_MALLOC_SIZE || len == 0) {
  ------------------
  |  |    3|   173k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (28:9): [True: 72, False: 86.5k]
  |  Branch (28:34): [True: 2, False: 86.5k]
  ------------------
   29|     74|        if (ptr)
  ------------------
  |  Branch (29:13): [True: 12, False: 62]
  ------------------
   30|     12|            free(ptr);
   31|     74|        return NULL;
   32|     74|    }
   33|  86.5k|    return realloc(ptr, len);
   34|  86.6k|}

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

sav_ctx_init:
   23|  6.43k|sav_ctx_t *sav_ctx_init(sav_file_header_record_t *header, readstat_io_t *io) {
   24|  6.43k|    sav_ctx_t *ctx = readstat_calloc(1, sizeof(sav_ctx_t));
   25|  6.43k|    if (ctx == NULL) {
  ------------------
  |  Branch (25:9): [True: 0, False: 6.43k]
  ------------------
   26|      0|        return NULL;
   27|      0|    }
   28|       |
   29|  6.43k|    if (memcmp(&header->rec_type, "$FL2", 4) == 0) {
  ------------------
  |  Branch (29:9): [True: 3.73k, False: 2.69k]
  ------------------
   30|  3.73k|        ctx->format_version = 2;
   31|  3.73k|    } else if (memcmp(&header->rec_type, "$FL3", 4) == 0) {
  ------------------
  |  Branch (31:16): [True: 2.66k, False: 31]
  ------------------
   32|  2.66k|        ctx->format_version = 3;
   33|  2.66k|    } else {
   34|     31|        sav_ctx_free(ctx);
   35|     31|        return NULL;
   36|     31|    }
   37|       |    
   38|  6.39k|    ctx->bswap = !(header->layout_code == 2 || header->layout_code == 3);
  ------------------
  |  Branch (38:20): [True: 4.35k, False: 2.04k]
  |  Branch (38:48): [True: 377, False: 1.66k]
  ------------------
   39|  6.39k|    ctx->endianness = (machine_is_little_endian() ^ ctx->bswap) ? READSTAT_ENDIAN_LITTLE : READSTAT_ENDIAN_BIG;
  ------------------
  |  Branch (39:23): [True: 4.73k, False: 1.66k]
  ------------------
   40|       |
   41|  6.39k|    if (header->compression == 1 || byteswap4(header->compression) == 1) {
  ------------------
  |  Branch (41:9): [True: 769, False: 5.63k]
  |  Branch (41:37): [True: 148, False: 5.48k]
  ------------------
   42|    917|        ctx->compression = READSTAT_COMPRESS_ROWS;
   43|  5.48k|    } else if (header->compression == 2 || byteswap4(header->compression) == 2) {
  ------------------
  |  Branch (43:16): [True: 456, False: 5.02k]
  |  Branch (43:44): [True: 140, False: 4.88k]
  ------------------
   44|    596|        ctx->compression = READSTAT_COMPRESS_BINARY;
   45|    596|    }
   46|  6.39k|    ctx->record_count = ctx->bswap ? byteswap4(header->ncases) : header->ncases;
  ------------------
  |  Branch (46:25): [True: 1.66k, False: 4.73k]
  ------------------
   47|  6.39k|    if (ctx->record_count < 0 || ctx->record_count > INT32_MAX / 2) {
  ------------------
  |  Branch (47:9): [True: 1.17k, False: 5.22k]
  |  Branch (47:34): [True: 746, False: 4.47k]
  ------------------
   48|       |        /* -1 means unknown; PSPP also treats implausibly large counts as unknown */
   49|  1.92k|        ctx->record_count = -1;
   50|  1.92k|    }
   51|  6.39k|    ctx->row_limit = -1;
   52|  6.39k|    ctx->fweight_index = ctx->bswap ? byteswap4(header->weight_index) : header->weight_index;
  ------------------
  |  Branch (52:26): [True: 1.66k, False: 4.73k]
  ------------------
   53|       |
   54|  6.39k|    ctx->missing_double = SAV_MISSING_DOUBLE;
  ------------------
  |  |   43|  6.39k|#define SAV_MISSING_DOUBLE   0xFFEFFFFFFFFFFFFFUL
  ------------------
   55|  6.39k|    ctx->lowest_double = SAV_LOWEST_DOUBLE;
  ------------------
  |  |   44|  6.39k|#define SAV_LOWEST_DOUBLE    0xFFEFFFFFFFFFFFFEUL
  ------------------
   56|  6.39k|    ctx->highest_double = SAV_HIGHEST_DOUBLE;
  ------------------
  |  |   42|  6.39k|#define SAV_HIGHEST_DOUBLE   0x7FEFFFFFFFFFFFFFUL
  ------------------
   57|       |    
   58|  6.39k|    ctx->bias = ctx->bswap ? byteswap_double(header->bias) : header->bias;
  ------------------
  |  Branch (58:17): [True: 1.66k, False: 4.73k]
  ------------------
   59|       |    
   60|  6.39k|    ctx->varinfo_capacity = SAV_VARINFO_INITIAL_CAPACITY;
  ------------------
  |  |   21|  6.39k|#define SAV_VARINFO_INITIAL_CAPACITY  512
  ------------------
   61|       |    
   62|  6.39k|    if ((ctx->varinfo = readstat_calloc(ctx->varinfo_capacity, sizeof(spss_varinfo_t *))) == NULL) {
  ------------------
  |  Branch (62:9): [True: 0, False: 6.39k]
  ------------------
   63|      0|        sav_ctx_free(ctx);
   64|      0|        return NULL;
   65|      0|    }
   66|       |
   67|  6.39k|    ctx->mr_sets = NULL;
   68|       |
   69|  6.39k|    ctx->io = io;
   70|       |    
   71|  6.39k|    return ctx;
   72|  6.39k|}
sav_ctx_free:
   74|  6.43k|void sav_ctx_free(sav_ctx_t *ctx) {
   75|  6.43k|    if (ctx->varinfo) {
  ------------------
  |  Branch (75:9): [True: 6.39k, False: 31]
  ------------------
   76|  6.39k|        int i;
   77|   481k|        for (i=0; i<ctx->var_index; i++) {
  ------------------
  |  Branch (77:19): [True: 475k, False: 6.39k]
  ------------------
   78|   475k|            spss_varinfo_free(ctx->varinfo[i]);
   79|   475k|        }
   80|  6.39k|        free(ctx->varinfo);
   81|  6.39k|    }
   82|  6.43k|    if (ctx->variables) {
  ------------------
  |  Branch (82:9): [True: 1.93k, False: 4.49k]
  ------------------
   83|  1.93k|        int i;
   84|  41.7k|        for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (84:19): [True: 39.8k, False: 1.93k]
  ------------------
   85|  39.8k|            if (ctx->variables[i])
  ------------------
  |  Branch (85:17): [True: 39.6k, False: 231]
  ------------------
   86|  39.6k|                free(ctx->variables[i]);
   87|  39.8k|        }
   88|  1.93k|        free(ctx->variables);
   89|  1.93k|    }
   90|  6.43k|    if (ctx->raw_string)
  ------------------
  |  Branch (90:9): [True: 1.63k, False: 4.79k]
  ------------------
   91|  1.63k|        free(ctx->raw_string);
   92|  6.43k|    if (ctx->utf8_string)
  ------------------
  |  Branch (92:9): [True: 1.59k, False: 4.83k]
  ------------------
   93|  1.59k|        free(ctx->utf8_string);
   94|  6.43k|    if (ctx->converter)
  ------------------
  |  Branch (94:9): [True: 190, False: 6.24k]
  ------------------
   95|    190|        iconv_close(ctx->converter);
   96|  6.43k|    if (ctx->variable_display_values) {
  ------------------
  |  Branch (96:9): [True: 222, False: 6.20k]
  ------------------
   97|    222|        free(ctx->variable_display_values);
   98|    222|    }
   99|  6.43k|    if (ctx->mr_sets) {
  ------------------
  |  Branch (99:9): [True: 850, False: 5.58k]
  ------------------
  100|  12.6k|        for (size_t i = 0; i < ctx->multiple_response_sets_length; i++) {
  ------------------
  |  Branch (100:28): [True: 11.7k, False: 850]
  ------------------
  101|  11.7k|            if (ctx->mr_sets[i].name) {
  ------------------
  |  Branch (101:17): [True: 11.7k, False: 0]
  ------------------
  102|  11.7k|                free(ctx->mr_sets[i].name);
  103|  11.7k|            }
  104|  11.7k|            if (ctx->mr_sets[i].label) {
  ------------------
  |  Branch (104:17): [True: 11.7k, False: 0]
  ------------------
  105|  11.7k|                free(ctx->mr_sets[i].label);
  106|  11.7k|            }
  107|  11.7k|            if (ctx->mr_sets[i].counted_string) {
  ------------------
  |  Branch (107:17): [True: 629, False: 11.1k]
  ------------------
  108|    629|                free(ctx->mr_sets[i].counted_string);
  109|    629|            }
  110|  11.7k|            if (ctx->mr_sets[i].subvariables) {
  ------------------
  |  Branch (110:17): [True: 10.7k, False: 1.08k]
  ------------------
  111|  37.8k|                for (size_t j = 0; j < ctx->mr_sets[i].num_subvars; j++) {
  ------------------
  |  Branch (111:36): [True: 27.1k, False: 10.7k]
  ------------------
  112|  27.1k|                    if (ctx->mr_sets[i].subvariables[j]) {
  ------------------
  |  Branch (112:25): [True: 27.1k, False: 0]
  ------------------
  113|  27.1k|                        free(ctx->mr_sets[i].subvariables[j]);
  114|  27.1k|                    }
  115|  27.1k|                }
  116|  10.7k|                free(ctx->mr_sets[i].subvariables);
  117|  10.7k|            }
  118|  11.7k|        }
  119|    850|        free(ctx->mr_sets);
  120|    850|    }
  121|  6.43k|    free(ctx);
  122|  6.43k|}

sav_decompress_row:
   77|  3.04M|void sav_decompress_row(struct sav_row_stream_s *state) {
   78|  3.04M|    double fp_value;
   79|  3.04M|    uint64_t missing_value = state->bswap ? byteswap8(state->missing_value) : state->missing_value;
  ------------------
  |  Branch (79:30): [True: 466k, False: 2.57M]
  ------------------
   80|  3.04M|    int i = 8 - state->i;
   81|  3.66M|    while (1) {
  ------------------
  |  Branch (81:12): [True: 3.66M, Folded]
  ------------------
   82|  3.66M|        if (i == 8) {
  ------------------
  |  Branch (82:13): [True: 1.00M, False: 2.66M]
  ------------------
   83|  1.00M|            if (state->avail_in < 8) {
  ------------------
  |  Branch (83:17): [True: 571, False: 999k]
  ------------------
   84|    571|                state->status = SAV_ROW_STREAM_NEED_DATA;
   85|    571|                goto done;
   86|    571|            }
   87|       |
   88|   999k|            memcpy(state->chunk, state->next_in, 8);
   89|   999k|            state->next_in += 8;
   90|   999k|            state->avail_in -= 8;
   91|   999k|            i = 0;
   92|   999k|        }
   93|       |
   94|  8.61M|        while (i<8) {
  ------------------
  |  Branch (94:16): [True: 7.99M, False: 620k]
  ------------------
   95|  7.99M|            switch (state->chunk[i]) {
   96|  4.36M|                case 0:
  ------------------
  |  Branch (96:17): [True: 4.36M, False: 3.62M]
  ------------------
   97|  4.36M|                    break;
   98|     86|                case 252:
  ------------------
  |  Branch (98:17): [True: 86, False: 7.99M]
  ------------------
   99|     86|                    state->status = SAV_ROW_STREAM_FINISHED_ALL;
  100|     86|                    goto done;
  101|   306k|                case 253:
  ------------------
  |  Branch (101:17): [True: 306k, False: 7.69M]
  ------------------
  102|   306k|                    if (state->avail_in < 8) {
  ------------------
  |  Branch (102:25): [True: 76, False: 306k]
  ------------------
  103|     76|                        state->status = SAV_ROW_STREAM_NEED_DATA;
  104|     76|                        goto done;
  105|     76|                    }
  106|   306k|                    memcpy(state->next_out, state->next_in, 8);
  107|   306k|                    state->next_out += 8;
  108|   306k|                    state->avail_out -= 8;
  109|   306k|                    state->next_in += 8;
  110|   306k|                    state->avail_in -= 8;
  111|   306k|                    break;
  112|  5.44k|                case 254:
  ------------------
  |  Branch (112:17): [True: 5.44k, False: 7.99M]
  ------------------
  113|  5.44k|                    memset(state->next_out, ' ', 8);
  114|  5.44k|                    state->next_out += 8;
  115|  5.44k|                    state->avail_out -= 8;
  116|  5.44k|                    break;
  117|  56.0k|                case 255:
  ------------------
  |  Branch (117:17): [True: 56.0k, False: 7.94M]
  ------------------
  118|  56.0k|                    memcpy(state->next_out, &missing_value, sizeof(uint64_t));
  119|  56.0k|                    state->next_out += 8;
  120|  56.0k|                    state->avail_out -= 8;
  121|  56.0k|                    break;
  122|  3.26M|                default:
  ------------------
  |  Branch (122:17): [True: 3.26M, False: 4.73M]
  ------------------
  123|  3.26M|                    fp_value = state->chunk[i] - state->bias;
  124|  3.26M|                    fp_value = state->bswap ? byteswap_double(fp_value) : fp_value;
  ------------------
  |  Branch (124:32): [True: 442k, False: 2.81M]
  ------------------
  125|  3.26M|                    memcpy(state->next_out, &fp_value, sizeof(double));
  126|  3.26M|                    state->next_out += 8;
  127|  3.26M|                    state->avail_out -= 8;
  128|  3.26M|                    break;
  129|  7.99M|            }
  130|  7.99M|            i++;
  131|  7.99M|            if (state->avail_out < 8) {
  ------------------
  |  Branch (131:17): [True: 3.04M, False: 4.95M]
  ------------------
  132|  3.04M|                state->status = SAV_ROW_STREAM_FINISHED_ROW;
  133|  3.04M|                goto done;
  134|  3.04M|            }
  135|  7.99M|        }
  136|  3.66M|    }
  137|  3.04M|done:
  138|  3.04M|    state->i = 8 - i;
  139|  3.04M|}

sav_parse_long_variable_names_record:
  159|  1.24k|readstat_error_t sav_parse_long_variable_names_record(void *data, int count, sav_ctx_t *ctx) {
  160|  1.24k|	unsigned char *c_data = (unsigned char *)data;
  161|  1.24k|	int var_count = count_vars(ctx);
  162|  1.24k|	readstat_error_t retval = READSTAT_OK;
  163|       |	
  164|  1.24k|	char temp_key[8+1];
  165|  1.24k|	char temp_val[64+1];
  166|  1.24k|	unsigned char *str_start = NULL;
  167|  1.24k|	size_t str_len = 0;
  168|       |	
  169|  1.24k|	char error_buf[8192];
  170|  1.24k|	unsigned char *p = c_data;
  171|  1.24k|	unsigned char *pe = c_data + count;
  172|       |	
  173|  1.24k|	varlookup_t *table = build_lookup_table(var_count, ctx);
  174|       |	
  175|  1.24k|	unsigned char *eof = pe;
  176|       |	
  177|  1.24k|	int cs;
  178|       |	
  179|       |	
  180|  1.24k|#line 181 "src/spss/readstat_sav_parse.c"
  181|  1.24k|	{
  182|  1.24k|		cs = (int)sav_long_variable_parse_start;
  183|  1.24k|	}
  184|       |	
  185|  1.24k|#line 186 "src/spss/readstat_sav_parse.c"
  186|  1.24k|	{
  187|  1.24k|		int _klen;
  188|  1.24k|		unsigned int _trans = 0;
  189|  1.24k|		const unsigned char * _keys;
  190|  1.24k|		const signed char * _acts;
  191|  1.24k|		unsigned int _nacts;
  192|  15.9k|		_resume: {}
  193|  15.9k|		if ( p == pe && p != eof )
  ------------------
  |  Branch (193:8): [True: 1.17k, False: 14.7k]
  |  Branch (193:19): [True: 0, False: 1.17k]
  ------------------
  194|      0|			goto _out;
  195|  15.9k|		if ( p == eof ) {
  ------------------
  |  Branch (195:8): [True: 1.17k, False: 14.7k]
  ------------------
  196|  1.17k|			if ( _sav_long_variable_parse_eof_trans[cs] > 0 ) {
  ------------------
  |  Branch (196:9): [True: 1.17k, False: 0]
  ------------------
  197|  1.17k|				_trans = (unsigned int)_sav_long_variable_parse_eof_trans[cs] - 1;
  198|  1.17k|			}
  199|  1.17k|		}
  200|  14.7k|		else {
  201|  14.7k|			_keys = ( _sav_long_variable_parse_trans_keys + (_sav_long_variable_parse_key_offsets[cs]));
  202|  14.7k|			_trans = (unsigned int)_sav_long_variable_parse_index_offsets[cs];
  203|       |			
  204|  14.7k|			_klen = (int)_sav_long_variable_parse_single_lengths[cs];
  205|  14.7k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (205:9): [True: 14.7k, False: 0]
  ------------------
  206|  14.7k|				const unsigned char *_lower = _keys;
  207|  14.7k|				const unsigned char *_upper = _keys + _klen - 1;
  208|  14.7k|				const unsigned char *_mid;
  209|  34.0k|				while ( 1 ) {
  ------------------
  |  Branch (209:13): [True: 34.0k, Folded]
  ------------------
  210|  34.0k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (210:11): [True: 10.7k, False: 23.2k]
  ------------------
  211|  10.7k|						_keys += _klen;
  212|  10.7k|						_trans += (unsigned int)_klen;
  213|  10.7k|						break;
  214|  10.7k|					}
  215|       |					
  216|  23.2k|					_mid = _lower + ((_upper-_lower) >> 1);
  217|  23.2k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (217:11): [True: 10.7k, False: 12.4k]
  ------------------
  218|  10.7k|						_upper = _mid - 1;
  219|  12.4k|					else if ( ( (*( p))) > (*( _mid)) )
  ------------------
  |  Branch (219:16): [True: 8.46k, False: 4.03k]
  ------------------
  220|  8.46k|						_lower = _mid + 1;
  221|  4.03k|					else {
  222|  4.03k|						_trans += (unsigned int)(_mid - _keys);
  223|  4.03k|						goto _match;
  224|  4.03k|					}
  225|  23.2k|				}
  226|  14.7k|			}
  227|       |			
  228|  10.7k|			_klen = (int)_sav_long_variable_parse_range_lengths[cs];
  229|  10.7k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (229:9): [True: 10.7k, False: 11]
  ------------------
  230|  10.7k|				const unsigned char *_lower = _keys;
  231|  10.7k|				const unsigned char *_upper = _keys + (_klen<<1) - 2;
  232|  10.7k|				const unsigned char *_mid;
  233|  28.1k|				while ( 1 ) {
  ------------------
  |  Branch (233:13): [True: 28.1k, Folded]
  ------------------
  234|  28.1k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (234:11): [True: 10.6k, False: 17.4k]
  ------------------
  235|  10.6k|						_trans += (unsigned int)_klen;
  236|  10.6k|						break;
  237|  10.6k|					}
  238|       |					
  239|  17.4k|					_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  240|  17.4k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (240:11): [True: 3.94k, False: 13.5k]
  ------------------
  241|  3.94k|						_upper = _mid - 2;
  242|  13.5k|					else if ( ( (*( p))) > (*( _mid + 1)) )
  ------------------
  |  Branch (242:16): [True: 13.4k, False: 51]
  ------------------
  243|  13.4k|						_lower = _mid + 2;
  244|     51|					else {
  245|     51|						_trans += (unsigned int)((_mid - _keys)>>1);
  246|     51|						break;
  247|     51|					}
  248|  17.4k|				}
  249|  10.7k|			}
  250|       |			
  251|  14.7k|			_match: {}
  252|  14.7k|		}
  253|  15.9k|		cs = (int)_sav_long_variable_parse_cond_targs[_trans];
  254|       |		
  255|  15.9k|		if ( _sav_long_variable_parse_cond_actions[_trans] != 0 ) {
  ------------------
  |  Branch (255:8): [True: 9.86k, False: 6.07k]
  ------------------
  256|       |			
  257|  9.86k|			_acts = ( _sav_long_variable_parse_actions + (_sav_long_variable_parse_cond_actions[_trans]));
  258|  9.86k|			_nacts = (unsigned int)(*( _acts));
  259|  9.86k|			_acts += 1;
  260|  27.0k|			while ( _nacts > 0 ) {
  ------------------
  |  Branch (260:12): [True: 17.1k, False: 9.86k]
  ------------------
  261|  17.1k|				switch ( (*( _acts)) )
  ------------------
  |  Branch (261:14): [True: 17.1k, False: 0]
  ------------------
  262|  17.1k|				{
  263|  2.44k|					case 0:  {
  ------------------
  |  Branch (263:6): [True: 2.44k, False: 14.7k]
  ------------------
  264|  2.44k|						{
  265|  2.44k|#line 13 "src/spss/readstat_sav_parse.rl"
  266|       |							
  267|  2.44k|							memcpy(temp_key, str_start, str_len);
  268|  2.44k|							temp_key[str_len] = '\0';
  269|  2.44k|						}
  270|       |						
  271|  2.44k|#line 272 "src/spss/readstat_sav_parse.c"
  272|       |						
  273|  2.44k|						break; 
  274|      0|					}
  275|  2.55k|					case 1:  {
  ------------------
  |  Branch (275:6): [True: 2.55k, False: 14.6k]
  ------------------
  276|  2.55k|						{
  277|  2.55k|#line 20 "src/spss/readstat_sav_parse.rl"
  278|  2.55k|							str_start = p; }
  279|       |						
  280|  2.55k|#line 281 "src/spss/readstat_sav_parse.c"
  281|       |						
  282|  2.55k|						break; 
  283|      0|					}
  284|  2.44k|					case 2:  {
  ------------------
  |  Branch (284:6): [True: 2.44k, False: 14.7k]
  ------------------
  285|  2.44k|						{
  286|  2.44k|#line 20 "src/spss/readstat_sav_parse.rl"
  287|  2.44k|							str_len = p - str_start; }
  288|       |						
  289|  2.44k|#line 290 "src/spss/readstat_sav_parse.c"
  290|       |						
  291|  2.44k|						break; 
  292|      0|					}
  293|  2.43k|					case 3:  {
  ------------------
  |  Branch (293:6): [True: 2.43k, False: 14.7k]
  ------------------
  294|  2.43k|						{
  295|  2.43k|#line 102 "src/spss/readstat_sav_parse.rl"
  296|       |							
  297|  2.43k|							varlookup_t *found = bsearch(temp_key, table, var_count, sizeof(varlookup_t), &compare_key_varlookup);
  298|  2.43k|							if (!found) {
  ------------------
  |  Branch (298:12): [True: 1.59k, False: 831]
  ------------------
  299|  1.59k|								snprintf(error_buf, sizeof(error_buf), "Failed to find %s", temp_key);
  300|  1.59k|								if (ctx->handle.error)
  ------------------
  |  Branch (300:13): [True: 0, False: 1.59k]
  ------------------
  301|      0|								ctx->handle.error(error_buf, ctx->user_ctx);
  302|  1.59k|							} else {
  303|       |								// Handle the edge case where a ghost variable name (from a multi-segment
  304|       |								// variable) is identical to a real variable name. Normally we handle this
  305|       |								// by incrementing the loop variable by n_segments, but n_segments hasn't
  306|       |								// been set when this record is processed. So just set the longname to every
  307|       |								// matching variable, ghost or real.
  308|    831|								varlookup_t *iter_match = found;
  309|  3.74k|								while (iter_match >= table && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (309:16): [True: 3.41k, False: 332]
  |  Branch (309:39): [True: 2.91k, False: 499]
  ------------------
  310|  2.91k|									spss_varinfo_t *info = ctx->varinfo[iter_match->index];
  311|  2.91k|									snprintf(info->longname, sizeof(info->longname), "%*s", (int)str_len, temp_val);
  312|  2.91k|									iter_match--;
  313|  2.91k|								}
  314|    831|								iter_match = found + 1;
  315|  3.56k|								while (iter_match - table < var_count && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (315:16): [True: 3.19k, False: 372]
  |  Branch (315:50): [True: 2.73k, False: 459]
  ------------------
  316|  2.73k|									spss_varinfo_t *info = ctx->varinfo[iter_match->index];
  317|  2.73k|									snprintf(info->longname, sizeof(info->longname), "%*s", (int)str_len, temp_val);
  318|  2.73k|									iter_match++;
  319|  2.73k|								}
  320|    831|							}
  321|  2.43k|						}
  322|       |						
  323|  2.43k|#line 324 "src/spss/readstat_sav_parse.c"
  324|       |						
  325|  2.43k|						break; 
  326|      0|					}
  327|  2.43k|					case 4:  {
  ------------------
  |  Branch (327:6): [True: 2.43k, False: 14.7k]
  ------------------
  328|  2.43k|						{
  329|  2.43k|#line 129 "src/spss/readstat_sav_parse.rl"
  330|       |							
  331|  2.43k|							if (str_len > sizeof(temp_val) - 1)
  ------------------
  |  Branch (331:12): [True: 0, False: 2.43k]
  ------------------
  332|      0|							str_len = sizeof(temp_val) - 1;
  333|  2.43k|							memcpy(temp_val, str_start, str_len);
  334|  2.43k|							temp_val[str_len] = '\0';
  335|  2.43k|						}
  336|       |						
  337|  2.43k|#line 338 "src/spss/readstat_sav_parse.c"
  338|       |						
  339|  2.43k|						break; 
  340|      0|					}
  341|  2.43k|					case 5:  {
  ------------------
  |  Branch (341:6): [True: 2.43k, False: 14.7k]
  ------------------
  342|  2.43k|						{
  343|  2.43k|#line 136 "src/spss/readstat_sav_parse.rl"
  344|  2.43k|							str_start = p; }
  345|       |						
  346|  2.43k|#line 347 "src/spss/readstat_sav_parse.c"
  347|       |						
  348|  2.43k|						break; 
  349|      0|					}
  350|  2.43k|					case 6:  {
  ------------------
  |  Branch (350:6): [True: 2.43k, False: 14.7k]
  ------------------
  351|  2.43k|						{
  352|  2.43k|#line 136 "src/spss/readstat_sav_parse.rl"
  353|  2.43k|							str_len = p - str_start; if (str_len > 64) str_len = 64; }
  ------------------
  |  Branch (353:37): [True: 10, False: 2.42k]
  ------------------
  354|       |						
  355|  2.43k|#line 356 "src/spss/readstat_sav_parse.c"
  356|       |						
  357|  2.43k|						break; 
  358|      0|					}
  359|  17.1k|				}
  360|  17.1k|				_nacts -= 1;
  361|  17.1k|				_acts += 1;
  362|  17.1k|			}
  363|       |			
  364|  9.86k|		}
  365|       |		
  366|  15.9k|		if ( p == eof ) {
  ------------------
  |  Branch (366:8): [True: 1.17k, False: 14.7k]
  ------------------
  367|  1.17k|			if ( cs >= 11 )
  ------------------
  |  Branch (367:9): [True: 1.07k, False: 106]
  ------------------
  368|  1.07k|				goto _out;
  369|  1.17k|		}
  370|  14.7k|		else {
  371|  14.7k|			if ( cs != 0 ) {
  ------------------
  |  Branch (371:9): [True: 14.7k, False: 65]
  ------------------
  372|  14.7k|				p += 1;
  373|  14.7k|				goto _resume;
  374|  14.7k|			}
  375|  14.7k|		}
  376|  1.24k|		_out: {}
  377|  1.24k|	}
  378|       |	
  379|      0|#line 144 "src/spss/readstat_sav_parse.rl"
  380|       |	
  381|       |	
  382|  1.24k|	if (cs < 
  ------------------
  |  Branch (382:6): [True: 171, False: 1.07k]
  ------------------
  383|  1.24k|#line 384 "src/spss/readstat_sav_parse.c"
  384|  1.24k|	11
  385|  1.07k|#line 146 "src/spss/readstat_sav_parse.rl"
  386|  1.07k|	|| p != pe) {
  ------------------
  |  Branch (386:5): [True: 0, False: 1.07k]
  ------------------
  387|    171|		if (ctx->handle.error) {
  ------------------
  |  Branch (387:7): [True: 0, False: 171]
  ------------------
  388|      0|			snprintf(error_buf, sizeof(error_buf), "Error parsing string \"%.*s\" around byte #%ld/%d, character %c", 
  389|      0|			count, (char *)data, (long)(p - c_data), count, p < pe ? *p : '?');
  ------------------
  |  Branch (389:52): [True: 0, False: 0]
  ------------------
  390|      0|			ctx->handle.error(error_buf, ctx->user_ctx);
  391|      0|		}
  392|    171|		retval = READSTAT_ERROR_PARSE;
  393|    171|	}
  394|       |	
  395|       |	
  396|  1.24k|	if (table)
  ------------------
  |  Branch (396:6): [True: 860, False: 382]
  ------------------
  397|    860|		free(table);
  398|       |	
  399|       |	/* suppress warning */
  400|  1.24k|	(void)sav_long_variable_parse_en_main;
  401|       |	
  402|  1.24k|	return retval;
  403|  15.9k|}
sav_parse_very_long_string_record:
  498|  1.86k|readstat_error_t sav_parse_very_long_string_record(void *data, int count, sav_ctx_t *ctx) {
  499|  1.86k|	unsigned char *c_data = (unsigned char *)data;
  500|  1.86k|	int var_count = count_vars(ctx);
  501|  1.86k|	readstat_error_t retval = READSTAT_OK;
  502|       |	
  503|  1.86k|	char temp_key[8*4+1];
  504|  1.86k|	unsigned int temp_val = 0;
  505|  1.86k|	unsigned char *str_start = NULL;
  506|  1.86k|	size_t str_len = 0;
  507|       |	
  508|  1.86k|	size_t error_buf_len = 1024 + count;
  509|  1.86k|	char *error_buf = NULL;
  510|  1.86k|	unsigned char *p = c_data;
  511|  1.86k|	unsigned char *pe = c_data + count;
  512|  1.86k|	unsigned char *eof = pe;
  513|       |	
  514|  1.86k|	varlookup_t *table = NULL;
  515|  1.86k|	int cs;
  516|       |	
  517|  1.86k|	error_buf = readstat_malloc(error_buf_len);
  518|  1.86k|	table = build_lookup_table(var_count, ctx);
  519|       |	
  520|       |	
  521|  1.86k|#line 522 "src/spss/readstat_sav_parse.c"
  522|  1.86k|	{
  523|  1.86k|		cs = (int)sav_very_long_string_parse_start;
  524|  1.86k|	}
  525|       |	
  526|  1.86k|#line 527 "src/spss/readstat_sav_parse.c"
  527|  1.86k|	{
  528|  1.86k|		int _klen;
  529|  1.86k|		unsigned int _trans = 0;
  530|  1.86k|		const unsigned char * _keys;
  531|  1.86k|		const signed char * _acts;
  532|  1.86k|		unsigned int _nacts;
  533|  19.8k|		_resume: {}
  534|  19.8k|		if ( p == pe && p != eof )
  ------------------
  |  Branch (534:8): [True: 1.55k, False: 18.3k]
  |  Branch (534:19): [True: 0, False: 1.55k]
  ------------------
  535|      0|			goto _out;
  536|  19.8k|		if ( p == eof ) {
  ------------------
  |  Branch (536:8): [True: 1.55k, False: 18.3k]
  ------------------
  537|  1.55k|			if ( _sav_very_long_string_parse_eof_trans[cs] > 0 ) {
  ------------------
  |  Branch (537:9): [True: 1.55k, False: 0]
  ------------------
  538|  1.55k|				_trans = (unsigned int)_sav_very_long_string_parse_eof_trans[cs] - 1;
  539|  1.55k|			}
  540|  1.55k|		}
  541|  18.3k|		else {
  542|  18.3k|			_keys = ( _sav_very_long_string_parse_trans_keys + (_sav_very_long_string_parse_key_offsets[cs]));
  543|  18.3k|			_trans = (unsigned int)_sav_very_long_string_parse_index_offsets[cs];
  544|       |			
  545|  18.3k|			_klen = (int)_sav_very_long_string_parse_single_lengths[cs];
  546|  18.3k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (546:9): [True: 15.4k, False: 2.89k]
  ------------------
  547|  15.4k|				const unsigned char *_lower = _keys;
  548|  15.4k|				const unsigned char *_upper = _keys + _klen - 1;
  549|  15.4k|				const unsigned char *_mid;
  550|  36.2k|				while ( 1 ) {
  ------------------
  |  Branch (550:13): [True: 36.2k, Folded]
  ------------------
  551|  36.2k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (551:11): [True: 10.6k, False: 25.6k]
  ------------------
  552|  10.6k|						_keys += _klen;
  553|  10.6k|						_trans += (unsigned int)_klen;
  554|  10.6k|						break;
  555|  10.6k|					}
  556|       |					
  557|  25.6k|					_mid = _lower + ((_upper-_lower) >> 1);
  558|  25.6k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (558:11): [True: 5.93k, False: 19.6k]
  ------------------
  559|  5.93k|						_upper = _mid - 1;
  560|  19.6k|					else if ( ( (*( p))) > (*( _mid)) )
  ------------------
  |  Branch (560:16): [True: 14.8k, False: 4.83k]
  ------------------
  561|  14.8k|						_lower = _mid + 1;
  562|  4.83k|					else {
  563|  4.83k|						_trans += (unsigned int)(_mid - _keys);
  564|  4.83k|						goto _match;
  565|  4.83k|					}
  566|  25.6k|				}
  567|  15.4k|			}
  568|       |			
  569|  13.5k|			_klen = (int)_sav_very_long_string_parse_range_lengths[cs];
  570|  13.5k|			if ( _klen > 0 ) {
  ------------------
  |  Branch (570:9): [True: 13.4k, False: 16]
  ------------------
  571|  13.4k|				const unsigned char *_lower = _keys;
  572|  13.4k|				const unsigned char *_upper = _keys + (_klen<<1) - 2;
  573|  13.4k|				const unsigned char *_mid;
  574|  27.3k|				while ( 1 ) {
  ------------------
  |  Branch (574:13): [True: 27.3k, Folded]
  ------------------
  575|  27.3k|					if ( _upper < _lower ) {
  ------------------
  |  Branch (575:11): [True: 5.82k, False: 21.5k]
  ------------------
  576|  5.82k|						_trans += (unsigned int)_klen;
  577|  5.82k|						break;
  578|  5.82k|					}
  579|       |					
  580|  21.5k|					_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  581|  21.5k|					if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (581:11): [True: 3.41k, False: 18.1k]
  ------------------
  582|  3.41k|						_upper = _mid - 2;
  583|  18.1k|					else if ( ( (*( p))) > (*( _mid + 1)) )
  ------------------
  |  Branch (583:16): [True: 10.4k, False: 7.66k]
  ------------------
  584|  10.4k|						_lower = _mid + 2;
  585|  7.66k|					else {
  586|  7.66k|						_trans += (unsigned int)((_mid - _keys)>>1);
  587|  7.66k|						break;
  588|  7.66k|					}
  589|  21.5k|				}
  590|  13.4k|			}
  591|       |			
  592|  18.3k|			_match: {}
  593|  18.3k|		}
  594|  19.8k|		cs = (int)_sav_very_long_string_parse_cond_targs[_trans];
  595|       |		
  596|  19.8k|		if ( _sav_very_long_string_parse_cond_actions[_trans] != 0 ) {
  ------------------
  |  Branch (596:8): [True: 16.1k, False: 3.70k]
  ------------------
  597|       |			
  598|  16.1k|			_acts = ( _sav_very_long_string_parse_actions + (_sav_very_long_string_parse_cond_actions[_trans]));
  599|  16.1k|			_nacts = (unsigned int)(*( _acts));
  600|  16.1k|			_acts += 1;
  601|  37.9k|			while ( _nacts > 0 ) {
  ------------------
  |  Branch (601:12): [True: 21.9k, False: 15.9k]
  ------------------
  602|  21.9k|				switch ( (*( _acts)) )
  ------------------
  |  Branch (602:14): [True: 21.9k, False: 0]
  ------------------
  603|  21.9k|				{
  604|  2.90k|					case 0:  {
  ------------------
  |  Branch (604:6): [True: 2.90k, False: 19.0k]
  ------------------
  605|  2.90k|						{
  606|  2.90k|#line 13 "src/spss/readstat_sav_parse.rl"
  607|       |							
  608|  2.90k|							memcpy(temp_key, str_start, str_len);
  609|  2.90k|							temp_key[str_len] = '\0';
  610|  2.90k|						}
  611|       |						
  612|  2.90k|#line 613 "src/spss/readstat_sav_parse.c"
  613|       |						
  614|  2.90k|						break; 
  615|      0|					}
  616|  3.01k|					case 1:  {
  ------------------
  |  Branch (616:6): [True: 3.01k, False: 18.9k]
  ------------------
  617|  3.01k|						{
  618|  3.01k|#line 20 "src/spss/readstat_sav_parse.rl"
  619|  3.01k|							str_start = p; }
  620|       |						
  621|  3.01k|#line 622 "src/spss/readstat_sav_parse.c"
  622|       |						
  623|  3.01k|						break; 
  624|      0|					}
  625|  2.90k|					case 2:  {
  ------------------
  |  Branch (625:6): [True: 2.90k, False: 19.0k]
  ------------------
  626|  2.90k|						{
  627|  2.90k|#line 20 "src/spss/readstat_sav_parse.rl"
  628|  2.90k|							str_len = p - str_start; }
  629|       |						
  630|  2.90k|#line 631 "src/spss/readstat_sav_parse.c"
  631|       |						
  632|  2.90k|						break; 
  633|      0|					}
  634|  2.63k|					case 3:  {
  ------------------
  |  Branch (634:6): [True: 2.63k, False: 19.3k]
  ------------------
  635|  2.63k|						{
  636|  2.63k|#line 195 "src/spss/readstat_sav_parse.rl"
  637|       |							
  638|  2.63k|							varlookup_t *found = bsearch(temp_key, table, var_count, sizeof(varlookup_t), &compare_key_varlookup);
  639|  2.63k|							if (found) {
  ------------------
  |  Branch (639:12): [True: 1.06k, False: 1.56k]
  ------------------
  640|       |								// See logic above; we need to apply this to all matching variables since ghost variable
  641|       |								// names may conflict with real variable names.
  642|  1.06k|								varlookup_t *first_match = found, *last_match = found;
  643|  1.06k|								varlookup_t *iter_match = found - 1;
  644|  2.00k|								while (iter_match >= table && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (644:16): [True: 1.43k, False: 572]
  |  Branch (644:39): [True: 937, False: 494]
  ------------------
  645|    937|									first_match = iter_match;
  646|    937|									iter_match--;
  647|    937|								}
  648|  1.06k|								iter_match = found + 1;
  649|  3.33k|								while (iter_match - table < var_count && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (649:16): [True: 2.81k, False: 518]
  |  Branch (649:50): [True: 2.26k, False: 548]
  ------------------
  650|  2.26k|									last_match = iter_match;
  651|  2.26k|									iter_match++;
  652|  2.26k|								}
  653|  5.33k|								for (iter_match=first_match; iter_match<=last_match; iter_match++) {
  ------------------
  |  Branch (653:38): [True: 4.27k, False: 1.06k]
  ------------------
  654|  4.27k|									ctx->varinfo[iter_match->index]->string_length = temp_val;
  655|  4.27k|									ctx->varinfo[iter_match->index]->write_format.width = temp_val;
  656|  4.27k|									ctx->varinfo[iter_match->index]->print_format.width = temp_val;
  657|  4.27k|								}
  658|  1.06k|							}
  659|  2.63k|						}
  660|       |						
  661|  2.63k|#line 662 "src/spss/readstat_sav_parse.c"
  662|       |						
  663|  2.63k|						break; 
  664|      0|					}
  665|  7.64k|					case 4:  {
  ------------------
  |  Branch (665:6): [True: 7.64k, False: 14.3k]
  ------------------
  666|  7.64k|						{
  667|  7.64k|#line 219 "src/spss/readstat_sav_parse.rl"
  668|       |							
  669|  7.64k|							if ((( (*( p)))) != '\0') {
  ------------------
  |  Branch (669:12): [True: 7.64k, False: 0]
  ------------------
  670|  7.64k|								unsigned char digit = (( (*( p)))) - '0';
  671|  7.64k|								if (temp_val <= (UINT_MAX - digit) / 10) {
  ------------------
  |  Branch (671:13): [True: 7.38k, False: 255]
  ------------------
  672|  7.38k|									temp_val = 10 * temp_val + digit;
  673|  7.38k|								} else {
  674|    255|									{p += 1; goto _out; }
  675|    255|								}
  676|  7.64k|							}
  677|  7.64k|						}
  678|       |						
  679|  7.38k|#line 680 "src/spss/readstat_sav_parse.c"
  680|       |						
  681|  7.38k|						break; 
  682|  7.64k|					}
  683|  7.38k|					case 5:  {
  ------------------
  |  Branch (683:6): [True: 2.89k, False: 19.0k]
  ------------------
  684|  2.89k|						{
  685|  2.89k|#line 230 "src/spss/readstat_sav_parse.rl"
  686|  2.89k|							temp_val = 0; }
  687|       |						
  688|  2.89k|#line 689 "src/spss/readstat_sav_parse.c"
  689|       |						
  690|  2.89k|						break; 
  691|  7.64k|					}
  692|  21.9k|				}
  693|  21.7k|				_nacts -= 1;
  694|  21.7k|				_acts += 1;
  695|  21.7k|			}
  696|       |			
  697|  16.1k|		}
  698|       |		
  699|  19.6k|		if ( p == eof ) {
  ------------------
  |  Branch (699:8): [True: 1.55k, False: 18.0k]
  ------------------
  700|  1.55k|			if ( cs >= 11 )
  ------------------
  |  Branch (700:9): [True: 1.45k, False: 102]
  ------------------
  701|  1.45k|				goto _out;
  702|  1.55k|		}
  703|  18.0k|		else {
  704|  18.0k|			if ( cs != 0 ) {
  ------------------
  |  Branch (704:9): [True: 18.0k, False: 56]
  ------------------
  705|  18.0k|				p += 1;
  706|  18.0k|				goto _resume;
  707|  18.0k|			}
  708|  18.0k|		}
  709|  1.86k|		_out: {}
  710|  1.86k|	}
  711|       |	
  712|      0|#line 238 "src/spss/readstat_sav_parse.rl"
  713|       |	
  714|       |	
  715|  1.86k|	if (cs < 
  ------------------
  |  Branch (715:6): [True: 158, False: 1.70k]
  ------------------
  716|  1.86k|#line 717 "src/spss/readstat_sav_parse.c"
  717|  1.86k|	11
  718|  1.70k|#line 240 "src/spss/readstat_sav_parse.rl"
  719|  1.70k|	|| p != pe) {
  ------------------
  |  Branch (719:5): [True: 2, False: 1.70k]
  ------------------
  720|    160|		if (ctx->handle.error) {
  ------------------
  |  Branch (720:7): [True: 0, False: 160]
  ------------------
  721|      0|			snprintf(error_buf, error_buf_len, "Parsed %ld of %ld bytes. Remaining bytes: %.*s",
  722|      0|			(long)(p - c_data), (long)(pe - c_data), (int)(pe - p), p);
  723|      0|			ctx->handle.error(error_buf, ctx->user_ctx);
  724|      0|		}
  725|    160|		retval = READSTAT_ERROR_PARSE;
  726|    160|	}
  727|       |	
  728|  1.86k|	if (table)
  ------------------
  |  Branch (728:6): [True: 1.26k, False: 602]
  ------------------
  729|  1.26k|		free(table);
  730|  1.86k|	if (error_buf)
  ------------------
  |  Branch (730:6): [True: 1.86k, False: 0]
  ------------------
  731|  1.86k|		free(error_buf);
  732|       |	
  733|       |	/* suppress warning */
  734|  1.86k|	(void)sav_very_long_string_parse_en_main;
  735|       |	
  736|  1.86k|	return retval;
  737|  19.6k|}
readstat_sav_parse.c:count_vars:
   32|  3.10k|static int count_vars(sav_ctx_t *ctx) {
   33|  3.10k|	int i;
   34|  3.10k|	spss_varinfo_t *last_info = NULL;
   35|  3.10k|	int var_count = 0;
   36|   558k|	for (i=0; i<ctx->var_index; i++) {
  ------------------
  |  Branch (36:12): [True: 555k, False: 3.10k]
  ------------------
   37|   555k|		spss_varinfo_t *info = ctx->varinfo[i];
   38|   555k|		if (last_info == NULL || strcmp(info->name, last_info->name) != 0) {
  ------------------
  |  Branch (38:7): [True: 2.12k, False: 553k]
  |  Branch (38:28): [True: 528k, False: 24.1k]
  ------------------
   39|   531k|			var_count++;
   40|   531k|		}
   41|   555k|		last_info = info;
   42|   555k|	}
   43|  3.10k|	return var_count;
   44|  3.10k|}
readstat_sav_parse.c:build_lookup_table:
   46|  3.10k|static varlookup_t *build_lookup_table(int var_count, sav_ctx_t *ctx) {
   47|  3.10k|	varlookup_t *table = readstat_malloc(var_count * sizeof(varlookup_t));
   48|  3.10k|	int offset = 0;
   49|  3.10k|	int i;
   50|  3.10k|	spss_varinfo_t *last_info = NULL;
   51|   558k|	for (i=0; i<ctx->var_index; i++) {
  ------------------
  |  Branch (51:12): [True: 555k, False: 3.10k]
  ------------------
   52|   555k|		spss_varinfo_t *info = ctx->varinfo[i];
   53|       |		
   54|   555k|		if (last_info == NULL || strcmp(info->name, last_info->name) != 0) {
  ------------------
  |  Branch (54:7): [True: 2.12k, False: 553k]
  |  Branch (54:28): [True: 528k, False: 24.1k]
  ------------------
   55|   531k|			varlookup_t *entry = &table[offset++];
   56|       |			
   57|   531k|			memcpy(entry->name, info->name, sizeof(info->name));
   58|   531k|			entry->index = info->index;
   59|   531k|		}
   60|   555k|		last_info = info;
   61|   555k|	}
   62|  3.10k|	qsort(table, var_count, sizeof(varlookup_t), &compare_varlookups);
   63|  3.10k|	return table;
   64|  3.10k|}
readstat_sav_parse.c:compare_varlookups:
   26|  5.17M|static int compare_varlookups(const void *elem1, const void *elem2) {
   27|  5.17M|	const varlookup_t *v1 = (const varlookup_t *)elem1;
   28|  5.17M|	const varlookup_t *v2 = (const varlookup_t *)elem2;
   29|  5.17M|	return strcasecmp(v1->name, v2->name);
   30|  5.17M|}
readstat_sav_parse.c:compare_key_varlookup:
   20|  8.39k|static int compare_key_varlookup(const void *elem1, const void *elem2) {
   21|  8.39k|	const char *key = (const char *)elem1;
   22|  8.39k|	const varlookup_t *v = (const varlookup_t *)elem2;
   23|  8.39k|	return strcasecmp(key, v->name);
   24|  8.39k|}

parse_mr_string:
  191|  44.6k|readstat_error_t parse_mr_string(const char *data, size_t data_len, mr_set_t **mr_sets, size_t *n_mr_lines, sav_ctx_t *ctx) {
  192|  44.6k|    readstat_error_t retval = READSTAT_OK;
  193|  44.6k|    const char *p = data;
  194|  44.6k|    const char *end = data + data_len;
  195|       |
  196|  67.0k|    while (p < end) {
  ------------------
  |  Branch (196:12): [True: 64.9k, False: 2.11k]
  ------------------
  197|  64.9k|        const char *line = p;
  198|   971k|        while (p < end && *p != '\n' && *p != '\0')
  ------------------
  |  Branch (198:16): [True: 964k, False: 7.15k]
  |  Branch (198:27): [True: 961k, False: 2.67k]
  |  Branch (198:41): [True: 906k, False: 55.1k]
  ------------------
  199|   906k|            p++;
  200|  64.9k|        size_t line_len = p - line;
  201|  64.9k|        if (p < end)
  ------------------
  |  Branch (201:13): [True: 57.7k, False: 7.15k]
  ------------------
  202|  57.7k|            p++; /* consume the line feed */
  203|  64.9k|        if (line_len && line[line_len-1] == '\r')
  ------------------
  |  Branch (203:13): [True: 54.3k, False: 10.5k]
  |  Branch (203:25): [True: 933, False: 53.4k]
  ------------------
  204|    933|            line_len--;
  205|  64.9k|        if (line_len == 0)
  ------------------
  |  Branch (205:13): [True: 10.5k, False: 54.3k]
  ------------------
  206|  10.5k|            continue; /* the spec allows any number of line feeds between sets */
  207|       |
  208|  54.3k|        mr_set_t *new_mr_sets = readstat_realloc(*mr_sets, ((*n_mr_lines) + 1) * sizeof(mr_set_t));
  209|  54.3k|        if (new_mr_sets == NULL) {
  ------------------
  |  Branch (209:13): [True: 0, False: 54.3k]
  ------------------
  210|      0|            retval = READSTAT_ERROR_MALLOC;
  211|      0|            goto cleanup;
  212|      0|        }
  213|  54.3k|        *mr_sets = new_mr_sets;
  214|       |
  215|  54.3k|        retval = parse_mr_line(line, line_len, &(*mr_sets)[*n_mr_lines], ctx);
  216|  54.3k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (216:13): [True: 42.5k, False: 11.7k]
  ------------------
  217|  42.5k|            goto cleanup;
  218|       |
  219|  11.7k|        (*n_mr_lines)++;
  220|  11.7k|    }
  221|       |
  222|  44.6k|cleanup:
  223|  44.6k|    return retval;
  224|  44.6k|}
readstat_sav_parse_mr_name.c:parse_mr_line:
   77|  54.3k|static readstat_error_t parse_mr_line(const char *line, size_t line_len, mr_set_t *result, sav_ctx_t *ctx) {
   78|  54.3k|    readstat_error_t retval = READSTAT_OK;
   79|  54.3k|    const char *p = line;
   80|  54.3k|    const char *end = line + line_len;
   81|  54.3k|    const char *str = NULL;
   82|  54.3k|    size_t str_len = 0;
   83|       |
   84|  54.3k|    memset(result, 0, sizeof(mr_set_t));
   85|       |
   86|       |    /* Name: begins with '$', runs up to '=' */
   87|  54.3k|    if (p == end || *p != '$') {
  ------------------
  |  Branch (87:9): [True: 0, False: 54.3k]
  |  Branch (87:21): [True: 7.20k, False: 47.1k]
  ------------------
   88|  7.20k|        retval = READSTAT_ERROR_BAD_MR_STRING;
   89|  7.20k|        goto cleanup;
   90|  7.20k|    }
   91|  47.1k|    str = p;
   92|   158k|    while (p < end && *p != '=' && *p != ' ')
  ------------------
  |  Branch (92:12): [True: 155k, False: 2.54k]
  |  Branch (92:23): [True: 116k, False: 39.6k]
  |  Branch (92:36): [True: 111k, False: 5.01k]
  ------------------
   93|   111k|        p++;
   94|  47.1k|    if (p == end || *p != '=' || p == str) {
  ------------------
  |  Branch (94:9): [True: 2.54k, False: 44.6k]
  |  Branch (94:21): [True: 5.01k, False: 39.6k]
  |  Branch (94:34): [True: 0, False: 39.6k]
  ------------------
   95|  7.56k|        retval = READSTAT_ERROR_BAD_MR_STRING;
   96|  7.56k|        goto cleanup;
   97|  7.56k|    }
   98|  39.6k|    if ((retval = mr_convert(&result->name, str, p - str, ctx)) != READSTAT_OK)
  ------------------
  |  Branch (98:9): [True: 196, False: 39.4k]
  ------------------
   99|    196|        goto cleanup;
  100|  39.4k|    p++;
  101|       |
  102|       |    /* Type */
  103|  39.4k|    if (p == end || (*p != 'C' && *p != 'D' && *p != 'E')) {
  ------------------
  |  Branch (103:9): [True: 310, False: 39.0k]
  |  Branch (103:22): [True: 23.7k, False: 15.3k]
  |  Branch (103:35): [True: 9.02k, False: 14.7k]
  |  Branch (103:48): [True: 2.73k, False: 6.29k]
  ------------------
  104|  3.04k|        retval = READSTAT_ERROR_BAD_MR_STRING;
  105|  3.04k|        goto cleanup;
  106|  3.04k|    }
  107|  36.3k|    result->type = *p++;
  108|  36.3k|    result->counted_value = -1;
  109|       |
  110|  36.3k|    if (result->type == 'E') {
  ------------------
  |  Branch (110:9): [True: 6.29k, False: 30.0k]
  ------------------
  111|       |        /* " 1 " or " 11 ": 11 means LABELSOURCE=VARLABEL */
  112|  6.29k|        long flag = 0;
  113|  6.29k|        if (p == end || *p != ' ') {
  ------------------
  |  Branch (113:13): [True: 344, False: 5.94k]
  |  Branch (113:25): [True: 720, False: 5.22k]
  ------------------
  114|  1.06k|            retval = READSTAT_ERROR_BAD_MR_STRING;
  115|  1.06k|            goto cleanup;
  116|  1.06k|        }
  117|  5.22k|        p++;
  118|  5.22k|        if (p == end || *p < '0' || *p > '9') {
  ------------------
  |  Branch (118:13): [True: 936, False: 4.29k]
  |  Branch (118:25): [True: 688, False: 3.60k]
  |  Branch (118:37): [True: 1.26k, False: 2.33k]
  ------------------
  119|  2.89k|            retval = READSTAT_ERROR_BAD_MR_STRING;
  120|  2.89k|            goto cleanup;
  121|  2.89k|        }
  122|  6.62k|        while (p < end && *p >= '0' && *p <= '9' && flag < 1000)
  ------------------
  |  Branch (122:16): [True: 6.39k, False: 232]
  |  Branch (122:27): [True: 4.54k, False: 1.84k]
  |  Branch (122:40): [True: 4.29k, False: 258]
  |  Branch (122:53): [True: 4.28k, False: 4]
  ------------------
  123|  4.28k|            flag = flag * 10 + (*p++ - '0');
  124|  2.33k|        if (p == end || *p != ' ') {
  ------------------
  |  Branch (124:13): [True: 232, False: 2.10k]
  |  Branch (124:25): [True: 1.46k, False: 638]
  ------------------
  125|  1.69k|            retval = READSTAT_ERROR_BAD_MR_STRING;
  126|  1.69k|            goto cleanup;
  127|  1.69k|        }
  128|    638|        p++;
  129|    638|        result->label_from_var_label = (flag == 11);
  130|    638|    }
  131|       |
  132|  30.7k|    if (result->type == 'D' || result->type == 'E') {
  ------------------
  |  Branch (132:9): [True: 14.7k, False: 15.9k]
  |  Branch (132:32): [True: 638, False: 15.3k]
  ------------------
  133|  15.3k|        result->is_dichotomy = 1;
  134|  15.3k|        if ((retval = mr_read_counted_string(&p, end, &str, &str_len)) != READSTAT_OK)
  ------------------
  |  Branch (134:13): [True: 5.16k, False: 10.2k]
  ------------------
  135|  5.16k|            goto cleanup;
  136|  10.2k|        if ((retval = mr_convert(&result->counted_string, str, str_len, ctx)) != READSTAT_OK)
  ------------------
  |  Branch (136:13): [True: 205, False: 10.0k]
  ------------------
  137|    205|            goto cleanup;
  138|       |        /* readstat_convert trims trailing spaces; older SPSS pads to 8 bytes */
  139|  10.0k|        if (result->counted_string[0] >= '0' && result->counted_string[0] <= '9') {
  ------------------
  |  Branch (139:13): [True: 2.92k, False: 7.07k]
  |  Branch (139:49): [True: 354, False: 2.57k]
  ------------------
  140|    354|            result->counted_value = (int)strtol(result->counted_string, NULL, 10);
  141|    354|        }
  142|  10.0k|        if (p == end || *p != ' ') {
  ------------------
  |  Branch (142:13): [True: 888, False: 9.11k]
  |  Branch (142:25): [True: 3.87k, False: 5.23k]
  ------------------
  143|  4.76k|            retval = READSTAT_ERROR_BAD_MR_STRING;
  144|  4.76k|            goto cleanup;
  145|  4.76k|        }
  146|  5.23k|        p++;
  147|  15.3k|    } else {
  148|  15.3k|        if (p == end || *p != ' ') {
  ------------------
  |  Branch (148:13): [True: 580, False: 14.7k]
  |  Branch (148:25): [True: 866, False: 13.8k]
  ------------------
  149|  1.44k|            retval = READSTAT_ERROR_BAD_MR_STRING;
  150|  1.44k|            goto cleanup;
  151|  1.44k|        }
  152|  13.8k|        p++;
  153|  13.8k|    }
  154|       |
  155|       |    /* Label */
  156|  19.1k|    if ((retval = mr_read_counted_string(&p, end, &str, &str_len)) != READSTAT_OK)
  ------------------
  |  Branch (156:9): [True: 6.24k, False: 12.8k]
  ------------------
  157|  6.24k|        goto cleanup;
  158|  12.8k|    if ((retval = mr_convert(&result->label, str, str_len, ctx)) != READSTAT_OK)
  ------------------
  |  Branch (158:9): [True: 449, False: 12.4k]
  ------------------
  159|    449|        goto cleanup;
  160|       |
  161|       |    /* Variables: space-separated; some files have zero or one variable */
  162|  76.6k|    while (p < end) {
  ------------------
  |  Branch (162:12): [True: 64.8k, False: 11.7k]
  ------------------
  163|  64.8k|        if (*p == ' ') {
  ------------------
  |  Branch (163:13): [True: 35.7k, False: 29.1k]
  ------------------
  164|  35.7k|            p++;
  165|  35.7k|            continue;
  166|  35.7k|        }
  167|  29.1k|        str = p;
  168|   395k|        while (p < end && *p != ' ')
  ------------------
  |  Branch (168:16): [True: 386k, False: 9.64k]
  |  Branch (168:27): [True: 366k, False: 19.4k]
  ------------------
  169|   366k|            p++;
  170|  29.1k|        char *subvar = NULL;
  171|  29.1k|        if ((retval = mr_convert(&subvar, str, p - str, ctx)) != READSTAT_OK)
  ------------------
  |  Branch (171:13): [True: 652, False: 28.4k]
  ------------------
  172|    652|            goto cleanup;
  173|  28.4k|        char **new_subvariables = readstat_realloc(result->subvariables,
  174|  28.4k|                sizeof(char *) * (result->num_subvars + 1));
  175|  28.4k|        if (new_subvariables == NULL) {
  ------------------
  |  Branch (175:13): [True: 0, False: 28.4k]
  ------------------
  176|      0|            free(subvar);
  177|      0|            retval = READSTAT_ERROR_MALLOC;
  178|      0|            goto cleanup;
  179|      0|        }
  180|  28.4k|        result->subvariables = new_subvariables;
  181|  28.4k|        result->subvariables[result->num_subvars++] = subvar;
  182|  28.4k|    }
  183|       |
  184|  54.3k|cleanup:
  185|  54.3k|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (185:9): [True: 42.5k, False: 11.7k]
  ------------------
  186|  42.5k|        mr_set_free_contents(result);
  187|  42.5k|    }
  188|  54.3k|    return retval;
  189|  12.4k|}
readstat_sav_parse_mr_name.c:mr_convert:
   38|  91.8k|static readstat_error_t mr_convert(char **out, const char *src, size_t src_len, sav_ctx_t *ctx) {
   39|  91.8k|    size_t dst_len = 4 * src_len + 1; /* UTF-8 expansion: up to 4 bytes per char */
   40|  91.8k|    char *dst = readstat_malloc(dst_len);
   41|  91.8k|    if (dst == NULL)
  ------------------
  |  Branch (41:9): [True: 0, False: 91.8k]
  ------------------
   42|      0|        return READSTAT_ERROR_MALLOC;
   43|  91.8k|    readstat_error_t retval = readstat_convert(dst, dst_len, src, src_len, ctx->converter);
   44|  91.8k|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (44:9): [True: 1.50k, False: 90.3k]
  ------------------
   45|  1.50k|        free(dst);
   46|  1.50k|        return retval;
   47|  1.50k|    }
   48|  90.3k|    *out = dst;
   49|  90.3k|    return READSTAT_OK;
   50|  91.8k|}
readstat_sav_parse_mr_name.c:mr_read_counted_string:
   55|  34.5k|        const char **str, size_t *str_len) {
   56|  34.5k|    const char *p = *pp;
   57|  34.5k|    size_t n = 0;
   58|  34.5k|    if (p == end || *p < '0' || *p > '9')
  ------------------
  |  Branch (58:9): [True: 1.77k, False: 32.7k]
  |  Branch (58:21): [True: 2.67k, False: 30.0k]
  |  Branch (58:33): [True: 1.52k, False: 28.5k]
  ------------------
   59|  5.97k|        return READSTAT_ERROR_BAD_MR_STRING;
   60|  66.8k|    while (p < end && *p >= '0' && *p <= '9') {
  ------------------
  |  Branch (60:12): [True: 66.0k, False: 778]
  |  Branch (60:23): [True: 40.1k, False: 25.9k]
  |  Branch (60:36): [True: 38.7k, False: 1.41k]
  ------------------
   61|  38.7k|        if (n > (size_t)(end - p))
  ------------------
  |  Branch (61:13): [True: 421, False: 38.3k]
  ------------------
   62|    421|            return READSTAT_ERROR_BAD_MR_STRING;
   63|  38.3k|        n = n * 10 + (*p - '0');
   64|  38.3k|        p++;
   65|  38.3k|    }
   66|  28.1k|    if (p == end || *p != ' ')
  ------------------
  |  Branch (66:9): [True: 778, False: 27.3k]
  |  Branch (66:21): [True: 2.89k, False: 24.4k]
  ------------------
   67|  3.67k|        return READSTAT_ERROR_BAD_MR_STRING;
   68|  24.4k|    p++;
   69|  24.4k|    if (n > (size_t)(end - p))
  ------------------
  |  Branch (69:9): [True: 1.34k, False: 23.1k]
  ------------------
   70|  1.34k|        return READSTAT_ERROR_BAD_MR_STRING;
   71|  23.1k|    *str = p;
   72|  23.1k|    *str_len = n;
   73|  23.1k|    *pp = p + n;
   74|  23.1k|    return READSTAT_OK;
   75|  24.4k|}
readstat_sav_parse_mr_name.c:mr_set_free_contents:
   20|  42.5k|static void mr_set_free_contents(mr_set_t *mr) {
   21|  42.5k|    if (mr->name)
  ------------------
  |  Branch (21:9): [True: 27.6k, False: 14.9k]
  ------------------
   22|  27.6k|        free(mr->name);
   23|  42.5k|    if (mr->label)
  ------------------
  |  Branch (23:9): [True: 652, False: 41.9k]
  ------------------
   24|    652|        free(mr->label);
   25|  42.5k|    if (mr->counted_string)
  ------------------
  |  Branch (25:9): [True: 9.37k, False: 33.1k]
  ------------------
   26|  9.37k|        free(mr->counted_string);
   27|  42.5k|    if (mr->subvariables) {
  ------------------
  |  Branch (27:9): [True: 236, False: 42.3k]
  ------------------
   28|    236|        int i;
   29|  1.56k|        for (i=0; i<mr->num_subvars; i++) {
  ------------------
  |  Branch (29:19): [True: 1.32k, False: 236]
  ------------------
   30|  1.32k|            if (mr->subvariables[i])
  ------------------
  |  Branch (30:17): [True: 1.32k, False: 0]
  ------------------
   31|  1.32k|                free(mr->subvariables[i]);
   32|  1.32k|        }
   33|    236|        free(mr->subvariables);
   34|    236|    }
   35|  42.5k|    memset(mr, 0, sizeof(mr_set_t));
   36|  42.5k|}

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

sav_parse_timestamp:
 1727|  6.39k|readstat_error_t sav_parse_timestamp(sav_ctx_t *ctx, sav_file_header_record_t *header) {
 1728|  6.39k|    readstat_error_t retval = READSTAT_OK;
 1729|  6.39k|    struct tm timestamp = { .tm_isdst = -1 };
 1730|       |
 1731|  6.39k|    if ((retval = sav_parse_time(header->creation_time, sizeof(header->creation_time),
  ------------------
  |  Branch (1731:9): [True: 5.80k, False: 591]
  ------------------
 1732|  6.39k|                    &timestamp, ctx->handle.error, ctx->user_ctx)) 
 1733|  6.39k|            != READSTAT_OK)
 1734|  5.80k|        goto cleanup;
 1735|       |
 1736|    591|    if ((retval = sav_parse_date(header->creation_date, sizeof(header->creation_date),
  ------------------
  |  Branch (1736:9): [True: 219, False: 372]
  ------------------
 1737|    591|                    &timestamp, ctx->handle.error, ctx->user_ctx)) 
 1738|    591|            != READSTAT_OK)
 1739|    219|        goto cleanup;
 1740|       |
 1741|    372|    ctx->timestamp = mktime(&timestamp);
 1742|       |
 1743|  6.39k|cleanup:
 1744|  6.39k|    return retval;
 1745|    372|}
readstat_parse_sav:
 1747|  6.44k|readstat_error_t readstat_parse_sav(readstat_parser_t *parser, const char *path, void *user_ctx) {
 1748|  6.44k|    readstat_error_t retval = READSTAT_OK;
 1749|  6.44k|    readstat_io_t *io = parser->io;
 1750|  6.44k|    sav_file_header_record_t header;
 1751|  6.44k|    sav_ctx_t *ctx = NULL;
 1752|  6.44k|    size_t file_size = 0;
 1753|       |    
 1754|  6.44k|    if (io->open(path, io->io_ctx) == -1) {
  ------------------
  |  Branch (1754:9): [True: 0, False: 6.44k]
  ------------------
 1755|      0|        return READSTAT_ERROR_OPEN;
 1756|      0|    }
 1757|       |
 1758|  6.44k|    file_size = io->seek(0, READSTAT_SEEK_END, io->io_ctx);
 1759|  6.44k|    if (file_size == -1) {
  ------------------
  |  Branch (1759:9): [True: 0, False: 6.44k]
  ------------------
 1760|      0|        retval = READSTAT_ERROR_SEEK;
 1761|      0|        goto cleanup;
 1762|      0|    }
 1763|       |
 1764|  6.44k|    if (io->seek(0, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (1764:9): [True: 0, False: 6.44k]
  ------------------
 1765|      0|        retval = READSTAT_ERROR_SEEK;
 1766|      0|        goto cleanup;
 1767|      0|    }
 1768|       |
 1769|  6.44k|    if (io->read(&header, sizeof(sav_file_header_record_t), io->io_ctx) < sizeof(sav_file_header_record_t)) {
  ------------------
  |  Branch (1769:9): [True: 18, False: 6.43k]
  ------------------
 1770|     18|        retval = READSTAT_ERROR_READ;
 1771|     18|        goto cleanup;
 1772|     18|    }
 1773|       |
 1774|  6.43k|    ctx = sav_ctx_init(&header, io);
 1775|  6.43k|    if (ctx == NULL) {
  ------------------
  |  Branch (1775:9): [True: 31, False: 6.39k]
  ------------------
 1776|     31|        retval = READSTAT_ERROR_PARSE;
 1777|     31|        goto cleanup;
 1778|     31|    }
 1779|       |
 1780|  6.39k|    ctx->handle = parser->handlers;
 1781|  6.39k|    ctx->input_encoding = parser->input_encoding;
 1782|  6.39k|    ctx->output_encoding = parser->output_encoding;
 1783|  6.39k|    ctx->user_ctx = user_ctx;
 1784|  6.39k|    ctx->file_size = file_size;
 1785|  6.39k|    if (parser->row_offset > 0)
  ------------------
  |  Branch (1785:9): [True: 0, False: 6.39k]
  ------------------
 1786|      0|        ctx->row_offset = parser->row_offset;
 1787|  6.39k|    if (ctx->record_count >= 0) {
  ------------------
  |  Branch (1787:9): [True: 4.47k, False: 1.92k]
  ------------------
 1788|  4.47k|        int record_count_after_skipping = ctx->record_count - ctx->row_offset;
 1789|  4.47k|        if (record_count_after_skipping < 0) {
  ------------------
  |  Branch (1789:13): [True: 0, False: 4.47k]
  ------------------
 1790|      0|            record_count_after_skipping = 0;
 1791|      0|            ctx->row_offset = ctx->record_count;
 1792|      0|        }
 1793|  4.47k|        ctx->row_limit = record_count_after_skipping;
 1794|  4.47k|        if (parser->row_limit > 0 && parser->row_limit < record_count_after_skipping) 
  ------------------
  |  Branch (1794:13): [True: 0, False: 4.47k]
  |  Branch (1794:38): [True: 0, False: 0]
  ------------------
 1795|      0|            ctx->row_limit = parser->row_limit;
 1796|  4.47k|    } else if (parser->row_limit > 0) {
  ------------------
  |  Branch (1796:16): [True: 0, False: 1.92k]
  ------------------
 1797|      0|        ctx->row_limit = parser->row_limit;
 1798|      0|    }
 1799|       |    
 1800|       |    /* ignore errors */
 1801|  6.39k|    sav_parse_timestamp(ctx, &header);
 1802|       |
 1803|  6.39k|    if ((retval = sav_parse_records_pass1(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1803:9): [True: 1.04k, False: 5.35k]
  ------------------
 1804|  1.04k|        goto cleanup;
 1805|       |
 1806|  5.35k|    if ((retval = sav_setup_converter(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1806:9): [True: 26, False: 5.32k]
  ------------------
 1807|     26|        goto cleanup;
 1808|       |    
 1809|  5.32k|    if (io->seek(sizeof(sav_file_header_record_t), READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (1809:9): [True: 0, False: 5.32k]
  ------------------
 1810|      0|        retval = READSTAT_ERROR_SEEK;
 1811|      0|        goto cleanup;
 1812|      0|    }
 1813|       |
 1814|  5.32k|    if ((retval = sav_update_progress(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1814:9): [True: 0, False: 5.32k]
  ------------------
 1815|      0|        goto cleanup;
 1816|       |
 1817|  5.32k|    if ((retval = sav_parse_records_pass2(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1817:9): [True: 3.25k, False: 2.07k]
  ------------------
 1818|  3.25k|        goto cleanup;
 1819|       | 
 1820|  2.07k|    if ((retval = sav_set_n_segments_and_var_count(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1820:9): [True: 45, False: 2.02k]
  ------------------
 1821|     45|        goto cleanup;
 1822|       |
 1823|  2.02k|    if (ctx->var_count == 0) {
  ------------------
  |  Branch (1823:9): [True: 90, False: 1.93k]
  ------------------
 1824|     90|        retval = READSTAT_ERROR_PARSE;
 1825|     90|        goto cleanup;
 1826|     90|    }
 1827|       |
 1828|  1.93k|    if (ctx->handle.metadata) {
  ------------------
  |  Branch (1828:9): [True: 1.93k, False: 0]
  ------------------
 1829|  1.93k|        readstat_metadata_t metadata = {
 1830|  1.93k|            .row_count = ctx->record_count < 0 ? -1 : ctx->row_limit,
  ------------------
  |  Branch (1830:26): [True: 568, False: 1.36k]
  ------------------
 1831|  1.93k|            .var_count = ctx->var_count,
 1832|  1.93k|            .file_encoding = ctx->input_encoding,
 1833|  1.93k|            .file_format_version = ctx->format_version,
 1834|  1.93k|            .creation_time = ctx->timestamp,
 1835|  1.93k|            .modified_time = ctx->timestamp,
 1836|  1.93k|            .compression = ctx->compression,
 1837|  1.93k|            .endianness = ctx->endianness
 1838|  1.93k|        };
 1839|  1.93k|        if ((retval = readstat_convert(ctx->file_label, sizeof(ctx->file_label),
  ------------------
  |  Branch (1839:13): [True: 15, False: 1.92k]
  ------------------
 1840|  1.93k|                        header.file_label, sizeof(header.file_label), ctx->converter)) != READSTAT_OK)
 1841|     15|            goto cleanup;
 1842|       |
 1843|  1.92k|        metadata.file_label = ctx->file_label;
 1844|       |
 1845|       |        // Replace short MR names with long names
 1846|  1.92k|        ck_hash_table_t *var_dict = ck_hash_table_init(ctx->var_index, 8);
 1847|   463k|        for (size_t i = 0; i < ctx->var_index; i++) {
  ------------------
  |  Branch (1847:28): [True: 461k, False: 1.92k]
  ------------------
 1848|   461k|            spss_varinfo_t *current_varinfo = ctx->varinfo[i];
 1849|   461k|            if (current_varinfo != NULL && current_varinfo->name[0] != '\0') {
  ------------------
  |  Branch (1849:17): [True: 461k, False: 0]
  |  Branch (1849:44): [True: 457k, False: 4.21k]
  ------------------
 1850|   457k|                ck_str_hash_insert(current_varinfo->name, current_varinfo, var_dict);
 1851|   457k|            }
 1852|   461k|        }
 1853|  12.8k|        for (size_t i = 0; i < ctx->multiple_response_sets_length; i++) {
  ------------------
  |  Branch (1853:28): [True: 10.9k, False: 1.92k]
  ------------------
 1854|  10.9k|            mr_set_t mr = ctx->mr_sets[i];
 1855|  36.2k|            for (size_t j = 0; j < mr.num_subvars; j++) {
  ------------------
  |  Branch (1855:32): [True: 25.2k, False: 10.9k]
  ------------------
 1856|  25.2k|                char* sv_name_upper = readstat_malloc(strlen(mr.subvariables[j]) + 1);
 1857|  25.2k|                if (sv_name_upper == NULL) {
  ------------------
  |  Branch (1857:21): [True: 0, False: 25.2k]
  ------------------
 1858|      0|                    retval = READSTAT_ERROR_MALLOC;
 1859|      0|                    goto cleanup;
 1860|      0|                }
 1861|  25.2k|                sv_name_upper[strlen(mr.subvariables[j])] = '\0';
 1862|   383k|                for (int c = 0; mr.subvariables[j][c] != '\0'; c++) {
  ------------------
  |  Branch (1862:33): [True: 358k, False: 25.2k]
  ------------------
 1863|   358k|                    sv_name_upper[c] = toupper((unsigned char) mr.subvariables[j][c]);
  ------------------
  |  Branch (1863:40): [True: 0, False: 0]
  |  Branch (1863:40): [True: 0, False: 0]
  |  Branch (1863:40): [Folded, False: 358k]
  ------------------
 1864|   358k|                }
 1865|  25.2k|                spss_varinfo_t *info = (spss_varinfo_t *)ck_str_hash_lookup(sv_name_upper, var_dict);
 1866|  25.2k|                if (info) {
  ------------------
  |  Branch (1866:21): [True: 295, False: 24.9k]
  ------------------
 1867|    295|                    free(mr.subvariables[j]);
 1868|       |                    // mr.subvariables[j] = NULL;
 1869|    295|                    if ((mr.subvariables[j] = readstat_malloc(strlen(info->longname) + 1)) == NULL) {
  ------------------
  |  Branch (1869:25): [True: 0, False: 295]
  ------------------
 1870|      0|                        retval = READSTAT_ERROR_MALLOC;
 1871|      0|                        goto cleanup;
 1872|      0|                    }
 1873|       |                    // mr.subvariables[j][strlen(info->longname)] = '\0';
 1874|    295|                    strcpy(mr.subvariables[j], info->longname);
 1875|       |                    // mr.subvariables[j] = info->longname;
 1876|    295|                }
 1877|  25.2k|                free(sv_name_upper);
 1878|       |                // sv_name_upper = NULL;
 1879|  25.2k|            }
 1880|  10.9k|        }
 1881|  1.92k|        if (var_dict)
  ------------------
  |  Branch (1881:13): [True: 1.92k, False: 0]
  ------------------
 1882|  1.92k|            ck_hash_table_free(var_dict);
 1883|       |
 1884|  1.92k|        metadata.multiple_response_sets_length = ctx->multiple_response_sets_length;
 1885|  1.92k|        metadata.mr_sets = ctx->mr_sets;
 1886|       |
 1887|  1.92k|        if (ctx->handle.metadata(&metadata, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|  1.92k|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (1887:13): [True: 0, False: 1.92k]
  ------------------
 1888|      0|            retval = READSTAT_ERROR_USER_ABORT;
 1889|      0|            goto cleanup;
 1890|      0|        }
 1891|  1.92k|    }
 1892|       |
 1893|  1.92k|    if ((retval = sav_parse_variable_display_parameter_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1893:9): [True: 0, False: 1.92k]
  ------------------
 1894|      0|        goto cleanup;
 1895|       |
 1896|  1.92k|    if ((retval = sav_handle_variables(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1896:9): [True: 0, False: 1.92k]
  ------------------
 1897|      0|        goto cleanup;
 1898|       |
 1899|       |
 1900|  1.92k|    if ((retval = sav_handle_fweight(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1900:9): [True: 0, False: 1.92k]
  ------------------
 1901|      0|        goto cleanup;
 1902|       |
 1903|  1.92k|    if (ctx->handle.value) {
  ------------------
  |  Branch (1903:9): [True: 1.92k, False: 0]
  ------------------
 1904|  1.92k|        retval = sav_read_data(ctx);
 1905|  1.92k|    }
 1906|       |    
 1907|  6.44k|cleanup:
 1908|  6.44k|    io->close(io->io_ctx);
 1909|  6.44k|    if (ctx)
  ------------------
  |  Branch (1909:9): [True: 6.39k, False: 49]
  ------------------
 1910|  6.39k|        sav_ctx_free(ctx);
 1911|       |    
 1912|  6.44k|    return retval;
 1913|  1.92k|}
readstat_sav_read.c:sav_parse_records_pass1:
 1423|  6.39k|static readstat_error_t sav_parse_records_pass1(sav_ctx_t *ctx) {
 1424|  6.39k|    char data_buf[4096];
 1425|  6.39k|    readstat_error_t retval = READSTAT_OK;
 1426|  6.39k|    readstat_io_t *io = ctx->io;
 1427|   661k|    while (1) {
  ------------------
  |  Branch (1427:12): [True: 661k, Folded]
  ------------------
 1428|   661k|        uint32_t rec_type;
 1429|   661k|        uint32_t extra_info[3];
 1430|   661k|        size_t data_len = 0;
 1431|   661k|        int i;
 1432|   661k|        int done = 0;
 1433|   661k|        if (io->read(&rec_type, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (1433:13): [True: 387, False: 661k]
  ------------------
 1434|    387|            retval = READSTAT_ERROR_READ;
 1435|    387|            goto cleanup;
 1436|    387|        }
 1437|       |        
 1438|   661k|        if (ctx->bswap) {
  ------------------
  |  Branch (1438:13): [True: 16.4k, False: 644k]
  ------------------
 1439|  16.4k|            rec_type = byteswap4(rec_type);
 1440|  16.4k|        }
 1441|       |        
 1442|   661k|        switch (rec_type) {
 1443|   497k|            case SAV_RECORD_TYPE_VARIABLE:
  ------------------
  |  |  117|   497k|#define SAV_RECORD_TYPE_VARIABLE                2
  ------------------
  |  Branch (1443:13): [True: 497k, False: 163k]
  ------------------
 1444|   497k|                retval = sav_skip_variable_record(ctx);
 1445|   497k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1445:21): [True: 147, False: 497k]
  ------------------
 1446|    147|                    goto cleanup;
 1447|   497k|                break;
 1448|   497k|            case SAV_RECORD_TYPE_VALUE_LABEL:
  ------------------
  |  |  118|  91.7k|#define SAV_RECORD_TYPE_VALUE_LABEL             3
  ------------------
  |  Branch (1448:13): [True: 91.7k, False: 569k]
  ------------------
 1449|  91.7k|                retval = sav_skip_value_label_record(ctx);
 1450|  91.7k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1450:21): [True: 180, False: 91.5k]
  ------------------
 1451|    180|                    goto cleanup;
 1452|  91.5k|                break;
 1453|  91.5k|            case SAV_RECORD_TYPE_DOCUMENT:
  ------------------
  |  |  120|  3.84k|#define SAV_RECORD_TYPE_DOCUMENT                6
  ------------------
  |  Branch (1453:13): [True: 3.84k, False: 657k]
  ------------------
 1454|  3.84k|                retval = sav_skip_document_record(ctx);
 1455|  3.84k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1455:21): [True: 52, False: 3.79k]
  ------------------
 1456|     52|                    goto cleanup;
 1457|  3.79k|                break;
 1458|  5.35k|            case SAV_RECORD_TYPE_DICT_TERMINATION:
  ------------------
  |  |  122|  5.35k|#define SAV_RECORD_TYPE_DICT_TERMINATION        999
  ------------------
  |  Branch (1458:13): [True: 5.35k, False: 655k]
  ------------------
 1459|  5.35k|                done = 1;
 1460|  5.35k|                break;
 1461|  62.8k|            case SAV_RECORD_TYPE_HAS_DATA:
  ------------------
  |  |  121|  62.8k|#define SAV_RECORD_TYPE_HAS_DATA                7
  ------------------
  |  Branch (1461:13): [True: 62.8k, False: 598k]
  ------------------
 1462|  62.8k|                if (io->read(extra_info, sizeof(extra_info), io->io_ctx) < sizeof(extra_info)) {
  ------------------
  |  Branch (1462:21): [True: 4, False: 62.7k]
  ------------------
 1463|      4|                    retval = READSTAT_ERROR_READ;
 1464|      4|                    goto cleanup;
 1465|      4|                }
 1466|  62.7k|                if (ctx->bswap) {
  ------------------
  |  Branch (1466:21): [True: 3.56k, False: 59.2k]
  ------------------
 1467|  14.2k|                    for (i=0; i<3; i++)
  ------------------
  |  Branch (1467:31): [True: 10.6k, False: 3.56k]
  ------------------
 1468|  10.6k|                        extra_info[i] = byteswap4(extra_info[i]);
 1469|  3.56k|                }
 1470|  62.7k|                uint32_t subtype = extra_info[0];
 1471|  62.7k|                size_t size = extra_info[1];
 1472|  62.7k|                size_t count = extra_info[2];
 1473|  62.7k|                if (size && count > SIZE_MAX / size) {
  ------------------
  |  Branch (1473:21): [True: 62.5k, False: 273]
  |  Branch (1473:29): [True: 0, False: 62.5k]
  ------------------
 1474|      0|                    retval = READSTAT_ERROR_PARSE;
 1475|      0|                    goto cleanup;
 1476|      0|                }
 1477|  62.7k|                data_len = size * count;
 1478|  62.7k|                if (subtype == SAV_RECORD_SUBTYPE_INTEGER_INFO ||
  ------------------
  |  |  124|   125k|#define SAV_RECORD_SUBTYPE_INTEGER_INFO       3
  ------------------
  |  Branch (1478:21): [True: 1.01k, False: 61.7k]
  ------------------
 1479|  61.7k|                        subtype == SAV_RECORD_SUBTYPE_FP_INFO ||
  ------------------
  |  |  125|   124k|#define SAV_RECORD_SUBTYPE_FP_INFO            4
  ------------------
  |  Branch (1479:25): [True: 1.84k, False: 59.9k]
  ------------------
 1480|  59.9k|                        subtype == SAV_RECORD_SUBTYPE_CHAR_ENCODING) {
  ------------------
  |  |  135|  59.9k|#define SAV_RECORD_SUBTYPE_CHAR_ENCODING     20
  ------------------
  |  Branch (1480:25): [True: 1.13k, False: 58.8k]
  ------------------
 1481|  3.99k|                    if (data_len > sizeof(data_buf)) {
  ------------------
  |  Branch (1481:25): [True: 58, False: 3.93k]
  ------------------
 1482|     58|                        retval = READSTAT_ERROR_PARSE;
 1483|     58|                        goto cleanup;
 1484|     58|                    }
 1485|  3.93k|                    if (data_len && io->read(data_buf, data_len, io->io_ctx) < data_len) {
  ------------------
  |  Branch (1485:25): [True: 3.01k, False: 919]
  |  Branch (1485:37): [True: 20, False: 2.99k]
  ------------------
 1486|     20|                        retval = READSTAT_ERROR_PARSE;
 1487|     20|                        goto cleanup;
 1488|     20|                    }
 1489|  3.91k|                    if (subtype == SAV_RECORD_SUBTYPE_INTEGER_INFO) {
  ------------------
  |  |  124|  3.91k|#define SAV_RECORD_SUBTYPE_INTEGER_INFO       3
  ------------------
  |  Branch (1489:25): [True: 971, False: 2.94k]
  ------------------
 1490|    971|                        retval = sav_parse_machine_integer_info_record(data_buf, data_len, ctx);
 1491|  2.94k|                    } else if (subtype == SAV_RECORD_SUBTYPE_FP_INFO) {
  ------------------
  |  |  125|  2.94k|#define SAV_RECORD_SUBTYPE_FP_INFO            4
  ------------------
  |  Branch (1491:32): [True: 1.82k, False: 1.12k]
  ------------------
 1492|       |                        /* Parsed here so the file's SYSMIS/LOWEST/HIGHEST are
 1493|       |                         * known before the variable records' missing values */
 1494|  1.82k|                        retval = sav_parse_machine_floating_point_record(data_buf, size, count, ctx);
 1495|  1.82k|                    } else {
 1496|  1.12k|                        retval = sav_parse_character_encoding_record(data_buf, data_len, ctx);
 1497|  1.12k|                    }
 1498|  3.91k|                    if (retval != READSTAT_OK)
  ------------------
  |  Branch (1498:25): [True: 0, False: 3.91k]
  ------------------
 1499|      0|                        goto cleanup;
 1500|  58.8k|                } else {
 1501|  58.8k|                    if (io->seek(data_len, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (1501:25): [True: 112, False: 58.6k]
  ------------------
 1502|    112|                        retval = READSTAT_ERROR_SEEK;
 1503|    112|                        goto cleanup;
 1504|    112|                    }
 1505|  58.8k|                }
 1506|  62.6k|                break;
 1507|  62.6k|            default:
  ------------------
  |  Branch (1507:13): [True: 89, False: 661k]
  ------------------
 1508|     89|                retval = READSTAT_ERROR_PARSE;
 1509|     89|                goto cleanup;
 1510|      0|                break;
 1511|   661k|        }
 1512|   660k|        if (done)
  ------------------
  |  Branch (1512:13): [True: 5.35k, False: 655k]
  ------------------
 1513|  5.35k|            break;
 1514|   660k|    }
 1515|  6.39k|cleanup:
 1516|  6.39k|    return retval;
 1517|  6.39k|}
readstat_sav_read.c:sav_skip_variable_record:
  190|   497k|static readstat_error_t sav_skip_variable_record(sav_ctx_t *ctx) {
  191|   497k|    sav_variable_record_t variable;
  192|   497k|    readstat_error_t retval = READSTAT_OK;
  193|   497k|    readstat_io_t *io = ctx->io;
  194|   497k|    if (io->read(&variable, sizeof(sav_variable_record_t), io->io_ctx) < sizeof(sav_variable_record_t)) {
  ------------------
  |  Branch (194:9): [True: 9, False: 497k]
  ------------------
  195|      9|        retval = READSTAT_ERROR_READ;
  196|      9|        goto cleanup;
  197|      9|    }
  198|   497k|    if (variable.has_var_label) {
  ------------------
  |  Branch (198:9): [True: 33.0k, False: 464k]
  ------------------
  199|  33.0k|        uint32_t label_len;
  200|  33.0k|        if (io->read(&label_len, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (200:13): [True: 43, False: 33.0k]
  ------------------
  201|     43|            retval = READSTAT_ERROR_READ;
  202|     43|            goto cleanup;
  203|     43|        }
  204|  33.0k|        label_len = ctx->bswap ? byteswap4(label_len) : label_len;
  ------------------
  |  Branch (204:21): [True: 896, False: 32.1k]
  ------------------
  205|  33.0k|        readstat_off_t label_capacity = ((readstat_off_t)label_len + 3) / 4 * 4;
  206|  33.0k|        if (io->seek(label_capacity, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (206:13): [True: 9, False: 33.0k]
  ------------------
  207|      9|            retval = READSTAT_ERROR_SEEK;
  208|      9|            goto cleanup;
  209|      9|        }
  210|  33.0k|    }
  211|   497k|    if (variable.n_missing_values) {
  ------------------
  |  Branch (211:9): [True: 36.9k, False: 460k]
  ------------------
  212|  36.9k|        int n_missing_values = ctx->bswap ? byteswap4(variable.n_missing_values) : variable.n_missing_values;
  ------------------
  |  Branch (212:32): [True: 3.02k, False: 33.9k]
  ------------------
  213|  36.9k|        if (n_missing_values > 3 || n_missing_values < -3) {
  ------------------
  |  Branch (213:13): [True: 18, False: 36.9k]
  |  Branch (213:37): [True: 52, False: 36.8k]
  ------------------
  214|     70|            retval = READSTAT_ERROR_PARSE;
  215|     70|            goto cleanup;
  216|     70|        }
  217|  36.8k|        if (io->seek(abs(n_missing_values) * sizeof(double), READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (217:13): [True: 16, False: 36.8k]
  ------------------
  218|     16|            retval = READSTAT_ERROR_SEEK;
  219|     16|            goto cleanup;
  220|     16|        }
  221|  36.8k|    }
  222|   497k|cleanup:
  223|   497k|    return retval;
  224|   497k|}
readstat_sav_read.c:sav_skip_value_label_record:
  470|  91.7k|static readstat_error_t sav_skip_value_label_record(sav_ctx_t *ctx) {
  471|  91.7k|    uint32_t label_count;
  472|  91.7k|    uint32_t rec_type;
  473|  91.7k|    uint32_t var_count;
  474|  91.7k|    readstat_error_t retval = READSTAT_OK;
  475|  91.7k|    readstat_io_t *io = ctx->io;
  476|  91.7k|    if (io->read(&label_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (476:9): [True: 3, False: 91.7k]
  ------------------
  477|      3|        retval = READSTAT_ERROR_READ;
  478|      3|        goto cleanup;
  479|      3|    }
  480|  91.7k|    if (ctx->bswap)
  ------------------
  |  Branch (480:9): [True: 2.84k, False: 88.8k]
  ------------------
  481|  2.84k|        label_count = byteswap4(label_count);
  482|  91.7k|    int i;
  483|   273k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (483:15): [True: 182k, False: 91.6k]
  ------------------
  484|   182k|        unsigned char unpadded_len = 0;
  485|   182k|        size_t padded_len = 0;
  486|   182k|        if (io->seek(8, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (486:13): [True: 72, False: 182k]
  ------------------
  487|     72|            retval = READSTAT_ERROR_SEEK;
  488|     72|            goto cleanup;
  489|     72|        }
  490|   182k|        if (io->read(&unpadded_len, 1, io->io_ctx) < 1) {
  ------------------
  |  Branch (490:13): [True: 18, False: 182k]
  ------------------
  491|     18|            retval = READSTAT_ERROR_READ;
  492|     18|            goto cleanup;
  493|     18|        }
  494|   182k|        padded_len = (unpadded_len + 8) / 8 * 8 - 1;
  495|   182k|        if (io->seek(padded_len, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (495:13): [True: 6, False: 182k]
  ------------------
  496|      6|            retval = READSTAT_ERROR_SEEK;
  497|      6|            goto cleanup;
  498|      6|        }
  499|   182k|    }
  500|       |
  501|  91.6k|    if (io->read(&rec_type, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (501:9): [True: 20, False: 91.5k]
  ------------------
  502|     20|        retval = READSTAT_ERROR_READ;
  503|     20|        goto cleanup;
  504|     20|    }
  505|  91.5k|    if (ctx->bswap)
  ------------------
  |  Branch (505:9): [True: 2.78k, False: 88.8k]
  ------------------
  506|  2.78k|        rec_type = byteswap4(rec_type);
  507|       |    
  508|  91.5k|    if (rec_type != 4) {
  ------------------
  |  Branch (508:9): [True: 46, False: 91.5k]
  ------------------
  509|     46|        retval = READSTAT_ERROR_PARSE;
  510|     46|        goto cleanup;
  511|     46|    }
  512|  91.5k|    if (io->read(&var_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (512:9): [True: 6, False: 91.5k]
  ------------------
  513|      6|        retval = READSTAT_ERROR_READ;
  514|      6|        goto cleanup;
  515|      6|    }
  516|  91.5k|    if (ctx->bswap)
  ------------------
  |  Branch (516:9): [True: 2.75k, False: 88.7k]
  ------------------
  517|  2.75k|        var_count = byteswap4(var_count);
  518|       |    
  519|  91.5k|    if (io->seek(var_count * sizeof(uint32_t), READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (519:9): [True: 9, False: 91.5k]
  ------------------
  520|      9|        retval = READSTAT_ERROR_SEEK;
  521|      9|        goto cleanup;
  522|      9|    }
  523|       |
  524|  91.7k|cleanup:
  525|  91.7k|    return retval;
  526|  91.5k|}
readstat_sav_read.c:sav_skip_document_record:
  682|  3.84k|static readstat_error_t sav_skip_document_record(sav_ctx_t *ctx) {
  683|  3.84k|    uint32_t n_lines;
  684|  3.84k|    readstat_error_t retval = READSTAT_OK;
  685|  3.84k|    readstat_io_t *io = ctx->io;
  686|  3.84k|    if (io->read(&n_lines, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (686:9): [True: 3, False: 3.84k]
  ------------------
  687|      3|        retval = READSTAT_ERROR_READ;
  688|      3|        goto cleanup;
  689|      3|    }
  690|  3.84k|    if (ctx->bswap)
  ------------------
  |  Branch (690:9): [True: 2.03k, False: 1.81k]
  ------------------
  691|  2.03k|        n_lines = byteswap4(n_lines);
  692|  3.84k|    if (io->seek((readstat_off_t)n_lines * SPSS_DOC_LINE_SIZE, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  |   40|  3.84k|#define SPSS_DOC_LINE_SIZE  80
  ------------------
  |  Branch (692:9): [True: 49, False: 3.79k]
  ------------------
  693|     49|        retval = READSTAT_ERROR_SEEK;
  694|     49|        goto cleanup;
  695|     49|    }
  696|       |    
  697|  3.84k|cleanup:
  698|  3.84k|    return retval;
  699|  3.84k|}
readstat_sav_read.c:sav_parse_machine_integer_info_record:
 1009|    971|static readstat_error_t sav_parse_machine_integer_info_record(const void *data, size_t data_len, sav_ctx_t *ctx) {
 1010|    971|    if (data_len != 32)
  ------------------
  |  Branch (1010:9): [True: 141, False: 830]
  ------------------
 1011|    141|        return READSTAT_OK; /* malformed; ignore the record like PSPP does */
 1012|       |
 1013|    830|    sav_machine_integer_info_record_t record;
 1014|    830|    memcpy(&record, data, data_len);
 1015|    830|    ctx->charset_code = ctx->bswap ? byteswap4(record.character_code) : record.character_code;
  ------------------
  |  Branch (1015:25): [True: 194, False: 636]
  ------------------
 1016|    830|    return READSTAT_OK;
 1017|    971|}
readstat_sav_read.c:sav_parse_machine_floating_point_record:
 1096|  1.82k|static readstat_error_t sav_parse_machine_floating_point_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
 1097|  1.82k|    if (size != 8 || count != 3)
  ------------------
  |  Branch (1097:9): [True: 905, False: 919]
  |  Branch (1097:22): [True: 310, False: 609]
  ------------------
 1098|  1.21k|        return READSTAT_OK; /* malformed; ignore the record like PSPP does */
 1099|       |
 1100|    609|    sav_machine_floating_point_info_record_t fp_info;
 1101|    609|    memcpy(&fp_info, data, sizeof(sav_machine_floating_point_info_record_t));
 1102|       |
 1103|    609|    ctx->missing_double = ctx->bswap ? byteswap8(fp_info.sysmis) : fp_info.sysmis;
  ------------------
  |  Branch (1103:27): [True: 219, False: 390]
  ------------------
 1104|    609|    ctx->highest_double = ctx->bswap ? byteswap8(fp_info.highest) : fp_info.highest;
  ------------------
  |  Branch (1104:27): [True: 219, False: 390]
  ------------------
 1105|    609|    ctx->lowest_double = ctx->bswap ? byteswap8(fp_info.lowest) : fp_info.lowest;
  ------------------
  |  Branch (1105:26): [True: 219, False: 390]
  ------------------
 1106|       |
 1107|    609|    return READSTAT_OK;
 1108|  1.82k|}
readstat_sav_read.c:sav_parse_character_encoding_record:
 1021|  1.12k|static readstat_error_t sav_parse_character_encoding_record(const void *data, size_t data_len, sav_ctx_t *ctx) {
 1022|  1.12k|    if (data_len == 0 || data_len >= sizeof(ctx->charset_name))
  ------------------
  |  Branch (1022:9): [True: 68, False: 1.05k]
  |  Branch (1022:26): [True: 490, False: 564]
  ------------------
 1023|    558|        return READSTAT_OK;
 1024|    564|    readstat_convert(ctx->charset_name, sizeof(ctx->charset_name), data, data_len, NULL);
 1025|    564|    return READSTAT_OK;
 1026|  1.12k|}
readstat_sav_read.c:sav_setup_converter:
 1047|  5.35k|static readstat_error_t sav_setup_converter(sav_ctx_t *ctx) {
 1048|  5.35k|    const char *dst_charset = ctx->output_encoding;
 1049|  5.35k|    const char *code_charset = sav_charset_name_for_code(ctx->charset_code);
 1050|  5.35k|    const char *src_charset = NULL;
 1051|  5.35k|    iconv_t converter = (iconv_t)-1;
 1052|       |
 1053|  5.35k|    if (ctx->input_encoding) {
  ------------------
  |  Branch (1053:9): [True: 0, False: 5.35k]
  ------------------
 1054|      0|        src_charset = ctx->input_encoding;
 1055|      0|        converter = sav_open_converter(src_charset, dst_charset);
 1056|  5.35k|    } else if (ctx->charset_name[0]) {
  ------------------
  |  Branch (1056:16): [True: 134, False: 5.21k]
  ------------------
 1057|    134|        src_charset = ctx->charset_name;
 1058|    134|        converter = sav_open_converter(src_charset, dst_charset);
 1059|    134|        if (converter == (iconv_t)-1 && code_charset) {
  ------------------
  |  Branch (1059:13): [True: 3, False: 131]
  |  Branch (1059:41): [True: 1, False: 2]
  ------------------
 1060|      1|            src_charset = code_charset;
 1061|      1|            converter = sav_open_converter(src_charset, dst_charset);
 1062|      1|        }
 1063|  5.21k|    } else if (code_charset) {
  ------------------
  |  Branch (1063:16): [True: 58, False: 5.15k]
  ------------------
 1064|     58|        src_charset = code_charset;
 1065|     58|        converter = sav_open_converter(src_charset, dst_charset);
 1066|  5.15k|    } else if (ctx->charset_code) {
  ------------------
  |  Branch (1066:16): [True: 24, False: 5.13k]
  ------------------
 1067|     24|        char error_buf[1024];
 1068|     24|        snprintf(error_buf, sizeof(error_buf), "Unsupported character set: %d\n", ctx->charset_code);
 1069|     24|        sav_report_error(ctx, error_buf);
 1070|     24|        return READSTAT_ERROR_UNSUPPORTED_CHARSET;
 1071|     24|    }
 1072|       |
 1073|  5.32k|    if (src_charset && dst_charset && converter == (iconv_t)-1) {
  ------------------
  |  Branch (1073:9): [True: 192, False: 5.13k]
  |  Branch (1073:24): [True: 192, False: 0]
  |  Branch (1073:39): [True: 2, False: 190]
  ------------------
 1074|      2|        char error_buf[1024];
 1075|      2|        snprintf(error_buf, sizeof(error_buf), "Unsupported character set: %s\n", src_charset);
 1076|      2|        sav_report_error(ctx, error_buf);
 1077|      2|        return READSTAT_ERROR_UNSUPPORTED_CHARSET;
 1078|      2|    }
 1079|       |
 1080|  5.32k|    ctx->input_encoding = src_charset;
 1081|  5.32k|    if (converter != (iconv_t)-1) {
  ------------------
  |  Branch (1081:9): [True: 190, False: 5.13k]
  ------------------
 1082|       |        // You might be tempted to skip the charset conversion when src_charset
 1083|       |        // and dst_charset are the same. However, some versions of SPSS insert
 1084|       |        // illegally truncated strings (e.g. the last character is three bytes
 1085|       |        // but the field only has room for two bytes). So to prevent the client
 1086|       |        // from receiving an invalid byte sequence, we ram everything through
 1087|       |        // our iconv machinery.
 1088|    190|        if (ctx->converter) {
  ------------------
  |  Branch (1088:13): [True: 0, False: 190]
  ------------------
 1089|      0|            iconv_close(ctx->converter);
 1090|      0|        }
 1091|    190|        ctx->converter = converter;
 1092|    190|    }
 1093|  5.32k|    return READSTAT_OK;
 1094|  5.32k|}
readstat_sav_read.c:sav_charset_name_for_code:
 1028|  5.35k|static const char *sav_charset_name_for_code(int code) {
 1029|  5.35k|    int i;
 1030|   426k|    for (i=0; i<sizeof(_charset_table)/sizeof(_charset_table[0]); i++) {
  ------------------
  |  Branch (1030:15): [True: 420k, False: 5.29k]
  ------------------
 1031|   420k|        if (code == _charset_table[i].code) {
  ------------------
  |  Branch (1031:13): [True: 59, False: 420k]
  ------------------
 1032|     59|            return _charset_table[i].name;
 1033|     59|        }
 1034|   420k|    }
 1035|  5.29k|    return NULL;
 1036|  5.35k|}
readstat_sav_read.c:sav_open_converter:
 1038|    193|static iconv_t sav_open_converter(const char *src_charset, const char *dst_charset) {
 1039|    193|    if (src_charset == NULL || dst_charset == NULL)
  ------------------
  |  Branch (1039:9): [True: 0, False: 193]
  |  Branch (1039:32): [True: 0, False: 193]
  ------------------
 1040|      0|        return (iconv_t)-1;
 1041|    193|    return iconv_open(dst_charset, src_charset);
 1042|    193|}
readstat_sav_read.c:sav_report_error:
  152|  45.2k|static void sav_report_error(sav_ctx_t *ctx, const char *message) {
  153|  45.2k|    if (ctx->handle.error) {
  ------------------
  |  Branch (153:9): [True: 0, False: 45.2k]
  ------------------
  154|      0|        ctx->handle.error(message, ctx->user_ctx);
  155|      0|    }
  156|  45.2k|}
readstat_sav_read.c:sav_update_progress:
  185|  7.89k|static readstat_error_t sav_update_progress(sav_ctx_t *ctx) {
  186|  7.89k|    readstat_io_t *io = ctx->io;
  187|  7.89k|    return io->update(ctx->file_size, ctx->handle.progress, ctx->user_ctx, io->io_ctx);
  188|  7.89k|}
readstat_sav_read.c:sav_parse_records_pass2:
 1519|  5.32k|static readstat_error_t sav_parse_records_pass2(sav_ctx_t *ctx) {
 1520|  5.32k|    void *data_buf = NULL;
 1521|  5.32k|    size_t data_buf_capacity = 4096;
 1522|  5.32k|    readstat_error_t retval = READSTAT_OK;
 1523|  5.32k|    readstat_io_t *io = ctx->io;
 1524|       |
 1525|  5.32k|    if ((data_buf = readstat_malloc(data_buf_capacity)) == NULL) {
  ------------------
  |  Branch (1525:9): [True: 0, False: 5.32k]
  ------------------
 1526|      0|        retval = READSTAT_ERROR_MALLOC;
 1527|      0|        goto cleanup;
 1528|      0|    }
 1529|       |
 1530|   620k|    while (1) {
  ------------------
  |  Branch (1530:12): [True: 620k, Folded]
  ------------------
 1531|   620k|        uint32_t rec_type;
 1532|   620k|        uint32_t extra_info[3];
 1533|   620k|        size_t data_len = 0;
 1534|   620k|        int i;
 1535|   620k|        int done = 0;
 1536|   620k|        if (io->read(&rec_type, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (1536:13): [True: 0, False: 620k]
  ------------------
 1537|      0|            retval = READSTAT_ERROR_READ;
 1538|      0|            goto cleanup;
 1539|      0|        }
 1540|       |        
 1541|   620k|        if (ctx->bswap) {
  ------------------
  |  Branch (1541:13): [True: 12.6k, False: 607k]
  ------------------
 1542|  12.6k|            rec_type = byteswap4(rec_type);
 1543|  12.6k|        }
 1544|       |        
 1545|   620k|        switch (rec_type) {
 1546|   479k|            case SAV_RECORD_TYPE_VARIABLE:
  ------------------
  |  |  117|   479k|#define SAV_RECORD_TYPE_VARIABLE                2
  ------------------
  |  Branch (1546:13): [True: 479k, False: 140k]
  ------------------
 1547|   479k|                if ((retval = sav_read_variable_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1547:21): [True: 48, False: 479k]
  ------------------
 1548|     48|                    goto cleanup;
 1549|   479k|                break;
 1550|   479k|            case SAV_RECORD_TYPE_VALUE_LABEL:
  ------------------
  |  |  118|  78.6k|#define SAV_RECORD_TYPE_VALUE_LABEL             3
  ------------------
  |  Branch (1550:13): [True: 78.6k, False: 541k]
  ------------------
 1551|  78.6k|                if ((retval = sav_read_value_label_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1551:21): [True: 10, False: 78.6k]
  ------------------
 1552|     10|                    goto cleanup;
 1553|  78.6k|                break;
 1554|  78.6k|            case SAV_RECORD_TYPE_DOCUMENT:
  ------------------
  |  |  120|  2.88k|#define SAV_RECORD_TYPE_DOCUMENT                6
  ------------------
  |  Branch (1554:13): [True: 2.88k, False: 617k]
  ------------------
 1555|  2.88k|                if ((retval = sav_read_document_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1555:21): [True: 2, False: 2.88k]
  ------------------
 1556|      2|                    goto cleanup;
 1557|  2.88k|                break;
 1558|  4.29k|            case SAV_RECORD_TYPE_DICT_TERMINATION:
  ------------------
  |  |  122|  4.29k|#define SAV_RECORD_TYPE_DICT_TERMINATION        999
  ------------------
  |  Branch (1558:13): [True: 4.29k, False: 615k]
  ------------------
 1559|  4.29k|                if ((retval = sav_read_dictionary_termination_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1559:21): [True: 2.22k, False: 2.07k]
  ------------------
 1560|  2.22k|                    goto cleanup;
 1561|  2.07k|                done = 1;
 1562|  2.07k|                break;
 1563|  54.9k|            case SAV_RECORD_TYPE_HAS_DATA:
  ------------------
  |  |  121|  54.9k|#define SAV_RECORD_TYPE_HAS_DATA                7
  ------------------
  |  Branch (1563:13): [True: 54.9k, False: 565k]
  ------------------
 1564|  54.9k|                if (io->read(extra_info, sizeof(extra_info), io->io_ctx) < sizeof(extra_info)) {
  ------------------
  |  Branch (1564:21): [True: 0, False: 54.9k]
  ------------------
 1565|      0|                    retval = READSTAT_ERROR_READ;
 1566|      0|                    goto cleanup;
 1567|      0|                }
 1568|  54.9k|                if (ctx->bswap) {
  ------------------
  |  Branch (1568:21): [True: 2.48k, False: 52.4k]
  ------------------
 1569|  9.94k|                    for (i=0; i<3; i++)
  ------------------
  |  Branch (1569:31): [True: 7.45k, False: 2.48k]
  ------------------
 1570|  7.45k|                        extra_info[i] = byteswap4(extra_info[i]);
 1571|  2.48k|                }
 1572|  54.9k|                uint32_t subtype = extra_info[0];
 1573|  54.9k|                size_t size = extra_info[1];
 1574|  54.9k|                size_t count = extra_info[2];
 1575|  54.9k|                if (size && count > SIZE_MAX / size) {
  ------------------
  |  Branch (1575:21): [True: 54.7k, False: 144]
  |  Branch (1575:29): [True: 0, False: 54.7k]
  ------------------
 1576|      0|                    retval = READSTAT_ERROR_PARSE;
 1577|      0|                    goto cleanup;
 1578|      0|                }
 1579|  54.9k|                data_len = size * count;
 1580|  54.9k|                if (data_buf_capacity < data_len) {
  ------------------
  |  Branch (1580:21): [True: 40, False: 54.8k]
  ------------------
 1581|     40|                    if ((data_buf = readstat_realloc(data_buf, data_buf_capacity = data_len)) == NULL) {
  ------------------
  |  Branch (1581:25): [True: 0, False: 40]
  ------------------
 1582|      0|                        retval = READSTAT_ERROR_MALLOC;
 1583|      0|                        goto cleanup;
 1584|      0|                    }
 1585|     40|                }
 1586|  54.9k|                if (data_len == 0)
  ------------------
  |  Branch (1586:21): [True: 1.50k, False: 53.4k]
  ------------------
 1587|  1.50k|                    break; /* nothing to parse */
 1588|  53.4k|                if (io->read(data_buf, data_len, io->io_ctx) < data_len) {
  ------------------
  |  Branch (1588:21): [True: 0, False: 53.4k]
  ------------------
 1589|      0|                    retval = READSTAT_ERROR_PARSE;
 1590|      0|                    goto cleanup;
 1591|      0|                }
 1592|       |                
 1593|  53.4k|                switch (subtype) {
 1594|    208|                    case SAV_RECORD_SUBTYPE_INTEGER_INFO:
  ------------------
  |  |  124|    208|#define SAV_RECORD_SUBTYPE_INTEGER_INFO       3
  ------------------
  |  Branch (1594:21): [True: 208, False: 53.1k]
  ------------------
 1595|    557|                    case SAV_RECORD_SUBTYPE_FP_INFO:
  ------------------
  |  |  125|    557|#define SAV_RECORD_SUBTYPE_FP_INFO            4
  ------------------
  |  Branch (1595:21): [True: 349, False: 53.0k]
  ------------------
 1596|    808|                    case SAV_RECORD_SUBTYPE_CHAR_ENCODING:
  ------------------
  |  |  135|    808|#define SAV_RECORD_SUBTYPE_CHAR_ENCODING     20
  ------------------
  |  Branch (1596:21): [True: 251, False: 53.1k]
  ------------------
 1597|       |                        /* parsed in pass 1 */
 1598|    808|                        break;
 1599|  42.3k|                    case SAV_RECORD_SUBTYPE_MULTIPLE_RESPONSE_SETS:
  ------------------
  |  |  126|  42.3k|#define SAV_RECORD_SUBTYPE_MULTIPLE_RESPONSE_SETS 7
  ------------------
  |  Branch (1599:21): [True: 42.3k, False: 11.0k]
  ------------------
 1600|  44.6k|                    case SAV_RECORD_SUBTYPE_MULTIPLE_RESPONSE_SETS_V14:
  ------------------
  |  |  127|  44.6k|#define SAV_RECORD_SUBTYPE_MULTIPLE_RESPONSE_SETS_V14 19
  ------------------
  |  Branch (1600:21): [True: 2.36k, False: 51.0k]
  ------------------
 1601|  44.6k|                        retval = sav_read_multiple_response_sets(data_buf, data_len, ctx);
 1602|  44.6k|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1602:29): [True: 0, False: 44.6k]
  ------------------
 1603|      0|                            goto cleanup;
 1604|  44.6k|                        break;
 1605|  44.6k|                    case SAV_RECORD_SUBTYPE_VAR_DISPLAY:
  ------------------
  |  |  129|    770|#define SAV_RECORD_SUBTYPE_VAR_DISPLAY       11
  ------------------
  |  Branch (1605:21): [True: 770, False: 52.6k]
  ------------------
 1606|    770|                        retval = sav_store_variable_display_parameter_record(data_buf, size, count, ctx);
 1607|    770|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1607:29): [True: 0, False: 770]
  ------------------
 1608|      0|                            goto cleanup;
 1609|    770|                        break;
 1610|  1.24k|                    case SAV_RECORD_SUBTYPE_LONG_VAR_NAME:
  ------------------
  |  |  130|  1.24k|#define SAV_RECORD_SUBTYPE_LONG_VAR_NAME     13
  ------------------
  |  Branch (1610:21): [True: 1.24k, False: 52.1k]
  ------------------
 1611|  1.24k|                        retval = sav_parse_long_variable_names_record(data_buf, count, ctx);
 1612|  1.24k|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1612:29): [True: 171, False: 1.07k]
  ------------------
 1613|    171|                            goto cleanup;
 1614|  1.07k|                        break;
 1615|  1.86k|                    case SAV_RECORD_SUBTYPE_VERY_LONG_STR:
  ------------------
  |  |  131|  1.86k|#define SAV_RECORD_SUBTYPE_VERY_LONG_STR     14
  ------------------
  |  Branch (1615:21): [True: 1.86k, False: 51.5k]
  ------------------
 1616|  1.86k|                        retval = sav_parse_very_long_string_record(data_buf, count, ctx);
 1617|  1.86k|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1617:29): [True: 160, False: 1.70k]
  ------------------
 1618|    160|                            goto cleanup;
 1619|  1.70k|                        break;
 1620|  1.70k|                    case SAV_RECORD_SUBTYPE_LONG_STRING_VALUE_LABELS:
  ------------------
  |  |  136|    794|#define SAV_RECORD_SUBTYPE_LONG_STRING_VALUE_LABELS   21
  ------------------
  |  Branch (1620:21): [True: 794, False: 52.6k]
  ------------------
 1621|    794|                        retval = sav_parse_long_string_value_labels_record(data_buf, size, count, ctx);
 1622|    794|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1622:29): [True: 323, False: 471]
  ------------------
 1623|    323|                            goto cleanup;
 1624|    471|                        break;
 1625|    944|                    case SAV_RECORD_SUBTYPE_LONG_STRING_MISSING_VALUES:
  ------------------
  |  |  137|    944|#define SAV_RECORD_SUBTYPE_LONG_STRING_MISSING_VALUES 22
  ------------------
  |  Branch (1625:21): [True: 944, False: 52.4k]
  ------------------
 1626|    944|                        retval = sav_parse_long_string_missing_values_record(data_buf, size, count, ctx);
 1627|    944|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1627:29): [True: 312, False: 632]
  ------------------
 1628|    312|                            goto cleanup;
 1629|    632|                        break;
 1630|  2.30k|                    default: /* misc. info */
  ------------------
  |  Branch (1630:21): [True: 2.30k, False: 51.1k]
  ------------------
 1631|  2.30k|                        break;
 1632|  53.4k|                }
 1633|  52.4k|                break;
 1634|  52.4k|            default:
  ------------------
  |  Branch (1634:13): [True: 0, False: 620k]
  ------------------
 1635|      0|                retval = READSTAT_ERROR_PARSE;
 1636|      0|                goto cleanup;
 1637|      0|                break;
 1638|   620k|        }
 1639|   616k|        if (done)
  ------------------
  |  Branch (1639:13): [True: 2.07k, False: 614k]
  ------------------
 1640|  2.07k|            break;
 1641|   616k|    }
 1642|  5.32k|cleanup:
 1643|  5.32k|    if (data_buf)
  ------------------
  |  Branch (1643:9): [True: 5.32k, False: 0]
  ------------------
 1644|  5.32k|        free(data_buf);
 1645|  5.32k|    return retval;
 1646|  5.32k|}
readstat_sav_read.c:sav_read_variable_record:
  364|   479k|static readstat_error_t sav_read_variable_record(sav_ctx_t *ctx) {
  365|   479k|    readstat_io_t *io = ctx->io;
  366|   479k|    sav_variable_record_t variable = { 0 };
  367|   479k|    spss_varinfo_t *info = NULL;
  368|   479k|    readstat_error_t retval = READSTAT_OK;
  369|   479k|    if (ctx->var_index == ctx->varinfo_capacity) {
  ------------------
  |  Branch (369:9): [True: 277, False: 479k]
  ------------------
  370|    277|        if ((ctx->varinfo = readstat_realloc(ctx->varinfo, (ctx->varinfo_capacity *= 2) * sizeof(spss_varinfo_t *))) == NULL) {
  ------------------
  |  Branch (370:13): [True: 0, False: 277]
  ------------------
  371|      0|            retval = READSTAT_ERROR_MALLOC;
  372|      0|            goto cleanup;
  373|      0|        }
  374|    277|    }
  375|   479k|    if (io->read(&variable, sizeof(sav_variable_record_t), io->io_ctx) < sizeof(sav_variable_record_t)) {
  ------------------
  |  Branch (375:9): [True: 0, False: 479k]
  ------------------
  376|      0|        retval = READSTAT_ERROR_READ;
  377|      0|        goto cleanup;
  378|      0|    }
  379|   479k|    variable.print = ctx->bswap ? byteswap4(variable.print) : variable.print;
  ------------------
  |  Branch (379:22): [True: 6.14k, False: 473k]
  ------------------
  380|   479k|    variable.write = ctx->bswap ? byteswap4(variable.write) : variable.write;
  ------------------
  |  Branch (380:22): [True: 6.14k, False: 473k]
  ------------------
  381|       |
  382|   479k|    int32_t type = ctx->bswap ? byteswap4(variable.type) : variable.type;
  ------------------
  |  Branch (382:20): [True: 6.14k, False: 473k]
  ------------------
  383|   479k|    if (type < 0) {
  ------------------
  |  Branch (383:9): [True: 3.95k, False: 475k]
  ------------------
  384|  3.95k|        if (ctx->var_index == 0 || ctx->varinfo[ctx->var_index-1]->type != READSTAT_TYPE_STRING) {
  ------------------
  |  Branch (384:13): [True: 31, False: 3.92k]
  |  Branch (384:36): [True: 1, False: 3.92k]
  ------------------
  385|     32|            return READSTAT_ERROR_PARSE;
  386|     32|        }
  387|       |        /* Some files put a label or missing values on continuation records;
  388|       |         * the spec says to parse them like any other variable record. */
  389|  3.92k|        if (variable.has_var_label) {
  ------------------
  |  Branch (389:13): [True: 1.14k, False: 2.78k]
  ------------------
  390|  1.14k|            spss_varinfo_t dummy = { .label = NULL };
  391|  1.14k|            if ((retval = sav_read_variable_label(&dummy, ctx)) != READSTAT_OK)
  ------------------
  |  Branch (391:17): [True: 1, False: 1.13k]
  ------------------
  392|      1|                return retval;
  393|  1.13k|            if (dummy.label)
  ------------------
  |  Branch (393:17): [True: 775, False: 364]
  ------------------
  394|    775|                free(dummy.label);
  395|  1.13k|        }
  396|  3.92k|        if (variable.n_missing_values) {
  ------------------
  |  Branch (396:13): [True: 1.66k, False: 2.26k]
  ------------------
  397|  1.66k|            spss_varinfo_t dummy = { .type = READSTAT_TYPE_DOUBLE };
  398|  1.66k|            dummy.n_missing_values = ctx->bswap ? byteswap4(variable.n_missing_values) : variable.n_missing_values;
  ------------------
  |  Branch (398:38): [True: 615, False: 1.04k]
  ------------------
  399|  1.66k|            if ((retval = sav_read_variable_missing_values(&dummy, ctx)) != READSTAT_OK)
  ------------------
  |  Branch (399:17): [True: 10, False: 1.65k]
  ------------------
  400|     10|                return retval;
  401|  1.66k|        }
  402|  3.91k|        ctx->var_offset++;
  403|  3.91k|        ctx->varinfo[ctx->var_index-1]->width++;
  404|  3.91k|        return retval;
  405|  3.92k|    }
  406|       |
  407|   475k|    sav_synthesize_missing_continuations(ctx);
  408|       |
  409|   475k|    if ((info = readstat_calloc(1, sizeof(spss_varinfo_t))) == NULL) {
  ------------------
  |  Branch (409:9): [True: 0, False: 475k]
  ------------------
  410|      0|        retval = READSTAT_ERROR_MALLOC;
  411|      0|        goto cleanup;
  412|      0|    }
  413|   475k|    info->width = 1;
  414|   475k|    info->n_segments = 1;
  415|   475k|    info->index = ctx->var_index;
  416|   475k|    info->offset = ctx->var_offset;
  417|   475k|    info->labels_index = -1;
  418|       |
  419|   475k|    retval = readstat_convert(info->name, sizeof(info->name),
  420|   475k|            variable.name, sizeof(variable.name), NULL);
  421|   475k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (421:9): [True: 0, False: 475k]
  ------------------
  422|      0|        goto cleanup;
  423|       |
  424|   475k|    retval = readstat_convert(info->longname, sizeof(info->longname), 
  425|   475k|            variable.name, sizeof(variable.name), NULL);
  426|   475k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (426:9): [True: 0, False: 475k]
  ------------------
  427|      0|        goto cleanup;
  428|       |
  429|   475k|    info->print_format.decimal_places = (variable.print & 0x000000FF);
  430|   475k|    info->print_format.width = (variable.print & 0x0000FF00) >> 8;
  431|   475k|    info->print_format.type = (variable.print  & 0x00FF0000) >> 16;
  432|       |
  433|   475k|    info->write_format.decimal_places = (variable.write & 0x000000FF);
  434|   475k|    info->write_format.width = (variable.write & 0x0000FF00) >> 8;
  435|   475k|    info->write_format.type = (variable.write  & 0x00FF0000) >> 16;
  436|       |
  437|   475k|    if (type > 0 || info->print_format.type == SPSS_FORMAT_TYPE_A || info->write_format.type == SPSS_FORMAT_TYPE_A) {
  ------------------
  |  |    2|   817k|#define SPSS_FORMAT_TYPE_A        1
  ------------------
                  if (type > 0 || info->print_format.type == SPSS_FORMAT_TYPE_A || info->write_format.type == SPSS_FORMAT_TYPE_A) {
  ------------------
  |  |    2|   213k|#define SPSS_FORMAT_TYPE_A        1
  ------------------
  |  Branch (437:9): [True: 133k, False: 342k]
  |  Branch (437:21): [True: 129k, False: 213k]
  |  Branch (437:70): [True: 108k, False: 104k]
  ------------------
  438|   370k|        info->type = READSTAT_TYPE_STRING;
  439|   370k|        info->string_length = type; /* may be raised by the very long string record */
  440|   370k|    } else {
  441|   104k|        info->type = READSTAT_TYPE_DOUBLE;
  442|   104k|    }
  443|       |    
  444|   475k|    if (variable.has_var_label) {
  ------------------
  |  Branch (444:9): [True: 27.6k, False: 447k]
  ------------------
  445|  27.6k|        if ((retval = sav_read_variable_label(info, ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (445:13): [True: 1, False: 27.6k]
  ------------------
  446|      1|            goto cleanup;
  447|      1|        }
  448|  27.6k|    }
  449|       |    
  450|   475k|    if (variable.n_missing_values) {
  ------------------
  |  Branch (450:9): [True: 29.5k, False: 445k]
  ------------------
  451|  29.5k|        info->n_missing_values = ctx->bswap ? byteswap4(variable.n_missing_values) : variable.n_missing_values;
  ------------------
  |  Branch (451:34): [True: 2.04k, False: 27.4k]
  ------------------
  452|  29.5k|        if ((retval = sav_read_variable_missing_values(info, ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (452:13): [True: 4, False: 29.5k]
  ------------------
  453|      4|            goto cleanup;
  454|      4|        }
  455|  29.5k|    }
  456|       |    
  457|   475k|    ctx->varinfo[ctx->var_index] = info;
  458|       |
  459|   475k|    ctx->var_index++;
  460|   475k|    ctx->var_offset++;
  461|       |    
  462|   475k|cleanup:
  463|   475k|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (463:9): [True: 5, False: 475k]
  ------------------
  464|      5|        spss_varinfo_free(info);
  465|      5|    }
  466|       |
  467|   475k|    return retval;
  468|   475k|}
readstat_sav_read.c:sav_read_variable_label:
  226|  28.7k|static readstat_error_t sav_read_variable_label(spss_varinfo_t *info, sav_ctx_t *ctx) {
  227|  28.7k|    readstat_io_t *io = ctx->io;
  228|  28.7k|    readstat_error_t retval = READSTAT_OK;
  229|  28.7k|    uint32_t label_len;
  230|  28.7k|    size_t label_capacity;
  231|  28.7k|    size_t out_label_len;
  232|  28.7k|    char *label_buf = NULL;
  233|  28.7k|    if (io->read(&label_len, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (233:9): [True: 0, False: 28.7k]
  ------------------
  234|      0|        retval = READSTAT_ERROR_READ;
  235|      0|        goto cleanup;
  236|      0|    }
  237|  28.7k|    label_len = ctx->bswap ? byteswap4(label_len) : label_len;
  ------------------
  |  Branch (237:17): [True: 630, False: 28.1k]
  ------------------
  238|       |
  239|  28.7k|    if (label_len == 0)
  ------------------
  |  Branch (239:9): [True: 17.2k, False: 11.5k]
  ------------------
  240|  17.2k|        goto cleanup;
  241|       |
  242|  11.5k|    label_capacity = ((size_t)label_len + 3) / 4 * 4;
  243|  11.5k|    if ((label_buf = readstat_malloc(label_capacity)) == NULL) {
  ------------------
  |  Branch (243:9): [True: 0, False: 11.5k]
  ------------------
  244|      0|        retval = READSTAT_ERROR_MALLOC;
  245|      0|        goto cleanup;
  246|      0|    }
  247|       |
  248|  11.5k|    out_label_len = (size_t)label_len*4+1;
  249|  11.5k|    if ((info->label = readstat_malloc(out_label_len)) == NULL) {
  ------------------
  |  Branch (249:9): [True: 0, False: 11.5k]
  ------------------
  250|      0|        retval = READSTAT_ERROR_MALLOC;
  251|      0|        goto cleanup;
  252|      0|    }
  253|       |
  254|  11.5k|    if (io->read(label_buf, label_capacity, io->io_ctx) < label_capacity) {
  ------------------
  |  Branch (254:9): [True: 0, False: 11.5k]
  ------------------
  255|      0|        retval = READSTAT_ERROR_READ;
  256|      0|        goto cleanup;
  257|      0|    }
  258|       |
  259|  11.5k|    retval = readstat_convert(info->label, out_label_len, label_buf, label_len, ctx->converter);
  260|  11.5k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (260:9): [True: 2, False: 11.5k]
  ------------------
  261|      2|        goto cleanup;
  262|       |
  263|  28.7k|cleanup:
  264|  28.7k|    if (label_buf)
  ------------------
  |  Branch (264:9): [True: 11.5k, False: 17.2k]
  ------------------
  265|  11.5k|        free(label_buf);
  266|       |
  267|  28.7k|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (267:9): [True: 2, False: 28.7k]
  ------------------
  268|      2|        if (info->label) {
  ------------------
  |  Branch (268:13): [True: 2, False: 0]
  ------------------
  269|      2|            free(info->label);
  270|      2|            info->label = NULL;
  271|      2|        }
  272|      2|    }
  273|       |
  274|  28.7k|    return retval;
  275|  11.5k|}
readstat_sav_read.c:sav_read_variable_missing_values:
  332|  31.1k|static readstat_error_t sav_read_variable_missing_values(spss_varinfo_t *info, sav_ctx_t *ctx) {
  333|  31.1k|    if (info->n_missing_values > 3 || info->n_missing_values < -3 || info->n_missing_values == -1) {
  ------------------
  |  Branch (333:9): [True: 0, False: 31.1k]
  |  Branch (333:39): [True: 0, False: 31.1k]
  |  Branch (333:70): [True: 13, False: 31.1k]
  ------------------
  334|     13|        return READSTAT_ERROR_PARSE;
  335|     13|    }
  336|  31.1k|    if (info->n_missing_values < 0) {
  ------------------
  |  Branch (336:9): [True: 11.5k, False: 19.5k]
  ------------------
  337|  11.5k|        info->missing_range = 1;
  338|  11.5k|        info->n_missing_values = abs(info->n_missing_values);
  339|  19.5k|    } else {
  340|  19.5k|        info->missing_range = 0;
  341|  19.5k|    }
  342|  31.1k|    if (info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (342:9): [True: 26.8k, False: 4.28k]
  ------------------
  343|  26.8k|        return sav_read_variable_missing_double_values(info, ctx);
  344|  26.8k|    }
  345|  4.28k|    return sav_read_variable_missing_string_values(info, ctx);
  346|  31.1k|}
readstat_sav_read.c:sav_read_variable_missing_double_values:
  277|  26.8k|static readstat_error_t sav_read_variable_missing_double_values(spss_varinfo_t *info, sav_ctx_t *ctx) {
  278|  26.8k|    readstat_io_t *io = ctx->io;
  279|  26.8k|    int i;
  280|  26.8k|    readstat_error_t retval = READSTAT_OK;
  281|  26.8k|    if (io->read(info->missing_double_values, info->n_missing_values * sizeof(double), io->io_ctx)
  ------------------
  |  Branch (281:9): [True: 0, False: 26.8k]
  ------------------
  282|  26.8k|            < info->n_missing_values * sizeof(double)) {
  283|      0|        retval = READSTAT_ERROR_READ;
  284|      0|        goto cleanup;
  285|      0|    }
  286|   106k|    for (i=0; i<info->n_missing_values; i++) {
  ------------------
  |  Branch (286:15): [True: 79.1k, False: 26.8k]
  ------------------
  287|  79.1k|        if (ctx->bswap) {
  ------------------
  |  Branch (287:13): [True: 4.84k, False: 74.2k]
  ------------------
  288|  4.84k|            info->missing_double_values[i] = byteswap_double(info->missing_double_values[i]);
  289|  4.84k|        }
  290|       |
  291|  79.1k|        uint64_t long_value = 0;
  292|  79.1k|        memcpy(&long_value, &info->missing_double_values[i], 8);
  293|       |
  294|  79.1k|        if (info->missing_range && i == 0 && long_value == ctx->missing_double) {
  ------------------
  |  Branch (294:13): [True: 31.0k, False: 48.0k]
  |  Branch (294:36): [True: 10.6k, False: 20.4k]
  |  Branch (294:46): [True: 236, False: 10.3k]
  ------------------
  295|       |            /* SPSS 21 and later write LOWEST with the same bit pattern as
  296|       |             * SYSMIS, which is unambiguous here because SYSMIS cannot be a
  297|       |             * range endpoint. */
  298|    236|            info->missing_double_values[i] = -HUGE_VAL;
  299|  78.9k|        } else if (long_value == ctx->missing_double) {
  ------------------
  |  Branch (299:20): [True: 383, False: 78.5k]
  ------------------
  300|    383|            info->missing_double_values[i] = NAN;
  301|  78.5k|        } else if (long_value == ctx->lowest_double) {
  ------------------
  |  Branch (301:20): [True: 12.2k, False: 66.3k]
  ------------------
  302|  12.2k|            info->missing_double_values[i] = -HUGE_VAL;
  303|  66.3k|        } else if (long_value == ctx->highest_double) {
  ------------------
  |  Branch (303:20): [True: 197, False: 66.1k]
  ------------------
  304|    197|            info->missing_double_values[i] = HUGE_VAL;
  305|    197|        }
  306|  79.1k|    }
  307|       |
  308|  26.8k|cleanup:
  309|  26.8k|    return retval;
  310|  26.8k|}
readstat_sav_read.c:sav_read_variable_missing_string_values:
  312|  4.28k|static readstat_error_t sav_read_variable_missing_string_values(spss_varinfo_t *info, sav_ctx_t *ctx) {
  313|  4.28k|    readstat_io_t *io = ctx->io;
  314|  4.28k|    int i;
  315|  4.28k|    readstat_error_t retval = READSTAT_OK;
  316|  16.2k|    for (i=0; i<info->n_missing_values; i++) {
  ------------------
  |  Branch (316:15): [True: 11.9k, False: 4.28k]
  ------------------
  317|  11.9k|        char missing_value[8];
  318|  11.9k|        if (io->read(missing_value, sizeof(missing_value), io->io_ctx) < sizeof(missing_value)) {
  ------------------
  |  Branch (318:13): [True: 0, False: 11.9k]
  ------------------
  319|      0|            retval = READSTAT_ERROR_READ;
  320|      0|            goto cleanup;
  321|      0|        }
  322|  11.9k|        retval = readstat_convert(info->missing_string_values[i], sizeof(info->missing_string_values[0]),
  323|  11.9k|                missing_value, sizeof(missing_value), ctx->converter);
  324|  11.9k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (324:13): [True: 1, False: 11.9k]
  ------------------
  325|      1|            goto cleanup;
  326|  11.9k|    }
  327|       |
  328|  4.28k|cleanup:
  329|  4.28k|    return retval;
  330|  4.28k|}
readstat_sav_read.c:sav_synthesize_missing_continuations:
  352|   479k|static void sav_synthesize_missing_continuations(sav_ctx_t *ctx) {
  353|   479k|    if (ctx->var_index == 0)
  ------------------
  |  Branch (353:9): [True: 4.74k, False: 474k]
  ------------------
  354|  4.74k|        return;
  355|   474k|    spss_varinfo_t *info = ctx->varinfo[ctx->var_index-1];
  356|   474k|    if (info->type == READSTAT_TYPE_STRING && info->width == 1 &&
  ------------------
  |  Branch (356:9): [True: 370k, False: 104k]
  |  Branch (356:47): [True: 368k, False: 2.40k]
  ------------------
  357|   368k|            info->string_length > 8 && info->string_length <= 255) {
  ------------------
  |  Branch (357:13): [True: 114k, False: 253k]
  |  Branch (357:40): [True: 36.3k, False: 78.3k]
  ------------------
  358|  36.3k|        int needed = (info->string_length + 7) / 8;
  359|  36.3k|        ctx->var_offset += needed - 1;
  360|  36.3k|        info->width = needed;
  361|  36.3k|    }
  362|   474k|}
readstat_sav_read.c:sav_read_value_label_record:
  547|  78.6k|static readstat_error_t sav_read_value_label_record(sav_ctx_t *ctx) {
  548|  78.6k|    uint32_t label_count;
  549|  78.6k|    readstat_error_t retval = READSTAT_OK;
  550|  78.6k|    readstat_io_t *io = ctx->io;
  551|  78.6k|    uint32_t *vars = NULL;
  552|  78.6k|    uint32_t var_count;
  553|  78.6k|    int32_t rec_type;
  554|  78.6k|    readstat_type_t value_type = READSTAT_TYPE_STRING;
  555|  78.6k|    char label_buf[256];
  556|  78.6k|    value_label_t *value_labels = NULL;
  557|       |
  558|  78.6k|    if (io->read(&label_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (558:9): [True: 0, False: 78.6k]
  ------------------
  559|      0|        retval = READSTAT_ERROR_READ;
  560|      0|        goto cleanup;
  561|      0|    }
  562|  78.6k|    if (ctx->bswap)
  ------------------
  |  Branch (562:9): [True: 1.53k, False: 77.1k]
  ------------------
  563|  1.53k|        label_count = byteswap4(label_count);
  564|       |    
  565|  78.6k|    if (label_count && (value_labels = readstat_calloc(label_count, sizeof(value_label_t))) == NULL) {
  ------------------
  |  Branch (565:9): [True: 954, False: 77.7k]
  |  Branch (565:24): [True: 0, False: 954]
  ------------------
  566|      0|        retval = READSTAT_ERROR_MALLOC;
  567|      0|        goto cleanup;
  568|      0|    }
  569|       |    
  570|  78.6k|    int i;
  571|   115k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (571:15): [True: 36.3k, False: 78.6k]
  ------------------
  572|  36.3k|        value_label_t *vlabel = &value_labels[i];
  573|  36.3k|        unsigned char unpadded_label_len = 0;
  574|  36.3k|        size_t padded_label_len = 0, utf8_label_len = 0;
  575|       |
  576|  36.3k|        if (io->read(vlabel->raw_value, 8, io->io_ctx) < 8) {
  ------------------
  |  Branch (576:13): [True: 0, False: 36.3k]
  ------------------
  577|      0|            retval = READSTAT_ERROR_READ;
  578|      0|            goto cleanup;
  579|      0|        }
  580|  36.3k|        if (io->read(&unpadded_label_len, 1, io->io_ctx) < 1) {
  ------------------
  |  Branch (580:13): [True: 0, False: 36.3k]
  ------------------
  581|      0|            retval = READSTAT_ERROR_READ;
  582|      0|            goto cleanup;
  583|      0|        }
  584|       |
  585|  36.3k|        padded_label_len = (unpadded_label_len + 8) / 8 * 8 - 1;
  586|  36.3k|        if (io->read(label_buf, padded_label_len, io->io_ctx) < padded_label_len) {
  ------------------
  |  Branch (586:13): [True: 0, False: 36.3k]
  ------------------
  587|      0|            retval = READSTAT_ERROR_READ;
  588|      0|            goto cleanup;
  589|      0|        }
  590|       |
  591|  36.3k|        utf8_label_len = padded_label_len*4+1;
  592|  36.3k|        if ((vlabel->label = readstat_malloc(utf8_label_len)) == NULL) {
  ------------------
  |  Branch (592:13): [True: 0, False: 36.3k]
  ------------------
  593|      0|            retval = READSTAT_ERROR_MALLOC;
  594|      0|            goto cleanup;
  595|      0|        }
  596|       |
  597|  36.3k|        retval = readstat_convert(vlabel->label, utf8_label_len, label_buf, unpadded_label_len, ctx->converter);
  598|  36.3k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (598:13): [True: 9, False: 36.3k]
  ------------------
  599|      9|            goto cleanup;
  600|  36.3k|    }
  601|       |
  602|  78.6k|    if (io->read(&rec_type, sizeof(int32_t), io->io_ctx) < sizeof(int32_t)) {
  ------------------
  |  Branch (602:9): [True: 0, False: 78.6k]
  ------------------
  603|      0|        retval = READSTAT_ERROR_READ;
  604|      0|        goto cleanup;
  605|      0|    }
  606|  78.6k|    if (ctx->bswap)
  ------------------
  |  Branch (606:9): [True: 1.53k, False: 77.1k]
  ------------------
  607|  1.53k|        rec_type = byteswap4(rec_type);
  608|       |    
  609|  78.6k|    if (rec_type != 4) {
  ------------------
  |  Branch (609:9): [True: 0, False: 78.6k]
  ------------------
  610|      0|        retval = READSTAT_ERROR_PARSE;
  611|      0|        goto cleanup;
  612|      0|    }
  613|  78.6k|    if (io->read(&var_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (613:9): [True: 0, False: 78.6k]
  ------------------
  614|      0|        retval = READSTAT_ERROR_READ;
  615|      0|        goto cleanup;
  616|      0|    }
  617|  78.6k|    if (ctx->bswap)
  ------------------
  |  Branch (617:9): [True: 1.53k, False: 77.1k]
  ------------------
  618|  1.53k|        var_count = byteswap4(var_count);
  619|       |    
  620|  78.6k|    if (var_count && (vars = readstat_malloc(var_count * sizeof(uint32_t))) == NULL) {
  ------------------
  |  Branch (620:9): [True: 33.6k, False: 45.0k]
  |  Branch (620:22): [True: 0, False: 33.6k]
  ------------------
  621|      0|        retval = READSTAT_ERROR_MALLOC;
  622|      0|        goto cleanup;
  623|      0|    }
  624|  78.6k|    if (io->read(vars, var_count * sizeof(uint32_t), io->io_ctx) < var_count * sizeof(uint32_t)) {
  ------------------
  |  Branch (624:9): [True: 0, False: 78.6k]
  ------------------
  625|      0|        retval = READSTAT_ERROR_READ;
  626|      0|        goto cleanup;
  627|      0|    }
  628|   546k|    for (i=0; i<var_count; i++) {
  ------------------
  |  Branch (628:15): [True: 467k, False: 78.6k]
  ------------------
  629|   467k|        uint32_t var_offset = vars[i];
  630|   467k|        if (ctx->bswap)
  ------------------
  |  Branch (630:13): [True: 3.54k, False: 464k]
  ------------------
  631|  3.54k|            var_offset = byteswap4(var_offset);
  632|       |
  633|   467k|        var_offset--; // Why subtract 1????
  634|   467k|        spss_varinfo_t **var = bsearch(&var_offset, ctx->varinfo, ctx->var_index, sizeof(spss_varinfo_t *),
  635|   467k|                &spss_varinfo_compare);
  636|   467k|        if (var) {
  ------------------
  |  Branch (636:13): [True: 65.8k, False: 401k]
  ------------------
  637|  65.8k|            (*var)->labels_index = ctx->value_labels_count;
  638|  65.8k|            value_type = (*var)->type;
  639|  65.8k|        }
  640|   467k|    }
  641|       |
  642|   115k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (642:15): [True: 36.3k, False: 78.6k]
  ------------------
  643|  36.3k|        value_label_t *vlabel = &value_labels[i];
  644|  36.3k|        double val_d = 0.0;
  645|  36.3k|        vlabel->final_value.type = value_type;
  646|  36.3k|        if (value_type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (646:13): [True: 16.0k, False: 20.2k]
  ------------------
  647|  16.0k|            memcpy(&val_d, vlabel->raw_value, 8);
  648|  16.0k|            if (ctx->bswap)
  ------------------
  |  Branch (648:17): [True: 398, False: 15.6k]
  ------------------
  649|    398|                val_d = byteswap_double(val_d);
  650|       |
  651|  16.0k|            vlabel->final_value.v.double_value = val_d;
  652|  16.0k|            sav_tag_missing_double(&vlabel->final_value, ctx);
  653|  20.2k|        } else {
  654|  20.2k|            retval = readstat_convert(vlabel->utf8_string_value, sizeof(vlabel->utf8_string_value),
  655|  20.2k|                    vlabel->raw_value, 8, ctx->converter);
  656|  20.2k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (656:17): [True: 1, False: 20.2k]
  ------------------
  657|      1|                break;
  658|       |
  659|  20.2k|            vlabel->final_value.v.string_value = vlabel->utf8_string_value;
  660|  20.2k|        }
  661|  36.3k|    }
  662|       |
  663|  78.6k|    if (ctx->handle.value_label) {
  ------------------
  |  Branch (663:9): [True: 78.6k, False: 0]
  ------------------
  664|  78.6k|        sav_submit_value_labels(value_labels, label_count, value_type, ctx);
  665|  78.6k|    }
  666|  78.6k|    ctx->value_labels_count++;
  667|  78.6k|cleanup:
  668|  78.6k|    if (vars)
  ------------------
  |  Branch (668:9): [True: 33.6k, False: 45.0k]
  ------------------
  669|  33.6k|        free(vars);
  670|  78.6k|    if (value_labels) {
  ------------------
  |  Branch (670:9): [True: 954, False: 77.7k]
  ------------------
  671|  37.6k|        for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (671:19): [True: 36.6k, False: 954]
  ------------------
  672|  36.6k|            value_label_t *vlabel = &value_labels[i];
  673|  36.6k|            if (vlabel->label)
  ------------------
  |  Branch (673:17): [True: 36.3k, False: 307]
  ------------------
  674|  36.3k|                free(vlabel->label);
  675|  36.6k|        }
  676|    954|        free(value_labels);
  677|    954|    }
  678|       |    
  679|  78.6k|    return retval;
  680|  78.6k|}
readstat_sav_read.c:sav_tag_missing_double:
  171|  1.47M|static void sav_tag_missing_double(readstat_value_t *value, sav_ctx_t *ctx) {
  172|  1.47M|    double fp_value = value->v.double_value;
  173|  1.47M|    uint64_t long_value = 0;
  174|  1.47M|    memcpy(&long_value, &fp_value, 8);
  175|  1.47M|    if (long_value == ctx->missing_double)
  ------------------
  |  Branch (175:9): [True: 11.8k, False: 1.46M]
  ------------------
  176|  11.8k|        value->is_system_missing = 1;
  177|  1.47M|    if (long_value == ctx->lowest_double)
  ------------------
  |  Branch (177:9): [True: 1.71k, False: 1.47M]
  ------------------
  178|  1.71k|        value->is_system_missing = 1;
  179|  1.47M|    if (long_value == ctx->highest_double)
  ------------------
  |  Branch (179:9): [True: 556, False: 1.47M]
  ------------------
  180|    556|        value->is_system_missing = 1;
  181|  1.47M|    if (isnan(fp_value))
  ------------------
  |  Branch (181:9): [True: 984, False: 1.47M]
  ------------------
  182|    984|        value->is_system_missing = 1;
  183|  1.47M|}
readstat_sav_read.c:sav_submit_value_labels:
  529|  78.6k|        readstat_type_t value_type, sav_ctx_t *ctx) {
  530|  78.6k|    char label_name_buf[256];
  531|  78.6k|    readstat_error_t retval = READSTAT_OK;
  532|  78.6k|    int32_t i;
  533|       |
  534|  78.6k|    snprintf(label_name_buf, sizeof(label_name_buf), SAV_LABEL_NAME_PREFIX "%d", ctx->value_labels_count);
  ------------------
  |  |  117|  78.6k|#define SAV_LABEL_NAME_PREFIX         "labels"
  ------------------
  535|       |
  536|   115k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (536:15): [True: 36.3k, False: 78.6k]
  ------------------
  537|  36.3k|        value_label_t *vlabel = &value_labels[i];
  538|  36.3k|        if (ctx->handle.value_label(label_name_buf, vlabel->final_value, vlabel->label, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|  36.3k|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (538:13): [True: 0, False: 36.3k]
  ------------------
  539|      0|            retval = READSTAT_ERROR_USER_ABORT;
  540|      0|            goto cleanup;
  541|      0|        }
  542|  36.3k|    }
  543|  78.6k|cleanup:
  544|  78.6k|    return retval;
  545|  78.6k|}
readstat_sav_read.c:sav_read_document_record:
  701|  2.88k|static readstat_error_t sav_read_document_record(sav_ctx_t *ctx) {
  702|  2.88k|    if (!ctx->handle.note)
  ------------------
  |  Branch (702:9): [True: 0, False: 2.88k]
  ------------------
  703|      0|        return sav_skip_document_record(ctx);
  704|       |
  705|  2.88k|    uint32_t n_lines;
  706|  2.88k|    readstat_error_t retval = READSTAT_OK;
  707|  2.88k|    readstat_io_t *io = ctx->io;
  708|  2.88k|    if (io->read(&n_lines, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (708:9): [True: 0, False: 2.88k]
  ------------------
  709|      0|        retval = READSTAT_ERROR_READ;
  710|      0|        goto cleanup;
  711|      0|    }
  712|  2.88k|    if (ctx->bswap)
  ------------------
  |  Branch (712:9): [True: 1.63k, False: 1.25k]
  ------------------
  713|  1.63k|        n_lines = byteswap4(n_lines);
  714|       |
  715|  2.88k|    char raw_buffer[SPSS_DOC_LINE_SIZE];
  716|  2.88k|    char utf8_buffer[4*SPSS_DOC_LINE_SIZE+1];
  717|  2.88k|    int i;
  718|  3.88k|    for (i=0; i<n_lines; i++) {
  ------------------
  |  Branch (718:15): [True: 999, False: 2.88k]
  ------------------
  719|    999|        if (io->read(raw_buffer, SPSS_DOC_LINE_SIZE, io->io_ctx) < SPSS_DOC_LINE_SIZE) {
  ------------------
  |  |   40|    999|#define SPSS_DOC_LINE_SIZE  80
  ------------------
                      if (io->read(raw_buffer, SPSS_DOC_LINE_SIZE, io->io_ctx) < SPSS_DOC_LINE_SIZE) {
  ------------------
  |  |   40|    999|#define SPSS_DOC_LINE_SIZE  80
  ------------------
  |  Branch (719:13): [True: 0, False: 999]
  ------------------
  720|      0|            retval = READSTAT_ERROR_READ;
  721|      0|            goto cleanup;
  722|      0|        }
  723|       |
  724|    999|        retval = readstat_convert(utf8_buffer, sizeof(utf8_buffer),
  725|    999|                raw_buffer, sizeof(raw_buffer), ctx->converter);
  726|    999|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (726:13): [True: 2, False: 997]
  ------------------
  727|      2|            goto cleanup;
  728|       |
  729|    997|        if (ctx->handle.note(i, utf8_buffer, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|    997|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (729:13): [True: 0, False: 997]
  ------------------
  730|      0|            retval = READSTAT_ERROR_USER_ABORT;
  731|      0|            goto cleanup;
  732|      0|        }
  733|    997|    }
  734|       |
  735|  2.88k|cleanup:
  736|  2.88k|    return retval;
  737|  2.88k|}
readstat_sav_read.c:sav_read_dictionary_termination_record:
  739|  4.29k|static readstat_error_t sav_read_dictionary_termination_record(sav_ctx_t *ctx) {
  740|  4.29k|    int32_t filler;
  741|  4.29k|    readstat_error_t retval = READSTAT_OK;
  742|  4.29k|    readstat_io_t *io = ctx->io;
  743|  4.29k|    sav_synthesize_missing_continuations(ctx);
  744|  4.29k|    if (io->read(&filler, sizeof(int32_t), io->io_ctx) < sizeof(int32_t)) {
  ------------------
  |  Branch (744:9): [True: 2.22k, False: 2.07k]
  ------------------
  745|  2.22k|        retval = READSTAT_ERROR_READ;
  746|  2.22k|    }
  747|  4.29k|    return retval;
  748|  4.29k|}
readstat_sav_read.c:sav_read_multiple_response_sets:
  160|  44.6k|static readstat_error_t sav_read_multiple_response_sets(const void *data, size_t data_len, sav_ctx_t *ctx) {
  161|  44.6k|    readstat_error_t retval = parse_mr_string(data, data_len,
  162|  44.6k|            &ctx->mr_sets, &ctx->multiple_response_sets_length, ctx);
  163|  44.6k|    if (retval == READSTAT_ERROR_MALLOC || retval == READSTAT_ERROR_USER_ABORT)
  ------------------
  |  Branch (163:9): [True: 0, False: 44.6k]
  |  Branch (163:44): [True: 0, False: 44.6k]
  ------------------
  164|      0|        return retval;
  165|  44.6k|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (165:9): [True: 42.5k, False: 2.11k]
  ------------------
  166|  42.5k|        sav_report_error(ctx, "Ignoring malformed multiple response set record");
  167|  42.5k|    }
  168|  44.6k|    return READSTAT_OK;
  169|  44.6k|}
readstat_sav_read.c:sav_store_variable_display_parameter_record:
 1112|    770|static readstat_error_t sav_store_variable_display_parameter_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
 1113|    770|    if (size != 4)
  ------------------
  |  Branch (1113:9): [True: 203, False: 567]
  ------------------
 1114|    203|        return READSTAT_OK; /* malformed; ignore the record like PSPP does */
 1115|       |
 1116|    567|    const uint32_t *data_ptr = data;
 1117|    567|    int i;
 1118|       |
 1119|    567|    ctx->variable_display_values = readstat_realloc(ctx->variable_display_values, count * sizeof(uint32_t));
 1120|    567|    if (count > 0 && ctx->variable_display_values == NULL)
  ------------------
  |  Branch (1120:9): [True: 567, False: 0]
  |  Branch (1120:22): [True: 0, False: 567]
  ------------------
 1121|      0|        return READSTAT_ERROR_MALLOC;
 1122|       |
 1123|    567|    ctx->variable_display_values_count = count;
 1124|  90.7k|    for (i=0; i<count; i++) {
  ------------------
  |  Branch (1124:15): [True: 90.1k, False: 567]
  ------------------
 1125|  90.1k|        ctx->variable_display_values[i] = ctx->bswap ? byteswap4(data_ptr[i]) : data_ptr[i];
  ------------------
  |  Branch (1125:43): [True: 1.83k, False: 88.3k]
  ------------------
 1126|  90.1k|    }
 1127|    567|    return READSTAT_OK;
 1128|    567|}
readstat_sav_read.c:sav_parse_long_string_value_labels_record:
 1191|    794|static readstat_error_t sav_parse_long_string_value_labels_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
 1192|    794|    if (!ctx->handle.value_label)
  ------------------
  |  Branch (1192:9): [True: 0, False: 794]
  ------------------
 1193|      0|        return READSTAT_OK;
 1194|    794|    if (size != 1)
  ------------------
  |  Branch (1194:9): [True: 6, False: 788]
  ------------------
 1195|      6|        return READSTAT_ERROR_PARSE;
 1196|       |
 1197|    788|    readstat_error_t retval = READSTAT_OK;
 1198|    788|    uint32_t label_count = 0;
 1199|    788|    uint32_t i = 0;
 1200|    788|    const char *data_ptr = data;
 1201|    788|    const char *data_end = data_ptr + count;
 1202|    788|    char var_name_buf[256+1]; // unconverted
 1203|    788|    char label_name_buf[256];
 1204|    788|    char *value_buffer = NULL;
 1205|    788|    char *label_buffer = NULL;
 1206|       |    
 1207|  2.35k|    while (data_ptr < data_end) {
  ------------------
  |  Branch (1207:12): [True: 1.88k, False: 471]
  ------------------
 1208|  1.88k|        memset(label_name_buf, '\0', sizeof(label_name_buf));
 1209|       |
 1210|  1.88k|        retval = sav_read_pascal_string(var_name_buf, sizeof(var_name_buf),
 1211|  1.88k|                &data_ptr, data_end - data_ptr, ctx);
 1212|  1.88k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1212:13): [True: 81, False: 1.80k]
  ------------------
 1213|     81|            goto cleanup;
 1214|       |
 1215|  8.00k|        for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1215:19): [True: 6.47k, False: 1.53k]
  ------------------
 1216|  6.47k|            spss_varinfo_t *info = ctx->varinfo[i];
 1217|  6.47k|            if (strcmp(var_name_buf, info->longname) == 0) {
  ------------------
  |  Branch (1217:17): [True: 265, False: 6.20k]
  ------------------
 1218|    265|                info->labels_index = ctx->value_labels_count++;
 1219|    265|                snprintf(label_name_buf, sizeof(label_name_buf),
 1220|    265|                        SAV_LABEL_NAME_PREFIX "%d", info->labels_index);
  ------------------
  |  |  117|    265|#define SAV_LABEL_NAME_PREFIX         "labels"
  ------------------
 1221|    265|                break;
 1222|    265|            }
 1223|  6.20k|            i += info->n_segments;
 1224|  6.20k|        }
 1225|       |
 1226|  1.80k|        if (label_name_buf[0] == '\0') {
  ------------------
  |  Branch (1226:13): [True: 1.53k, False: 265]
  ------------------
 1227|  1.53k|            sav_report_error(ctx, "Ignoring long string value labels for unknown variable");
 1228|  1.53k|        }
 1229|       |
 1230|  1.80k|        data_ptr += sizeof(uint32_t);
 1231|       |
 1232|  1.80k|        if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1232:13): [True: 97, False: 1.70k]
  ------------------
 1233|     97|            retval = READSTAT_ERROR_PARSE;
 1234|     97|            goto cleanup;
 1235|     97|        }
 1236|       |
 1237|  1.70k|        memcpy(&label_count, data_ptr, sizeof(uint32_t));
 1238|  1.70k|        if (ctx->bswap)
  ------------------
  |  Branch (1238:13): [True: 946, False: 758]
  ------------------
 1239|    946|            label_count = byteswap4(label_count);
 1240|       |
 1241|  1.70k|        data_ptr += sizeof(uint32_t);
 1242|       |
 1243|  3.01k|        for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (1243:19): [True: 1.44k, False: 1.56k]
  ------------------
 1244|  1.44k|            uint32_t value_len = 0, label_len = 0;
 1245|  1.44k|            size_t value_buffer_len = 0, label_buffer_len = 0;
 1246|       |
 1247|  1.44k|            if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1247:17): [True: 59, False: 1.38k]
  ------------------
 1248|     59|                retval = READSTAT_ERROR_PARSE;
 1249|     59|                goto cleanup;
 1250|     59|            }
 1251|       |
 1252|  1.38k|            memcpy(&value_len, data_ptr, sizeof(uint32_t));
 1253|  1.38k|            if (ctx->bswap)
  ------------------
  |  Branch (1253:17): [True: 888, False: 498]
  ------------------
 1254|    888|                value_len = byteswap4(value_len);
 1255|       |
 1256|  1.38k|            data_ptr += sizeof(uint32_t);
 1257|       |
 1258|  1.38k|            value_buffer_len = (size_t)value_len*4+1;
 1259|  1.38k|            value_buffer = readstat_realloc(value_buffer, value_buffer_len);
 1260|  1.38k|            if (value_buffer == NULL) {
  ------------------
  |  Branch (1260:17): [True: 26, False: 1.36k]
  ------------------
 1261|     26|                retval = READSTAT_ERROR_MALLOC;
 1262|     26|                goto cleanup;
 1263|     26|            }
 1264|       |
 1265|  1.36k|            if (data_ptr + value_len > data_end) {
  ------------------
  |  Branch (1265:17): [True: 35, False: 1.32k]
  ------------------
 1266|     35|                retval = READSTAT_ERROR_PARSE;
 1267|     35|                goto cleanup;
 1268|     35|            }
 1269|       |
 1270|  1.32k|            retval = readstat_convert(value_buffer, value_buffer_len, data_ptr, value_len, ctx->converter);
 1271|  1.32k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (1271:17): [True: 1, False: 1.32k]
  ------------------
 1272|      1|                goto cleanup;
 1273|       |
 1274|  1.32k|            data_ptr += value_len;
 1275|       |
 1276|  1.32k|            if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1276:17): [True: 5, False: 1.31k]
  ------------------
 1277|      5|                retval = READSTAT_ERROR_PARSE;
 1278|      5|                goto cleanup;
 1279|      5|            }
 1280|       |
 1281|  1.31k|            memcpy(&label_len, data_ptr, sizeof(uint32_t));
 1282|  1.31k|            if (ctx->bswap)
  ------------------
  |  Branch (1282:17): [True: 858, False: 461]
  ------------------
 1283|    858|                label_len = byteswap4(label_len);
 1284|       |
 1285|  1.31k|            data_ptr += sizeof(uint32_t);
 1286|       |
 1287|  1.31k|            label_buffer_len = (size_t)label_len*4+1;
 1288|  1.31k|            label_buffer = readstat_realloc(label_buffer, label_buffer_len);
 1289|  1.31k|            if (label_buffer == NULL) {
  ------------------
  |  Branch (1289:17): [True: 5, False: 1.31k]
  ------------------
 1290|      5|                retval = READSTAT_ERROR_MALLOC;
 1291|      5|                goto cleanup;
 1292|      5|            }
 1293|       |
 1294|  1.31k|            if (data_ptr + label_len > data_end) {
  ------------------
  |  Branch (1294:17): [True: 7, False: 1.30k]
  ------------------
 1295|      7|                retval = READSTAT_ERROR_PARSE;
 1296|      7|                goto cleanup;
 1297|      7|            }
 1298|       |
 1299|  1.30k|            retval = readstat_convert(label_buffer, label_buffer_len, data_ptr, label_len, ctx->converter);
 1300|  1.30k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (1300:17): [True: 1, False: 1.30k]
  ------------------
 1301|      1|                goto cleanup;
 1302|       |
 1303|  1.30k|            data_ptr += label_len;
 1304|       |
 1305|  1.30k|            readstat_value_t value = { .type = READSTAT_TYPE_STRING };
 1306|  1.30k|            value.v.string_value = value_buffer;
 1307|       |
 1308|  1.30k|            if (label_name_buf[0] == '\0')
  ------------------
  |  Branch (1308:17): [True: 961, False: 345]
  ------------------
 1309|    961|                continue;
 1310|       |
 1311|    345|            if (ctx->handle.value_label(label_name_buf, value, label_buffer, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|    345|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (1311:17): [True: 0, False: 345]
  ------------------
 1312|      0|                retval = READSTAT_ERROR_USER_ABORT;
 1313|      0|                goto cleanup;
 1314|      0|            }
 1315|    345|        }
 1316|  1.70k|    }
 1317|       |
 1318|    471|    if (data_ptr != data_end) {
  ------------------
  |  Branch (1318:9): [True: 0, False: 471]
  ------------------
 1319|      0|        retval = READSTAT_ERROR_PARSE;
 1320|      0|    }
 1321|       |
 1322|    788|cleanup:
 1323|    788|    if (value_buffer)
  ------------------
  |  Branch (1323:9): [True: 338, False: 450]
  ------------------
 1324|    338|        free(value_buffer);
 1325|    788|    if (label_buffer)
  ------------------
  |  Branch (1325:9): [True: 309, False: 479]
  ------------------
 1326|    309|        free(label_buffer);
 1327|    788|    return retval;
 1328|    471|}
readstat_sav_read.c:sav_read_pascal_string:
 1157|  3.41k|        const char **inout_data_ptr, size_t data_ptr_len, sav_ctx_t *ctx) {
 1158|  3.41k|    const char *data_ptr = *inout_data_ptr;
 1159|  3.41k|    const char *data_end = data_ptr + data_ptr_len;
 1160|  3.41k|    readstat_error_t retval = READSTAT_OK;
 1161|  3.41k|    uint32_t var_name_len = 0;
 1162|       |
 1163|  3.41k|    if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1163:9): [True: 26, False: 3.39k]
  ------------------
 1164|     26|        retval = READSTAT_ERROR_PARSE;
 1165|     26|        goto cleanup;
 1166|     26|    }
 1167|       |
 1168|  3.39k|    memcpy(&var_name_len, data_ptr, sizeof(uint32_t));
 1169|  3.39k|    if (ctx->bswap)
  ------------------
  |  Branch (1169:9): [True: 1.97k, False: 1.41k]
  ------------------
 1170|  1.97k|        var_name_len = byteswap4(var_name_len);
 1171|       |
 1172|  3.39k|    data_ptr += sizeof(uint32_t);
 1173|       |
 1174|  3.39k|    if (data_ptr + var_name_len > data_end) {
  ------------------
  |  Branch (1174:9): [True: 129, False: 3.26k]
  ------------------
 1175|    129|        retval = READSTAT_ERROR_PARSE;
 1176|    129|        goto cleanup;
 1177|    129|    }
 1178|       |
 1179|  3.26k|    retval = readstat_convert(buf, buf_len, data_ptr, var_name_len, NULL);
 1180|  3.26k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (1180:9): [True: 9, False: 3.25k]
  ------------------
 1181|      9|        goto cleanup;
 1182|       |
 1183|  3.25k|    data_ptr += var_name_len;
 1184|       |
 1185|  3.41k|cleanup:
 1186|  3.41k|    *inout_data_ptr = data_ptr;
 1187|       |
 1188|  3.41k|    return retval;
 1189|  3.25k|}
readstat_sav_read.c:sav_parse_long_string_missing_values_record:
 1330|    944|static readstat_error_t sav_parse_long_string_missing_values_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
 1331|    944|    if (size != 1)
  ------------------
  |  Branch (1331:9): [True: 8, False: 936]
  ------------------
 1332|      8|        return READSTAT_ERROR_PARSE;
 1333|       |
 1334|    936|    readstat_error_t retval = READSTAT_OK;
 1335|    936|    uint32_t i = 0, j = 0;
 1336|    936|    const char *data_ptr = data;
 1337|    936|    const char *data_end = data_ptr + count;
 1338|    936|    char var_name_buf[256+1];
 1339|       |
 1340|  2.16k|    while (data_ptr < data_end) {
  ------------------
  |  Branch (1340:12): [True: 1.53k, False: 632]
  ------------------
 1341|  1.53k|        retval = sav_read_pascal_string(var_name_buf, sizeof(var_name_buf),
 1342|  1.53k|                &data_ptr, data_end - data_ptr, ctx);
 1343|  1.53k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1343:13): [True: 83, False: 1.45k]
  ------------------
 1344|     83|            goto cleanup;
 1345|       |
 1346|  1.45k|        if (data_ptr == data_end) {
  ------------------
  |  Branch (1346:13): [True: 6, False: 1.44k]
  ------------------
 1347|      6|            retval = READSTAT_ERROR_PARSE;
 1348|      6|            goto cleanup;
 1349|      6|        }
 1350|       |
 1351|  1.44k|        char n_missing_values = *data_ptr++;
 1352|  1.44k|        if (n_missing_values < 1 || n_missing_values > 3) {
  ------------------
  |  Branch (1352:13): [True: 13, False: 1.43k]
  |  Branch (1352:37): [True: 4, False: 1.42k]
  ------------------
 1353|     17|            retval = READSTAT_ERROR_PARSE;
 1354|     17|            goto cleanup;
 1355|     17|        }
 1356|       |
 1357|  1.42k|        spss_varinfo_t *info = NULL;
 1358|  1.96k|        for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1358:19): [True: 1.05k, False: 909]
  ------------------
 1359|  1.05k|            if (strcmp(var_name_buf, ctx->varinfo[i]->longname) == 0) {
  ------------------
  |  Branch (1359:17): [True: 520, False: 539]
  ------------------
 1360|    520|                info = ctx->varinfo[i];
 1361|    520|                break;
 1362|    520|            }
 1363|    539|            i += ctx->varinfo[i]->n_segments;
 1364|    539|        }
 1365|  1.42k|        if (info == NULL || info->type != READSTAT_TYPE_STRING) {
  ------------------
  |  Branch (1365:13): [True: 909, False: 520]
  |  Branch (1365:29): [True: 231, False: 289]
  ------------------
 1366|  1.14k|            sav_report_error(ctx, "Ignoring long string missing values for unknown or numeric variable");
 1367|  1.14k|            info = NULL;
 1368|  1.14k|        }
 1369|       |
 1370|  1.42k|        uint32_t value_len = 0;
 1371|       |
 1372|  1.42k|        if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1372:13): [True: 98, False: 1.33k]
  ------------------
 1373|     98|            retval = READSTAT_ERROR_PARSE;
 1374|     98|            goto cleanup;
 1375|     98|        }
 1376|       |
 1377|  1.33k|        memcpy(&value_len, data_ptr, sizeof(uint32_t));
 1378|  1.33k|        if (ctx->bswap)
  ------------------
  |  Branch (1378:13): [True: 851, False: 480]
  ------------------
 1379|    851|            value_len = byteswap4(value_len);
 1380|       |
 1381|  1.33k|        data_ptr += sizeof(uint32_t);
 1382|       |
 1383|  4.73k|        for (j=0; j<n_missing_values; j++) {
  ------------------
  |  Branch (1383:19): [True: 3.49k, False: 1.23k]
  ------------------
 1384|       |            /* Old versions of PSPP repeated the value length (always 8)
 1385|       |             * before each value; tolerate that as PSPP itself does. */
 1386|  3.49k|            if (value_len == 8 && data_ptr + sizeof(uint32_t) <= data_end) {
  ------------------
  |  Branch (1386:17): [True: 145, False: 3.35k]
  |  Branch (1386:35): [True: 143, False: 2]
  ------------------
 1387|    143|                uint32_t repeated_len = 0;
 1388|    143|                memcpy(&repeated_len, data_ptr, sizeof(uint32_t));
 1389|    143|                if (ctx->bswap)
  ------------------
  |  Branch (1389:21): [True: 55, False: 88]
  ------------------
 1390|     55|                    repeated_len = byteswap4(repeated_len);
 1391|    143|                if (repeated_len == 8)
  ------------------
  |  Branch (1391:21): [True: 25, False: 118]
  ------------------
 1392|     25|                    data_ptr += sizeof(uint32_t);
 1393|    143|            }
 1394|  3.49k|            if (data_ptr + value_len > data_end) {
  ------------------
  |  Branch (1394:17): [True: 95, False: 3.40k]
  ------------------
 1395|     95|                retval = READSTAT_ERROR_PARSE;
 1396|     95|                goto cleanup;
 1397|     95|            }
 1398|       |
 1399|  3.40k|            if (info) {
  ------------------
  |  Branch (1399:17): [True: 777, False: 2.62k]
  ------------------
 1400|    777|                retval = readstat_convert(info->missing_string_values[j],
 1401|    777|                        sizeof(info->missing_string_values[0]),
 1402|    777|                        data_ptr, value_len, ctx->converter);
 1403|    777|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1403:21): [True: 5, False: 772]
  ------------------
 1404|      5|                    goto cleanup;
 1405|    777|            }
 1406|       |
 1407|  3.39k|            data_ptr += value_len;
 1408|  3.39k|        }
 1409|  1.23k|        if (info) {
  ------------------
  |  Branch (1409:13): [True: 272, False: 959]
  ------------------
 1410|    272|            info->n_missing_values = n_missing_values;
 1411|    272|            info->missing_range = 0;
 1412|    272|        }
 1413|  1.23k|    }
 1414|       |
 1415|    632|    if (data_ptr != data_end) {
  ------------------
  |  Branch (1415:9): [True: 0, False: 632]
  ------------------
 1416|      0|        retval = READSTAT_ERROR_PARSE;
 1417|      0|    }
 1418|       |
 1419|    936|cleanup:
 1420|    936|    return retval;
 1421|    632|}
readstat_sav_read.c:sav_set_n_segments_and_var_count:
 1648|  2.07k|static readstat_error_t sav_set_n_segments_and_var_count(sav_ctx_t *ctx) {
 1649|  2.07k|    int i;
 1650|  2.07k|    ctx->var_count = 0;
 1651|  41.9k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1651:15): [True: 39.8k, False: 2.02k]
  ------------------
 1652|  39.8k|        spss_varinfo_t *info = ctx->varinfo[i];
 1653|  39.8k|        if (info->string_length > VERY_LONG_STRING_MAX_LENGTH)
  ------------------
  |  |   30|  39.8k|#define VERY_LONG_STRING_MAX_LENGTH INT_MAX
  ------------------
  |  Branch (1653:13): [True: 45, False: 39.8k]
  ------------------
 1654|     45|            return READSTAT_ERROR_PARSE;
 1655|  39.8k|        if (info->string_length > 255) {
  ------------------
  |  Branch (1655:13): [True: 5.84k, False: 33.9k]
  ------------------
 1656|  5.84k|            info->n_segments = (info->string_length + 251) / 252;
 1657|  5.84k|        }
 1658|  39.8k|        info->index = ctx->var_count++;
 1659|  39.8k|        i += info->n_segments;
 1660|  39.8k|    }
 1661|  2.02k|    ctx->variables = readstat_calloc(ctx->var_count, sizeof(readstat_variable_t *));
 1662|  2.02k|    return READSTAT_OK;
 1663|  2.07k|}
readstat_sav_read.c:sav_parse_variable_display_parameter_record:
 1130|  1.92k|static readstat_error_t sav_parse_variable_display_parameter_record(sav_ctx_t *ctx) {
 1131|  1.92k|    if (!ctx->variable_display_values)
  ------------------
  |  Branch (1131:9): [True: 1.74k, False: 179]
  ------------------
 1132|  1.74k|        return READSTAT_OK;
 1133|       |
 1134|    179|    int i;
 1135|    179|    long count = ctx->variable_display_values_count;
 1136|    179|    if (count != 2 * ctx->var_index && count != 3 * ctx->var_index) {
  ------------------
  |  Branch (1136:9): [True: 78, False: 101]
  |  Branch (1136:40): [True: 27, False: 51]
  ------------------
 1137|     27|        sav_report_error(ctx, "Ignoring variable display record with unexpected length");
 1138|     27|        return READSTAT_OK;
 1139|     27|    }
 1140|    152|    int has_display_width = ctx->var_index > 0 && (count / ctx->var_index == 3);
  ------------------
  |  Branch (1140:29): [True: 152, False: 0]
  |  Branch (1140:51): [True: 51, False: 101]
  ------------------
 1141|    152|    int offset = 0;
 1142|  1.14k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1142:15): [True: 993, False: 152]
  ------------------
 1143|    993|        spss_varinfo_t *info = ctx->varinfo[i];
 1144|    993|        offset = (2 + has_display_width)*i;
 1145|    993|        info->measure = spss_measure_to_readstat_measure(ctx->variable_display_values[offset++]);
 1146|    993|        if (has_display_width) {
  ------------------
  |  Branch (1146:13): [True: 256, False: 737]
  ------------------
 1147|    256|            info->display_width = ctx->variable_display_values[offset++];
 1148|    256|        }
 1149|    993|        info->alignment = spss_alignment_to_readstat_alignment(ctx->variable_display_values[offset++]);
 1150|       |
 1151|    993|        i += info->n_segments;
 1152|    993|    }
 1153|    152|    return READSTAT_OK;
 1154|    179|}
readstat_sav_read.c:sav_handle_variables:
 1665|  1.92k|static readstat_error_t sav_handle_variables(sav_ctx_t *ctx) {
 1666|  1.92k|    int i;
 1667|  1.92k|    int index_after_skipping = 0;
 1668|  1.92k|    readstat_error_t retval = READSTAT_OK;
 1669|       |
 1670|  41.5k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1670:15): [True: 39.6k, False: 1.92k]
  ------------------
 1671|  39.6k|        char label_name_buf[256];
 1672|  39.6k|        spss_varinfo_t *info = ctx->varinfo[i];
 1673|  39.6k|        ctx->variables[info->index] = spss_init_variable_for_info(info, index_after_skipping, ctx->converter);
 1674|  39.6k|        if (ctx->variables[info->index] == NULL) {
  ------------------
  |  Branch (1674:13): [True: 0, False: 39.6k]
  ------------------
 1675|      0|            retval = READSTAT_ERROR_MALLOC;
 1676|      0|            goto cleanup;
 1677|      0|        }
 1678|       |
 1679|  39.6k|        snprintf(label_name_buf, sizeof(label_name_buf), SAV_LABEL_NAME_PREFIX "%d", info->labels_index);
  ------------------
  |  |  117|  39.6k|#define SAV_LABEL_NAME_PREFIX         "labels"
  ------------------
 1680|       |
 1681|  39.6k|        int cb_retval = READSTAT_HANDLER_OK;
  ------------------
  |  |   22|  39.6k|#define READSTAT_HANDLER_OK             0
  ------------------
 1682|  39.6k|        if (ctx->handle.variable) {
  ------------------
  |  Branch (1682:13): [True: 39.6k, False: 0]
  ------------------
 1683|  39.6k|            cb_retval = ctx->handle.variable(info->index, ctx->variables[info->index],
 1684|  39.6k|                    info->labels_index == -1 ? NULL : label_name_buf,
  ------------------
  |  Branch (1684:21): [True: 39.2k, False: 315]
  ------------------
 1685|  39.6k|                    ctx->user_ctx);
 1686|  39.6k|        }
 1687|       |
 1688|  39.6k|        if (cb_retval == READSTAT_HANDLER_ABORT) {
  ------------------
  |  |   23|  39.6k|#define READSTAT_HANDLER_ABORT          1
  ------------------
  |  Branch (1688:13): [True: 0, False: 39.6k]
  ------------------
 1689|      0|            retval = READSTAT_ERROR_USER_ABORT;
 1690|      0|            goto cleanup;
 1691|      0|        }
 1692|       |
 1693|  39.6k|        if (cb_retval == READSTAT_HANDLER_SKIP_VARIABLE) {
  ------------------
  |  |   24|  39.6k|#define READSTAT_HANDLER_SKIP_VARIABLE  2
  ------------------
  |  Branch (1693:13): [True: 0, False: 39.6k]
  ------------------
 1694|      0|            ctx->variables[info->index]->skip = 1;
 1695|  39.6k|        } else {
 1696|  39.6k|            index_after_skipping++;
 1697|  39.6k|        }
 1698|       |
 1699|  39.6k|        i += info->n_segments;
 1700|  39.6k|    }
 1701|  1.92k|cleanup:
 1702|  1.92k|    return retval;
 1703|  1.92k|}
readstat_sav_read.c:sav_handle_fweight:
 1705|  1.92k|static readstat_error_t sav_handle_fweight(sav_ctx_t *ctx) {
 1706|  1.92k|    readstat_error_t retval = READSTAT_OK;
 1707|  1.92k|    int i;
 1708|  1.92k|    if (ctx->handle.fweight && ctx->fweight_index >= 0) {
  ------------------
  |  Branch (1708:9): [True: 1.92k, False: 0]
  |  Branch (1708:32): [True: 1.29k, False: 627]
  ------------------
 1709|  39.0k|        for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1709:19): [True: 37.7k, False: 1.26k]
  ------------------
 1710|  37.7k|            spss_varinfo_t *info = ctx->varinfo[i];
 1711|  37.7k|            if (info->offset == ctx->fweight_index - 1) {
  ------------------
  |  Branch (1711:17): [True: 26, False: 37.7k]
  ------------------
 1712|     26|                if (info->type != READSTAT_TYPE_DOUBLE)
  ------------------
  |  Branch (1712:21): [True: 18, False: 8]
  ------------------
 1713|     18|                    break; /* PSPP ignores a weight that names a string variable */
 1714|      8|                if (ctx->handle.fweight(ctx->variables[info->index], ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|      8|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (1714:21): [True: 0, False: 8]
  ------------------
 1715|      0|                    retval = READSTAT_ERROR_USER_ABORT;
 1716|      0|                    goto cleanup;
 1717|      0|                }
 1718|      8|                break;
 1719|      8|            }
 1720|  37.7k|            i += info->n_segments;
 1721|  37.7k|        }
 1722|  1.29k|    }
 1723|  1.92k|cleanup:
 1724|  1.92k|    return retval;
 1725|  1.92k|}
readstat_sav_read.c:sav_read_data:
  840|  1.92k|static readstat_error_t sav_read_data(sav_ctx_t *ctx) {
  841|  1.92k|    readstat_error_t retval = READSTAT_OK;
  842|  1.92k|    size_t longest_string = 256;
  843|  1.92k|    int i;
  844|       |
  845|  41.5k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (845:15): [True: 39.6k, False: 1.92k]
  ------------------
  846|  39.6k|        spss_varinfo_t *info = ctx->varinfo[i];
  847|  39.6k|        if (info->string_length > longest_string) {
  ------------------
  |  Branch (847:13): [True: 1.23k, False: 38.3k]
  ------------------
  848|  1.23k|            longest_string = info->string_length;
  849|  1.23k|        }
  850|  39.6k|        i += info->n_segments;
  851|  39.6k|    }
  852|       |
  853|  1.92k|    ctx->raw_string_len = longest_string + sizeof(SAV_EIGHT_SPACES)-2;
  ------------------
  |  |  146|  1.92k|#define SAV_EIGHT_SPACES              "        "
  ------------------
  854|  1.92k|    ctx->raw_string = readstat_malloc(ctx->raw_string_len);
  855|       |
  856|  1.92k|    ctx->utf8_string_len = 4*longest_string+1 + sizeof(SAV_EIGHT_SPACES)-2;
  ------------------
  |  |  146|  1.92k|#define SAV_EIGHT_SPACES              "        "
  ------------------
  857|  1.92k|    ctx->utf8_string = readstat_malloc(ctx->utf8_string_len);
  858|       |
  859|  1.92k|    if (ctx->raw_string == NULL || ctx->utf8_string == NULL) {
  ------------------
  |  Branch (859:9): [True: 286, False: 1.63k]
  |  Branch (859:36): [True: 38, False: 1.59k]
  ------------------
  860|    324|        retval = READSTAT_ERROR_MALLOC;
  861|    324|        goto done;
  862|    324|    }
  863|       |
  864|  1.59k|    if (ctx->compression == READSTAT_COMPRESS_ROWS) {
  ------------------
  |  Branch (864:9): [True: 620, False: 978]
  ------------------
  865|    620|        retval = sav_read_compressed_data(ctx, &sav_process_row);
  866|    978|    } else if (ctx->compression == READSTAT_COMPRESS_BINARY) {
  ------------------
  |  Branch (866:16): [True: 430, False: 548]
  ------------------
  867|    430|#if HAVE_ZLIB
  868|    430|        retval = zsav_read_compressed_data(ctx, &sav_process_row);
  869|       |#else
  870|       |        retval = READSTAT_ERROR_UNSUPPORTED_COMPRESSION;
  871|       |#endif
  872|    548|    } else {
  873|    548|        retval = sav_read_uncompressed_data(ctx, &sav_process_row);
  874|    548|    }
  875|  1.59k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (875:9): [True: 517, False: 1.08k]
  ------------------
  876|    517|        goto done;
  877|       |
  878|  1.08k|    if (ctx->record_count >= 0 && ctx->current_row != ctx->row_limit) {
  ------------------
  |  Branch (878:9): [True: 788, False: 293]
  |  Branch (878:35): [True: 693, False: 95]
  ------------------
  879|    693|        retval = READSTAT_ERROR_ROW_COUNT_MISMATCH;
  880|    693|    }
  881|       |
  882|  1.92k|done:
  883|  1.92k|    return retval;
  884|  1.08k|}
readstat_sav_read.c:sav_read_compressed_data:
  927|    620|        readstat_error_t (*row_handler)(unsigned char *, size_t, sav_ctx_t *)) {
  928|    620|    readstat_error_t retval = READSTAT_OK;
  929|    620|    readstat_io_t *io = ctx->io;
  930|    620|    readstat_off_t data_offset = 0;
  931|    620|    unsigned char buffer[DATA_BUFFER_SIZE];
  932|    620|    int buffer_used = 0;
  933|    620|    int trailing_bytes = 0;
  934|       |
  935|    620|    size_t uncompressed_row_len = ctx->var_offset * 8;
  936|    620|    readstat_off_t uncompressed_offset = 0;
  937|    620|    unsigned char *uncompressed_row = NULL;
  938|       |
  939|    620|    struct sav_row_stream_s state = { 
  940|    620|        .missing_value = ctx->missing_double,
  941|    620|        .bias = ctx->bias,
  942|    620|        .bswap = ctx->bswap };
  943|       |
  944|    620|    if (uncompressed_row_len && (uncompressed_row = readstat_malloc(uncompressed_row_len)) == NULL) {
  ------------------
  |  Branch (944:9): [True: 620, False: 0]
  |  Branch (944:33): [True: 0, False: 620]
  ------------------
  945|      0|        retval = READSTAT_ERROR_MALLOC;
  946|      0|        goto done;
  947|      0|    }
  948|       |
  949|  1.09k|    while (1) {
  ------------------
  |  Branch (949:12): [True: 1.09k, Folded]
  ------------------
  950|  1.09k|        retval = sav_update_progress(ctx);
  951|  1.09k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (951:13): [True: 0, False: 1.09k]
  ------------------
  952|      0|            goto done;
  953|       |
  954|  1.09k|        buffer_used = io->read(buffer, sizeof(buffer), io->io_ctx);
  955|  1.09k|        if (buffer_used == -1 || buffer_used == 0) {
  ------------------
  |  Branch (955:13): [True: 0, False: 1.09k]
  |  Branch (955:34): [True: 391, False: 706]
  ------------------
  956|    391|            if (uncompressed_offset != 0 && (ctx->row_limit < 0 || ctx->current_row < ctx->row_limit)) {
  ------------------
  |  Branch (956:17): [True: 93, False: 298]
  |  Branch (956:46): [True: 14, False: 79]
  |  Branch (956:68): [True: 60, False: 19]
  ------------------
  957|       |                /* File ends in the middle of a row */
  958|     74|                retval = READSTAT_ERROR_PARSE;
  959|     74|            }
  960|    391|            goto done;
  961|    391|        }
  962|       |        /* Decode every complete opcode block; a trailing fragment ends the data */
  963|    706|        trailing_bytes = buffer_used % 8;
  964|    706|        buffer_used -= trailing_bytes;
  965|       |
  966|    706|        state.status = SAV_ROW_STREAM_HAVE_DATA;
  967|    706|        data_offset = 0;
  968|       |
  969|  3.04M|        while (state.status != SAV_ROW_STREAM_NEED_DATA) {
  ------------------
  |  Branch (969:16): [True: 3.04M, False: 647]
  ------------------
  970|  3.04M|            state.next_in = &buffer[data_offset];
  971|  3.04M|            state.avail_in = buffer_used - data_offset;
  972|       |
  973|  3.04M|            state.next_out = &uncompressed_row[uncompressed_offset];
  974|  3.04M|            state.avail_out = uncompressed_row_len - uncompressed_offset;
  975|       |
  976|  3.04M|            sav_decompress_row(&state);
  977|       |
  978|  3.04M|            uncompressed_offset = uncompressed_row_len - state.avail_out;
  979|  3.04M|            data_offset = buffer_used - state.avail_in;
  980|       |
  981|  3.04M|            if (state.status == SAV_ROW_STREAM_FINISHED_ROW) {
  ------------------
  |  Branch (981:17): [True: 3.04M, False: 690]
  ------------------
  982|  3.04M|                retval = row_handler(uncompressed_row, uncompressed_row_len, ctx);
  983|  3.04M|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (983:21): [True: 10, False: 3.04M]
  ------------------
  984|     10|                    goto done;
  985|       |
  986|  3.04M|                uncompressed_offset = 0;
  987|  3.04M|            }
  988|       |
  989|  3.04M|            if (state.status == SAV_ROW_STREAM_FINISHED_ALL)
  ------------------
  |  Branch (989:17): [True: 43, False: 3.04M]
  ------------------
  990|     43|                goto done;
  991|  3.04M|            if (ctx->row_limit > 0 && ctx->current_row == ctx->row_limit)
  ------------------
  |  Branch (991:17): [True: 591k, False: 2.45M]
  |  Branch (991:39): [True: 6, False: 591k]
  ------------------
  992|      6|                goto done;
  993|  3.04M|        }
  994|    647|        if (trailing_bytes) {
  ------------------
  |  Branch (994:13): [True: 170, False: 477]
  ------------------
  995|    170|            if (uncompressed_offset != 0 && (ctx->row_limit < 0 || ctx->current_row < ctx->row_limit)) {
  ------------------
  |  Branch (995:17): [True: 80, False: 90]
  |  Branch (995:46): [True: 3, False: 77]
  |  Branch (995:68): [True: 47, False: 30]
  ------------------
  996|     50|                retval = READSTAT_ERROR_PARSE;
  997|     50|            }
  998|    170|            goto done;
  999|    170|        }
 1000|    647|    }
 1001|       |
 1002|    620|done:
 1003|    620|    if (uncompressed_row)
  ------------------
  |  Branch (1003:9): [True: 620, False: 0]
  ------------------
 1004|    620|        free(uncompressed_row);
 1005|       |
 1006|    620|    return retval;
 1007|    620|}
readstat_sav_read.c:sav_process_row:
  750|  3.04M|static readstat_error_t sav_process_row(unsigned char *buffer, size_t buffer_len, sav_ctx_t *ctx) {
  751|  3.04M|    if (ctx->row_offset) {
  ------------------
  |  Branch (751:9): [True: 0, False: 3.04M]
  ------------------
  752|      0|        ctx->row_offset--;
  753|      0|        return READSTAT_OK;
  754|      0|    }
  755|       |
  756|  3.04M|    readstat_error_t retval = READSTAT_OK;
  757|  3.04M|    double fp_value;
  758|  3.04M|    int offset = 0;
  759|  3.04M|    readstat_off_t data_offset = 0;
  760|  3.04M|    size_t raw_str_used = 0;
  761|  3.04M|    int segment_offset = 0;
  762|  3.04M|    int var_index = 0, col = 0;
  763|  3.04M|    int raw_str_is_utf8 = ctx->input_encoding && !strcmp(ctx->input_encoding, "UTF-8");
  ------------------
  |  Branch (763:27): [True: 746, False: 3.04M]
  |  Branch (763:50): [True: 357, False: 389]
  ------------------
  764|       |
  765|  6.57M|    while (data_offset < buffer_len && col < ctx->var_index && var_index < ctx->var_index) {
  ------------------
  |  Branch (765:12): [True: 3.52M, False: 3.04M]
  |  Branch (765:40): [True: 3.52M, False: 194]
  |  Branch (765:64): [True: 3.52M, False: 48]
  ------------------
  766|  3.52M|        spss_varinfo_t *col_info = ctx->varinfo[col];
  767|  3.52M|        spss_varinfo_t *var_info = ctx->varinfo[var_index];
  768|  3.52M|        readstat_value_t value = { .type = var_info->type };
  769|  3.52M|        if (offset > 31) {
  ------------------
  |  Branch (769:13): [True: 1, False: 3.52M]
  ------------------
  770|      1|            retval = READSTAT_ERROR_PARSE;
  771|      1|            goto done;
  772|      1|        }
  773|  3.52M|        if (var_info->type == READSTAT_TYPE_STRING) {
  ------------------
  |  Branch (773:13): [True: 2.06M, False: 1.45M]
  ------------------
  774|       |            // If we're in the last column of a segment, only read 7 bytes
  775|       |            // (Segments contain 255 bytes but have room for 256)
  776|  2.06M|            size_t read_len = 8 - (offset == 31);
  777|       |            /* Data in padding and in the unused space of very long string
  778|       |             * segments is ignored, per the spec */
  779|  2.06M|            if (raw_str_used + read_len > var_info->string_length) {
  ------------------
  |  Branch (779:17): [True: 11.1k, False: 2.05M]
  ------------------
  780|  11.1k|                read_len = var_info->string_length > raw_str_used ? var_info->string_length - raw_str_used : 0;
  ------------------
  |  Branch (780:28): [True: 6.36k, False: 4.82k]
  ------------------
  781|  11.1k|            }
  782|  2.06M|            if (read_len && raw_str_used + read_len <= ctx->raw_string_len) {
  ------------------
  |  Branch (782:17): [True: 2.06M, False: 4.82k]
  |  Branch (782:29): [True: 2.06M, False: 0]
  ------------------
  783|  2.06M|                if (raw_str_is_utf8) {
  ------------------
  |  Branch (783:21): [True: 426, False: 2.06M]
  ------------------
  784|       |                    /* Skip null bytes, see https://github.com/tidyverse/haven/issues/560  */
  785|    426|                    char c;
  786|  2.55k|                    for (int i=0; i<read_len; i++)
  ------------------
  |  Branch (786:35): [True: 2.12k, False: 426]
  ------------------
  787|  2.12k|                        if ((c = buffer[data_offset+i]))
  ------------------
  |  Branch (787:29): [True: 1.29k, False: 832]
  ------------------
  788|  1.29k|                            ctx->raw_string[raw_str_used++] = c;
  789|  2.06M|                } else {
  790|  2.06M|                    memcpy(ctx->raw_string + raw_str_used, &buffer[data_offset], read_len);
  791|  2.06M|                    raw_str_used += read_len;
  792|  2.06M|                }
  793|  2.06M|            }
  794|  2.06M|            if (++offset == col_info->width) {
  ------------------
  |  Branch (794:17): [True: 1.96M, False: 104k]
  ------------------
  795|  1.96M|                offset = 0;
  796|  1.96M|                col++;
  797|  1.96M|                segment_offset++;
  798|  1.96M|            }
  799|  2.06M|            if (segment_offset == var_info->n_segments) {
  ------------------
  |  Branch (799:17): [True: 14.1k, False: 2.05M]
  ------------------
  800|  14.1k|                if (!ctx->variables[var_info->index]->skip) {
  ------------------
  |  Branch (800:21): [True: 14.1k, False: 0]
  ------------------
  801|  14.1k|                    retval = readstat_convert(ctx->utf8_string, ctx->utf8_string_len, 
  802|  14.1k|                            ctx->raw_string, raw_str_used, ctx->converter);
  803|  14.1k|                    if (retval != READSTAT_OK)
  ------------------
  |  Branch (803:25): [True: 14, False: 14.1k]
  ------------------
  804|     14|                        goto done;
  805|  14.1k|                    value.v.string_value = ctx->utf8_string;
  806|  14.1k|                    if (ctx->handle.value(ctx->current_row, ctx->variables[var_info->index],
  ------------------
  |  Branch (806:25): [True: 0, False: 14.1k]
  ------------------
  807|  14.1k|                                value, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|  14.1k|#define READSTAT_HANDLER_OK             0
  ------------------
  808|      0|                        retval = READSTAT_ERROR_USER_ABORT;
  809|      0|                        goto done;
  810|      0|                    }
  811|  14.1k|                }
  812|  14.1k|                raw_str_used = 0;
  813|  14.1k|                segment_offset = 0;
  814|  14.1k|                var_index += var_info->n_segments;
  815|  14.1k|            }
  816|  2.06M|        } else if (var_info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (816:20): [True: 1.45M, False: 0]
  ------------------
  817|  1.45M|            if (!ctx->variables[var_info->index]->skip) {
  ------------------
  |  Branch (817:17): [True: 1.45M, False: 0]
  ------------------
  818|  1.45M|                memcpy(&fp_value, &buffer[data_offset], 8);
  819|  1.45M|                if (ctx->bswap) {
  ------------------
  |  Branch (819:21): [True: 159k, False: 1.29M]
  ------------------
  820|   159k|                    fp_value = byteswap_double(fp_value);
  821|   159k|                }
  822|  1.45M|                value.v.double_value = fp_value;
  823|  1.45M|                sav_tag_missing_double(&value, ctx);
  824|  1.45M|                if (ctx->handle.value(ctx->current_row, ctx->variables[var_info->index],
  ------------------
  |  Branch (824:21): [True: 0, False: 1.45M]
  ------------------
  825|  1.45M|                            value, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|  1.45M|#define READSTAT_HANDLER_OK             0
  ------------------
  826|      0|                    retval = READSTAT_ERROR_USER_ABORT;
  827|      0|                    goto done;
  828|      0|                }
  829|  1.45M|            }
  830|  1.45M|            var_index += var_info->n_segments;
  831|  1.45M|            col++;
  832|  1.45M|        }
  833|  3.52M|        data_offset += 8;
  834|  3.52M|    }
  835|  3.04M|    ctx->current_row++;
  836|  3.04M|done:
  837|  3.04M|    return retval;
  838|  3.04M|}
readstat_sav_read.c:sav_read_uncompressed_data:
  887|    548|        readstat_error_t (*row_handler)(unsigned char *, size_t, sav_ctx_t *)) {
  888|    548|    readstat_error_t retval = READSTAT_OK;
  889|    548|    readstat_io_t *io = ctx->io;
  890|    548|    unsigned char *buffer = NULL;
  891|    548|    size_t bytes_read = 0;
  892|    548|    size_t buffer_len = ctx->var_offset * 8;
  893|       |
  894|    548|    if ((buffer = readstat_malloc(buffer_len)) == NULL) {
  ------------------
  |  Branch (894:9): [True: 0, False: 548]
  ------------------
  895|      0|        retval = READSTAT_ERROR_MALLOC;
  896|      0|        goto done;
  897|      0|    }
  898|       |
  899|    548|    if (ctx->row_offset) {
  ------------------
  |  Branch (899:9): [True: 0, False: 548]
  ------------------
  900|      0|        if (io->seek(buffer_len * ctx->row_offset, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (900:13): [True: 0, False: 0]
  ------------------
  901|      0|            retval = READSTAT_ERROR_SEEK;
  902|      0|            goto done;
  903|      0|        }
  904|      0|        ctx->row_offset = 0;
  905|      0|    }
  906|       |
  907|  1.50k|    while (ctx->row_limit == -1 || ctx->current_row < ctx->row_limit) {
  ------------------
  |  Branch (907:12): [True: 675, False: 828]
  |  Branch (907:36): [True: 796, False: 32]
  ------------------
  908|  1.47k|        retval = sav_update_progress(ctx);
  909|  1.47k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (909:13): [True: 0, False: 1.47k]
  ------------------
  910|      0|            goto done;
  911|       |
  912|  1.47k|        if ((bytes_read = io->read(buffer, buffer_len, io->io_ctx)) != buffer_len)
  ------------------
  |  Branch (912:13): [True: 512, False: 959]
  ------------------
  913|    512|            goto done;
  914|       |
  915|    959|        retval = row_handler(buffer, buffer_len, ctx);
  916|    959|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (916:13): [True: 4, False: 955]
  ------------------
  917|      4|            goto done;
  918|    959|    }
  919|    548|done:
  920|    548|    if (buffer)
  ------------------
  |  Branch (920:9): [True: 548, False: 0]
  ------------------
  921|    548|        free(buffer);
  922|       |
  923|    548|    return retval;
  924|    548|}

spss_format:
   51|  39.6k|int spss_format(char *buffer, size_t len, spss_format_t *format) {
   52|  39.6k|    if (format->type < 0 
  ------------------
  |  Branch (52:9): [True: 0, False: 39.6k]
  ------------------
   53|  39.6k|            || format->type >= sizeof(spss_type_strings)/sizeof(spss_type_strings[0])
  ------------------
  |  Branch (53:16): [True: 10.3k, False: 29.2k]
  ------------------
   54|  29.2k|            || spss_type_strings[format->type][0] == '\0') {
  ------------------
  |  Branch (54:16): [True: 13.7k, False: 15.5k]
  ------------------
   55|  24.0k|        return 0;
   56|  24.0k|    }
   57|  15.5k|    char *string = spss_type_strings[format->type];
   58|       |
   59|  15.5k|    if (format->decimal_places || format->type == SPSS_FORMAT_TYPE_F) {
  ------------------
  |  |    6|  10.0k|#define SPSS_FORMAT_TYPE_F        5
  ------------------
  |  Branch (59:9): [True: 5.44k, False: 10.0k]
  |  Branch (59:35): [True: 195, False: 9.87k]
  ------------------
   60|  5.64k|        snprintf(buffer, len, "%s%d.%d", string, format->width, format->decimal_places);
   61|  9.87k|    } else if (format->width) {
  ------------------
  |  Branch (61:16): [True: 6.04k, False: 3.83k]
  ------------------
   62|  6.04k|        snprintf(buffer, len, "%s%d", string, format->width);
   63|  6.04k|    } else {
   64|  3.83k|        snprintf(buffer, len, "%s", string);
   65|  3.83k|    }
   66|       |
   67|  15.5k|    return 1;
   68|  39.6k|}
spss_varinfo_compare:
   70|  3.17M|int spss_varinfo_compare(const void *elem1, const void *elem2) {
   71|  3.17M|    int offset = *(int *)elem1;
   72|  3.17M|    const spss_varinfo_t *v = *(const spss_varinfo_t **)elem2;
   73|  3.17M|    if (offset < v->offset)
  ------------------
  |  Branch (73:9): [True: 1.85M, False: 1.31M]
  ------------------
   74|  1.85M|        return -1;
   75|  1.31M|    return (offset > v->offset);
   76|  3.17M|}
spss_varinfo_free:
   78|   475k|void spss_varinfo_free(spss_varinfo_t *info) {
   79|   475k|    if (info) {
  ------------------
  |  Branch (79:9): [True: 475k, False: 0]
  ------------------
   80|   475k|        if (info->label)
  ------------------
  |  Branch (80:13): [True: 10.7k, False: 464k]
  ------------------
   81|  10.7k|            free(info->label);
   82|   475k|        free(info);
   83|   475k|    }
   84|   475k|}
spss_missingness_for_info:
  127|  39.6k|readstat_missingness_t spss_missingness_for_info(spss_varinfo_t *info) {
  128|  39.6k|    readstat_missingness_t missingness;
  129|  39.6k|    memset(&missingness, '\0', sizeof(readstat_missingness_t));
  130|       |
  131|  39.6k|    if (info->missing_range) {
  ------------------
  |  Branch (131:9): [True: 8.71k, False: 30.8k]
  ------------------
  132|  8.71k|        missingness.missing_ranges_count++;
  133|  8.71k|        missingness.missing_ranges[0] = spss_boxed_missing_value(info, 0);
  134|  8.71k|        missingness.missing_ranges[1] = spss_boxed_missing_value(info, 1);
  135|       |
  136|  8.71k|        if (info->n_missing_values == 3) {
  ------------------
  |  Branch (136:13): [True: 8.06k, False: 646]
  ------------------
  137|  8.06k|            missingness.missing_ranges_count++;
  138|  8.06k|            missingness.missing_ranges[2] = missingness.missing_ranges[3] = spss_boxed_missing_value(info, 2);
  139|  8.06k|        }
  140|  30.8k|    } else if (info->n_missing_values > 0) {
  ------------------
  |  Branch (140:16): [True: 12.6k, False: 18.2k]
  ------------------
  141|  12.6k|        missingness.missing_ranges_count = info->n_missing_values;
  142|  12.6k|        int i=0;
  143|  50.4k|        for (i=0; i<info->n_missing_values; i++) {
  ------------------
  |  Branch (143:19): [True: 37.7k, False: 12.6k]
  ------------------
  144|  37.7k|            missingness.missing_ranges[2*i] = missingness.missing_ranges[2*i+1] = spss_boxed_missing_value(info, i);
  145|  37.7k|        }
  146|  12.6k|    }
  147|  39.6k|    return missingness;
  148|  39.6k|}
spss_init_variable_for_info:
  151|  39.6k|        iconv_t converter) {
  152|  39.6k|    readstat_variable_t *variable = calloc(1, sizeof(readstat_variable_t));
  153|       |
  154|  39.6k|    variable->index = info->index;
  155|  39.6k|    variable->index_after_skipping = index_after_skipping;
  156|  39.6k|    variable->type = info->type;
  157|  39.6k|    if (info->string_length) {
  ------------------
  |  Branch (157:9): [True: 9.20k, False: 30.3k]
  ------------------
  158|  9.20k|        variable->storage_width = info->string_length;
  159|  30.3k|    } else {
  160|  30.3k|        variable->storage_width = 8 * info->width;
  161|  30.3k|    }
  162|       |
  163|  39.6k|    if (info->longname[0]) {
  ------------------
  |  Branch (163:9): [True: 37.2k, False: 2.30k]
  ------------------
  164|  37.2k|        readstat_convert(variable->name, sizeof(variable->name),
  165|  37.2k|                info->longname, sizeof(info->longname), converter);
  166|  37.2k|    } else {
  167|  2.30k|        readstat_convert(variable->name, sizeof(variable->name),
  168|  2.30k|                info->name, sizeof(info->name), converter);
  169|  2.30k|    }
  170|  39.6k|    if (info->label) {
  ------------------
  |  Branch (170:9): [True: 7.93k, False: 31.6k]
  ------------------
  171|  7.93k|        snprintf(variable->label, sizeof(variable->label), "%s", info->label);
  172|  7.93k|    }
  173|       |
  174|  39.6k|    spss_format(variable->format, sizeof(variable->format), &info->print_format);
  175|       |
  176|  39.6k|    variable->missingness = spss_missingness_for_info(info);
  177|  39.6k|    variable->measure = info->measure;
  178|  39.6k|    variable->alignment = info->alignment;
  179|  39.6k|    if (info->display_width) {
  ------------------
  |  Branch (179:9): [True: 182, False: 39.4k]
  ------------------
  180|    182|        variable->display_width = info->display_width;
  181|  39.4k|    } else {
  182|  39.4k|        variable->display_width = info->print_format.width;
  183|  39.4k|    }
  184|       |
  185|  39.6k|    return variable;
  186|  39.6k|}
spss_measure_to_readstat_measure:
  200|    993|readstat_measure_t spss_measure_to_readstat_measure(uint32_t sav_measure) {
  201|    993|    if (sav_measure == SAV_MEASURE_NOMINAL)
  ------------------
  |  |   47|    993|#define SAV_MEASURE_NOMINAL     1
  ------------------
  |  Branch (201:9): [True: 44, False: 949]
  ------------------
  202|     44|        return READSTAT_MEASURE_NOMINAL;
  203|    949|    if (sav_measure == SAV_MEASURE_ORDINAL)
  ------------------
  |  |   48|    949|#define SAV_MEASURE_ORDINAL     2
  ------------------
  |  Branch (203:9): [True: 43, False: 906]
  ------------------
  204|     43|        return READSTAT_MEASURE_ORDINAL;
  205|    906|    if (sav_measure == SAV_MEASURE_SCALE)
  ------------------
  |  |   49|    906|#define SAV_MEASURE_SCALE       3
  ------------------
  |  Branch (205:9): [True: 78, False: 828]
  ------------------
  206|     78|        return READSTAT_MEASURE_SCALE;
  207|    828|    return READSTAT_MEASURE_UNKNOWN;
  208|    906|}
spss_alignment_to_readstat_alignment:
  222|    993|readstat_alignment_t spss_alignment_to_readstat_alignment(uint32_t sav_alignment) {
  223|    993|    if (sav_alignment == SAV_ALIGNMENT_LEFT)
  ------------------
  |  |   51|    993|#define SAV_ALIGNMENT_LEFT      0
  ------------------
  |  Branch (223:9): [True: 380, False: 613]
  ------------------
  224|    380|        return READSTAT_ALIGNMENT_LEFT;
  225|    613|    if (sav_alignment == SAV_ALIGNMENT_CENTER)
  ------------------
  |  |   53|    613|#define SAV_ALIGNMENT_CENTER    2
  ------------------
  |  Branch (225:9): [True: 38, False: 575]
  ------------------
  226|     38|        return READSTAT_ALIGNMENT_CENTER;
  227|    575|    if (sav_alignment == SAV_ALIGNMENT_RIGHT)
  ------------------
  |  |   52|    575|#define SAV_ALIGNMENT_RIGHT     1
  ------------------
  |  Branch (227:9): [True: 58, False: 517]
  ------------------
  228|     58|        return READSTAT_ALIGNMENT_RIGHT;
  229|    517|    return READSTAT_ALIGNMENT_UNKNOWN;
  230|    575|}
readstat_spss.c:spss_boxed_missing_value:
  120|  63.2k|static readstat_value_t spss_boxed_missing_value(spss_varinfo_t *info, int i) {
  121|  63.2k|    if (info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (121:9): [True: 55.5k, False: 7.74k]
  ------------------
  122|  55.5k|        return spss_boxed_double_value(info->missing_double_values[i]);
  123|  55.5k|    }
  124|  7.74k|    return spss_boxed_string_value(info->missing_string_values[i]);
  125|  63.2k|}
readstat_spss.c:spss_boxed_double_value:
  103|  55.5k|static readstat_value_t spss_boxed_double_value(double fp_value) {
  104|  55.5k|    readstat_value_t value = {
  105|  55.5k|        .type = READSTAT_TYPE_DOUBLE,
  106|  55.5k|        .v = { .double_value = fp_value },
  107|       |        .is_system_missing = isnan(fp_value)
  108|  55.5k|    };
  109|  55.5k|    return value;
  110|  55.5k|}
readstat_spss.c:spss_boxed_string_value:
  112|  7.74k|static readstat_value_t spss_boxed_string_value(const char *string) {
  113|  7.74k|    readstat_value_t value = {
  114|  7.74k|        .type = READSTAT_TYPE_STRING,
  115|  7.74k|        .v = { .string_value = string }
  116|  7.74k|    };
  117|  7.74k|    return value;
  118|  7.74k|}

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

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

