ck_str_hash_lookup:
  146|  2.13k|const void *ck_str_hash_lookup(const char *key, ck_hash_table_t *table) {
  147|  2.13k|    size_t keylen = strlen(key);
  148|  2.13k|    return ck_str_n_hash_lookup(key, keylen, table);
  149|  2.13k|}
ck_str_n_hash_lookup:
  152|  2.13k|{
  153|  2.13k|	if (table->count == 0)
  ------------------
  |  Branch (153:6): [True: 573, False: 1.55k]
  ------------------
  154|    573|		return NULL;
  155|       |    	
  156|  1.55k|	if (keylen == 0)
  ------------------
  |  Branch (156:6): [True: 250, False: 1.30k]
  ------------------
  157|    250|		return NULL;
  158|       |	
  159|  1.30k|    uint64_t hash_key = ck_hash_str(key, keylen);
  160|  1.30k|	hash_key %= table->capacity;
  161|  1.30k|    uint64_t end = hash_key;
  162|  1.95k|    do {
  163|  1.95k|        char *this_key = &table->keys[table->entries[hash_key].key_offset];
  164|  1.95k|        size_t this_keylen = table->entries[hash_key].key_length;
  165|  1.95k|        if (this_keylen == 0)
  ------------------
  |  Branch (165:13): [True: 1.26k, False: 690]
  ------------------
  166|  1.26k|            return NULL;
  167|    690|        if (this_keylen == keylen && memcmp(this_key, key, keylen) == 0) {
  ------------------
  |  Branch (167:13): [True: 212, False: 478]
  |  Branch (167:38): [True: 47, False: 165]
  ------------------
  168|     47|			return table->entries[hash_key].value;
  169|     47|		}
  170|    643|		hash_key++;
  171|    643|		hash_key %= table->capacity;
  172|    643|    } while (hash_key != end);
  ------------------
  |  Branch (172:14): [True: 643, False: 0]
  ------------------
  173|      0|	return NULL;
  174|  1.30k|}
ck_str_hash_insert:
  177|   312k|{
  178|   312k|    size_t keylen = strlen(key);
  179|   312k|    return ck_str_n_hash_insert(key, keylen, value, table);
  180|   312k|}
ck_str_n_hash_insert:
  210|   312k|{    
  211|   312k|	if (table->capacity == 0)
  ------------------
  |  Branch (211:6): [True: 0, False: 312k]
  ------------------
  212|      0|		return 0;
  213|       |    	
  214|   312k|	if (keylen == 0)
  ------------------
  |  Branch (214:6): [True: 0, False: 312k]
  ------------------
  215|      0|		return 0;
  216|       |    
  217|   312k|    if (table->count >= 0.75 * table->capacity) {
  ------------------
  |  Branch (217:9): [True: 0, False: 312k]
  ------------------
  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|   312k|    uint64_t hash_key = ck_hash_str(key, keylen);
  224|   312k|	hash_key %= table->capacity;
  225|   312k|    uint64_t end = hash_key;
  226|   314k|    do {
  227|   314k|        ck_hash_entry_t *entry = &table->entries[hash_key];
  228|   314k|        char *this_key = &table->keys[entry->key_offset];
  229|   314k|        if (entry->key_length == 0) {
  ------------------
  |  Branch (229:13): [True: 8.77k, False: 305k]
  ------------------
  230|  8.77k|            table->count++;
  231|  8.77k|            while (table->keys_used + keylen > table->keys_capacity) {
  ------------------
  |  Branch (231:20): [True: 0, False: 8.77k]
  ------------------
  232|      0|                table->keys_capacity *= 2;
  233|      0|                table->keys = realloc(table->keys, table->keys_capacity);
  234|      0|            }
  235|  8.77k|            memcpy(table->keys + table->keys_used, key, keylen);
  236|  8.77k|            entry->key_offset = table->keys_used;
  237|  8.77k|            entry->key_length = keylen;
  238|  8.77k|            table->keys_used += keylen;
  239|  8.77k|            entry->value = value;
  240|  8.77k|            return 1;
  241|   305k|        } else if (entry->key_length == keylen &&
  ------------------
  |  Branch (241:20): [True: 304k, False: 1.26k]
  ------------------
  242|   304k|                   memcmp(this_key, key, keylen) == 0) {
  ------------------
  |  Branch (242:20): [True: 303k, False: 764]
  ------------------
  243|   303k|			table->entries[hash_key].value = value;
  244|   303k|			return 1;
  245|   303k|		}
  246|  2.03k|		hash_key++;
  247|  2.03k|		hash_key %= table->capacity;
  248|  2.03k|    } while (hash_key != end);
  ------------------
  |  Branch (248:14): [True: 2.03k, False: 0]
  ------------------
  249|      0|	return 0;
  250|   312k|}
ck_hash_table_init:
  253|  1.88k|{
  254|  1.88k|	ck_hash_table_t *table;
  255|  1.88k|	if ((table = malloc(sizeof(ck_hash_table_t))) == NULL)
  ------------------
  |  Branch (255:6): [True: 0, False: 1.88k]
  ------------------
  256|      0|		return NULL;
  257|       |    
  258|  1.88k|    if ((table->keys = malloc(num_entries * mean_key_length)) == NULL) {
  ------------------
  |  Branch (258:9): [True: 0, False: 1.88k]
  ------------------
  259|      0|        free(table);
  260|      0|        return NULL;
  261|      0|    }
  262|  1.88k|    table->keys_capacity = num_entries * mean_key_length;
  263|       |    
  264|  1.88k|    num_entries *= 2;
  265|       |    
  266|  1.88k|    if ((table->entries = malloc(num_entries * sizeof(ck_hash_entry_t))) == NULL) {
  ------------------
  |  Branch (266:9): [True: 0, False: 1.88k]
  ------------------
  267|      0|        free(table->keys);
  268|      0|        free(table);
  269|      0|        return NULL;
  270|      0|    }
  271|  1.88k|	table->capacity = num_entries;
  272|  1.88k|    ck_hash_table_wipe(table);
  273|  1.88k|	return table;
  274|  1.88k|}
ck_hash_table_free:
  276|  1.88k|void ck_hash_table_free(ck_hash_table_t *table) {
  277|  1.88k|    free(table->entries);
  278|  1.88k|    if (table->keys)
  ------------------
  |  Branch (278:9): [True: 1.88k, False: 0]
  ------------------
  279|  1.88k|        free(table->keys);
  280|  1.88k|    free(table);
  281|  1.88k|}
ck_hash_table_wipe:
  283|  1.88k|void ck_hash_table_wipe(ck_hash_table_t *table) {
  284|  1.88k|    table->keys_used = 0;
  285|  1.88k|    table->count = 0;
  286|  1.88k|    memset(table->entries, 0, table->capacity * sizeof(ck_hash_entry_t));
  287|  1.88k|}
CKHashTable.c:ck_hash_str:
  121|   313k|{
  122|   313k|    uint64_t hash;
  123|   313k|    unsigned char k[16] = { 0 };
  124|   313k|    siphash((unsigned char *)&hash, (const unsigned char *)str, keylen, k);
  125|   313k|    return hash;
  126|   313k|}
CKHashTable.c:siphash:
   57|   313k|{
   58|       |    /* "somepseudorandomlygeneratedbytes" */
   59|   313k|    u64 v0 = 0x736f6d6570736575ULL;
   60|   313k|    u64 v1 = 0x646f72616e646f6dULL;
   61|   313k|    u64 v2 = 0x6c7967656e657261ULL;
   62|   313k|    u64 v3 = 0x7465646279746573ULL;
   63|   313k|    u64 b;
   64|   313k|    u64 k0 = U8TO64_LE( k );
  ------------------
  |  |   37|   313k|#define U8TO64_LE(p) \
  |  |   38|   313k|(((u64)((p)[0])      ) | \
  |  |   39|   313k|((u64)((p)[1]) <<  8) | \
  |  |   40|   313k|((u64)((p)[2]) << 16) | \
  |  |   41|   313k|((u64)((p)[3]) << 24) | \
  |  |   42|   313k|((u64)((p)[4]) << 32) | \
  |  |   43|   313k|((u64)((p)[5]) << 40) | \
  |  |   44|   313k|((u64)((p)[6]) << 48) | \
  |  |   45|   313k|((u64)((p)[7]) << 56))
  ------------------
   65|   313k|    u64 k1 = U8TO64_LE( k + 8 );
  ------------------
  |  |   37|   313k|#define U8TO64_LE(p) \
  |  |   38|   313k|(((u64)((p)[0])      ) | \
  |  |   39|   313k|((u64)((p)[1]) <<  8) | \
  |  |   40|   313k|((u64)((p)[2]) << 16) | \
  |  |   41|   313k|((u64)((p)[3]) << 24) | \
  |  |   42|   313k|((u64)((p)[4]) << 32) | \
  |  |   43|   313k|((u64)((p)[5]) << 40) | \
  |  |   44|   313k|((u64)((p)[6]) << 48) | \
  |  |   45|   313k|((u64)((p)[7]) << 56))
  ------------------
   66|   313k|    u64 m;
   67|   313k|    const u8 *end = in + inlen - ( inlen % sizeof( u64 ) );
   68|   313k|    const int left = inlen & 7;
   69|   313k|    b = ( ( u64 )inlen ) << 56;
   70|   313k|    v3 ^= k1;
   71|   313k|    v2 ^= k0;
   72|   313k|    v1 ^= k1;
   73|   313k|    v0 ^= k0;
   74|       |    
   75|   373k|    for ( ; in != end; in += 8 )
  ------------------
  |  Branch (75:13): [True: 59.5k, False: 313k]
  ------------------
   76|  59.5k|    {
   77|  59.5k|        m = U8TO64_LE( in );
  ------------------
  |  |   37|  59.5k|#define U8TO64_LE(p) \
  |  |   38|  59.5k|(((u64)((p)[0])      ) | \
  |  |   39|  59.5k|((u64)((p)[1]) <<  8) | \
  |  |   40|  59.5k|((u64)((p)[2]) << 16) | \
  |  |   41|  59.5k|((u64)((p)[3]) << 24) | \
  |  |   42|  59.5k|((u64)((p)[4]) << 32) | \
  |  |   43|  59.5k|((u64)((p)[5]) << 40) | \
  |  |   44|  59.5k|((u64)((p)[6]) << 48) | \
  |  |   45|  59.5k|((u64)((p)[7]) << 56))
  ------------------
   78|       |        
   79|  59.5k|        v3 ^= m;
   80|       |        
   81|  59.5k|        SIPROUND;
  ------------------
  |  |   47|  59.5k|#define SIPROUND            \
  |  |   48|  59.5k|do {              \
  |  |   49|  59.5k|v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|  59.5k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|  59.5k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   50|  59.5k|v2 += v3; v3=ROTL(v3,16); v3 ^= v2;     \
  |  |  ------------------
  |  |  |  |   27|  59.5k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   51|  59.5k|v0 += v3; v3=ROTL(v3,21); v3 ^= v0;     \
  |  |  ------------------
  |  |  |  |   27|  59.5k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   52|  59.5k|v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|  59.5k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|  59.5k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   53|  59.5k|} while(0)
  |  |  ------------------
  |  |  |  Branch (53:9): [Folded, False: 59.5k]
  |  |  ------------------
  ------------------
   82|       |        
   83|  59.5k|        v0 ^= m;
   84|  59.5k|    }
   85|       |    
   86|   313k|    switch( left )
  ------------------
  |  Branch (86:13): [True: 313k, False: 0]
  ------------------
   87|   313k|    {
   88|  18.6k|        case 7: b |= ( ( u64 )in[ 6] )  << 48;
  ------------------
  |  Branch (88:9): [True: 18.6k, False: 295k]
  ------------------
   89|       |            
   90|  35.7k|        case 6: b |= ( ( u64 )in[ 5] )  << 40;
  ------------------
  |  Branch (90:9): [True: 17.1k, False: 296k]
  ------------------
   91|       |            
   92|  61.2k|        case 5: b |= ( ( u64 )in[ 4] )  << 32;
  ------------------
  |  Branch (92:9): [True: 25.4k, False: 288k]
  ------------------
   93|       |            
   94|  63.3k|        case 4: b |= ( ( u64 )in[ 3] )  << 24;
  ------------------
  |  Branch (94:9): [True: 2.16k, False: 311k]
  ------------------
   95|       |            
   96|  65.1k|        case 3: b |= ( ( u64 )in[ 2] )  << 16;
  ------------------
  |  Branch (96:9): [True: 1.78k, False: 312k]
  ------------------
   97|       |            
   98|   212k|        case 2: b |= ( ( u64 )in[ 1] )  <<  8;
  ------------------
  |  Branch (98:9): [True: 147k, False: 166k]
  ------------------
   99|       |            
  100|   254k|        case 1: b |= ( ( u64 )in[ 0] ); break;
  ------------------
  |  Branch (100:9): [True: 41.9k, False: 271k]
  ------------------
  101|       |            
  102|  59.0k|        case 0: break;
  ------------------
  |  Branch (102:9): [True: 59.0k, False: 254k]
  ------------------
  103|   313k|    }
  104|       |
  105|   313k|    v3 ^= b;
  106|       |    
  107|   313k|    SIPROUND;
  ------------------
  |  |   47|   313k|#define SIPROUND            \
  |  |   48|   313k|do {              \
  |  |   49|   313k|v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   50|   313k|v2 += v3; v3=ROTL(v3,16); v3 ^= v2;     \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   51|   313k|v0 += v3; v3=ROTL(v3,21); v3 ^= v0;     \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   52|   313k|v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   53|   313k|} while(0)
  |  |  ------------------
  |  |  |  Branch (53:9): [Folded, False: 313k]
  |  |  ------------------
  ------------------
  108|       |    
  109|   313k|    v0 ^= b;
  110|   313k|    v2 ^= 0xff;
  111|       |    
  112|   313k|    SIPROUND;
  ------------------
  |  |   47|   313k|#define SIPROUND            \
  |  |   48|   313k|do {              \
  |  |   49|   313k|v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   50|   313k|v2 += v3; v3=ROTL(v3,16); v3 ^= v2;     \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   51|   313k|v0 += v3; v3=ROTL(v3,21); v3 ^= v0;     \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   52|   313k|v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   53|   313k|} while(0)
  |  |  ------------------
  |  |  |  Branch (53:9): [Folded, False: 313k]
  |  |  ------------------
  ------------------
  113|   313k|    SIPROUND;
  ------------------
  |  |   47|   313k|#define SIPROUND            \
  |  |   48|   313k|do {              \
  |  |   49|   313k|v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   50|   313k|v2 += v3; v3=ROTL(v3,16); v3 ^= v2;     \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   51|   313k|v0 += v3; v3=ROTL(v3,21); v3 ^= v0;     \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   52|   313k|v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |               v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
  |  |  ------------------
  |  |  |  |   27|   313k|#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
  |  |  ------------------
  |  |   53|   313k|} while(0)
  |  |  ------------------
  |  |  |  Branch (53:9): [Folded, False: 313k]
  |  |  ------------------
  ------------------
  114|       |    
  115|   313k|    b = v0 ^ v1 ^ v2  ^ v3;
  116|   313k|    U64TO8_LE( out, b );
  ------------------
  |  |   33|   313k|#define U64TO8_LE(p, v)         \
  |  |  ------------------
  |  |  |  |   29|   313k|#define U32TO8_LE(p, v)         \
  |  |  |  |   30|   313k|(p)[0] = (u8)((v)      ); (p)[1] = (u8)((v) >>  8); \
  |  |  |  |   31|   313k|(p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24);
  |  |  ------------------
  |  |   34|   313k|U32TO8_LE((p),     (u32)((v)      ));   \
  |  |  ------------------
  |  |  |  |   29|   313k|#define U32TO8_LE(p, v)         \
  |  |  |  |   30|   313k|(p)[0] = (u8)((v)      ); (p)[1] = (u8)((v) >>  8); \
  |  |  |  |   31|   313k|(p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24);
  |  |  ------------------
  |  |   35|   313k|U32TO8_LE((p) + 4, (u32)((v) >> 32));
  ------------------
  117|   313k|    return 0;
  118|   313k|}

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

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

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

readstat_convert:
    7|  2.32M|readstat_error_t readstat_convert(char *dst, size_t dst_len, const char *src, size_t src_len, iconv_t converter) {
    8|       |    /* strip off spaces from the input because the programs use ASCII space
    9|       |     * padding even with non-ASCII encoding. */
   10|  26.6M|    while (src_len && (src[src_len-1] == ' ' || src[src_len-1] == '\0')) {
  ------------------
  |  Branch (10:12): [True: 26.6M, False: 19.9k]
  |  Branch (10:24): [True: 3.08M, False: 23.5M]
  |  Branch (10:49): [True: 21.2M, False: 2.30M]
  ------------------
   11|  24.3M|        src_len--;
   12|  24.3M|    }
   13|  2.32M|    if (dst_len == 0) {
  ------------------
  |  Branch (13:9): [True: 0, False: 2.32M]
  ------------------
   14|      0|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   15|  2.32M|    } else if (converter) {
  ------------------
  |  Branch (15:16): [True: 2.15k, False: 2.32M]
  ------------------
   16|  2.15k|        size_t dst_left = dst_len - 1;
   17|  2.15k|        char *dst_end = dst;
   18|  2.15k|        size_t status = iconv(converter, (readstat_iconv_inbuf_t)&src, &src_len, &dst_end, &dst_left);
   19|  2.15k|        if (status == (size_t)-1) {
  ------------------
  |  Branch (19:13): [True: 897, False: 1.25k]
  ------------------
   20|    897|            if (errno == E2BIG) {
  ------------------
  |  Branch (20:17): [True: 1, False: 896]
  ------------------
   21|      1|                return READSTAT_ERROR_CONVERT_LONG_STRING;
   22|    896|            } else if (errno == EILSEQ) {
  ------------------
  |  Branch (22:24): [True: 501, False: 395]
  ------------------
   23|    501|                return READSTAT_ERROR_CONVERT_BAD_STRING;
   24|    501|            } else if (errno != EINVAL) { /* EINVAL indicates improper truncation; accept it */
  ------------------
  |  Branch (24:24): [True: 0, False: 395]
  ------------------
   25|      0|                return READSTAT_ERROR_CONVERT;
   26|      0|            }
   27|    897|        }
   28|  1.64k|        dst[dst_len - dst_left - 1] = '\0';
   29|  2.32M|    } else if (src_len + 1 > dst_len) {
  ------------------
  |  Branch (29:16): [True: 17, False: 2.32M]
  ------------------
   30|     17|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   31|  2.32M|    } else {
   32|  2.32M|        memcpy(dst, src, src_len);
   33|  2.32M|        dst[src_len] = '\0';
   34|  2.32M|    }
   35|  2.32M|    return READSTAT_OK;
   36|  2.32M|}

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

readstat_malloc:
   10|  48.6k|void *readstat_malloc(size_t len) {
   11|  48.6k|    if (len > MAX_MALLOC_SIZE || len == 0) {
  ------------------
  |  |    3|  97.3k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (11:9): [True: 261, False: 48.3k]
  |  Branch (11:34): [True: 1.20k, False: 47.1k]
  ------------------
   12|  1.46k|        return NULL;
   13|  1.46k|    }
   14|  47.1k|    return malloc(len);
   15|  48.6k|}
readstat_calloc:
   17|   482k|void *readstat_calloc(size_t count, size_t size) {
   18|   482k|    if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|   965k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
                  if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|   965k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
                  if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|   482k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (18:9): [True: 25, False: 482k]
  |  Branch (18:36): [True: 0, False: 482k]
  |  Branch (18:62): [True: 29, False: 482k]
  ------------------
   19|     54|        return NULL;
   20|     54|    }
   21|   482k|    if (count == 0 || size == 0) {
  ------------------
  |  Branch (21:9): [True: 18, False: 482k]
  |  Branch (21:23): [True: 0, False: 482k]
  ------------------
   22|     18|        return NULL;
   23|     18|    }
   24|   482k|    return calloc(count, size);
   25|   482k|}
readstat_realloc:
   27|  7.52k|void *readstat_realloc(void *ptr, size_t len) {
   28|  7.52k|    if (len > MAX_MALLOC_SIZE || len == 0) {
  ------------------
  |  |    3|  15.0k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (28:9): [True: 127, False: 7.40k]
  |  Branch (28:34): [True: 1, False: 7.40k]
  ------------------
   29|    128|        if (ptr)
  ------------------
  |  Branch (29:13): [True: 60, False: 68]
  ------------------
   30|     60|            free(ptr);
   31|    128|        return NULL;
   32|    128|    }
   33|  7.40k|    return realloc(ptr, len);
   34|  7.52k|}

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

sav_ctx_init:
   23|  5.86k|sav_ctx_t *sav_ctx_init(sav_file_header_record_t *header, readstat_io_t *io) {
   24|  5.86k|    sav_ctx_t *ctx = readstat_calloc(1, sizeof(sav_ctx_t));
   25|  5.86k|    if (ctx == NULL) {
  ------------------
  |  Branch (25:9): [True: 0, False: 5.86k]
  ------------------
   26|      0|        return NULL;
   27|      0|    }
   28|       |
   29|  5.86k|    if (memcmp(&header->rec_type, "$FL2", 4) == 0) {
  ------------------
  |  Branch (29:9): [True: 3.66k, False: 2.20k]
  ------------------
   30|  3.66k|        ctx->format_version = 2;
   31|  3.66k|    } else if (memcmp(&header->rec_type, "$FL3", 4) == 0) {
  ------------------
  |  Branch (31:16): [True: 2.17k, False: 30]
  ------------------
   32|  2.17k|        ctx->format_version = 3;
   33|  2.17k|    } else {
   34|     30|        sav_ctx_free(ctx);
   35|     30|        return NULL;
   36|     30|    }
   37|       |    
   38|  5.83k|    ctx->bswap = !(header->layout_code == 2 || header->layout_code == 3);
  ------------------
  |  Branch (38:20): [True: 3.68k, False: 2.14k]
  |  Branch (38:48): [True: 316, False: 1.82k]
  ------------------
   39|  5.83k|    ctx->endianness = (machine_is_little_endian() ^ ctx->bswap) ? READSTAT_ENDIAN_LITTLE : READSTAT_ENDIAN_BIG;
  ------------------
  |  Branch (39:23): [True: 4.00k, False: 1.82k]
  ------------------
   40|       |
   41|  5.83k|    if (header->compression == 1 || byteswap4(header->compression) == 1) {
  ------------------
  |  Branch (41:9): [True: 376, False: 5.45k]
  |  Branch (41:37): [True: 151, False: 5.30k]
  ------------------
   42|    527|        ctx->compression = READSTAT_COMPRESS_ROWS;
   43|  5.30k|    } else if (header->compression == 2 || byteswap4(header->compression) == 2) {
  ------------------
  |  Branch (43:16): [True: 470, False: 4.83k]
  |  Branch (43:44): [True: 92, False: 4.74k]
  ------------------
   44|    562|        ctx->compression = READSTAT_COMPRESS_BINARY;
   45|    562|    }
   46|  5.83k|    ctx->record_count = ctx->bswap ? byteswap4(header->ncases) : header->ncases;
  ------------------
  |  Branch (46:25): [True: 1.82k, False: 4.00k]
  ------------------
   47|  5.83k|    ctx->fweight_index = ctx->bswap ? byteswap4(header->weight_index) : header->weight_index;
  ------------------
  |  Branch (47:26): [True: 1.82k, False: 4.00k]
  ------------------
   48|       |
   49|  5.83k|    ctx->missing_double = SAV_MISSING_DOUBLE;
  ------------------
  |  |   43|  5.83k|#define SAV_MISSING_DOUBLE   0xFFEFFFFFFFFFFFFFUL
  ------------------
   50|  5.83k|    ctx->lowest_double = SAV_LOWEST_DOUBLE;
  ------------------
  |  |   44|  5.83k|#define SAV_LOWEST_DOUBLE    0xFFEFFFFFFFFFFFFEUL
  ------------------
   51|  5.83k|    ctx->highest_double = SAV_HIGHEST_DOUBLE;
  ------------------
  |  |   42|  5.83k|#define SAV_HIGHEST_DOUBLE   0x7FEFFFFFFFFFFFFFUL
  ------------------
   52|       |    
   53|  5.83k|    ctx->bias = ctx->bswap ? byteswap_double(header->bias) : header->bias;
  ------------------
  |  Branch (53:17): [True: 1.82k, False: 4.00k]
  ------------------
   54|       |    
   55|  5.83k|    ctx->varinfo_capacity = SAV_VARINFO_INITIAL_CAPACITY;
  ------------------
  |  |   21|  5.83k|#define SAV_VARINFO_INITIAL_CAPACITY  512
  ------------------
   56|       |    
   57|  5.83k|    if ((ctx->varinfo = readstat_calloc(ctx->varinfo_capacity, sizeof(spss_varinfo_t *))) == NULL) {
  ------------------
  |  Branch (57:9): [True: 0, False: 5.83k]
  ------------------
   58|      0|        sav_ctx_free(ctx);
   59|      0|        return NULL;
   60|      0|    }
   61|       |
   62|  5.83k|    ctx->mr_sets = NULL;
   63|       |
   64|  5.83k|    ctx->io = io;
   65|       |    
   66|  5.83k|    return ctx;
   67|  5.83k|}
sav_ctx_free:
   69|  5.86k|void sav_ctx_free(sav_ctx_t *ctx) {
   70|  5.86k|    if (ctx->varinfo) {
  ------------------
  |  Branch (70:9): [True: 5.83k, False: 30]
  ------------------
   71|  5.83k|        int i;
   72|   473k|        for (i=0; i<ctx->var_index; i++) {
  ------------------
  |  Branch (72:19): [True: 468k, False: 5.83k]
  ------------------
   73|   468k|            spss_varinfo_free(ctx->varinfo[i]);
   74|   468k|        }
   75|  5.83k|        free(ctx->varinfo);
   76|  5.83k|    }
   77|  5.86k|    if (ctx->variables) {
  ------------------
  |  Branch (77:9): [True: 1.89k, False: 3.96k]
  ------------------
   78|  1.89k|        int i;
   79|   312k|        for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (79:19): [True: 310k, False: 1.89k]
  ------------------
   80|   310k|            if (ctx->variables[i])
  ------------------
  |  Branch (80:17): [True: 307k, False: 3.01k]
  ------------------
   81|   307k|                free(ctx->variables[i]);
   82|   310k|        }
   83|  1.89k|        free(ctx->variables);
   84|  1.89k|    }
   85|  5.86k|    if (ctx->raw_string)
  ------------------
  |  Branch (85:9): [True: 1.82k, False: 4.03k]
  ------------------
   86|  1.82k|        free(ctx->raw_string);
   87|  5.86k|    if (ctx->utf8_string)
  ------------------
  |  Branch (87:9): [True: 1.81k, False: 4.04k]
  ------------------
   88|  1.81k|        free(ctx->utf8_string);
   89|  5.86k|    if (ctx->converter)
  ------------------
  |  Branch (89:9): [True: 120, False: 5.74k]
  ------------------
   90|    120|        iconv_close(ctx->converter);
   91|  5.86k|    if (ctx->variable_display_values) {
  ------------------
  |  Branch (91:9): [True: 261, False: 5.59k]
  ------------------
   92|    261|        free(ctx->variable_display_values);
   93|    261|    }
   94|  5.86k|    if (ctx->mr_sets) {
  ------------------
  |  Branch (94:9): [True: 230, False: 5.63k]
  ------------------
   95|    788|        for (size_t i = 0; i < ctx->multiple_response_sets_length; i++) {
  ------------------
  |  Branch (95:28): [True: 558, False: 230]
  ------------------
   96|    558|            if (ctx->mr_sets[i].name) {
  ------------------
  |  Branch (96:17): [True: 558, False: 0]
  ------------------
   97|    558|                free(ctx->mr_sets[i].name);
   98|    558|            }
   99|    558|            if (ctx->mr_sets[i].label) {
  ------------------
  |  Branch (99:17): [True: 558, False: 0]
  ------------------
  100|    558|                free(ctx->mr_sets[i].label);
  101|    558|            }
  102|    558|            if (ctx->mr_sets[i].subvariables) {
  ------------------
  |  Branch (102:17): [True: 395, False: 163]
  ------------------
  103|  3.83k|                for (size_t j = 0; j < ctx->mr_sets[i].num_subvars; j++) {
  ------------------
  |  Branch (103:36): [True: 3.43k, False: 395]
  ------------------
  104|  3.43k|                    if (ctx->mr_sets[i].subvariables[j]) {
  ------------------
  |  Branch (104:25): [True: 3.43k, False: 0]
  ------------------
  105|  3.43k|                        free(ctx->mr_sets[i].subvariables[j]);
  106|  3.43k|                    }
  107|  3.43k|                }
  108|    395|                free(ctx->mr_sets[i].subvariables);
  109|    395|            }
  110|    558|        }
  111|    230|        free(ctx->mr_sets);
  112|    230|    }
  113|  5.86k|    free(ctx);
  114|  5.86k|}

sav_decompress_row:
   77|  2.25M|void sav_decompress_row(struct sav_row_stream_s *state) {
   78|  2.25M|    double fp_value;
   79|  2.25M|    uint64_t missing_value = state->bswap ? byteswap8(state->missing_value) : state->missing_value;
  ------------------
  |  Branch (79:30): [True: 328k, False: 1.92M]
  ------------------
   80|  2.25M|    int i = 8 - state->i;
   81|  2.62M|    while (1) {
  ------------------
  |  Branch (81:12): [True: 2.62M, Folded]
  ------------------
   82|  2.62M|        if (i == 8) {
  ------------------
  |  Branch (82:13): [True: 650k, False: 1.97M]
  ------------------
   83|   650k|            if (state->avail_in < 8) {
  ------------------
  |  Branch (83:17): [True: 279, False: 650k]
  ------------------
   84|    279|                state->status = SAV_ROW_STREAM_NEED_DATA;
   85|    279|                goto done;
   86|    279|            }
   87|       |
   88|   650k|            memcpy(state->chunk, state->next_in, 8);
   89|   650k|            state->next_in += 8;
   90|   650k|            state->avail_in -= 8;
   91|   650k|            i = 0;
   92|   650k|        }
   93|       |
   94|  5.57M|        while (i<8) {
  ------------------
  |  Branch (94:16): [True: 5.20M, False: 372k]
  ------------------
   95|  5.20M|            switch (state->chunk[i]) {
   96|  2.63M|                case 0:
  ------------------
  |  Branch (96:17): [True: 2.63M, False: 2.56M]
  ------------------
   97|  2.63M|                    break;
   98|     55|                case 252:
  ------------------
  |  Branch (98:17): [True: 55, False: 5.20M]
  ------------------
   99|     55|                    state->status = SAV_ROW_STREAM_FINISHED_ALL;
  100|     55|                    goto done;
  101|   111k|                case 253:
  ------------------
  |  Branch (101:17): [True: 111k, False: 5.09M]
  ------------------
  102|   111k|                    if (state->avail_in < 8) {
  ------------------
  |  Branch (102:25): [True: 52, False: 111k]
  ------------------
  103|     52|                        state->status = SAV_ROW_STREAM_NEED_DATA;
  104|     52|                        goto done;
  105|     52|                    }
  106|   111k|                    memcpy(state->next_out, state->next_in, 8);
  107|   111k|                    state->next_out += 8;
  108|   111k|                    state->avail_out -= 8;
  109|   111k|                    state->next_in += 8;
  110|   111k|                    state->avail_in -= 8;
  111|   111k|                    break;
  112|  1.90k|                case 254:
  ------------------
  |  Branch (112:17): [True: 1.90k, False: 5.20M]
  ------------------
  113|  1.90k|                    memset(state->next_out, ' ', 8);
  114|  1.90k|                    state->next_out += 8;
  115|  1.90k|                    state->avail_out -= 8;
  116|  1.90k|                    break;
  117|  76.1k|                case 255:
  ------------------
  |  Branch (117:17): [True: 76.1k, False: 5.12M]
  ------------------
  118|  76.1k|                    memcpy(state->next_out, &missing_value, sizeof(uint64_t));
  119|  76.1k|                    state->next_out += 8;
  120|  76.1k|                    state->avail_out -= 8;
  121|  76.1k|                    break;
  122|  2.37M|                default:
  ------------------
  |  Branch (122:17): [True: 2.37M, False: 2.82M]
  ------------------
  123|  2.37M|                    fp_value = state->chunk[i] - state->bias;
  124|  2.37M|                    fp_value = state->bswap ? byteswap_double(fp_value) : fp_value;
  ------------------
  |  Branch (124:32): [True: 312k, False: 2.06M]
  ------------------
  125|  2.37M|                    memcpy(state->next_out, &fp_value, sizeof(double));
  126|  2.37M|                    state->next_out += 8;
  127|  2.37M|                    state->avail_out -= 8;
  128|  2.37M|                    break;
  129|  5.20M|            }
  130|  5.20M|            i++;
  131|  5.20M|            if (state->avail_out < 8) {
  ------------------
  |  Branch (131:17): [True: 2.25M, False: 2.95M]
  ------------------
  132|  2.25M|                state->status = SAV_ROW_STREAM_FINISHED_ROW;
  133|  2.25M|                goto done;
  134|  2.25M|            }
  135|  5.20M|        }
  136|  2.62M|    }
  137|  2.25M|done:
  138|  2.25M|    state->i = 8 - i;
  139|  2.25M|}

sav_parse_long_variable_names_record:
  284|  3.16k|readstat_error_t sav_parse_long_variable_names_record(void *data, int count, sav_ctx_t *ctx) {
  285|  3.16k|    unsigned char *c_data = (unsigned char *)data;
  286|  3.16k|    int var_count = count_vars(ctx);
  287|  3.16k|    readstat_error_t retval = READSTAT_OK;
  288|       |
  289|  3.16k|    char temp_key[8+1];
  290|  3.16k|    char temp_val[64+1];
  291|  3.16k|    unsigned char *str_start = NULL;
  292|  3.16k|    size_t str_len = 0;
  293|       |    
  294|  3.16k|    char error_buf[8192];
  295|  3.16k|    unsigned char *p = c_data;
  296|  3.16k|    unsigned char *pe = c_data + count;
  297|       |
  298|  3.16k|    varlookup_t *table = build_lookup_table(var_count, ctx);
  299|       |
  300|  3.16k|    unsigned char *eof = pe;
  301|       |
  302|  3.16k|    int cs;
  303|       |
  304|       |    
  305|  3.16k|#line 306 "src/spss/readstat_sav_parse.c"
  306|  3.16k|	{
  307|  3.16k|	cs = sav_long_variable_parse_start;
  308|  3.16k|	}
  309|       |
  310|  3.16k|#line 311 "src/spss/readstat_sav_parse.c"
  311|  3.16k|	{
  312|  3.16k|	int _klen;
  313|  3.16k|	unsigned int _trans;
  314|  3.16k|	const char *_acts;
  315|  3.16k|	unsigned int _nacts;
  316|  3.16k|	const unsigned char *_keys;
  317|       |
  318|  3.16k|	if ( p == pe )
  ------------------
  |  Branch (318:7): [True: 0, False: 3.16k]
  ------------------
  319|      0|		goto _test_eof;
  320|  3.16k|	if ( cs == 0 )
  ------------------
  |  Branch (320:7): [True: 0, False: 3.16k]
  ------------------
  321|      0|		goto _out;
  322|  40.6k|_resume:
  323|  40.6k|	_keys = _sav_long_variable_parse_trans_keys + _sav_long_variable_parse_key_offsets[cs];
  324|  40.6k|	_trans = _sav_long_variable_parse_index_offsets[cs];
  325|       |
  326|  40.6k|	_klen = _sav_long_variable_parse_single_lengths[cs];
  327|  40.6k|	if ( _klen > 0 ) {
  ------------------
  |  Branch (327:7): [True: 40.6k, False: 0]
  ------------------
  328|  40.6k|		const unsigned char *_lower = _keys;
  329|  40.6k|		const unsigned char *_mid;
  330|  40.6k|		const unsigned char *_upper = _keys + _klen - 1;
  331|  95.5k|		while (1) {
  ------------------
  |  Branch (331:10): [True: 95.5k, Folded]
  ------------------
  332|  95.5k|			if ( _upper < _lower )
  ------------------
  |  Branch (332:9): [True: 31.0k, False: 64.4k]
  ------------------
  333|  31.0k|				break;
  334|       |
  335|  64.4k|			_mid = _lower + ((_upper-_lower) >> 1);
  336|  64.4k|			if ( (*p) < *_mid )
  ------------------
  |  Branch (336:9): [True: 34.5k, False: 29.8k]
  ------------------
  337|  34.5k|				_upper = _mid - 1;
  338|  29.8k|			else if ( (*p) > *_mid )
  ------------------
  |  Branch (338:14): [True: 20.3k, False: 9.51k]
  ------------------
  339|  20.3k|				_lower = _mid + 1;
  340|  9.51k|			else {
  341|  9.51k|				_trans += (unsigned int)(_mid - _keys);
  342|  9.51k|				goto _match;
  343|  9.51k|			}
  344|  64.4k|		}
  345|  31.0k|		_keys += _klen;
  346|  31.0k|		_trans += _klen;
  347|  31.0k|	}
  348|       |
  349|  31.0k|	_klen = _sav_long_variable_parse_range_lengths[cs];
  350|  31.0k|	if ( _klen > 0 ) {
  ------------------
  |  Branch (350:7): [True: 31.0k, False: 4]
  ------------------
  351|  31.0k|		const unsigned char *_lower = _keys;
  352|  31.0k|		const unsigned char *_mid;
  353|  31.0k|		const unsigned char *_upper = _keys + (_klen<<1) - 2;
  354|  82.7k|		while (1) {
  ------------------
  |  Branch (354:10): [True: 82.7k, Folded]
  ------------------
  355|  82.7k|			if ( _upper < _lower )
  ------------------
  |  Branch (355:9): [True: 30.9k, False: 51.8k]
  ------------------
  356|  30.9k|				break;
  357|       |
  358|  51.8k|			_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  359|  51.8k|			if ( (*p) < _mid[0] )
  ------------------
  |  Branch (359:9): [True: 11.6k, False: 40.2k]
  ------------------
  360|  11.6k|				_upper = _mid - 2;
  361|  40.2k|			else if ( (*p) > _mid[1] )
  ------------------
  |  Branch (361:14): [True: 40.0k, False: 178]
  ------------------
  362|  40.0k|				_lower = _mid + 2;
  363|    178|			else {
  364|    178|				_trans += (unsigned int)((_mid - _keys)>>1);
  365|    178|				goto _match;
  366|    178|			}
  367|  51.8k|		}
  368|  30.9k|		_trans += _klen;
  369|  30.9k|	}
  370|       |
  371|  40.6k|_match:
  372|  40.6k|	_trans = _sav_long_variable_parse_indicies[_trans];
  373|  40.6k|	cs = _sav_long_variable_parse_trans_targs[_trans];
  374|       |
  375|  40.6k|	if ( _sav_long_variable_parse_trans_actions[_trans] == 0 )
  ------------------
  |  Branch (375:7): [True: 18.9k, False: 21.6k]
  ------------------
  376|  18.9k|		goto _again;
  377|       |
  378|  21.6k|	_acts = _sav_long_variable_parse_actions + _sav_long_variable_parse_trans_actions[_trans];
  379|  21.6k|	_nacts = (unsigned int) *_acts++;
  380|  56.1k|	while ( _nacts-- > 0 )
  ------------------
  |  Branch (380:10): [True: 34.5k, False: 21.6k]
  ------------------
  381|  34.5k|	{
  382|  34.5k|		switch ( *_acts++ )
  ------------------
  |  Branch (382:12): [True: 34.5k, False: 0]
  ------------------
  383|  34.5k|		{
  384|  6.03k|	case 0:
  ------------------
  |  Branch (384:2): [True: 6.03k, False: 28.5k]
  ------------------
  385|  6.03k|#line 13 "src/spss/readstat_sav_parse.rl"
  386|  6.03k|	{
  387|  6.03k|        memcpy(temp_key, str_start, str_len);
  388|  6.03k|        temp_key[str_len] = '\0';
  389|  6.03k|    }
  390|  6.03k|	break;
  391|  6.08k|	case 1:
  ------------------
  |  Branch (391:2): [True: 6.08k, False: 28.4k]
  ------------------
  392|  6.08k|#line 20 "src/spss/readstat_sav_parse.rl"
  393|  6.08k|	{ str_start = p; }
  394|  6.08k|	break;
  395|  6.03k|	case 2:
  ------------------
  |  Branch (395:2): [True: 6.03k, False: 28.5k]
  ------------------
  396|  6.03k|#line 20 "src/spss/readstat_sav_parse.rl"
  397|  6.03k|	{ str_len = p - str_start; }
  398|  6.03k|	break;
  399|  3.47k|	case 3:
  ------------------
  |  Branch (399:2): [True: 3.47k, False: 31.1k]
  ------------------
  400|  3.47k|#line 102 "src/spss/readstat_sav_parse.rl"
  401|  3.47k|	{
  402|  3.47k|            varlookup_t *found = bsearch(temp_key, table, var_count, sizeof(varlookup_t), &compare_key_varlookup);
  403|  3.47k|            if (!found) {
  ------------------
  |  Branch (403:17): [True: 1.72k, False: 1.74k]
  ------------------
  404|  1.72k|                snprintf(error_buf, sizeof(error_buf), "Failed to find %s", temp_key);
  405|  1.72k|                if (ctx->handle.error)
  ------------------
  |  Branch (405:21): [True: 0, False: 1.72k]
  ------------------
  406|      0|                    ctx->handle.error(error_buf, ctx->user_ctx);
  407|  1.74k|            } else {
  408|       |                // Handle the edge case where a ghost variable name (from a multi-segment
  409|       |                // variable) is identical to a real variable name. Normally we handle this
  410|       |                // by incrementing the loop variable by n_segments, but n_segments hasn't
  411|       |                // been set when this record is processed. So just set the longname to every
  412|       |                // matching variable, ghost or real.
  413|  1.74k|                varlookup_t *iter_match = found;
  414|  9.11k|                while (iter_match >= table && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (414:24): [True: 8.42k, False: 690]
  |  Branch (414:47): [True: 7.36k, False: 1.05k]
  ------------------
  415|  7.36k|                    spss_varinfo_t *info = ctx->varinfo[iter_match->index];
  416|  7.36k|                    snprintf(info->longname, sizeof(info->longname), "%*s", (int)str_len, temp_val);
  417|  7.36k|                    iter_match--;
  418|  7.36k|                }
  419|  1.74k|                iter_match = found + 1;
  420|  5.63k|                while (iter_match - table < var_count && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (420:24): [True: 4.62k, False: 1.00k]
  |  Branch (420:58): [True: 3.88k, False: 739]
  ------------------
  421|  3.88k|                    spss_varinfo_t *info = ctx->varinfo[iter_match->index];
  422|  3.88k|                    snprintf(info->longname, sizeof(info->longname), "%*s", (int)str_len, temp_val);
  423|  3.88k|                    iter_match++;
  424|  3.88k|                }
  425|  1.74k|            }
  426|  3.47k|        }
  427|  3.47k|	break;
  428|  3.47k|	case 4:
  ------------------
  |  Branch (428:2): [True: 3.47k, False: 31.1k]
  ------------------
  429|  3.47k|#line 129 "src/spss/readstat_sav_parse.rl"
  430|  3.47k|	{
  431|  3.47k|            memcpy(temp_val, str_start, str_len);
  432|  3.47k|            temp_val[str_len] = '\0';
  433|  3.47k|        }
  434|  3.47k|	break;
  435|  6.01k|	case 5:
  ------------------
  |  Branch (435:2): [True: 6.01k, False: 28.5k]
  ------------------
  436|  6.01k|#line 134 "src/spss/readstat_sav_parse.rl"
  437|  6.01k|	{ str_start = p; }
  438|  6.01k|	break;
  439|  3.47k|	case 6:
  ------------------
  |  Branch (439:2): [True: 3.47k, False: 31.1k]
  ------------------
  440|  3.47k|#line 134 "src/spss/readstat_sav_parse.rl"
  441|  3.47k|	{ str_len = p - str_start; }
  442|  3.47k|	break;
  443|  34.5k|#line 444 "src/spss/readstat_sav_parse.c"
  444|  34.5k|		}
  445|  34.5k|	}
  446|       |
  447|  40.6k|_again:
  448|  40.6k|	if ( cs == 0 )
  ------------------
  |  Branch (448:7): [True: 187, False: 40.4k]
  ------------------
  449|    187|		goto _out;
  450|  40.4k|	if ( ++p != pe )
  ------------------
  |  Branch (450:7): [True: 37.4k, False: 2.97k]
  ------------------
  451|  37.4k|		goto _resume;
  452|  2.97k|	_test_eof: {}
  453|  2.97k|	if ( p == eof )
  ------------------
  |  Branch (453:7): [True: 2.97k, False: 0]
  ------------------
  454|  2.97k|	{
  455|  2.97k|	const char *__acts = _sav_long_variable_parse_actions + _sav_long_variable_parse_eof_actions[cs];
  456|  2.97k|	unsigned int __nacts = (unsigned int) *__acts++;
  457|  10.5k|	while ( __nacts-- > 0 ) {
  ------------------
  |  Branch (457:10): [True: 7.59k, False: 2.97k]
  ------------------
  458|  7.59k|		switch ( *__acts++ ) {
  ------------------
  |  Branch (458:12): [True: 7.59k, False: 0]
  ------------------
  459|  2.53k|	case 3:
  ------------------
  |  Branch (459:2): [True: 2.53k, False: 5.06k]
  ------------------
  460|  2.53k|#line 102 "src/spss/readstat_sav_parse.rl"
  461|  2.53k|	{
  462|  2.53k|            varlookup_t *found = bsearch(temp_key, table, var_count, sizeof(varlookup_t), &compare_key_varlookup);
  463|  2.53k|            if (!found) {
  ------------------
  |  Branch (463:17): [True: 1.53k, False: 997]
  ------------------
  464|  1.53k|                snprintf(error_buf, sizeof(error_buf), "Failed to find %s", temp_key);
  465|  1.53k|                if (ctx->handle.error)
  ------------------
  |  Branch (465:21): [True: 0, False: 1.53k]
  ------------------
  466|      0|                    ctx->handle.error(error_buf, ctx->user_ctx);
  467|  1.53k|            } else {
  468|       |                // Handle the edge case where a ghost variable name (from a multi-segment
  469|       |                // variable) is identical to a real variable name. Normally we handle this
  470|       |                // by incrementing the loop variable by n_segments, but n_segments hasn't
  471|       |                // been set when this record is processed. So just set the longname to every
  472|       |                // matching variable, ghost or real.
  473|    997|                varlookup_t *iter_match = found;
  474|  2.48k|                while (iter_match >= table && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (474:24): [True: 2.15k, False: 326]
  |  Branch (474:47): [True: 1.48k, False: 671]
  ------------------
  475|  1.48k|                    spss_varinfo_t *info = ctx->varinfo[iter_match->index];
  476|  1.48k|                    snprintf(info->longname, sizeof(info->longname), "%*s", (int)str_len, temp_val);
  477|  1.48k|                    iter_match--;
  478|  1.48k|                }
  479|    997|                iter_match = found + 1;
  480|  1.76k|                while (iter_match - table < var_count && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (480:24): [True: 1.22k, False: 539]
  |  Branch (480:58): [True: 763, False: 458]
  ------------------
  481|    763|                    spss_varinfo_t *info = ctx->varinfo[iter_match->index];
  482|    763|                    snprintf(info->longname, sizeof(info->longname), "%*s", (int)str_len, temp_val);
  483|    763|                    iter_match++;
  484|    763|                }
  485|    997|            }
  486|  2.53k|        }
  487|  2.53k|	break;
  488|  2.53k|	case 4:
  ------------------
  |  Branch (488:2): [True: 2.53k, False: 5.06k]
  ------------------
  489|  2.53k|#line 129 "src/spss/readstat_sav_parse.rl"
  490|  2.53k|	{
  491|  2.53k|            memcpy(temp_val, str_start, str_len);
  492|  2.53k|            temp_val[str_len] = '\0';
  493|  2.53k|        }
  494|  2.53k|	break;
  495|  2.53k|	case 6:
  ------------------
  |  Branch (495:2): [True: 2.53k, False: 5.06k]
  ------------------
  496|  2.53k|#line 134 "src/spss/readstat_sav_parse.rl"
  497|  2.53k|	{ str_len = p - str_start; }
  498|  2.53k|	break;
  499|  7.59k|#line 500 "src/spss/readstat_sav_parse.c"
  500|  7.59k|		}
  501|  7.59k|	}
  502|  2.97k|	}
  503|       |
  504|  3.16k|	_out: {}
  505|  3.16k|	}
  506|       |
  507|      0|#line 142 "src/spss/readstat_sav_parse.rl"
  508|       |
  509|       |
  510|  3.16k|    if (cs < 11|| p != pe) {
  ------------------
  |  Branch (510:9): [True: 224, False: 2.93k]
  |  Branch (510:19): [True: 0, False: 2.93k]
  ------------------
  511|    224|        if (ctx->handle.error) {
  ------------------
  |  Branch (511:13): [True: 0, False: 224]
  ------------------
  512|      0|            snprintf(error_buf, sizeof(error_buf), "Error parsing string \"%.*s\" around byte #%ld/%d, character %c", 
  513|      0|                    count, (char *)data, (long)(p - c_data), count, *p);
  514|      0|            ctx->handle.error(error_buf, ctx->user_ctx);
  515|      0|        }
  516|    224|        retval = READSTAT_ERROR_PARSE;
  517|    224|    }
  518|       |    
  519|       |
  520|  3.16k|    if (table)
  ------------------
  |  Branch (520:9): [True: 2.60k, False: 558]
  ------------------
  521|  2.60k|        free(table);
  522|       |
  523|       |    /* suppress warning */
  524|  3.16k|    (void)sav_long_variable_parse_en_main;
  525|       |
  526|  3.16k|    return retval;
  527|  2.97k|}
sav_parse_very_long_string_record:
  612|  4.00k|readstat_error_t sav_parse_very_long_string_record(void *data, int count, sav_ctx_t *ctx) {
  613|  4.00k|    unsigned char *c_data = (unsigned char *)data;
  614|  4.00k|    int var_count = count_vars(ctx);
  615|  4.00k|    readstat_error_t retval = READSTAT_OK;
  616|       |
  617|  4.00k|    char temp_key[8*4+1];
  618|  4.00k|    unsigned int temp_val = 0;
  619|  4.00k|    unsigned char *str_start = NULL;
  620|  4.00k|    size_t str_len = 0;
  621|       |
  622|  4.00k|    size_t error_buf_len = 1024 + count;
  623|  4.00k|    char *error_buf = NULL;
  624|  4.00k|    unsigned char *p = c_data;
  625|  4.00k|    unsigned char *pe = c_data + count;
  626|  4.00k|    unsigned char *eof = pe;
  627|       |
  628|  4.00k|    varlookup_t *table = NULL;
  629|  4.00k|    int cs;
  630|       |
  631|  4.00k|    error_buf = readstat_malloc(error_buf_len);
  632|  4.00k|    table = build_lookup_table(var_count, ctx);
  633|       |    
  634|       |    
  635|  4.00k|#line 636 "src/spss/readstat_sav_parse.c"
  636|  4.00k|	{
  637|  4.00k|	cs = sav_very_long_string_parse_start;
  638|  4.00k|	}
  639|       |
  640|  4.00k|#line 641 "src/spss/readstat_sav_parse.c"
  641|  4.00k|	{
  642|  4.00k|	int _klen;
  643|  4.00k|	unsigned int _trans;
  644|  4.00k|	const char *_acts;
  645|  4.00k|	unsigned int _nacts;
  646|  4.00k|	const unsigned char *_keys;
  647|       |
  648|  4.00k|	if ( p == pe )
  ------------------
  |  Branch (648:7): [True: 0, False: 4.00k]
  ------------------
  649|      0|		goto _test_eof;
  650|  4.00k|	if ( cs == 0 )
  ------------------
  |  Branch (650:7): [True: 0, False: 4.00k]
  ------------------
  651|      0|		goto _out;
  652|  38.1k|_resume:
  653|  38.1k|	_keys = _sav_very_long_string_parse_trans_keys + _sav_very_long_string_parse_key_offsets[cs];
  654|  38.1k|	_trans = _sav_very_long_string_parse_index_offsets[cs];
  655|       |
  656|  38.1k|	_klen = _sav_very_long_string_parse_single_lengths[cs];
  657|  38.1k|	if ( _klen > 0 ) {
  ------------------
  |  Branch (657:7): [True: 32.2k, False: 5.95k]
  ------------------
  658|  32.2k|		const unsigned char *_lower = _keys;
  659|  32.2k|		const unsigned char *_mid;
  660|  32.2k|		const unsigned char *_upper = _keys + _klen - 1;
  661|  74.7k|		while (1) {
  ------------------
  |  Branch (661:10): [True: 74.7k, Folded]
  ------------------
  662|  74.7k|			if ( _upper < _lower )
  ------------------
  |  Branch (662:9): [True: 21.8k, False: 52.8k]
  ------------------
  663|  21.8k|				break;
  664|       |
  665|  52.8k|			_mid = _lower + ((_upper-_lower) >> 1);
  666|  52.8k|			if ( (*p) < *_mid )
  ------------------
  |  Branch (666:9): [True: 15.0k, False: 37.8k]
  ------------------
  667|  15.0k|				_upper = _mid - 1;
  668|  37.8k|			else if ( (*p) > *_mid )
  ------------------
  |  Branch (668:14): [True: 27.4k, False: 10.3k]
  ------------------
  669|  27.4k|				_lower = _mid + 1;
  670|  10.3k|			else {
  671|  10.3k|				_trans += (unsigned int)(_mid - _keys);
  672|  10.3k|				goto _match;
  673|  10.3k|			}
  674|  52.8k|		}
  675|  21.8k|		_keys += _klen;
  676|  21.8k|		_trans += _klen;
  677|  21.8k|	}
  678|       |
  679|  27.8k|	_klen = _sav_very_long_string_parse_range_lengths[cs];
  680|  27.8k|	if ( _klen > 0 ) {
  ------------------
  |  Branch (680:7): [True: 27.7k, False: 57]
  ------------------
  681|  27.7k|		const unsigned char *_lower = _keys;
  682|  27.7k|		const unsigned char *_mid;
  683|  27.7k|		const unsigned char *_upper = _keys + (_klen<<1) - 2;
  684|  63.1k|		while (1) {
  ------------------
  |  Branch (684:10): [True: 63.1k, Folded]
  ------------------
  685|  63.1k|			if ( _upper < _lower )
  ------------------
  |  Branch (685:9): [True: 14.8k, False: 48.2k]
  ------------------
  686|  14.8k|				break;
  687|       |
  688|  48.2k|			_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  689|  48.2k|			if ( (*p) < _mid[0] )
  ------------------
  |  Branch (689:9): [True: 10.5k, False: 37.6k]
  ------------------
  690|  10.5k|				_upper = _mid - 2;
  691|  37.6k|			else if ( (*p) > _mid[1] )
  ------------------
  |  Branch (691:14): [True: 24.8k, False: 12.8k]
  ------------------
  692|  24.8k|				_lower = _mid + 2;
  693|  12.8k|			else {
  694|  12.8k|				_trans += (unsigned int)((_mid - _keys)>>1);
  695|  12.8k|				goto _match;
  696|  12.8k|			}
  697|  48.2k|		}
  698|  14.8k|		_trans += _klen;
  699|  14.8k|	}
  700|       |
  701|  38.1k|_match:
  702|  38.1k|	_trans = _sav_very_long_string_parse_indicies[_trans];
  703|  38.1k|	cs = _sav_very_long_string_parse_trans_targs[_trans];
  704|       |
  705|  38.1k|	if ( _sav_very_long_string_parse_trans_actions[_trans] == 0 )
  ------------------
  |  Branch (705:7): [True: 10.3k, False: 27.8k]
  ------------------
  706|  10.3k|		goto _again;
  707|       |
  708|  27.8k|	_acts = _sav_very_long_string_parse_actions + _sav_very_long_string_parse_trans_actions[_trans];
  709|  27.8k|	_nacts = (unsigned int) *_acts++;
  710|  67.3k|	while ( _nacts-- > 0 )
  ------------------
  |  Branch (710:10): [True: 39.7k, False: 27.6k]
  ------------------
  711|  39.7k|	{
  712|  39.7k|		switch ( *_acts++ )
  ------------------
  |  Branch (712:12): [True: 39.7k, False: 0]
  ------------------
  713|  39.7k|		{
  714|  5.95k|	case 0:
  ------------------
  |  Branch (714:2): [True: 5.95k, False: 33.7k]
  ------------------
  715|  5.95k|#line 13 "src/spss/readstat_sav_parse.rl"
  716|  5.95k|	{
  717|  5.95k|        memcpy(temp_key, str_start, str_len);
  718|  5.95k|        temp_key[str_len] = '\0';
  719|  5.95k|    }
  720|  5.95k|	break;
  721|  6.04k|	case 1:
  ------------------
  |  Branch (721:2): [True: 6.04k, False: 33.6k]
  ------------------
  722|  6.04k|#line 20 "src/spss/readstat_sav_parse.rl"
  723|  6.04k|	{ str_start = p; }
  724|  6.04k|	break;
  725|  5.95k|	case 2:
  ------------------
  |  Branch (725:2): [True: 5.95k, False: 33.7k]
  ------------------
  726|  5.95k|#line 20 "src/spss/readstat_sav_parse.rl"
  727|  5.95k|	{ str_len = p - str_start; }
  728|  5.95k|	break;
  729|  3.06k|	case 3:
  ------------------
  |  Branch (729:2): [True: 3.06k, False: 36.6k]
  ------------------
  730|  3.06k|#line 193 "src/spss/readstat_sav_parse.rl"
  731|  3.06k|	{
  732|  3.06k|            varlookup_t *found = bsearch(temp_key, table, var_count, sizeof(varlookup_t), &compare_key_varlookup);
  733|  3.06k|            if (found) {
  ------------------
  |  Branch (733:17): [True: 1.54k, False: 1.51k]
  ------------------
  734|       |                // See logic above; we need to apply this to all matching variables since ghost variable
  735|       |                // names may conflict with real variable names.
  736|  1.54k|                varlookup_t *first_match = found, *last_match = found;
  737|  1.54k|                varlookup_t *iter_match = found - 1;
  738|  4.87k|                while (iter_match >= table && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (738:24): [True: 4.27k, False: 602]
  |  Branch (738:47): [True: 3.33k, False: 944]
  ------------------
  739|  3.33k|                    first_match = iter_match;
  740|  3.33k|                    iter_match--;
  741|  3.33k|                }
  742|  1.54k|                iter_match = found + 1;
  743|  5.29k|                while (iter_match - table < var_count && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (743:24): [True: 4.48k, False: 815]
  |  Branch (743:58): [True: 3.75k, False: 731]
  ------------------
  744|  3.75k|                    last_match = iter_match;
  745|  3.75k|                    iter_match++;
  746|  3.75k|                }
  747|  10.1k|                for (iter_match=first_match; iter_match<=last_match; iter_match++) {
  ------------------
  |  Branch (747:46): [True: 8.62k, False: 1.54k]
  ------------------
  748|  8.62k|                    ctx->varinfo[iter_match->index]->string_length = temp_val;
  749|  8.62k|                    ctx->varinfo[iter_match->index]->write_format.width = temp_val;
  750|  8.62k|                    ctx->varinfo[iter_match->index]->print_format.width = temp_val;
  751|  8.62k|                }
  752|  1.54k|            }
  753|  3.06k|        }
  754|  3.06k|	break;
  755|  12.7k|	case 4:
  ------------------
  |  Branch (755:2): [True: 12.7k, False: 26.9k]
  ------------------
  756|  12.7k|#line 217 "src/spss/readstat_sav_parse.rl"
  757|  12.7k|	{
  758|  12.7k|            if ((*p) != '\0') {
  ------------------
  |  Branch (758:17): [True: 12.7k, False: 0]
  ------------------
  759|  12.7k|                unsigned char digit = (*p) - '0';
  760|  12.7k|                if (temp_val <= (UINT_MAX - digit) / 10) {
  ------------------
  |  Branch (760:21): [True: 12.5k, False: 216]
  ------------------
  761|  12.5k|                    temp_val = 10 * temp_val + digit;
  762|  12.5k|                } else {
  763|    216|                    {p++; goto _out; }
  764|    216|                }
  765|  12.7k|            }
  766|  12.7k|        }
  767|  12.5k|	break;
  768|  12.5k|	case 5:
  ------------------
  |  Branch (768:2): [True: 5.94k, False: 33.7k]
  ------------------
  769|  5.94k|#line 228 "src/spss/readstat_sav_parse.rl"
  770|  5.94k|	{ temp_val = 0; }
  771|  5.94k|	break;
  772|  39.7k|#line 773 "src/spss/readstat_sav_parse.c"
  773|  39.7k|		}
  774|  39.7k|	}
  775|       |
  776|  37.9k|_again:
  777|  37.9k|	if ( cs == 0 )
  ------------------
  |  Branch (777:7): [True: 161, False: 37.8k]
  ------------------
  778|    161|		goto _out;
  779|  37.8k|	if ( ++p != pe )
  ------------------
  |  Branch (779:7): [True: 34.1k, False: 3.63k]
  ------------------
  780|  34.1k|		goto _resume;
  781|  3.63k|	_test_eof: {}
  782|  3.63k|	if ( p == eof )
  ------------------
  |  Branch (782:7): [True: 3.63k, False: 0]
  ------------------
  783|  3.63k|	{
  784|  3.63k|	const char *__acts = _sav_very_long_string_parse_actions + _sav_very_long_string_parse_eof_actions[cs];
  785|  3.63k|	unsigned int __nacts = (unsigned int) *__acts++;
  786|  6.28k|	while ( __nacts-- > 0 ) {
  ------------------
  |  Branch (786:10): [True: 2.65k, False: 3.63k]
  ------------------
  787|  2.65k|		switch ( *__acts++ ) {
  ------------------
  |  Branch (787:12): [True: 2.65k, False: 0]
  ------------------
  788|  2.65k|	case 3:
  ------------------
  |  Branch (788:2): [True: 2.65k, False: 0]
  ------------------
  789|  2.65k|#line 193 "src/spss/readstat_sav_parse.rl"
  790|  2.65k|	{
  791|  2.65k|            varlookup_t *found = bsearch(temp_key, table, var_count, sizeof(varlookup_t), &compare_key_varlookup);
  792|  2.65k|            if (found) {
  ------------------
  |  Branch (792:17): [True: 1.31k, False: 1.33k]
  ------------------
  793|       |                // See logic above; we need to apply this to all matching variables since ghost variable
  794|       |                // names may conflict with real variable names.
  795|  1.31k|                varlookup_t *first_match = found, *last_match = found;
  796|  1.31k|                varlookup_t *iter_match = found - 1;
  797|  4.59k|                while (iter_match >= table && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (797:24): [True: 4.10k, False: 486]
  |  Branch (797:47): [True: 3.27k, False: 832]
  ------------------
  798|  3.27k|                    first_match = iter_match;
  799|  3.27k|                    iter_match--;
  800|  3.27k|                }
  801|  1.31k|                iter_match = found + 1;
  802|  3.66k|                while (iter_match - table < var_count && strcmp(iter_match->name, temp_key) == 0) {
  ------------------
  |  Branch (802:24): [True: 3.19k, False: 470]
  |  Branch (802:58): [True: 2.34k, False: 848]
  ------------------
  803|  2.34k|                    last_match = iter_match;
  804|  2.34k|                    iter_match++;
  805|  2.34k|                }
  806|  8.26k|                for (iter_match=first_match; iter_match<=last_match; iter_match++) {
  ------------------
  |  Branch (806:46): [True: 6.94k, False: 1.31k]
  ------------------
  807|  6.94k|                    ctx->varinfo[iter_match->index]->string_length = temp_val;
  808|  6.94k|                    ctx->varinfo[iter_match->index]->write_format.width = temp_val;
  809|  6.94k|                    ctx->varinfo[iter_match->index]->print_format.width = temp_val;
  810|  6.94k|                }
  811|  1.31k|            }
  812|  2.65k|        }
  813|  2.65k|	break;
  814|  2.65k|#line 815 "src/spss/readstat_sav_parse.c"
  815|  2.65k|		}
  816|  2.65k|	}
  817|  3.63k|	}
  818|       |
  819|  4.00k|	_out: {}
  820|  4.00k|	}
  821|       |
  822|      0|#line 236 "src/spss/readstat_sav_parse.rl"
  823|       |
  824|       |    
  825|  4.00k|    if (cs < 11 || p != pe) {
  ------------------
  |  Branch (825:9): [True: 229, False: 3.77k]
  |  Branch (825:20): [True: 1, False: 3.77k]
  ------------------
  826|    230|        if (ctx->handle.error) {
  ------------------
  |  Branch (826:13): [True: 0, False: 230]
  ------------------
  827|      0|            snprintf(error_buf, error_buf_len, "Parsed %ld of %ld bytes. Remaining bytes: %.*s",
  828|      0|                    (long)(p - c_data), (long)(pe - c_data), (int)(pe - p), p);
  829|      0|            ctx->handle.error(error_buf, ctx->user_ctx);
  830|      0|        }
  831|    230|        retval = READSTAT_ERROR_PARSE;
  832|    230|    }
  833|       |    
  834|  4.00k|    if (table)
  ------------------
  |  Branch (834:9): [True: 3.36k, False: 640]
  ------------------
  835|  3.36k|        free(table);
  836|  4.00k|    if (error_buf)
  ------------------
  |  Branch (836:9): [True: 4.00k, False: 0]
  ------------------
  837|  4.00k|        free(error_buf);
  838|       |
  839|       |    /* suppress warning */
  840|  4.00k|    (void)sav_very_long_string_parse_en_main;
  841|       |
  842|  4.00k|    return retval;
  843|  3.63k|}
readstat_sav_parse.c:count_vars:
   33|  7.17k|static int count_vars(sav_ctx_t *ctx) {
   34|  7.17k|    int i;
   35|  7.17k|    spss_varinfo_t *last_info = NULL;
   36|  7.17k|    int var_count = 0;
   37|   796k|    for (i=0; i<ctx->var_index; i++) {
  ------------------
  |  Branch (37:15): [True: 789k, False: 7.17k]
  ------------------
   38|   789k|        spss_varinfo_t *info = ctx->varinfo[i];
   39|   789k|        if (last_info == NULL || strcmp(info->name, last_info->name) != 0) {
  ------------------
  |  Branch (39:13): [True: 5.97k, False: 783k]
  |  Branch (39:34): [True: 693k, False: 89.7k]
  ------------------
   40|   699k|            var_count++;
   41|   699k|        }
   42|   789k|        last_info = info;
   43|   789k|    }
   44|  7.17k|    return var_count;
   45|  7.17k|}
readstat_sav_parse.c:build_lookup_table:
   47|  7.17k|static varlookup_t *build_lookup_table(int var_count, sav_ctx_t *ctx) {
   48|  7.17k|    varlookup_t *table = readstat_malloc(var_count * sizeof(varlookup_t));
   49|  7.17k|    int offset = 0;
   50|  7.17k|    int i;
   51|  7.17k|    spss_varinfo_t *last_info = NULL;
   52|   796k|    for (i=0; i<ctx->var_index; i++) {
  ------------------
  |  Branch (52:15): [True: 789k, False: 7.17k]
  ------------------
   53|   789k|        spss_varinfo_t *info = ctx->varinfo[i];
   54|       |
   55|   789k|        if (last_info == NULL || strcmp(info->name, last_info->name) != 0) {
  ------------------
  |  Branch (55:13): [True: 5.97k, False: 783k]
  |  Branch (55:34): [True: 693k, False: 89.7k]
  ------------------
   56|   699k|            varlookup_t *entry = &table[offset++];
   57|       |
   58|   699k|            memcpy(entry->name, info->name, sizeof(info->name));
   59|   699k|            entry->index = info->index;
   60|   699k|        }
   61|   789k|        last_info = info;
   62|   789k|    }
   63|  7.17k|    qsort(table, var_count, sizeof(varlookup_t), &compare_varlookups);
   64|  7.17k|    return table;
   65|  7.17k|}
readstat_sav_parse.c:compare_varlookups:
   27|  5.84M|static int compare_varlookups(const void *elem1, const void *elem2) {
   28|  5.84M|    const varlookup_t *v1 = (const varlookup_t *)elem1;
   29|  5.84M|    const varlookup_t *v2 = (const varlookup_t *)elem2;
   30|  5.84M|    return strcasecmp(v1->name, v2->name);
   31|  5.84M|}
readstat_sav_parse.c:compare_key_varlookup:
   21|  24.1k|static int compare_key_varlookup(const void *elem1, const void *elem2) {
   22|  24.1k|    const char *key = (const char *)elem1;
   23|  24.1k|    const varlookup_t *v = (const varlookup_t *)elem2;
   24|  24.1k|    return strcasecmp(key, v->name);
   25|  24.1k|}

extract_mr_data:
   76|    672|readstat_error_t extract_mr_data(const char *line, mr_set_t *result, sav_ctx_t *ctx) {
   77|    672|    readstat_error_t retval = READSTAT_OK;
   78|       |
   79|       |    // Variables needed for Ragel operation
   80|    672|    int cs = 0;
   81|    672|    char *p = (char *)line;
   82|    672|    char *start = p;
   83|    672|    char *pe = p + strlen(p) + 1;
   84|       |
   85|       |    // Variables needed for passing Ragel intermediate results
   86|    672|    char mr_type = '\0';
   87|    672|    int mr_counted_value = -1;
   88|    672|    int mr_subvar_count = 0;
   89|    672|    char **mr_subvariables = NULL;
   90|    672|    char *mr_name = NULL;
   91|    672|    char *mr_label = NULL;
   92|       |
   93|       |    // Execute Ragel finite state machine (FSM)
   94|       |    
   95|    672|#line 89 "src/spss/readstat_sav_parse_mr_name.c"
   96|    672|	{
   97|    672|	cs = mr_extractor_start;
   98|    672|	}
   99|       |
  100|    672|#line 142 "src/spss/readstat_sav_parse_mr_name.rl"
  101|       |    
  102|    672|#line 92 "src/spss/readstat_sav_parse_mr_name.c"
  103|    672|	{
  104|    672|	int _klen;
  105|    672|	unsigned int _trans;
  106|    672|	const char *_acts;
  107|    672|	unsigned int _nacts;
  108|    672|	const char *_keys;
  109|       |
  110|    672|	if ( p == pe )
  ------------------
  |  Branch (110:7): [True: 0, False: 672]
  ------------------
  111|      0|		goto _test_eof;
  112|    672|	if ( cs == 0 )
  ------------------
  |  Branch (112:7): [True: 0, False: 672]
  ------------------
  113|      0|		goto _out;
  114|  24.3k|_resume:
  115|  24.3k|	_keys = _mr_extractor_trans_keys + _mr_extractor_key_offsets[cs];
  116|  24.3k|	_trans = _mr_extractor_index_offsets[cs];
  117|       |
  118|  24.3k|	_klen = _mr_extractor_single_lengths[cs];
  119|  24.3k|	if ( _klen > 0 ) {
  ------------------
  |  Branch (119:7): [True: 23.1k, False: 1.23k]
  ------------------
  120|  23.1k|		const char *_lower = _keys;
  121|  23.1k|		const char *_mid;
  122|  23.1k|		const char *_upper = _keys + _klen - 1;
  123|  62.3k|		while (1) {
  ------------------
  |  Branch (123:10): [True: 62.3k, Folded]
  ------------------
  124|  62.3k|			if ( _upper < _lower )
  ------------------
  |  Branch (124:9): [True: 19.6k, False: 42.7k]
  ------------------
  125|  19.6k|				break;
  126|       |
  127|  42.7k|			_mid = _lower + ((_upper-_lower) >> 1);
  128|  42.7k|			if ( (*p) < *_mid )
  ------------------
  |  Branch (128:9): [True: 11.1k, False: 31.5k]
  ------------------
  129|  11.1k|				_upper = _mid - 1;
  130|  31.5k|			else if ( (*p) > *_mid )
  ------------------
  |  Branch (130:14): [True: 28.1k, False: 3.47k]
  ------------------
  131|  28.1k|				_lower = _mid + 1;
  132|  3.47k|			else {
  133|  3.47k|				_trans += (unsigned int)(_mid - _keys);
  134|  3.47k|				goto _match;
  135|  3.47k|			}
  136|  42.7k|		}
  137|  19.6k|		_keys += _klen;
  138|  19.6k|		_trans += _klen;
  139|  19.6k|	}
  140|       |
  141|  20.8k|	_klen = _mr_extractor_range_lengths[cs];
  142|  20.8k|	if ( _klen > 0 ) {
  ------------------
  |  Branch (142:7): [True: 17.6k, False: 3.21k]
  ------------------
  143|  17.6k|		const char *_lower = _keys;
  144|  17.6k|		const char *_mid;
  145|  17.6k|		const char *_upper = _keys + (_klen<<1) - 2;
  146|  30.4k|		while (1) {
  ------------------
  |  Branch (146:10): [True: 30.4k, Folded]
  ------------------
  147|  30.4k|			if ( _upper < _lower )
  ------------------
  |  Branch (147:9): [True: 12.7k, False: 17.6k]
  ------------------
  148|  12.7k|				break;
  149|       |
  150|  17.6k|			_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  151|  17.6k|			if ( (*p) < _mid[0] )
  ------------------
  |  Branch (151:9): [True: 2.99k, False: 14.6k]
  ------------------
  152|  2.99k|				_upper = _mid - 2;
  153|  14.6k|			else if ( (*p) > _mid[1] )
  ------------------
  |  Branch (153:14): [True: 9.80k, False: 4.86k]
  ------------------
  154|  9.80k|				_lower = _mid + 2;
  155|  4.86k|			else {
  156|  4.86k|				_trans += (unsigned int)((_mid - _keys)>>1);
  157|  4.86k|				goto _match;
  158|  4.86k|			}
  159|  17.6k|		}
  160|  12.7k|		_trans += _klen;
  161|  12.7k|	}
  162|       |
  163|  24.3k|_match:
  164|  24.3k|	_trans = _mr_extractor_indicies[_trans];
  165|  24.3k|	cs = _mr_extractor_trans_targs[_trans];
  166|       |
  167|  24.3k|	if ( _mr_extractor_trans_actions[_trans] == 0 )
  ------------------
  |  Branch (167:7): [True: 17.2k, False: 7.06k]
  ------------------
  168|  17.2k|		goto _again;
  169|       |
  170|  7.06k|	_acts = _mr_extractor_actions + _mr_extractor_trans_actions[_trans];
  171|  7.06k|	_nacts = (unsigned int) *_acts++;
  172|  14.0k|	while ( _nacts-- > 0 )
  ------------------
  |  Branch (172:10): [True: 7.06k, False: 7.02k]
  ------------------
  173|  7.06k|	{
  174|  7.06k|		switch ( *_acts++ )
  ------------------
  |  Branch (174:12): [True: 7.06k, False: 0]
  ------------------
  175|  7.06k|		{
  176|    640|	case 0:
  ------------------
  |  Branch (176:2): [True: 640, False: 6.42k]
  ------------------
  177|    640|#line 13 "src/spss/readstat_sav_parse_mr_name.rl"
  178|    640|	{
  179|    640|        size_t src_len = p - start;
  180|    640|        size_t dst_len = 4 * src_len + 1;  // UTF-8 expansion: up to 4 bytes per char
  181|    640|        mr_name = (char *)readstat_malloc(dst_len);
  182|    640|        if (mr_name == NULL) {
  ------------------
  |  Branch (182:13): [True: 0, False: 640]
  ------------------
  183|      0|            retval = READSTAT_ERROR_MALLOC;
  184|      0|            goto cleanup;
  185|      0|        }
  186|    640|        retval = readstat_convert(mr_name, dst_len, start, src_len, ctx->converter);
  187|    640|        if (retval != READSTAT_OK) {
  ------------------
  |  Branch (187:13): [True: 1, False: 639]
  ------------------
  188|      1|            goto cleanup;
  189|      1|        }
  190|    640|    }
  191|    639|	break;
  192|    639|	case 1:
  ------------------
  |  Branch (192:2): [True: 632, False: 6.43k]
  ------------------
  193|    632|#line 27 "src/spss/readstat_sav_parse_mr_name.rl"
  194|    632|	{
  195|    632|        mr_type = *p;
  196|    632|        start = p + 1;
  197|    632|    }
  198|    632|	break;
  199|    626|	case 2:
  ------------------
  |  Branch (199:2): [True: 626, False: 6.43k]
  ------------------
  200|    626|#line 32 "src/spss/readstat_sav_parse_mr_name.rl"
  201|    626|	{
  202|    626|        int n_cv_digs = p - start;
  203|    626|        char *n_dig_str = (char *)readstat_malloc(n_cv_digs + 1);
  204|    626|        if (n_dig_str == NULL) {
  ------------------
  |  Branch (204:13): [True: 0, False: 626]
  ------------------
  205|      0|            retval = READSTAT_ERROR_MALLOC;
  206|      0|            goto cleanup;
  207|      0|        }
  208|    626|        memcpy(n_dig_str, start, n_cv_digs);
  209|    626|        n_dig_str[n_cv_digs] = '\0';
  210|    626|        int n_digs = strtol(n_dig_str, NULL, 10);
  211|    626|        free(n_dig_str);
  212|    626|        if (n_digs != 0) {
  ------------------
  |  Branch (212:13): [True: 70, False: 556]
  ------------------
  213|     70|            char *cv = (char *)readstat_malloc(n_digs + 1);
  214|     70|            if (cv == NULL) {
  ------------------
  |  Branch (214:17): [True: 26, False: 44]
  ------------------
  215|     26|                retval = READSTAT_ERROR_MALLOC;
  216|     26|                goto cleanup;
  217|     26|            }
  218|     44|            memcpy(cv, p + 1, n_digs);
  219|     44|            cv[n_digs] = '\0';
  220|     44|            mr_counted_value = strtol(cv, NULL, 10);
  221|     44|            free(cv);
  222|     44|            p = p + 1 + n_digs;
  223|     44|            start = p + 1;
  224|     44|        }
  225|    556|        else {
  226|    556|            mr_counted_value = -1;
  227|    556|        }
  228|    626|    }
  229|    600|	break;
  230|    600|	case 3:
  ------------------
  |  Branch (230:2): [True: 586, False: 6.47k]
  ------------------
  231|    586|#line 61 "src/spss/readstat_sav_parse_mr_name.rl"
  232|    586|	{
  233|    586|        char *lbl_len_str = (char *)readstat_malloc(p - start + 1);
  234|    586|        if (lbl_len_str == NULL) {
  ------------------
  |  Branch (234:13): [True: 0, False: 586]
  ------------------
  235|      0|            retval = READSTAT_ERROR_MALLOC;
  236|      0|            goto cleanup;
  237|      0|        }
  238|    586|        memcpy(lbl_len_str, start, p - start);
  239|    586|        lbl_len_str[p - start] = '\0';
  240|    586|        int len = strtol(lbl_len_str, NULL, 10);
  241|    586|        free(lbl_len_str);
  242|    586|        size_t dst_len = 4 * len + 1;  // UTF-8 expansion: up to 4 bytes per char
  243|    586|        mr_label = (char *)readstat_malloc(dst_len);
  244|    586|        if (mr_label == NULL) {
  ------------------
  |  Branch (244:13): [True: 6, False: 580]
  ------------------
  245|      6|            retval = READSTAT_ERROR_MALLOC;
  246|      6|            goto cleanup;
  247|      6|        }
  248|    580|        retval = readstat_convert(mr_label, dst_len, p + 1, len, ctx->converter);
  249|    580|        if (retval != READSTAT_OK) {
  ------------------
  |  Branch (249:13): [True: 1, False: 579]
  ------------------
  250|      1|            goto cleanup;
  251|      1|        }
  252|    579|        p = p + 1 + len;
  253|    579|        start = p + 1;
  254|    579|    }
  255|      0|	break;
  256|  4.57k|	case 4:
  ------------------
  |  Branch (256:2): [True: 4.57k, False: 2.48k]
  ------------------
  257|  4.57k|#line 85 "src/spss/readstat_sav_parse_mr_name.rl"
  258|  4.57k|	{
  259|  4.57k|        size_t src_len = p - start;
  260|  4.57k|        size_t dst_len = 4 * src_len + 1;  // UTF-8 expansion: up to 4 bytes per char
  261|  4.57k|        char *subvar = (char *)readstat_malloc(dst_len);
  262|  4.57k|        if (subvar == NULL) {
  ------------------
  |  Branch (262:13): [True: 0, False: 4.57k]
  ------------------
  263|      0|            retval = READSTAT_ERROR_MALLOC;
  264|      0|            goto cleanup;
  265|      0|        }
  266|  4.57k|        retval = readstat_convert(subvar, dst_len, start, src_len, ctx->converter);
  267|  4.57k|        if (retval != READSTAT_OK) {
  ------------------
  |  Branch (267:13): [True: 1, False: 4.57k]
  ------------------
  268|      1|            free(subvar);
  269|      1|            goto cleanup;
  270|      1|        }
  271|  4.57k|        start = p + 1;
  272|  4.57k|        char **new_subvariables = readstat_realloc(mr_subvariables, sizeof(char *) * (mr_subvar_count + 1));
  273|  4.57k|        if (new_subvariables == NULL) {
  ------------------
  |  Branch (273:13): [True: 0, False: 4.57k]
  ------------------
  274|      0|            free(subvar);
  275|      0|            retval = READSTAT_ERROR_MALLOC;
  276|      0|            goto cleanup;
  277|      0|        }
  278|  4.57k|        mr_subvariables = new_subvariables;
  279|  4.57k|        mr_subvariables[mr_subvar_count++] = subvar;
  280|  4.57k|    }
  281|      0|	break;
  282|  7.06k|#line 266 "src/spss/readstat_sav_parse_mr_name.c"
  283|  7.06k|		}
  284|  7.06k|	}
  285|       |
  286|  24.3k|_again:
  287|  24.3k|	if ( cs == 0 )
  ------------------
  |  Branch (287:7): [True: 48, False: 24.2k]
  ------------------
  288|     48|		goto _out;
  289|  24.2k|	if ( ++p != pe )
  ------------------
  |  Branch (289:7): [True: 23.6k, False: 589]
  ------------------
  290|  23.6k|		goto _resume;
  291|    589|	_test_eof: {}
  292|    637|	_out: {}
  293|    637|	}
  294|       |
  295|      0|#line 143 "src/spss/readstat_sav_parse_mr_name.rl"
  296|       |
  297|       |    // Check if FSM finished successfully
  298|    637|    if (cs < 8 || p != pe) {
  ------------------
  |  Branch (298:9): [True: 79, False: 558]
  |  Branch (298:19): [True: 0, False: 558]
  ------------------
  299|     79|        retval = READSTAT_ERROR_BAD_MR_STRING;
  300|     79|        goto cleanup;
  301|     79|    }
  302|       |
  303|    558|    (void)mr_extractor_en_main;
  304|       |
  305|       |    // Assign parsed values to output parameter
  306|    558|    result->name = mr_name;
  307|    558|    result->label = mr_label;
  308|    558|    result->type = mr_type;
  309|    558|    result->counted_value = mr_counted_value;
  310|    558|    result->subvariables = mr_subvariables;
  311|    558|    result->num_subvars = mr_subvar_count;
  312|    558|    if (result->type == 'D') {
  ------------------
  |  Branch (312:9): [True: 399, False: 159]
  ------------------
  313|    399|        result->is_dichotomy = 1;
  314|    399|    }
  315|       |
  316|    672|cleanup:
  317|    672|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (317:9): [True: 114, False: 558]
  ------------------
  318|    114|        if (mr_subvariables != NULL) {
  ------------------
  |  Branch (318:13): [True: 20, False: 94]
  ------------------
  319|  1.16k|            for (int i = 0; i < mr_subvar_count; i++) {
  ------------------
  |  Branch (319:29): [True: 1.14k, False: 20]
  ------------------
  320|  1.14k|                if (mr_subvariables[i] != NULL) free(mr_subvariables[i]);
  ------------------
  |  Branch (320:21): [True: 1.14k, False: 0]
  ------------------
  321|  1.14k|            }
  322|     20|            free(mr_subvariables);
  323|     20|        }
  324|    114|        if (mr_name != NULL) free(mr_name);
  ------------------
  |  Branch (324:13): [True: 82, False: 32]
  ------------------
  325|    114|        if (mr_label != NULL) free(mr_label);
  ------------------
  |  Branch (325:13): [True: 22, False: 92]
  ------------------
  326|    114|    }
  327|    672|    return retval;
  328|    558|}
parse_mr_line:
  331|    672|readstat_error_t parse_mr_line(const char *line, mr_set_t *result, sav_ctx_t *ctx) {
  332|    672|    *result = (mr_set_t){0};
  333|    672|    return extract_mr_data(line, result, ctx);
  334|    672|}
parse_mr_string:
  383|    243|readstat_error_t parse_mr_string(const char *line, mr_set_t **mr_sets, size_t *n_mr_lines, sav_ctx_t *ctx) {
  384|    243|    readstat_error_t retval = READSTAT_OK;
  385|    243|    int cs = 0;
  386|    243|    char *p = (char *)line;
  387|    243|    char *start = p;
  388|    243|    char *pe = p + strlen(p) + 1;
  389|    243|    *mr_sets = NULL;
  390|    243|    *n_mr_lines = 0;
  391|       |
  392|       |    
  393|    243|#line 369 "src/spss/readstat_sav_parse_mr_name.c"
  394|    243|	{
  395|    243|	cs = mr_parser_start;
  396|    243|	}
  397|       |
  398|    243|#line 228 "src/spss/readstat_sav_parse_mr_name.rl"
  399|       |    
  400|    243|#line 372 "src/spss/readstat_sav_parse_mr_name.c"
  401|    243|	{
  402|    243|	int _klen;
  403|    243|	unsigned int _trans;
  404|    243|	const char *_acts;
  405|    243|	unsigned int _nacts;
  406|    243|	const char *_keys;
  407|       |
  408|    243|	if ( p == pe )
  ------------------
  |  Branch (408:7): [True: 0, False: 243]
  ------------------
  409|      0|		goto _test_eof;
  410|    243|	if ( cs == 0 )
  ------------------
  |  Branch (410:7): [True: 0, False: 243]
  ------------------
  411|      0|		goto _out;
  412|  28.2k|_resume:
  413|  28.2k|	_keys = _mr_parser_trans_keys + _mr_parser_key_offsets[cs];
  414|  28.2k|	_trans = _mr_parser_index_offsets[cs];
  415|       |
  416|  28.2k|	_klen = _mr_parser_single_lengths[cs];
  417|  28.2k|	if ( _klen > 0 ) {
  ------------------
  |  Branch (417:7): [True: 28.2k, False: 0]
  ------------------
  418|  28.2k|		const char *_lower = _keys;
  419|  28.2k|		const char *_mid;
  420|  28.2k|		const char *_upper = _keys + _klen - 1;
  421|  55.9k|		while (1) {
  ------------------
  |  Branch (421:10): [True: 55.9k, Folded]
  ------------------
  422|  55.9k|			if ( _upper < _lower )
  ------------------
  |  Branch (422:9): [True: 27.2k, False: 28.7k]
  ------------------
  423|  27.2k|				break;
  424|       |
  425|  28.7k|			_mid = _lower + ((_upper-_lower) >> 1);
  426|  28.7k|			if ( (*p) < *_mid )
  ------------------
  |  Branch (426:9): [True: 4.61k, False: 24.1k]
  ------------------
  427|  4.61k|				_upper = _mid - 1;
  428|  24.1k|			else if ( (*p) > *_mid )
  ------------------
  |  Branch (428:14): [True: 23.0k, False: 1.01k]
  ------------------
  429|  23.0k|				_lower = _mid + 1;
  430|  1.01k|			else {
  431|  1.01k|				_trans += (unsigned int)(_mid - _keys);
  432|  1.01k|				goto _match;
  433|  1.01k|			}
  434|  28.7k|		}
  435|  27.2k|		_keys += _klen;
  436|  27.2k|		_trans += _klen;
  437|  27.2k|	}
  438|       |
  439|  27.2k|	_klen = _mr_parser_range_lengths[cs];
  440|  27.2k|	if ( _klen > 0 ) {
  ------------------
  |  Branch (440:7): [True: 0, False: 27.2k]
  ------------------
  441|      0|		const char *_lower = _keys;
  442|      0|		const char *_mid;
  443|      0|		const char *_upper = _keys + (_klen<<1) - 2;
  444|      0|		while (1) {
  ------------------
  |  Branch (444:10): [True: 0, Folded]
  ------------------
  445|      0|			if ( _upper < _lower )
  ------------------
  |  Branch (445:9): [True: 0, False: 0]
  ------------------
  446|      0|				break;
  447|       |
  448|      0|			_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  449|      0|			if ( (*p) < _mid[0] )
  ------------------
  |  Branch (449:9): [True: 0, False: 0]
  ------------------
  450|      0|				_upper = _mid - 2;
  451|      0|			else if ( (*p) > _mid[1] )
  ------------------
  |  Branch (451:14): [True: 0, False: 0]
  ------------------
  452|      0|				_lower = _mid + 2;
  453|      0|			else {
  454|      0|				_trans += (unsigned int)((_mid - _keys)>>1);
  455|      0|				goto _match;
  456|      0|			}
  457|      0|		}
  458|      0|		_trans += _klen;
  459|      0|	}
  460|       |
  461|  28.2k|_match:
  462|  28.2k|	_trans = _mr_parser_indicies[_trans];
  463|  28.2k|	cs = _mr_parser_trans_targs[_trans];
  464|       |
  465|  28.2k|	if ( _mr_parser_trans_actions[_trans] == 0 )
  ------------------
  |  Branch (465:7): [True: 27.5k, False: 675]
  ------------------
  466|  27.5k|		goto _again;
  467|       |
  468|    675|	_acts = _mr_parser_actions + _mr_parser_trans_actions[_trans];
  469|    675|	_nacts = (unsigned int) *_acts++;
  470|  1.23k|	while ( _nacts-- > 0 )
  ------------------
  |  Branch (470:10): [True: 675, False: 558]
  ------------------
  471|    675|	{
  472|    675|		switch ( *_acts++ )
  ------------------
  |  Branch (472:12): [True: 675, False: 0]
  ------------------
  473|    675|		{
  474|    675|	case 0:
  ------------------
  |  Branch (474:2): [True: 675, False: 0]
  ------------------
  475|    675|#line 186 "src/spss/readstat_sav_parse_mr_name.rl"
  476|    675|	{
  477|    675|        char *mln = (char *)readstat_malloc(p - start);
  478|    675|        if (mln == NULL) {
  ------------------
  |  Branch (478:13): [True: 3, False: 672]
  ------------------
  479|      3|            retval = READSTAT_ERROR_MALLOC;
  480|      3|            goto cleanup;
  481|      3|        }
  482|    672|        memcpy(mln, start + 1, p - start);
  483|    672|        mln[p - start - 1] = '\0';
  484|    672|        mr_set_t *new_mr_sets = readstat_realloc(*mr_sets, ((*n_mr_lines) + 1) * sizeof(mr_set_t));
  485|    672|        if (new_mr_sets == NULL) {
  ------------------
  |  Branch (485:13): [True: 0, False: 672]
  ------------------
  486|      0|            free(mln);
  487|      0|            retval = READSTAT_ERROR_MALLOC;
  488|      0|            goto cleanup;
  489|      0|        }
  490|    672|        *mr_sets = new_mr_sets;
  491|    672|        retval = parse_mr_line(mln, &(*mr_sets)[*n_mr_lines], ctx);
  492|    672|        free(mln);
  493|    672|        if (retval != READSTAT_OK) {
  ------------------
  |  Branch (493:13): [True: 114, False: 558]
  ------------------
  494|    114|            goto cleanup;
  495|    114|        }
  496|    558|        (*n_mr_lines)++;
  497|    558|        start = p + 1;
  498|    558|    }
  499|      0|	break;
  500|    675|#line 470 "src/spss/readstat_sav_parse_mr_name.c"
  501|    675|		}
  502|    675|	}
  503|       |
  504|  28.1k|_again:
  505|  28.1k|	if ( cs == 0 )
  ------------------
  |  Branch (505:7): [True: 0, False: 28.1k]
  ------------------
  506|      0|		goto _out;
  507|  28.1k|	if ( ++p != pe )
  ------------------
  |  Branch (507:7): [True: 28.0k, False: 126]
  ------------------
  508|  28.0k|		goto _resume;
  509|    126|	_test_eof: {}
  510|    126|	_out: {}
  511|    126|	}
  512|       |
  513|      0|#line 229 "src/spss/readstat_sav_parse_mr_name.rl"
  514|       |
  515|    126|    if (cs < 4 || p != pe) {
  ------------------
  |  Branch (515:9): [True: 32, False: 94]
  |  Branch (515:19): [True: 0, False: 94]
  ------------------
  516|     32|        retval = READSTAT_ERROR_BAD_MR_STRING;
  517|     32|        goto cleanup;
  518|     32|    }
  519|       |
  520|     94|    (void)mr_parser_en_main;
  521|       |
  522|    243|cleanup:
  523|    243|    return retval;
  524|     94|}

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

sav_parse_timestamp:
 1587|  5.83k|readstat_error_t sav_parse_timestamp(sav_ctx_t *ctx, sav_file_header_record_t *header) {
 1588|  5.83k|    readstat_error_t retval = READSTAT_OK;
 1589|  5.83k|    struct tm timestamp = { .tm_isdst = -1 };
 1590|       |
 1591|  5.83k|    if ((retval = sav_parse_time(header->creation_time, sizeof(header->creation_time),
  ------------------
  |  Branch (1591:9): [True: 5.11k, False: 720]
  ------------------
 1592|  5.83k|                    &timestamp, ctx->handle.error, ctx->user_ctx)) 
 1593|  5.83k|            != READSTAT_OK)
 1594|  5.11k|        goto cleanup;
 1595|       |
 1596|    720|    if ((retval = sav_parse_date(header->creation_date, sizeof(header->creation_date),
  ------------------
  |  Branch (1596:9): [True: 259, False: 461]
  ------------------
 1597|    720|                    &timestamp, ctx->handle.error, ctx->user_ctx)) 
 1598|    720|            != READSTAT_OK)
 1599|    259|        goto cleanup;
 1600|       |
 1601|    461|    ctx->timestamp = mktime(&timestamp);
 1602|       |
 1603|  5.83k|cleanup:
 1604|  5.83k|    return retval;
 1605|    461|}
readstat_parse_sav:
 1607|  5.87k|readstat_error_t readstat_parse_sav(readstat_parser_t *parser, const char *path, void *user_ctx) {
 1608|  5.87k|    readstat_error_t retval = READSTAT_OK;
 1609|  5.87k|    readstat_io_t *io = parser->io;
 1610|  5.87k|    sav_file_header_record_t header;
 1611|  5.87k|    sav_ctx_t *ctx = NULL;
 1612|  5.87k|    size_t file_size = 0;
 1613|       |    
 1614|  5.87k|    if (io->open(path, io->io_ctx) == -1) {
  ------------------
  |  Branch (1614:9): [True: 0, False: 5.87k]
  ------------------
 1615|      0|        return READSTAT_ERROR_OPEN;
 1616|      0|    }
 1617|       |
 1618|  5.87k|    file_size = io->seek(0, READSTAT_SEEK_END, io->io_ctx);
 1619|  5.87k|    if (file_size == -1) {
  ------------------
  |  Branch (1619:9): [True: 0, False: 5.87k]
  ------------------
 1620|      0|        retval = READSTAT_ERROR_SEEK;
 1621|      0|        goto cleanup;
 1622|      0|    }
 1623|       |
 1624|  5.87k|    if (io->seek(0, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (1624:9): [True: 0, False: 5.87k]
  ------------------
 1625|      0|        retval = READSTAT_ERROR_SEEK;
 1626|      0|        goto cleanup;
 1627|      0|    }
 1628|       |
 1629|  5.87k|    if (io->read(&header, sizeof(sav_file_header_record_t), io->io_ctx) < sizeof(sav_file_header_record_t)) {
  ------------------
  |  Branch (1629:9): [True: 18, False: 5.86k]
  ------------------
 1630|     18|        retval = READSTAT_ERROR_READ;
 1631|     18|        goto cleanup;
 1632|     18|    }
 1633|       |
 1634|  5.86k|    ctx = sav_ctx_init(&header, io);
 1635|  5.86k|    if (ctx == NULL) {
  ------------------
  |  Branch (1635:9): [True: 30, False: 5.83k]
  ------------------
 1636|     30|        retval = READSTAT_ERROR_PARSE;
 1637|     30|        goto cleanup;
 1638|     30|    }
 1639|       |
 1640|  5.83k|    ctx->handle = parser->handlers;
 1641|  5.83k|    ctx->input_encoding = parser->input_encoding;
 1642|  5.83k|    ctx->output_encoding = parser->output_encoding;
 1643|  5.83k|    ctx->user_ctx = user_ctx;
 1644|  5.83k|    ctx->file_size = file_size;
 1645|  5.83k|    if (parser->row_offset > 0)
  ------------------
  |  Branch (1645:9): [True: 0, False: 5.83k]
  ------------------
 1646|      0|        ctx->row_offset = parser->row_offset;
 1647|  5.83k|    if (ctx->record_count >= 0) {
  ------------------
  |  Branch (1647:9): [True: 4.40k, False: 1.42k]
  ------------------
 1648|  4.40k|        int record_count_after_skipping = ctx->record_count - ctx->row_offset;
 1649|  4.40k|        if (record_count_after_skipping < 0) {
  ------------------
  |  Branch (1649:13): [True: 0, False: 4.40k]
  ------------------
 1650|      0|            record_count_after_skipping = 0;
 1651|      0|            ctx->row_offset = ctx->record_count;
 1652|      0|        }
 1653|  4.40k|        ctx->row_limit = record_count_after_skipping;
 1654|  4.40k|        if (parser->row_limit > 0 && parser->row_limit < record_count_after_skipping) 
  ------------------
  |  Branch (1654:13): [True: 0, False: 4.40k]
  |  Branch (1654:38): [True: 0, False: 0]
  ------------------
 1655|      0|            ctx->row_limit = parser->row_limit;
 1656|  4.40k|    } else if (parser->row_limit > 0) {
  ------------------
  |  Branch (1656:16): [True: 0, False: 1.42k]
  ------------------
 1657|      0|        ctx->row_limit = parser->row_limit;
 1658|      0|    }
 1659|       |    
 1660|       |    /* ignore errors */
 1661|  5.83k|    sav_parse_timestamp(ctx, &header);
 1662|       |
 1663|  5.83k|    if ((retval = sav_parse_records_pass1(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1663:9): [True: 1.17k, False: 4.65k]
  ------------------
 1664|  1.17k|        goto cleanup;
 1665|       |    
 1666|  4.65k|    if (io->seek(sizeof(sav_file_header_record_t), READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (1666:9): [True: 0, False: 4.65k]
  ------------------
 1667|      0|        retval = READSTAT_ERROR_SEEK;
 1668|      0|        goto cleanup;
 1669|      0|    }
 1670|       |
 1671|  4.65k|    if ((retval = sav_update_progress(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1671:9): [True: 0, False: 4.65k]
  ------------------
 1672|      0|        goto cleanup;
 1673|       |
 1674|  4.65k|    if ((retval = sav_parse_records_pass2(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1674:9): [True: 2.71k, False: 1.94k]
  ------------------
 1675|  2.71k|        goto cleanup;
 1676|       | 
 1677|  1.94k|    if ((retval = sav_set_n_segments_and_var_count(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1677:9): [True: 33, False: 1.91k]
  ------------------
 1678|     33|        goto cleanup;
 1679|       |
 1680|  1.91k|    if (ctx->var_count == 0) {
  ------------------
  |  Branch (1680:9): [True: 18, False: 1.89k]
  ------------------
 1681|     18|        retval = READSTAT_ERROR_PARSE;
 1682|     18|        goto cleanup;
 1683|     18|    }
 1684|       |
 1685|  1.89k|    if (ctx->handle.metadata) {
  ------------------
  |  Branch (1685:9): [True: 1.89k, False: 0]
  ------------------
 1686|  1.89k|        readstat_metadata_t metadata = {
 1687|  1.89k|            .row_count = ctx->record_count < 0 ? -1 : ctx->row_limit,
  ------------------
  |  Branch (1687:26): [True: 445, False: 1.44k]
  ------------------
 1688|  1.89k|            .var_count = ctx->var_count,
 1689|  1.89k|            .file_encoding = ctx->input_encoding,
 1690|  1.89k|            .file_format_version = ctx->format_version,
 1691|  1.89k|            .creation_time = ctx->timestamp,
 1692|  1.89k|            .modified_time = ctx->timestamp,
 1693|  1.89k|            .compression = ctx->compression,
 1694|  1.89k|            .endianness = ctx->endianness
 1695|  1.89k|        };
 1696|  1.89k|        if ((retval = readstat_convert(ctx->file_label, sizeof(ctx->file_label),
  ------------------
  |  Branch (1696:13): [True: 4, False: 1.88k]
  ------------------
 1697|  1.89k|                        header.file_label, sizeof(header.file_label), ctx->converter)) != READSTAT_OK)
 1698|      4|            goto cleanup;
 1699|       |
 1700|  1.88k|        metadata.file_label = ctx->file_label;
 1701|       |
 1702|       |        // Replace short MR names with long names
 1703|  1.88k|        ck_hash_table_t *var_dict = ck_hash_table_init(ctx->var_index, 8);
 1704|   317k|        for (size_t i = 0; i < ctx->var_index; i++) {
  ------------------
  |  Branch (1704:28): [True: 315k, False: 1.88k]
  ------------------
 1705|   315k|            spss_varinfo_t *current_varinfo = ctx->varinfo[i];
 1706|   315k|            if (current_varinfo != NULL && current_varinfo->name[0] != '\0') {
  ------------------
  |  Branch (1706:17): [True: 315k, False: 0]
  |  Branch (1706:44): [True: 312k, False: 3.42k]
  ------------------
 1707|   312k|                ck_str_hash_insert(current_varinfo->name, current_varinfo, var_dict);
 1708|   312k|            }
 1709|   315k|        }
 1710|  2.09k|        for (size_t i = 0; i < ctx->multiple_response_sets_length; i++) {
  ------------------
  |  Branch (1710:28): [True: 203, False: 1.88k]
  ------------------
 1711|    203|            mr_set_t mr = ctx->mr_sets[i];
 1712|  2.33k|            for (size_t j = 0; j < mr.num_subvars; j++) {
  ------------------
  |  Branch (1712:32): [True: 2.13k, False: 203]
  ------------------
 1713|  2.13k|                char* sv_name_upper = readstat_malloc(strlen(mr.subvariables[j]) + 1);
 1714|  2.13k|                if (sv_name_upper == NULL) {
  ------------------
  |  Branch (1714:21): [True: 0, False: 2.13k]
  ------------------
 1715|      0|                    retval = READSTAT_ERROR_MALLOC;
 1716|      0|                    goto cleanup;
 1717|      0|                }
 1718|  2.13k|                sv_name_upper[strlen(mr.subvariables[j])] = '\0';
 1719|  11.4k|                for (int c = 0; mr.subvariables[j][c] != '\0'; c++) {
  ------------------
  |  Branch (1719:33): [True: 9.33k, False: 2.13k]
  ------------------
 1720|  9.33k|                    sv_name_upper[c] = toupper((unsigned char) mr.subvariables[j][c]);
  ------------------
  |  Branch (1720:40): [True: 0, False: 0]
  |  Branch (1720:40): [True: 0, False: 0]
  |  Branch (1720:40): [Folded, False: 9.33k]
  ------------------
 1721|  9.33k|                }
 1722|  2.13k|                spss_varinfo_t *info = (spss_varinfo_t *)ck_str_hash_lookup(sv_name_upper, var_dict);
 1723|  2.13k|                if (info) {
  ------------------
  |  Branch (1723:21): [True: 47, False: 2.08k]
  ------------------
 1724|     47|                    free(mr.subvariables[j]);
 1725|       |                    // mr.subvariables[j] = NULL;
 1726|     47|                    if ((mr.subvariables[j] = readstat_malloc(strlen(info->longname) + 1)) == NULL) {
  ------------------
  |  Branch (1726:25): [True: 0, False: 47]
  ------------------
 1727|      0|                        retval = READSTAT_ERROR_MALLOC;
 1728|      0|                        goto cleanup;
 1729|      0|                    }
 1730|       |                    // mr.subvariables[j][strlen(info->longname)] = '\0';
 1731|     47|                    strcpy(mr.subvariables[j], info->longname);
 1732|       |                    // mr.subvariables[j] = info->longname;
 1733|     47|                }
 1734|  2.13k|                free(sv_name_upper);
 1735|       |                // sv_name_upper = NULL;
 1736|  2.13k|            }
 1737|    203|        }
 1738|  1.88k|        if (var_dict)
  ------------------
  |  Branch (1738:13): [True: 1.88k, False: 0]
  ------------------
 1739|  1.88k|            ck_hash_table_free(var_dict);
 1740|       |
 1741|  1.88k|        metadata.multiple_response_sets_length = ctx->multiple_response_sets_length;
 1742|  1.88k|        metadata.mr_sets = ctx->mr_sets;
 1743|       |
 1744|  1.88k|        if (ctx->handle.metadata(&metadata, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (1744:13): [True: 0, False: 1.88k]
  ------------------
 1745|      0|            retval = READSTAT_ERROR_USER_ABORT;
 1746|      0|            goto cleanup;
 1747|      0|        }
 1748|  1.88k|    }
 1749|       |
 1750|  1.88k|    if ((retval = sav_parse_variable_display_parameter_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1750:9): [True: 36, False: 1.85k]
  ------------------
 1751|     36|        goto cleanup;
 1752|       |
 1753|  1.85k|    if ((retval = sav_handle_variables(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1753:9): [True: 0, False: 1.85k]
  ------------------
 1754|      0|        goto cleanup;
 1755|       |
 1756|       |
 1757|  1.85k|    if ((retval = sav_handle_fweight(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1757:9): [True: 0, False: 1.85k]
  ------------------
 1758|      0|        goto cleanup;
 1759|       |
 1760|  1.85k|    if (ctx->handle.value) {
  ------------------
  |  Branch (1760:9): [True: 1.85k, False: 0]
  ------------------
 1761|  1.85k|        retval = sav_read_data(ctx);
 1762|  1.85k|    }
 1763|       |    
 1764|  5.87k|cleanup:
 1765|  5.87k|    io->close(io->io_ctx);
 1766|  5.87k|    if (ctx)
  ------------------
  |  Branch (1766:9): [True: 5.83k, False: 48]
  ------------------
 1767|  5.83k|        sav_ctx_free(ctx);
 1768|       |    
 1769|  5.87k|    return retval;
 1770|  1.85k|}
readstat_sav_read.c:sav_parse_records_pass1:
 1304|  5.83k|static readstat_error_t sav_parse_records_pass1(sav_ctx_t *ctx) {
 1305|  5.83k|    char data_buf[4096];
 1306|  5.83k|    readstat_error_t retval = READSTAT_OK;
 1307|  5.83k|    readstat_io_t *io = ctx->io;
 1308|   505k|    while (1) {
  ------------------
  |  Branch (1308:12): [True: 505k, Folded]
  ------------------
 1309|   505k|        uint32_t rec_type;
 1310|   505k|        uint32_t extra_info[3];
 1311|   505k|        size_t data_len = 0;
 1312|   505k|        int i;
 1313|   505k|        int done = 0;
 1314|   505k|        if (io->read(&rec_type, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (1314:13): [True: 258, False: 505k]
  ------------------
 1315|    258|            retval = READSTAT_ERROR_READ;
 1316|    258|            goto cleanup;
 1317|    258|        }
 1318|       |        
 1319|   505k|        if (ctx->bswap) {
  ------------------
  |  Branch (1319:13): [True: 13.2k, False: 491k]
  ------------------
 1320|  13.2k|            rec_type = byteswap4(rec_type);
 1321|  13.2k|        }
 1322|       |        
 1323|   505k|        switch (rec_type) {
 1324|   479k|            case SAV_RECORD_TYPE_VARIABLE:
  ------------------
  |  |  115|   479k|#define SAV_RECORD_TYPE_VARIABLE                2
  ------------------
  |  Branch (1324:13): [True: 479k, False: 26.0k]
  ------------------
 1325|   479k|                retval = sav_skip_variable_record(ctx);
 1326|   479k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1326:21): [True: 103, False: 479k]
  ------------------
 1327|    103|                    goto cleanup;
 1328|   479k|                break;
 1329|   479k|            case SAV_RECORD_TYPE_VALUE_LABEL:
  ------------------
  |  |  116|  5.82k|#define SAV_RECORD_TYPE_VALUE_LABEL             3
  ------------------
  |  Branch (1329:13): [True: 5.82k, False: 499k]
  ------------------
 1330|  5.82k|                retval = sav_skip_value_label_record(ctx);
 1331|  5.82k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1331:21): [True: 184, False: 5.63k]
  ------------------
 1332|    184|                    goto cleanup;
 1333|  5.63k|                break;
 1334|  5.63k|            case SAV_RECORD_TYPE_DOCUMENT:
  ------------------
  |  |  118|  1.23k|#define SAV_RECORD_TYPE_DOCUMENT                6
  ------------------
  |  Branch (1334:13): [True: 1.23k, False: 504k]
  ------------------
 1335|  1.23k|                retval = sav_skip_document_record(ctx);
 1336|  1.23k|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (1336:21): [True: 30, False: 1.20k]
  ------------------
 1337|     30|                    goto cleanup;
 1338|  1.20k|                break;
 1339|  4.65k|            case SAV_RECORD_TYPE_DICT_TERMINATION:
  ------------------
  |  |  120|  4.65k|#define SAV_RECORD_TYPE_DICT_TERMINATION        999
  ------------------
  |  Branch (1339:13): [True: 4.65k, False: 500k]
  ------------------
 1340|  4.65k|                done = 1;
 1341|  4.65k|                break;
 1342|  14.2k|            case SAV_RECORD_TYPE_HAS_DATA:
  ------------------
  |  |  119|  14.2k|#define SAV_RECORD_TYPE_HAS_DATA                7
  ------------------
  |  Branch (1342:13): [True: 14.2k, False: 491k]
  ------------------
 1343|  14.2k|                if (io->read(extra_info, sizeof(extra_info), io->io_ctx) < sizeof(extra_info)) {
  ------------------
  |  Branch (1343:21): [True: 6, False: 14.2k]
  ------------------
 1344|      6|                    retval = READSTAT_ERROR_READ;
 1345|      6|                    goto cleanup;
 1346|      6|                }
 1347|  14.2k|                if (ctx->bswap) {
  ------------------
  |  Branch (1347:21): [True: 3.24k, False: 11.0k]
  ------------------
 1348|  12.9k|                    for (i=0; i<3; i++)
  ------------------
  |  Branch (1348:31): [True: 9.74k, False: 3.24k]
  ------------------
 1349|  9.74k|                        extra_info[i] = byteswap4(extra_info[i]);
 1350|  3.24k|                }
 1351|  14.2k|                uint32_t subtype = extra_info[0];
 1352|  14.2k|                size_t size = extra_info[1];
 1353|  14.2k|                size_t count = extra_info[2];
 1354|  14.2k|                data_len = size * count;
 1355|  14.2k|                if (subtype == SAV_RECORD_SUBTYPE_INTEGER_INFO) {
  ------------------
  |  |  122|  14.2k|#define SAV_RECORD_SUBTYPE_INTEGER_INFO       3
  ------------------
  |  Branch (1355:21): [True: 779, False: 13.4k]
  ------------------
 1356|    779|                    if (data_len > sizeof(data_buf)) {
  ------------------
  |  Branch (1356:25): [True: 68, False: 711]
  ------------------
 1357|     68|                        retval = READSTAT_ERROR_PARSE;
 1358|     68|                        goto cleanup;
 1359|     68|                    }
 1360|    711|                    if (io->read(data_buf, data_len, io->io_ctx) < data_len) {
  ------------------
  |  Branch (1360:25): [True: 15, False: 696]
  ------------------
 1361|     15|                        retval = READSTAT_ERROR_PARSE;
 1362|     15|                        goto cleanup;
 1363|     15|                    }
 1364|    696|                    retval = sav_parse_machine_integer_info_record(data_buf, data_len, ctx);
 1365|    696|                    if (retval != READSTAT_OK)
  ------------------
  |  Branch (1365:25): [True: 29, False: 667]
  ------------------
 1366|     29|                        goto cleanup;
 1367|  13.4k|                } else if (subtype == SAV_RECORD_SUBTYPE_MULTIPLE_RESPONSE_SETS) {
  ------------------
  |  |  124|  13.4k|#define SAV_RECORD_SUBTYPE_MULTIPLE_RESPONSE_SETS 7
  ------------------
  |  Branch (1367:28): [True: 345, False: 13.1k]
  ------------------
 1368|    345|                    if (ctx->mr_sets != NULL) {
  ------------------
  |  Branch (1368:25): [True: 1, False: 344]
  ------------------
 1369|      1|                        retval = READSTAT_ERROR_BAD_MR_STRING;
 1370|      1|                        goto cleanup;
 1371|      1|                    }
 1372|    344|                    retval = sav_read_multiple_response_sets(data_len, ctx);
 1373|    344|                    if (retval != READSTAT_OK)
  ------------------
  |  Branch (1373:25): [True: 250, False: 94]
  ------------------
 1374|    250|                        goto cleanup;
 1375|  13.1k|                } else {
 1376|  13.1k|                    if (io->seek(data_len, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (1376:25): [True: 125, False: 13.0k]
  ------------------
 1377|    125|                        retval = READSTAT_ERROR_SEEK;
 1378|    125|                        goto cleanup;
 1379|    125|                    }
 1380|  13.1k|                }
 1381|  13.7k|                break;
 1382|  13.7k|            default:
  ------------------
  |  Branch (1382:13): [True: 103, False: 505k]
  ------------------
 1383|    103|                retval = READSTAT_ERROR_PARSE;
 1384|    103|                goto cleanup;
 1385|      0|                break;
 1386|   505k|        }
 1387|   504k|        if (done)
  ------------------
  |  Branch (1387:13): [True: 4.65k, False: 499k]
  ------------------
 1388|  4.65k|            break;
 1389|   504k|    }
 1390|  5.83k|cleanup:
 1391|  5.83k|    return retval;
 1392|  5.83k|}
readstat_sav_read.c:sav_skip_variable_record:
  196|   479k|static readstat_error_t sav_skip_variable_record(sav_ctx_t *ctx) {
  197|   479k|    sav_variable_record_t variable;
  198|   479k|    readstat_error_t retval = READSTAT_OK;
  199|   479k|    readstat_io_t *io = ctx->io;
  200|   479k|    if (io->read(&variable, sizeof(sav_variable_record_t), io->io_ctx) < sizeof(sav_variable_record_t)) {
  ------------------
  |  Branch (200:9): [True: 10, False: 479k]
  ------------------
  201|     10|        retval = READSTAT_ERROR_READ;
  202|     10|        goto cleanup;
  203|     10|    }
  204|   479k|    if (variable.has_var_label) {
  ------------------
  |  Branch (204:9): [True: 2.66k, False: 476k]
  ------------------
  205|  2.66k|        uint32_t label_len;
  206|  2.66k|        if (io->read(&label_len, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (206:13): [True: 43, False: 2.62k]
  ------------------
  207|     43|            retval = READSTAT_ERROR_READ;
  208|     43|            goto cleanup;
  209|     43|        }
  210|  2.62k|        label_len = ctx->bswap ? byteswap4(label_len) : label_len;
  ------------------
  |  Branch (210:21): [True: 839, False: 1.78k]
  ------------------
  211|  2.62k|        uint32_t label_capacity = (label_len + 3) / 4 * 4;
  212|  2.62k|        if (io->seek(label_capacity, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (212:13): [True: 11, False: 2.60k]
  ------------------
  213|     11|            retval = READSTAT_ERROR_SEEK;
  214|     11|            goto cleanup;
  215|     11|        }
  216|  2.62k|    }
  217|   479k|    if (variable.n_missing_values) {
  ------------------
  |  Branch (217:9): [True: 7.89k, False: 471k]
  ------------------
  218|  7.89k|        int n_missing_values = ctx->bswap ? byteswap4(variable.n_missing_values) : variable.n_missing_values;
  ------------------
  |  Branch (218:32): [True: 1.87k, False: 6.02k]
  ------------------
  219|  7.89k|        if (io->seek(abs(n_missing_values) * sizeof(double), READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (219:13): [True: 39, False: 7.85k]
  ------------------
  220|     39|            retval = READSTAT_ERROR_SEEK;
  221|     39|            goto cleanup;
  222|     39|        }
  223|  7.89k|    }
  224|   479k|cleanup:
  225|   479k|    return retval;
  226|   479k|}
readstat_sav_read.c:sav_skip_value_label_record:
  431|  5.82k|static readstat_error_t sav_skip_value_label_record(sav_ctx_t *ctx) {
  432|  5.82k|    uint32_t label_count;
  433|  5.82k|    uint32_t rec_type;
  434|  5.82k|    uint32_t var_count;
  435|  5.82k|    readstat_error_t retval = READSTAT_OK;
  436|  5.82k|    readstat_io_t *io = ctx->io;
  437|  5.82k|    if (io->read(&label_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (437:9): [True: 5, False: 5.81k]
  ------------------
  438|      5|        retval = READSTAT_ERROR_READ;
  439|      5|        goto cleanup;
  440|      5|    }
  441|  5.81k|    if (ctx->bswap)
  ------------------
  |  Branch (441:9): [True: 2.65k, False: 3.16k]
  ------------------
  442|  2.65k|        label_count = byteswap4(label_count);
  443|  5.81k|    int i;
  444|   135k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (444:15): [True: 130k, False: 5.71k]
  ------------------
  445|   130k|        unsigned char unpadded_len = 0;
  446|   130k|        size_t padded_len = 0;
  447|   130k|        if (io->seek(8, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (447:13): [True: 66, False: 130k]
  ------------------
  448|     66|            retval = READSTAT_ERROR_SEEK;
  449|     66|            goto cleanup;
  450|     66|        }
  451|   130k|        if (io->read(&unpadded_len, 1, io->io_ctx) < 1) {
  ------------------
  |  Branch (451:13): [True: 10, False: 130k]
  ------------------
  452|     10|            retval = READSTAT_ERROR_READ;
  453|     10|            goto cleanup;
  454|     10|        }
  455|   130k|        padded_len = (unpadded_len + 8) / 8 * 8 - 1;
  456|   130k|        if (io->seek(padded_len, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (456:13): [True: 23, False: 130k]
  ------------------
  457|     23|            retval = READSTAT_ERROR_SEEK;
  458|     23|            goto cleanup;
  459|     23|        }
  460|   130k|    }
  461|       |
  462|  5.71k|    if (io->read(&rec_type, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (462:9): [True: 19, False: 5.69k]
  ------------------
  463|     19|        retval = READSTAT_ERROR_READ;
  464|     19|        goto cleanup;
  465|     19|    }
  466|  5.69k|    if (ctx->bswap)
  ------------------
  |  Branch (466:9): [True: 2.59k, False: 3.10k]
  ------------------
  467|  2.59k|        rec_type = byteswap4(rec_type);
  468|       |    
  469|  5.69k|    if (rec_type != 4) {
  ------------------
  |  Branch (469:9): [True: 50, False: 5.64k]
  ------------------
  470|     50|        retval = READSTAT_ERROR_PARSE;
  471|     50|        goto cleanup;
  472|     50|    }
  473|  5.64k|    if (io->read(&var_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (473:9): [True: 7, False: 5.64k]
  ------------------
  474|      7|        retval = READSTAT_ERROR_READ;
  475|      7|        goto cleanup;
  476|      7|    }
  477|  5.64k|    if (ctx->bswap)
  ------------------
  |  Branch (477:9): [True: 2.55k, False: 3.08k]
  ------------------
  478|  2.55k|        var_count = byteswap4(var_count);
  479|       |    
  480|  5.64k|    if (io->seek(var_count * sizeof(uint32_t), READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (480:9): [True: 4, False: 5.63k]
  ------------------
  481|      4|        retval = READSTAT_ERROR_SEEK;
  482|      4|        goto cleanup;
  483|      4|    }
  484|       |
  485|  5.82k|cleanup:
  486|  5.82k|    return retval;
  487|  5.64k|}
readstat_sav_read.c:sav_skip_document_record:
  643|  1.23k|static readstat_error_t sav_skip_document_record(sav_ctx_t *ctx) {
  644|  1.23k|    uint32_t n_lines;
  645|  1.23k|    readstat_error_t retval = READSTAT_OK;
  646|  1.23k|    readstat_io_t *io = ctx->io;
  647|  1.23k|    if (io->read(&n_lines, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (647:9): [True: 3, False: 1.22k]
  ------------------
  648|      3|        retval = READSTAT_ERROR_READ;
  649|      3|        goto cleanup;
  650|      3|    }
  651|  1.22k|    if (ctx->bswap)
  ------------------
  |  Branch (651:9): [True: 459, False: 769]
  ------------------
  652|    459|        n_lines = byteswap4(n_lines);
  653|  1.22k|    if (io->seek(n_lines * SPSS_DOC_LINE_SIZE, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  |   40|  1.22k|#define SPSS_DOC_LINE_SIZE  80
  ------------------
  |  Branch (653:9): [True: 27, False: 1.20k]
  ------------------
  654|     27|        retval = READSTAT_ERROR_SEEK;
  655|     27|        goto cleanup;
  656|     27|    }
  657|       |    
  658|  1.23k|cleanup:
  659|  1.23k|    return retval;
  660|  1.22k|}
readstat_sav_read.c:sav_parse_machine_integer_info_record:
  946|    696|static readstat_error_t sav_parse_machine_integer_info_record(const void *data, size_t data_len, sav_ctx_t *ctx) {
  947|    696|    if (data_len != 32)
  ------------------
  |  Branch (947:9): [True: 8, False: 688]
  ------------------
  948|      8|        return READSTAT_ERROR_PARSE;
  949|       |
  950|    688|    const char *src_charset = NULL;
  951|    688|    const char *dst_charset = ctx->output_encoding;
  952|    688|    sav_machine_integer_info_record_t record;
  953|    688|    memcpy(&record, data, data_len);
  954|    688|    if (ctx->bswap) {
  ------------------
  |  Branch (954:9): [True: 103, False: 585]
  ------------------
  955|    103|        record.character_code = byteswap4(record.character_code);
  956|    103|    }
  957|    688|    if (ctx->input_encoding) {
  ------------------
  |  Branch (957:9): [True: 547, False: 141]
  ------------------
  958|    547|        src_charset = ctx->input_encoding;
  959|    547|    } else {
  960|    141|        int i;
  961|  9.19k|        for (i=0; i<sizeof(_charset_table)/sizeof(_charset_table[0]); i++) {
  ------------------
  |  Branch (961:19): [True: 9.17k, False: 20]
  ------------------
  962|  9.17k|            if (record.character_code  == _charset_table[i].code) {
  ------------------
  |  Branch (962:17): [True: 121, False: 9.05k]
  ------------------
  963|    121|                src_charset = _charset_table[i].name;
  964|    121|                break;
  965|    121|            }
  966|  9.17k|        }
  967|    141|        if (src_charset == NULL) {
  ------------------
  |  Branch (967:13): [True: 20, False: 121]
  ------------------
  968|     20|            if (ctx->handle.error) {
  ------------------
  |  Branch (968:17): [True: 0, False: 20]
  ------------------
  969|      0|                char error_buf[1024];
  970|      0|                snprintf(error_buf, sizeof(error_buf), "Unsupported character set: %d\n", record.character_code);
  971|      0|                ctx->handle.error(error_buf, ctx->user_ctx);
  972|      0|            }
  973|     20|            return READSTAT_ERROR_UNSUPPORTED_CHARSET;
  974|     20|        }
  975|    121|        ctx->input_encoding = src_charset;
  976|    121|    }
  977|    668|    if (src_charset && dst_charset) {
  ------------------
  |  Branch (977:9): [True: 668, False: 0]
  |  Branch (977:24): [True: 668, False: 0]
  ------------------
  978|       |        // You might be tempted to skip the charset conversion when src_charset
  979|       |        // and dst_charset are the same. However, some versions of SPSS insert
  980|       |        // illegally truncated strings (e.g. the last character is three bytes
  981|       |        // but the field only has room for two bytes). So to prevent the client
  982|       |        // from receiving an invalid byte sequence, we ram everything through
  983|       |        // our iconv machinery.
  984|    668|        iconv_t converter = iconv_open(dst_charset, src_charset);
  985|    668|        if (converter == (iconv_t)-1) {
  ------------------
  |  Branch (985:13): [True: 1, False: 667]
  ------------------
  986|      1|            return READSTAT_ERROR_UNSUPPORTED_CHARSET;
  987|      1|        }
  988|    667|        if (ctx->converter) {
  ------------------
  |  Branch (988:13): [True: 547, False: 120]
  ------------------
  989|    547|            iconv_close(ctx->converter);
  990|    547|        }
  991|    667|        ctx->converter = converter;
  992|    667|    }
  993|    667|    return READSTAT_OK;
  994|    668|}
readstat_sav_read.c:sav_read_multiple_response_sets:
  152|    344|static readstat_error_t sav_read_multiple_response_sets(size_t data_len, sav_ctx_t *ctx) {
  153|    344|    readstat_error_t retval = READSTAT_OK;
  154|       |
  155|    344|    char *mr_string = readstat_malloc(data_len + 1);
  156|    344|    if (mr_string == NULL) {
  ------------------
  |  Branch (156:9): [True: 51, False: 293]
  ------------------
  157|     51|        retval = READSTAT_ERROR_MALLOC;
  158|     51|        goto cleanup;
  159|     51|    }
  160|    293|    mr_string[data_len] = '\0';
  161|    293|    if (ctx->io->read(mr_string, data_len, ctx->io->io_ctx) < data_len) {
  ------------------
  |  Branch (161:9): [True: 39, False: 254]
  ------------------
  162|     39|        retval = READSTAT_ERROR_PARSE;
  163|     39|        goto cleanup;
  164|     39|    }
  165|    254|    if (mr_string[0] != '$') {
  ------------------
  |  Branch (165:9): [True: 11, False: 243]
  ------------------
  166|     11|        retval = READSTAT_ERROR_BAD_MR_STRING;
  167|     11|        goto cleanup;
  168|     11|    }
  169|       |
  170|    243|    retval = parse_mr_string(mr_string, &ctx->mr_sets, &ctx->multiple_response_sets_length, ctx);
  171|       |
  172|    344|cleanup:
  173|    344|    free(mr_string);
  174|    344|    return retval;
  175|    243|}
readstat_sav_read.c:sav_update_progress:
  191|  7.13k|static readstat_error_t sav_update_progress(sav_ctx_t *ctx) {
  192|  7.13k|    readstat_io_t *io = ctx->io;
  193|  7.13k|    return io->update(ctx->file_size, ctx->handle.progress, ctx->user_ctx, io->io_ctx);
  194|  7.13k|}
readstat_sav_read.c:sav_parse_records_pass2:
 1394|  4.65k|static readstat_error_t sav_parse_records_pass2(sav_ctx_t *ctx) {
 1395|  4.65k|    void *data_buf = NULL;
 1396|  4.65k|    size_t data_buf_capacity = 4096;
 1397|  4.65k|    readstat_error_t retval = READSTAT_OK;
 1398|  4.65k|    readstat_io_t *io = ctx->io;
 1399|       |
 1400|  4.65k|    if ((data_buf = readstat_malloc(data_buf_capacity)) == NULL) {
  ------------------
  |  Branch (1400:9): [True: 0, False: 4.65k]
  ------------------
 1401|      0|        retval = READSTAT_ERROR_MALLOC;
 1402|      0|        goto cleanup;
 1403|      0|    }
 1404|       |
 1405|   496k|    while (1) {
  ------------------
  |  Branch (1405:12): [True: 496k, Folded]
  ------------------
 1406|   496k|        uint32_t rec_type;
 1407|   496k|        uint32_t extra_info[3];
 1408|   496k|        size_t data_len = 0;
 1409|   496k|        int i;
 1410|   496k|        int done = 0;
 1411|   496k|        if (io->read(&rec_type, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (1411:13): [True: 23, False: 496k]
  ------------------
 1412|     23|            retval = READSTAT_ERROR_READ;
 1413|     23|            goto cleanup;
 1414|     23|        }
 1415|       |        
 1416|   496k|        if (ctx->bswap) {
  ------------------
  |  Branch (1416:13): [True: 11.2k, False: 484k]
  ------------------
 1417|  11.2k|            rec_type = byteswap4(rec_type);
 1418|  11.2k|        }
 1419|       |        
 1420|   496k|        switch (rec_type) {
 1421|   475k|            case SAV_RECORD_TYPE_VARIABLE:
  ------------------
  |  |  115|   475k|#define SAV_RECORD_TYPE_VARIABLE                2
  ------------------
  |  Branch (1421:13): [True: 475k, False: 20.8k]
  ------------------
 1422|   475k|                if ((retval = sav_read_variable_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1422:21): [True: 176, False: 475k]
  ------------------
 1423|    176|                    goto cleanup;
 1424|   475k|                break;
 1425|   475k|            case SAV_RECORD_TYPE_VALUE_LABEL:
  ------------------
  |  |  116|  4.51k|#define SAV_RECORD_TYPE_VALUE_LABEL             3
  ------------------
  |  Branch (1425:13): [True: 4.51k, False: 491k]
  ------------------
 1426|  4.51k|                if ((retval = sav_read_value_label_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1426:21): [True: 212, False: 4.30k]
  ------------------
 1427|    212|                    goto cleanup;
 1428|  4.30k|                break;
 1429|  4.30k|            case SAV_RECORD_TYPE_DOCUMENT:
  ------------------
  |  |  118|  1.05k|#define SAV_RECORD_TYPE_DOCUMENT                6
  ------------------
  |  Branch (1429:13): [True: 1.05k, False: 495k]
  ------------------
 1430|  1.05k|                if ((retval = sav_read_document_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1430:21): [True: 64, False: 987]
  ------------------
 1431|     64|                    goto cleanup;
 1432|    987|                break;
 1433|  3.07k|            case SAV_RECORD_TYPE_DICT_TERMINATION:
  ------------------
  |  |  120|  3.07k|#define SAV_RECORD_TYPE_DICT_TERMINATION        999
  ------------------
  |  Branch (1433:13): [True: 3.07k, False: 493k]
  ------------------
 1434|  3.07k|                if ((retval = sav_read_dictionary_termination_record(ctx)) != READSTAT_OK)
  ------------------
  |  Branch (1434:21): [True: 1.13k, False: 1.94k]
  ------------------
 1435|  1.13k|                    goto cleanup;
 1436|  1.94k|                done = 1;
 1437|  1.94k|                break;
 1438|  12.1k|            case SAV_RECORD_TYPE_HAS_DATA:
  ------------------
  |  |  119|  12.1k|#define SAV_RECORD_TYPE_HAS_DATA                7
  ------------------
  |  Branch (1438:13): [True: 12.1k, False: 483k]
  ------------------
 1439|  12.1k|                if (io->read(extra_info, sizeof(extra_info), io->io_ctx) < sizeof(extra_info)) {
  ------------------
  |  Branch (1439:21): [True: 5, False: 12.1k]
  ------------------
 1440|      5|                    retval = READSTAT_ERROR_READ;
 1441|      5|                    goto cleanup;
 1442|      5|                }
 1443|  12.1k|                if (ctx->bswap) {
  ------------------
  |  Branch (1443:21): [True: 3.01k, False: 9.16k]
  ------------------
 1444|  12.0k|                    for (i=0; i<3; i++)
  ------------------
  |  Branch (1444:31): [True: 9.03k, False: 3.01k]
  ------------------
 1445|  9.03k|                        extra_info[i] = byteswap4(extra_info[i]);
 1446|  3.01k|                }
 1447|  12.1k|                uint32_t subtype = extra_info[0];
 1448|  12.1k|                size_t size = extra_info[1];
 1449|  12.1k|                size_t count = extra_info[2];
 1450|  12.1k|                data_len = size * count;
 1451|  12.1k|                if (data_buf_capacity < data_len) {
  ------------------
  |  Branch (1451:21): [True: 118, False: 12.0k]
  ------------------
 1452|    118|                    if ((data_buf = readstat_realloc(data_buf, data_buf_capacity = data_len)) == NULL) {
  ------------------
  |  Branch (1452:25): [True: 55, False: 63]
  ------------------
 1453|     55|                        retval = READSTAT_ERROR_MALLOC;
 1454|     55|                        goto cleanup;
 1455|     55|                    }
 1456|    118|                }
 1457|  12.1k|                if (data_len == 0 || io->read(data_buf, data_len, io->io_ctx) < data_len) {
  ------------------
  |  Branch (1457:21): [True: 13, False: 12.1k]
  |  Branch (1457:38): [True: 42, False: 12.0k]
  ------------------
 1458|     55|                    retval = READSTAT_ERROR_PARSE;
 1459|     55|                    goto cleanup;
 1460|     55|                }
 1461|       |                
 1462|  12.0k|                switch (subtype) {
 1463|    334|                    case SAV_RECORD_SUBTYPE_INTEGER_INFO:
  ------------------
  |  |  122|    334|#define SAV_RECORD_SUBTYPE_INTEGER_INFO       3
  ------------------
  |  Branch (1463:21): [True: 334, False: 11.7k]
  ------------------
 1464|       |                        /* parsed in pass 1 */
 1465|    334|                        break;
 1466|    691|                    case SAV_RECORD_SUBTYPE_FP_INFO:
  ------------------
  |  |  123|    691|#define SAV_RECORD_SUBTYPE_FP_INFO            4
  ------------------
  |  Branch (1466:21): [True: 691, False: 11.3k]
  ------------------
 1467|    691|                        retval = sav_parse_machine_floating_point_record(data_buf, size, count, ctx);
 1468|    691|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1468:29): [True: 16, False: 675]
  ------------------
 1469|     16|                            goto cleanup;
 1470|    675|                        break;
 1471|    675|                    case SAV_RECORD_SUBTYPE_VAR_DISPLAY:
  ------------------
  |  |  126|    503|#define SAV_RECORD_SUBTYPE_VAR_DISPLAY       11
  ------------------
  |  Branch (1471:21): [True: 503, False: 11.5k]
  ------------------
 1472|    503|                        retval = sav_store_variable_display_parameter_record(data_buf, size, count, ctx);
 1473|    503|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1473:29): [True: 15, False: 488]
  ------------------
 1474|     15|                            goto cleanup;
 1475|    488|                        break;
 1476|  3.16k|                    case SAV_RECORD_SUBTYPE_LONG_VAR_NAME:
  ------------------
  |  |  127|  3.16k|#define SAV_RECORD_SUBTYPE_LONG_VAR_NAME     13
  ------------------
  |  Branch (1476:21): [True: 3.16k, False: 8.89k]
  ------------------
 1477|  3.16k|                        retval = sav_parse_long_variable_names_record(data_buf, count, ctx);
 1478|  3.16k|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1478:29): [True: 224, False: 2.93k]
  ------------------
 1479|    224|                            goto cleanup;
 1480|  2.93k|                        break;
 1481|  4.00k|                    case SAV_RECORD_SUBTYPE_VERY_LONG_STR:
  ------------------
  |  |  128|  4.00k|#define SAV_RECORD_SUBTYPE_VERY_LONG_STR     14
  ------------------
  |  Branch (1481:21): [True: 4.00k, False: 8.05k]
  ------------------
 1482|  4.00k|                        retval = sav_parse_very_long_string_record(data_buf, count, ctx);
 1483|  4.00k|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1483:29): [True: 230, False: 3.77k]
  ------------------
 1484|    230|                            goto cleanup;
 1485|  3.77k|                        break;
 1486|  3.77k|                    case SAV_RECORD_SUBTYPE_LONG_STRING_VALUE_LABELS:
  ------------------
  |  |  133|    679|#define SAV_RECORD_SUBTYPE_LONG_STRING_VALUE_LABELS   21
  ------------------
  |  Branch (1486:21): [True: 679, False: 11.3k]
  ------------------
 1487|    679|                        retval = sav_parse_long_string_value_labels_record(data_buf, size, count, ctx);
 1488|    679|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1488:29): [True: 254, False: 425]
  ------------------
 1489|    254|                            goto cleanup;
 1490|    425|                        break;
 1491|    438|                    case SAV_RECORD_SUBTYPE_LONG_STRING_MISSING_VALUES:
  ------------------
  |  |  134|    438|#define SAV_RECORD_SUBTYPE_LONG_STRING_MISSING_VALUES 22
  ------------------
  |  Branch (1491:21): [True: 438, False: 11.6k]
  ------------------
 1492|    438|                        retval = sav_parse_long_string_missing_values_record(data_buf, size, count, ctx);
 1493|    438|                        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1493:29): [True: 169, False: 269]
  ------------------
 1494|    169|                            goto cleanup;
 1495|    269|                        break;
 1496|  2.24k|                    default: /* misc. info */
  ------------------
  |  Branch (1496:21): [True: 2.24k, False: 9.81k]
  ------------------
 1497|  2.24k|                        break;
 1498|  12.0k|                }
 1499|  11.1k|                break;
 1500|  11.1k|            default:
  ------------------
  |  Branch (1500:13): [True: 86, False: 496k]
  ------------------
 1501|     86|                retval = READSTAT_ERROR_PARSE;
 1502|     86|                goto cleanup;
 1503|      0|                break;
 1504|   496k|        }
 1505|   493k|        if (done)
  ------------------
  |  Branch (1505:13): [True: 1.94k, False: 491k]
  ------------------
 1506|  1.94k|            break;
 1507|   493k|    }
 1508|  4.65k|cleanup:
 1509|  4.65k|    if (data_buf)
  ------------------
  |  Branch (1509:9): [True: 4.60k, False: 55]
  ------------------
 1510|  4.60k|        free(data_buf);
 1511|  4.65k|    return retval;
 1512|  4.65k|}
readstat_sav_read.c:sav_read_variable_record:
  343|   475k|static readstat_error_t sav_read_variable_record(sav_ctx_t *ctx) {
  344|   475k|    readstat_io_t *io = ctx->io;
  345|   475k|    sav_variable_record_t variable = { 0 };
  346|   475k|    spss_varinfo_t *info = NULL;
  347|   475k|    readstat_error_t retval = READSTAT_OK;
  348|   475k|    if (ctx->var_index == ctx->varinfo_capacity) {
  ------------------
  |  Branch (348:9): [True: 221, False: 474k]
  ------------------
  349|    221|        if ((ctx->varinfo = readstat_realloc(ctx->varinfo, (ctx->varinfo_capacity *= 2) * sizeof(spss_varinfo_t *))) == NULL) {
  ------------------
  |  Branch (349:13): [True: 0, False: 221]
  ------------------
  350|      0|            retval = READSTAT_ERROR_MALLOC;
  351|      0|            goto cleanup;
  352|      0|        }
  353|    221|    }
  354|   475k|    if (io->read(&variable, sizeof(sav_variable_record_t), io->io_ctx) < sizeof(sav_variable_record_t)) {
  ------------------
  |  Branch (354:9): [True: 13, False: 475k]
  ------------------
  355|     13|        retval = READSTAT_ERROR_READ;
  356|     13|        goto cleanup;
  357|     13|    }
  358|   475k|    variable.print = ctx->bswap ? byteswap4(variable.print) : variable.print;
  ------------------
  |  Branch (358:22): [True: 5.17k, False: 470k]
  ------------------
  359|   475k|    variable.write = ctx->bswap ? byteswap4(variable.write) : variable.write;
  ------------------
  |  Branch (359:22): [True: 5.17k, False: 470k]
  ------------------
  360|       |
  361|   475k|    int32_t type = ctx->bswap ? byteswap4(variable.type) : variable.type;
  ------------------
  |  Branch (361:20): [True: 5.17k, False: 470k]
  ------------------
  362|   475k|    if (type < 0) {
  ------------------
  |  Branch (362:9): [True: 7.01k, False: 468k]
  ------------------
  363|  7.01k|        if (ctx->var_index == 0) {
  ------------------
  |  Branch (363:13): [True: 25, False: 6.99k]
  ------------------
  364|     25|            return READSTAT_ERROR_PARSE;
  365|     25|        }
  366|  6.99k|        ctx->var_offset++;
  367|  6.99k|        ctx->varinfo[ctx->var_index-1]->width++;
  368|  6.99k|        return retval;
  369|  7.01k|    }
  370|       |
  371|   468k|    if ((info = readstat_calloc(1, sizeof(spss_varinfo_t))) == NULL) {
  ------------------
  |  Branch (371:9): [True: 0, False: 468k]
  ------------------
  372|      0|        retval = READSTAT_ERROR_MALLOC;
  373|      0|        goto cleanup;
  374|      0|    }
  375|   468k|    info->width = 1;
  376|   468k|    info->n_segments = 1;
  377|   468k|    info->index = ctx->var_index;
  378|   468k|    info->offset = ctx->var_offset;
  379|   468k|    info->labels_index = -1;
  380|       |
  381|   468k|    retval = readstat_convert(info->name, sizeof(info->name),
  382|   468k|            variable.name, sizeof(variable.name), NULL);
  383|   468k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (383:9): [True: 0, False: 468k]
  ------------------
  384|      0|        goto cleanup;
  385|       |
  386|   468k|    retval = readstat_convert(info->longname, sizeof(info->longname), 
  387|   468k|            variable.name, sizeof(variable.name), NULL);
  388|   468k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (388:9): [True: 0, False: 468k]
  ------------------
  389|      0|        goto cleanup;
  390|       |
  391|   468k|    info->print_format.decimal_places = (variable.print & 0x000000FF);
  392|   468k|    info->print_format.width = (variable.print & 0x0000FF00) >> 8;
  393|   468k|    info->print_format.type = (variable.print  & 0x00FF0000) >> 16;
  394|       |
  395|   468k|    info->write_format.decimal_places = (variable.write & 0x000000FF);
  396|   468k|    info->write_format.width = (variable.write & 0x0000FF00) >> 8;
  397|   468k|    info->write_format.type = (variable.write  & 0x00FF0000) >> 16;
  398|       |
  399|   468k|    if (type > 0 || info->print_format.type == SPSS_FORMAT_TYPE_A || info->write_format.type == SPSS_FORMAT_TYPE_A) {
  ------------------
  |  |    2|   797k|#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|   195k|#define SPSS_FORMAT_TYPE_A        1
  ------------------
  |  Branch (399:9): [True: 139k, False: 328k]
  |  Branch (399:21): [True: 133k, False: 195k]
  |  Branch (399:70): [True: 112k, False: 82.9k]
  ------------------
  400|   385k|        info->type = READSTAT_TYPE_STRING;
  401|   385k|    } else {
  402|  82.9k|        info->type = READSTAT_TYPE_DOUBLE;
  403|  82.9k|    }
  404|       |    
  405|   468k|    if (variable.has_var_label) {
  ------------------
  |  Branch (405:9): [True: 1.95k, False: 466k]
  ------------------
  406|  1.95k|        if ((retval = sav_read_variable_label(info, ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (406:13): [True: 55, False: 1.90k]
  ------------------
  407|     55|            goto cleanup;
  408|     55|        }
  409|  1.95k|    }
  410|       |    
  411|   468k|    if (variable.n_missing_values) {
  ------------------
  |  Branch (411:9): [True: 6.01k, False: 462k]
  ------------------
  412|  6.01k|        info->n_missing_values = ctx->bswap ? byteswap4(variable.n_missing_values) : variable.n_missing_values;
  ------------------
  |  Branch (412:34): [True: 1.51k, False: 4.49k]
  ------------------
  413|  6.01k|        if ((retval = sav_read_variable_missing_values(info, ctx)) != READSTAT_OK) {
  ------------------
  |  Branch (413:13): [True: 83, False: 5.92k]
  ------------------
  414|     83|            goto cleanup;
  415|     83|        }
  416|  6.01k|    }
  417|       |    
  418|   468k|    ctx->varinfo[ctx->var_index] = info;
  419|       |
  420|   468k|    ctx->var_index++;
  421|   468k|    ctx->var_offset++;
  422|       |    
  423|   468k|cleanup:
  424|   468k|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (424:9): [True: 151, False: 468k]
  ------------------
  425|    151|        spss_varinfo_free(info);
  426|    151|    }
  427|       |
  428|   468k|    return retval;
  429|   468k|}
readstat_sav_read.c:sav_read_variable_label:
  228|  1.95k|static readstat_error_t sav_read_variable_label(spss_varinfo_t *info, sav_ctx_t *ctx) {
  229|  1.95k|    readstat_io_t *io = ctx->io;
  230|  1.95k|    readstat_error_t retval = READSTAT_OK;
  231|  1.95k|    uint32_t label_len, label_capacity;
  232|  1.95k|    size_t out_label_len;
  233|  1.95k|    char *label_buf = NULL;
  234|  1.95k|    if (io->read(&label_len, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (234:9): [True: 5, False: 1.95k]
  ------------------
  235|      5|        retval = READSTAT_ERROR_READ;
  236|      5|        goto cleanup;
  237|      5|    }
  238|  1.95k|    label_len = ctx->bswap ? byteswap4(label_len) : label_len;
  ------------------
  |  Branch (238:17): [True: 551, False: 1.40k]
  ------------------
  239|       |
  240|  1.95k|    if (label_len == 0)
  ------------------
  |  Branch (240:9): [True: 800, False: 1.15k]
  ------------------
  241|    800|        goto cleanup;
  242|       |
  243|  1.15k|    label_capacity = (label_len + 3) / 4 * 4;
  244|  1.15k|    if ((label_buf = readstat_malloc(label_capacity)) == NULL) {
  ------------------
  |  Branch (244:9): [True: 38, False: 1.11k]
  ------------------
  245|     38|        retval = READSTAT_ERROR_MALLOC;
  246|     38|        goto cleanup;
  247|     38|    }
  248|       |
  249|  1.11k|    out_label_len = (size_t)label_len*4+1;
  250|  1.11k|    if ((info->label = readstat_malloc(out_label_len)) == NULL) {
  ------------------
  |  Branch (250:9): [True: 8, False: 1.10k]
  ------------------
  251|      8|        retval = READSTAT_ERROR_MALLOC;
  252|      8|        goto cleanup;
  253|      8|    }
  254|       |
  255|  1.10k|    if (io->read(label_buf, label_capacity, io->io_ctx) < label_capacity) {
  ------------------
  |  Branch (255:9): [True: 4, False: 1.10k]
  ------------------
  256|      4|        retval = READSTAT_ERROR_READ;
  257|      4|        goto cleanup;
  258|      4|    }
  259|       |
  260|  1.10k|    retval = readstat_convert(info->label, out_label_len, label_buf, label_len, ctx->converter);
  261|  1.10k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (261:9): [True: 0, False: 1.10k]
  ------------------
  262|      0|        goto cleanup;
  263|       |
  264|  1.95k|cleanup:
  265|  1.95k|    if (label_buf)
  ------------------
  |  Branch (265:9): [True: 1.11k, False: 843]
  ------------------
  266|  1.11k|        free(label_buf);
  267|       |
  268|  1.95k|    if (retval != READSTAT_OK) {
  ------------------
  |  Branch (268:9): [True: 55, False: 1.90k]
  ------------------
  269|     55|        if (info->label) {
  ------------------
  |  Branch (269:13): [True: 4, False: 51]
  ------------------
  270|      4|            free(info->label);
  271|      4|            info->label = NULL;
  272|      4|        }
  273|     55|    }
  274|       |
  275|  1.95k|    return retval;
  276|  1.10k|}
readstat_sav_read.c:sav_read_variable_missing_values:
  327|  6.01k|static readstat_error_t sav_read_variable_missing_values(spss_varinfo_t *info, sav_ctx_t *ctx) {
  328|  6.01k|    if (info->n_missing_values > 3 || info->n_missing_values < -3) {
  ------------------
  |  Branch (328:9): [True: 14, False: 5.99k]
  |  Branch (328:39): [True: 55, False: 5.94k]
  ------------------
  329|     69|        return READSTAT_ERROR_PARSE;
  330|     69|    }
  331|  5.94k|    if (info->n_missing_values < 0) {
  ------------------
  |  Branch (331:9): [True: 3.54k, False: 2.39k]
  ------------------
  332|  3.54k|        info->missing_range = 1;
  333|  3.54k|        info->n_missing_values = abs(info->n_missing_values);
  334|  3.54k|    } else {
  335|  2.39k|        info->missing_range = 0;
  336|  2.39k|    }
  337|  5.94k|    if (info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (337:9): [True: 3.04k, False: 2.90k]
  ------------------
  338|  3.04k|        return sav_read_variable_missing_double_values(info, ctx);
  339|  3.04k|    }
  340|  2.90k|    return sav_read_variable_missing_string_values(info, ctx);
  341|  5.94k|}
readstat_sav_read.c:sav_read_variable_missing_double_values:
  278|  3.04k|static readstat_error_t sav_read_variable_missing_double_values(spss_varinfo_t *info, sav_ctx_t *ctx) {
  279|  3.04k|    readstat_io_t *io = ctx->io;
  280|  3.04k|    int i;
  281|  3.04k|    readstat_error_t retval = READSTAT_OK;
  282|  3.04k|    if (io->read(info->missing_double_values, info->n_missing_values * sizeof(double), io->io_ctx)
  ------------------
  |  Branch (282:9): [True: 8, False: 3.03k]
  ------------------
  283|  3.04k|            < info->n_missing_values * sizeof(double)) {
  284|      8|        retval = READSTAT_ERROR_READ;
  285|      8|        goto cleanup;
  286|      8|    }
  287|  9.57k|    for (i=0; i<info->n_missing_values; i++) {
  ------------------
  |  Branch (287:15): [True: 6.54k, False: 3.03k]
  ------------------
  288|  6.54k|        if (ctx->bswap) {
  ------------------
  |  Branch (288:13): [True: 1.90k, False: 4.64k]
  ------------------
  289|  1.90k|            info->missing_double_values[i] = byteswap_double(info->missing_double_values[i]);
  290|  1.90k|        }
  291|       |
  292|  6.54k|        uint64_t long_value = 0;
  293|  6.54k|        memcpy(&long_value, &info->missing_double_values[i], 8);
  294|       |
  295|  6.54k|        if (long_value == ctx->missing_double)
  ------------------
  |  Branch (295:13): [True: 490, False: 6.05k]
  ------------------
  296|    490|            info->missing_double_values[i] = NAN;
  297|  6.54k|        if (long_value == ctx->lowest_double)
  ------------------
  |  Branch (297:13): [True: 460, False: 6.08k]
  ------------------
  298|    460|            info->missing_double_values[i] = -HUGE_VAL;
  299|  6.54k|        if (long_value == ctx->highest_double)
  ------------------
  |  Branch (299:13): [True: 358, False: 6.18k]
  ------------------
  300|    358|            info->missing_double_values[i] = HUGE_VAL;
  301|  6.54k|    }
  302|       |
  303|  3.04k|cleanup:
  304|  3.04k|    return retval;
  305|  3.03k|}
readstat_sav_read.c:sav_read_variable_missing_string_values:
  307|  2.90k|static readstat_error_t sav_read_variable_missing_string_values(spss_varinfo_t *info, sav_ctx_t *ctx) {
  308|  2.90k|    readstat_io_t *io = ctx->io;
  309|  2.90k|    int i;
  310|  2.90k|    readstat_error_t retval = READSTAT_OK;
  311|  8.48k|    for (i=0; i<info->n_missing_values; i++) {
  ------------------
  |  Branch (311:15): [True: 5.59k, False: 2.89k]
  ------------------
  312|  5.59k|        char missing_value[8];
  313|  5.59k|        if (io->read(missing_value, sizeof(missing_value), io->io_ctx) < sizeof(missing_value)) {
  ------------------
  |  Branch (313:13): [True: 5, False: 5.58k]
  ------------------
  314|      5|            retval = READSTAT_ERROR_READ;
  315|      5|            goto cleanup;
  316|      5|        }
  317|  5.58k|        retval = readstat_convert(info->missing_string_values[i], sizeof(info->missing_string_values[0]),
  318|  5.58k|                missing_value, sizeof(missing_value), ctx->converter);
  319|  5.58k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (319:13): [True: 1, False: 5.58k]
  ------------------
  320|      1|            goto cleanup;
  321|  5.58k|    }
  322|       |
  323|  2.90k|cleanup:
  324|  2.90k|    return retval;
  325|  2.90k|}
readstat_sav_read.c:sav_read_value_label_record:
  508|  4.51k|static readstat_error_t sav_read_value_label_record(sav_ctx_t *ctx) {
  509|  4.51k|    uint32_t label_count;
  510|  4.51k|    readstat_error_t retval = READSTAT_OK;
  511|  4.51k|    readstat_io_t *io = ctx->io;
  512|  4.51k|    uint32_t *vars = NULL;
  513|  4.51k|    uint32_t var_count;
  514|  4.51k|    int32_t rec_type;
  515|  4.51k|    readstat_type_t value_type = READSTAT_TYPE_STRING;
  516|  4.51k|    char label_buf[256];
  517|  4.51k|    value_label_t *value_labels = NULL;
  518|       |
  519|  4.51k|    if (io->read(&label_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (519:9): [True: 6, False: 4.50k]
  ------------------
  520|      6|        retval = READSTAT_ERROR_READ;
  521|      6|        goto cleanup;
  522|      6|    }
  523|  4.50k|    if (ctx->bswap)
  ------------------
  |  Branch (523:9): [True: 1.75k, False: 2.74k]
  ------------------
  524|  1.75k|        label_count = byteswap4(label_count);
  525|       |    
  526|  4.50k|    if (label_count && (value_labels = readstat_calloc(label_count, sizeof(value_label_t))) == NULL) {
  ------------------
  |  Branch (526:9): [True: 859, False: 3.64k]
  |  Branch (526:24): [True: 54, False: 805]
  ------------------
  527|     54|        retval = READSTAT_ERROR_MALLOC;
  528|     54|        goto cleanup;
  529|     54|    }
  530|       |    
  531|  4.45k|    int i;
  532|  17.9k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (532:15): [True: 13.5k, False: 4.41k]
  ------------------
  533|  13.5k|        value_label_t *vlabel = &value_labels[i];
  534|  13.5k|        unsigned char unpadded_label_len = 0;
  535|  13.5k|        size_t padded_label_len = 0, utf8_label_len = 0;
  536|       |
  537|  13.5k|        if (io->read(vlabel->raw_value, 8, io->io_ctx) < 8) {
  ------------------
  |  Branch (537:13): [True: 24, False: 13.5k]
  ------------------
  538|     24|            retval = READSTAT_ERROR_READ;
  539|     24|            goto cleanup;
  540|     24|        }
  541|  13.5k|        if (io->read(&unpadded_label_len, 1, io->io_ctx) < 1) {
  ------------------
  |  Branch (541:13): [True: 6, False: 13.5k]
  ------------------
  542|      6|            retval = READSTAT_ERROR_READ;
  543|      6|            goto cleanup;
  544|      6|        }
  545|       |
  546|  13.5k|        padded_label_len = (unpadded_label_len + 8) / 8 * 8 - 1;
  547|  13.5k|        if (io->read(label_buf, padded_label_len, io->io_ctx) < padded_label_len) {
  ------------------
  |  Branch (547:13): [True: 10, False: 13.5k]
  ------------------
  548|     10|            retval = READSTAT_ERROR_READ;
  549|     10|            goto cleanup;
  550|     10|        }
  551|       |
  552|  13.5k|        utf8_label_len = padded_label_len*4+1;
  553|  13.5k|        if ((vlabel->label = readstat_malloc(utf8_label_len)) == NULL) {
  ------------------
  |  Branch (553:13): [True: 0, False: 13.5k]
  ------------------
  554|      0|            retval = READSTAT_ERROR_MALLOC;
  555|      0|            goto cleanup;
  556|      0|        }
  557|       |
  558|  13.5k|        retval = readstat_convert(vlabel->label, utf8_label_len, label_buf, padded_label_len, ctx->converter);
  559|  13.5k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (559:13): [True: 1, False: 13.5k]
  ------------------
  560|      1|            goto cleanup;
  561|  13.5k|    }
  562|       |
  563|  4.41k|    if (io->read(&rec_type, sizeof(int32_t), io->io_ctx) < sizeof(int32_t)) {
  ------------------
  |  Branch (563:9): [True: 3, False: 4.40k]
  ------------------
  564|      3|        retval = READSTAT_ERROR_READ;
  565|      3|        goto cleanup;
  566|      3|    }
  567|  4.40k|    if (ctx->bswap)
  ------------------
  |  Branch (567:9): [True: 1.74k, False: 2.66k]
  ------------------
  568|  1.74k|        rec_type = byteswap4(rec_type);
  569|       |    
  570|  4.40k|    if (rec_type != 4) {
  ------------------
  |  Branch (570:9): [True: 51, False: 4.35k]
  ------------------
  571|     51|        retval = READSTAT_ERROR_PARSE;
  572|     51|        goto cleanup;
  573|     51|    }
  574|  4.35k|    if (io->read(&var_count, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (574:9): [True: 1, False: 4.35k]
  ------------------
  575|      1|        retval = READSTAT_ERROR_READ;
  576|      1|        goto cleanup;
  577|      1|    }
  578|  4.35k|    if (ctx->bswap)
  ------------------
  |  Branch (578:9): [True: 1.71k, False: 2.63k]
  ------------------
  579|  1.71k|        var_count = byteswap4(var_count);
  580|       |    
  581|  4.35k|    if (var_count && (vars = readstat_malloc(var_count * sizeof(uint32_t))) == NULL) {
  ------------------
  |  Branch (581:9): [True: 1.27k, False: 3.08k]
  |  Branch (581:22): [True: 45, False: 1.22k]
  ------------------
  582|     45|        retval = READSTAT_ERROR_MALLOC;
  583|     45|        goto cleanup;
  584|     45|    }
  585|  4.31k|    if (io->read(vars, var_count * sizeof(uint32_t), io->io_ctx) < var_count * sizeof(uint32_t)) {
  ------------------
  |  Branch (585:9): [True: 9, False: 4.30k]
  ------------------
  586|      9|        retval = READSTAT_ERROR_READ;
  587|      9|        goto cleanup;
  588|      9|    }
  589|   171k|    for (i=0; i<var_count; i++) {
  ------------------
  |  Branch (589:15): [True: 167k, False: 4.30k]
  ------------------
  590|   167k|        uint32_t var_offset = vars[i];
  591|   167k|        if (ctx->bswap)
  ------------------
  |  Branch (591:13): [True: 78.7k, False: 88.5k]
  ------------------
  592|  78.7k|            var_offset = byteswap4(var_offset);
  593|       |
  594|   167k|        var_offset--; // Why subtract 1????
  595|   167k|        spss_varinfo_t **var = bsearch(&var_offset, ctx->varinfo, ctx->var_index, sizeof(spss_varinfo_t *),
  596|   167k|                &spss_varinfo_compare);
  597|   167k|        if (var) {
  ------------------
  |  Branch (597:13): [True: 6.28k, False: 160k]
  ------------------
  598|  6.28k|            (*var)->labels_index = ctx->value_labels_count;
  599|  6.28k|            value_type = (*var)->type;
  600|  6.28k|        }
  601|   167k|    }
  602|       |
  603|  17.6k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (603:15): [True: 13.3k, False: 4.30k]
  ------------------
  604|  13.3k|        value_label_t *vlabel = &value_labels[i];
  605|  13.3k|        double val_d = 0.0;
  606|  13.3k|        vlabel->final_value.type = value_type;
  607|  13.3k|        if (value_type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (607:13): [True: 2.17k, False: 11.1k]
  ------------------
  608|  2.17k|            memcpy(&val_d, vlabel->raw_value, 8);
  609|  2.17k|            if (ctx->bswap)
  ------------------
  |  Branch (609:17): [True: 1.29k, False: 886]
  ------------------
  610|  1.29k|                val_d = byteswap_double(val_d);
  611|       |
  612|  2.17k|            vlabel->final_value.v.double_value = val_d;
  613|  2.17k|            sav_tag_missing_double(&vlabel->final_value, ctx);
  614|  11.1k|        } else {
  615|  11.1k|            retval = readstat_convert(vlabel->utf8_string_value, sizeof(vlabel->utf8_string_value),
  616|  11.1k|                    vlabel->raw_value, 8, ctx->converter);
  617|  11.1k|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (617:17): [True: 2, False: 11.1k]
  ------------------
  618|      2|                break;
  619|       |
  620|  11.1k|            vlabel->final_value.v.string_value = vlabel->utf8_string_value;
  621|  11.1k|        }
  622|  13.3k|    }
  623|       |
  624|  4.30k|    if (ctx->handle.value_label) {
  ------------------
  |  Branch (624:9): [True: 4.30k, False: 0]
  ------------------
  625|  4.30k|        sav_submit_value_labels(value_labels, label_count, value_type, ctx);
  626|  4.30k|    }
  627|  4.30k|    ctx->value_labels_count++;
  628|  4.51k|cleanup:
  629|  4.51k|    if (vars)
  ------------------
  |  Branch (629:9): [True: 1.22k, False: 3.28k]
  ------------------
  630|  1.22k|        free(vars);
  631|  4.51k|    if (value_labels) {
  ------------------
  |  Branch (631:9): [True: 805, False: 3.70k]
  ------------------
  632|  4.11M|        for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (632:19): [True: 4.11M, False: 805]
  ------------------
  633|  4.11M|            value_label_t *vlabel = &value_labels[i];
  634|  4.11M|            if (vlabel->label)
  ------------------
  |  Branch (634:17): [True: 13.5k, False: 4.09M]
  ------------------
  635|  13.5k|                free(vlabel->label);
  636|  4.11M|        }
  637|    805|        free(value_labels);
  638|    805|    }
  639|       |    
  640|  4.51k|    return retval;
  641|  4.30k|}
readstat_sav_read.c:sav_tag_missing_double:
  177|  1.24M|static void sav_tag_missing_double(readstat_value_t *value, sav_ctx_t *ctx) {
  178|  1.24M|    double fp_value = value->v.double_value;
  179|  1.24M|    uint64_t long_value = 0;
  180|  1.24M|    memcpy(&long_value, &fp_value, 8);
  181|  1.24M|    if (long_value == ctx->missing_double)
  ------------------
  |  Branch (181:9): [True: 34.4k, False: 1.20M]
  ------------------
  182|  34.4k|        value->is_system_missing = 1;
  183|  1.24M|    if (long_value == ctx->lowest_double)
  ------------------
  |  Branch (183:9): [True: 517, False: 1.24M]
  ------------------
  184|    517|        value->is_system_missing = 1;
  185|  1.24M|    if (long_value == ctx->highest_double)
  ------------------
  |  Branch (185:9): [True: 495, False: 1.24M]
  ------------------
  186|    495|        value->is_system_missing = 1;
  187|  1.24M|    if (isnan(fp_value))
  ------------------
  |  Branch (187:9): [True: 921, False: 1.24M]
  ------------------
  188|    921|        value->is_system_missing = 1;
  189|  1.24M|}
readstat_sav_read.c:sav_submit_value_labels:
  490|  4.30k|        readstat_type_t value_type, sav_ctx_t *ctx) {
  491|  4.30k|    char label_name_buf[256];
  492|  4.30k|    readstat_error_t retval = READSTAT_OK;
  493|  4.30k|    int32_t i;
  494|       |
  495|  4.30k|    snprintf(label_name_buf, sizeof(label_name_buf), SAV_LABEL_NAME_PREFIX "%d", ctx->value_labels_count);
  ------------------
  |  |  117|  4.30k|#define SAV_LABEL_NAME_PREFIX         "labels"
  ------------------
  496|       |
  497|  17.6k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (497:15): [True: 13.3k, False: 4.30k]
  ------------------
  498|  13.3k|        value_label_t *vlabel = &value_labels[i];
  499|  13.3k|        if (ctx->handle.value_label(label_name_buf, vlabel->final_value, vlabel->label, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (499:13): [True: 0, False: 13.3k]
  ------------------
  500|      0|            retval = READSTAT_ERROR_USER_ABORT;
  501|      0|            goto cleanup;
  502|      0|        }
  503|  13.3k|    }
  504|  4.30k|cleanup:
  505|  4.30k|    return retval;
  506|  4.30k|}
readstat_sav_read.c:sav_read_document_record:
  662|  1.05k|static readstat_error_t sav_read_document_record(sav_ctx_t *ctx) {
  663|  1.05k|    if (!ctx->handle.note)
  ------------------
  |  Branch (663:9): [True: 0, False: 1.05k]
  ------------------
  664|      0|        return sav_skip_document_record(ctx);
  665|       |
  666|  1.05k|    uint32_t n_lines;
  667|  1.05k|    readstat_error_t retval = READSTAT_OK;
  668|  1.05k|    readstat_io_t *io = ctx->io;
  669|  1.05k|    if (io->read(&n_lines, sizeof(uint32_t), io->io_ctx) < sizeof(uint32_t)) {
  ------------------
  |  Branch (669:9): [True: 1, False: 1.05k]
  ------------------
  670|      1|        retval = READSTAT_ERROR_READ;
  671|      1|        goto cleanup;
  672|      1|    }
  673|  1.05k|    if (ctx->bswap)
  ------------------
  |  Branch (673:9): [True: 359, False: 691]
  ------------------
  674|    359|        n_lines = byteswap4(n_lines);
  675|       |
  676|  1.05k|    char raw_buffer[SPSS_DOC_LINE_SIZE];
  677|  1.05k|    char utf8_buffer[4*SPSS_DOC_LINE_SIZE+1];
  678|  1.05k|    int i;
  679|  1.44k|    for (i=0; i<n_lines; i++) {
  ------------------
  |  Branch (679:15): [True: 457, False: 987]
  ------------------
  680|    457|        if (io->read(raw_buffer, SPSS_DOC_LINE_SIZE, io->io_ctx) < SPSS_DOC_LINE_SIZE) {
  ------------------
  |  |   40|    457|#define SPSS_DOC_LINE_SIZE  80
  ------------------
                      if (io->read(raw_buffer, SPSS_DOC_LINE_SIZE, io->io_ctx) < SPSS_DOC_LINE_SIZE) {
  ------------------
  |  |   40|    457|#define SPSS_DOC_LINE_SIZE  80
  ------------------
  |  Branch (680:13): [True: 62, False: 395]
  ------------------
  681|     62|            retval = READSTAT_ERROR_READ;
  682|     62|            goto cleanup;
  683|     62|        }
  684|       |
  685|    395|        retval = readstat_convert(utf8_buffer, sizeof(utf8_buffer),
  686|    395|                raw_buffer, sizeof(raw_buffer), ctx->converter);
  687|    395|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (687:13): [True: 1, False: 394]
  ------------------
  688|      1|            goto cleanup;
  689|       |
  690|    394|        if (ctx->handle.note(i, utf8_buffer, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (690:13): [True: 0, False: 394]
  ------------------
  691|      0|            retval = READSTAT_ERROR_USER_ABORT;
  692|      0|            goto cleanup;
  693|      0|        }
  694|    394|    }
  695|       |
  696|  1.05k|cleanup:
  697|  1.05k|    return retval;
  698|  1.05k|}
readstat_sav_read.c:sav_read_dictionary_termination_record:
  700|  3.07k|static readstat_error_t sav_read_dictionary_termination_record(sav_ctx_t *ctx) {
  701|  3.07k|    int32_t filler;
  702|  3.07k|    readstat_error_t retval = READSTAT_OK;
  703|  3.07k|    readstat_io_t *io = ctx->io;
  704|  3.07k|    if (io->read(&filler, sizeof(int32_t), io->io_ctx) < sizeof(int32_t)) {
  ------------------
  |  Branch (704:9): [True: 1.13k, False: 1.94k]
  ------------------
  705|  1.13k|        retval = READSTAT_ERROR_READ;
  706|  1.13k|    }
  707|  3.07k|    return retval;
  708|  3.07k|}
readstat_sav_read.c:sav_parse_machine_floating_point_record:
  996|    691|static readstat_error_t sav_parse_machine_floating_point_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
  997|    691|    if (size != 8 || count != 3)
  ------------------
  |  Branch (997:9): [True: 2, False: 689]
  |  Branch (997:22): [True: 14, False: 675]
  ------------------
  998|     16|        return READSTAT_ERROR_PARSE;
  999|       |
 1000|    675|    sav_machine_floating_point_info_record_t fp_info;
 1001|    675|    memcpy(&fp_info, data, sizeof(sav_machine_floating_point_info_record_t));
 1002|       |
 1003|    675|    ctx->missing_double = ctx->bswap ? byteswap8(fp_info.sysmis) : fp_info.sysmis;
  ------------------
  |  Branch (1003:27): [True: 268, False: 407]
  ------------------
 1004|    675|    ctx->highest_double = ctx->bswap ? byteswap8(fp_info.highest) : fp_info.highest;
  ------------------
  |  Branch (1004:27): [True: 268, False: 407]
  ------------------
 1005|    675|    ctx->lowest_double = ctx->bswap ? byteswap8(fp_info.lowest) : fp_info.lowest;
  ------------------
  |  Branch (1005:26): [True: 268, False: 407]
  ------------------
 1006|       |
 1007|    675|    return READSTAT_OK;
 1008|    691|}
readstat_sav_read.c:sav_store_variable_display_parameter_record:
 1012|    503|static readstat_error_t sav_store_variable_display_parameter_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
 1013|    503|    if (size != 4)
  ------------------
  |  Branch (1013:9): [True: 15, False: 488]
  ------------------
 1014|     15|        return READSTAT_ERROR_PARSE;
 1015|       |
 1016|    488|    const uint32_t *data_ptr = data;
 1017|    488|    int i;
 1018|       |
 1019|    488|    ctx->variable_display_values = readstat_realloc(ctx->variable_display_values, count * sizeof(uint32_t));
 1020|    488|    if (count > 0 && ctx->variable_display_values == NULL)
  ------------------
  |  Branch (1020:9): [True: 488, False: 0]
  |  Branch (1020:22): [True: 0, False: 488]
  ------------------
 1021|      0|        return READSTAT_ERROR_MALLOC;
 1022|       |
 1023|    488|    ctx->variable_display_values_count = count;
 1024|   264k|    for (i=0; i<count; i++) {
  ------------------
  |  Branch (1024:15): [True: 264k, False: 488]
  ------------------
 1025|   264k|        ctx->variable_display_values[i] = ctx->bswap ? byteswap4(data_ptr[i]) : data_ptr[i];
  ------------------
  |  Branch (1025:43): [True: 133k, False: 130k]
  ------------------
 1026|   264k|    }
 1027|    488|    return READSTAT_OK;
 1028|    488|}
readstat_sav_read.c:sav_parse_long_string_value_labels_record:
 1090|    679|static readstat_error_t sav_parse_long_string_value_labels_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
 1091|    679|    if (!ctx->handle.value_label)
  ------------------
  |  Branch (1091:9): [True: 0, False: 679]
  ------------------
 1092|      0|        return READSTAT_OK;
 1093|    679|    if (size != 1)
  ------------------
  |  Branch (1093:9): [True: 4, False: 675]
  ------------------
 1094|      4|        return READSTAT_ERROR_PARSE;
 1095|       |
 1096|    675|    readstat_error_t retval = READSTAT_OK;
 1097|    675|    uint32_t label_count = 0;
 1098|    675|    uint32_t i = 0;
 1099|    675|    const char *data_ptr = data;
 1100|    675|    const char *data_end = data_ptr + count;
 1101|    675|    char var_name_buf[256+1]; // unconverted
 1102|    675|    char label_name_buf[256];
 1103|    675|    char *value_buffer = NULL;
 1104|    675|    char *label_buffer = NULL;
 1105|       |    
 1106|  1.83k|    while (data_ptr < data_end) {
  ------------------
  |  Branch (1106:12): [True: 1.41k, False: 425]
  ------------------
 1107|  1.41k|        memset(label_name_buf, '\0', sizeof(label_name_buf));
 1108|       |
 1109|  1.41k|        retval = sav_read_pascal_string(var_name_buf, sizeof(var_name_buf),
 1110|  1.41k|                &data_ptr, data_end - data_ptr, ctx);
 1111|  1.41k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1111:13): [True: 79, False: 1.33k]
  ------------------
 1112|     79|            goto cleanup;
 1113|       |
 1114|  4.10k|        for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1114:19): [True: 4.02k, False: 77]
  ------------------
 1115|  4.02k|            spss_varinfo_t *info = ctx->varinfo[i];
 1116|  4.02k|            if (strcmp(var_name_buf, info->longname) == 0) {
  ------------------
  |  Branch (1116:17): [True: 1.25k, False: 2.76k]
  ------------------
 1117|  1.25k|                info->labels_index = ctx->value_labels_count++;
 1118|  1.25k|                snprintf(label_name_buf, sizeof(label_name_buf),
 1119|  1.25k|                        SAV_LABEL_NAME_PREFIX "%d", info->labels_index);
  ------------------
  |  |  117|  1.25k|#define SAV_LABEL_NAME_PREFIX         "labels"
  ------------------
 1120|  1.25k|                break;
 1121|  1.25k|            }
 1122|  2.76k|            i += info->n_segments;
 1123|  2.76k|        }
 1124|       |
 1125|  1.33k|        if (label_name_buf[0] == '\0') {
  ------------------
  |  Branch (1125:13): [True: 77, False: 1.25k]
  ------------------
 1126|     77|            retval = READSTAT_ERROR_PARSE;
 1127|     77|            goto cleanup;
 1128|     77|        }
 1129|       |
 1130|  1.25k|        data_ptr += sizeof(uint32_t);
 1131|       |
 1132|  1.25k|        if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1132:13): [True: 15, False: 1.24k]
  ------------------
 1133|     15|            retval = READSTAT_ERROR_PARSE;
 1134|     15|            goto cleanup;
 1135|     15|        }
 1136|       |
 1137|  1.24k|        memcpy(&label_count, data_ptr, sizeof(uint32_t));
 1138|  1.24k|        if (ctx->bswap)
  ------------------
  |  Branch (1138:13): [True: 516, False: 727]
  ------------------
 1139|    516|            label_count = byteswap4(label_count);
 1140|       |
 1141|  1.24k|        data_ptr += sizeof(uint32_t);
 1142|       |
 1143|  1.81k|        for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (1143:19): [True: 649, False: 1.16k]
  ------------------
 1144|    649|            uint32_t value_len = 0, label_len = 0;
 1145|    649|            uint32_t value_buffer_len = 0, label_buffer_len = 0;
 1146|       |
 1147|    649|            if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1147:17): [True: 22, False: 627]
  ------------------
 1148|     22|                retval = READSTAT_ERROR_PARSE;
 1149|     22|                goto cleanup;
 1150|     22|            }
 1151|       |
 1152|    627|            memcpy(&value_len, data_ptr, sizeof(uint32_t));
 1153|    627|            if (ctx->bswap)
  ------------------
  |  Branch (1153:17): [True: 340, False: 287]
  ------------------
 1154|    340|                value_len = byteswap4(value_len);
 1155|       |
 1156|    627|            data_ptr += sizeof(uint32_t);
 1157|       |
 1158|    627|            value_buffer_len = value_len*4+1;
 1159|    627|            value_buffer = readstat_realloc(value_buffer, value_buffer_len);
 1160|    627|            if (value_buffer == NULL) {
  ------------------
  |  Branch (1160:17): [True: 22, False: 605]
  ------------------
 1161|     22|                retval = READSTAT_ERROR_MALLOC;
 1162|     22|                goto cleanup;
 1163|     22|            }
 1164|       |
 1165|    605|            if (data_ptr + value_len > data_end) {
  ------------------
  |  Branch (1165:17): [True: 11, False: 594]
  ------------------
 1166|     11|                retval = READSTAT_ERROR_PARSE;
 1167|     11|                goto cleanup;
 1168|     11|            }
 1169|       |
 1170|    594|            retval = readstat_convert(value_buffer, value_buffer_len, data_ptr, value_len, ctx->converter);
 1171|    594|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (1171:17): [True: 1, False: 593]
  ------------------
 1172|      1|                goto cleanup;
 1173|       |
 1174|    593|            data_ptr += value_len;
 1175|       |
 1176|    593|            if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1176:17): [True: 6, False: 587]
  ------------------
 1177|      6|                retval = READSTAT_ERROR_PARSE;
 1178|      6|                goto cleanup;
 1179|      6|            }
 1180|       |
 1181|    587|            memcpy(&label_len, data_ptr, sizeof(uint32_t));
 1182|    587|            if (ctx->bswap)
  ------------------
  |  Branch (1182:17): [True: 321, False: 266]
  ------------------
 1183|    321|                label_len = byteswap4(label_len);
 1184|       |
 1185|    587|            data_ptr += sizeof(uint32_t);
 1186|       |
 1187|    587|            label_buffer_len = label_len*4+1;
 1188|    587|            label_buffer = readstat_realloc(label_buffer, label_buffer_len);
 1189|    587|            if (label_buffer == NULL) {
  ------------------
  |  Branch (1189:17): [True: 4, False: 583]
  ------------------
 1190|      4|                retval = READSTAT_ERROR_MALLOC;
 1191|      4|                goto cleanup;
 1192|      4|            }
 1193|       |
 1194|    583|            if (data_ptr + label_len > data_end) {
  ------------------
  |  Branch (1194:17): [True: 12, False: 571]
  ------------------
 1195|     12|                retval = READSTAT_ERROR_PARSE;
 1196|     12|                goto cleanup;
 1197|     12|            }
 1198|       |
 1199|    571|            retval = readstat_convert(label_buffer, label_buffer_len, data_ptr, label_len, ctx->converter);
 1200|    571|            if (retval != READSTAT_OK)
  ------------------
  |  Branch (1200:17): [True: 1, False: 570]
  ------------------
 1201|      1|                goto cleanup;
 1202|       |
 1203|    570|            data_ptr += label_len;
 1204|       |
 1205|    570|            readstat_value_t value = { .type = READSTAT_TYPE_STRING };
 1206|    570|            value.v.string_value = value_buffer;
 1207|       |
 1208|    570|            if (ctx->handle.value_label(label_name_buf, value, label_buffer, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (1208:17): [True: 0, False: 570]
  ------------------
 1209|      0|                retval = READSTAT_ERROR_USER_ABORT;
 1210|      0|                goto cleanup;
 1211|      0|            }
 1212|    570|        }
 1213|  1.24k|    }
 1214|       |
 1215|    425|    if (data_ptr != data_end) {
  ------------------
  |  Branch (1215:9): [True: 0, False: 425]
  ------------------
 1216|      0|        retval = READSTAT_ERROR_PARSE;
 1217|      0|    }
 1218|       |
 1219|    675|cleanup:
 1220|    675|    if (value_buffer)
  ------------------
  |  Branch (1220:9): [True: 272, False: 403]
  ------------------
 1221|    272|        free(value_buffer);
 1222|    675|    if (label_buffer)
  ------------------
  |  Branch (1222:9): [True: 257, False: 418]
  ------------------
 1223|    257|        free(label_buffer);
 1224|    675|    return retval;
 1225|    425|}
readstat_sav_read.c:sav_read_pascal_string:
 1056|  2.30k|        const char **inout_data_ptr, size_t data_ptr_len, sav_ctx_t *ctx) {
 1057|  2.30k|    const char *data_ptr = *inout_data_ptr;
 1058|  2.30k|    const char *data_end = data_ptr + data_ptr_len;
 1059|  2.30k|    readstat_error_t retval = READSTAT_OK;
 1060|  2.30k|    uint32_t var_name_len = 0;
 1061|       |
 1062|  2.30k|    if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1062:9): [True: 20, False: 2.28k]
  ------------------
 1063|     20|        retval = READSTAT_ERROR_PARSE;
 1064|     20|        goto cleanup;
 1065|     20|    }
 1066|       |
 1067|  2.28k|    memcpy(&var_name_len, data_ptr, sizeof(uint32_t));
 1068|  2.28k|    if (ctx->bswap)
  ------------------
  |  Branch (1068:9): [True: 906, False: 1.38k]
  ------------------
 1069|    906|        var_name_len = byteswap4(var_name_len);
 1070|       |
 1071|  2.28k|    data_ptr += sizeof(uint32_t);
 1072|       |
 1073|  2.28k|    if (data_ptr + var_name_len > data_end) {
  ------------------
  |  Branch (1073:9): [True: 102, False: 2.18k]
  ------------------
 1074|    102|        retval = READSTAT_ERROR_PARSE;
 1075|    102|        goto cleanup;
 1076|    102|    }
 1077|       |
 1078|  2.18k|    retval = readstat_convert(buf, buf_len, data_ptr, var_name_len, NULL);
 1079|  2.18k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (1079:9): [True: 10, False: 2.17k]
  ------------------
 1080|     10|        goto cleanup;
 1081|       |
 1082|  2.17k|    data_ptr += var_name_len;
 1083|       |
 1084|  2.30k|cleanup:
 1085|  2.30k|    *inout_data_ptr = data_ptr;
 1086|       |
 1087|  2.30k|    return retval;
 1088|  2.17k|}
readstat_sav_read.c:sav_parse_long_string_missing_values_record:
 1227|    438|static readstat_error_t sav_parse_long_string_missing_values_record(const void *data, size_t size, size_t count, sav_ctx_t *ctx) {
 1228|    438|    if (size != 1)
  ------------------
  |  Branch (1228:9): [True: 2, False: 436]
  ------------------
 1229|      2|        return READSTAT_ERROR_PARSE;
 1230|       |
 1231|    436|    readstat_error_t retval = READSTAT_OK;
 1232|    436|    uint32_t i = 0, j = 0;
 1233|    436|    const char *data_ptr = data;
 1234|    436|    const char *data_end = data_ptr + count;
 1235|    436|    char var_name_buf[256+1];
 1236|       |
 1237|  1.16k|    while (data_ptr < data_end) {
  ------------------
  |  Branch (1237:12): [True: 894, False: 269]
  ------------------
 1238|    894|        retval = sav_read_pascal_string(var_name_buf, sizeof(var_name_buf),
 1239|    894|                &data_ptr, data_end - data_ptr, ctx);
 1240|    894|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (1240:13): [True: 53, False: 841]
  ------------------
 1241|     53|            goto cleanup;
 1242|       |
 1243|    841|        if (data_ptr == data_end) {
  ------------------
  |  Branch (1243:13): [True: 8, False: 833]
  ------------------
 1244|      8|            retval = READSTAT_ERROR_PARSE;
 1245|      8|            goto cleanup;
 1246|      8|        }
 1247|       |
 1248|    833|        char n_missing_values = *data_ptr++;
 1249|    833|        if (n_missing_values < 1 || n_missing_values > 3) {
  ------------------
  |  Branch (1249:13): [True: 13, False: 820]
  |  Branch (1249:37): [True: 9, False: 811]
  ------------------
 1250|     22|            retval = READSTAT_ERROR_PARSE;
 1251|     22|            goto cleanup;
 1252|     22|        }
 1253|       |
 1254|   114k|        for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1254:19): [True: 114k, False: 60]
  ------------------
 1255|   114k|            spss_varinfo_t *info = ctx->varinfo[i];
 1256|   114k|            if (strcmp(var_name_buf, info->longname) == 0) {
  ------------------
  |  Branch (1256:17): [True: 751, False: 113k]
  ------------------
 1257|    751|                info->n_missing_values = n_missing_values;
 1258|       |
 1259|    751|                uint32_t var_name_len = 0;
 1260|       |
 1261|    751|                if (data_ptr + sizeof(uint32_t) > data_end) {
  ------------------
  |  Branch (1261:21): [True: 10, False: 741]
  ------------------
 1262|     10|                    retval = READSTAT_ERROR_PARSE;
 1263|     10|                    goto cleanup;
 1264|     10|                }
 1265|       |
 1266|    741|                memcpy(&var_name_len, data_ptr, sizeof(uint32_t));
 1267|    741|                if (ctx->bswap)
  ------------------
  |  Branch (1267:21): [True: 322, False: 419]
  ------------------
 1268|    322|                    var_name_len = byteswap4(var_name_len);
 1269|       |
 1270|    741|                data_ptr += sizeof(uint32_t);
 1271|       |
 1272|  2.72k|                for (j=0; j<n_missing_values; j++) {
  ------------------
  |  Branch (1272:27): [True: 1.99k, False: 727]
  ------------------
 1273|  1.99k|                    if (data_ptr + var_name_len > data_end) {
  ------------------
  |  Branch (1273:25): [True: 5, False: 1.99k]
  ------------------
 1274|      5|                        retval = READSTAT_ERROR_PARSE;
 1275|      5|                        goto cleanup;
 1276|      5|                    }
 1277|       |
 1278|  1.99k|                    retval = readstat_convert(info->missing_string_values[j],
 1279|  1.99k|                            sizeof(info->missing_string_values[0]),
 1280|  1.99k|                            data_ptr, var_name_len, ctx->converter);
 1281|  1.99k|                    if (retval != READSTAT_OK)
  ------------------
  |  Branch (1281:25): [True: 9, False: 1.98k]
  ------------------
 1282|      9|                        goto cleanup;
 1283|       |
 1284|  1.98k|                    data_ptr += var_name_len;
 1285|  1.98k|                }
 1286|    727|                break;
 1287|    741|            }
 1288|   113k|            i += info->n_segments;
 1289|   113k|        }
 1290|    787|        if (i == ctx->var_index) {
  ------------------
  |  Branch (1290:13): [True: 60, False: 727]
  ------------------
 1291|     60|            retval = READSTAT_ERROR_PARSE;
 1292|     60|            goto cleanup;
 1293|     60|        }
 1294|    787|    }
 1295|       |
 1296|    269|    if (data_ptr != data_end) {
  ------------------
  |  Branch (1296:9): [True: 0, False: 269]
  ------------------
 1297|      0|        retval = READSTAT_ERROR_PARSE;
 1298|      0|    }
 1299|       |
 1300|    436|cleanup:
 1301|    436|    return retval;
 1302|    269|}
readstat_sav_read.c:sav_set_n_segments_and_var_count:
 1514|  1.94k|static readstat_error_t sav_set_n_segments_and_var_count(sav_ctx_t *ctx) {
 1515|  1.94k|    int i;
 1516|  1.94k|    ctx->var_count = 0;
 1517|   312k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1517:15): [True: 310k, False: 1.91k]
  ------------------
 1518|   310k|        spss_varinfo_t *info = ctx->varinfo[i];
 1519|   310k|        if (info->string_length > VERY_LONG_STRING_MAX_LENGTH)
  ------------------
  |  |   30|   310k|#define VERY_LONG_STRING_MAX_LENGTH INT_MAX
  ------------------
  |  Branch (1519:13): [True: 33, False: 310k]
  ------------------
 1520|     33|            return READSTAT_ERROR_PARSE;
 1521|   310k|        if (info->string_length) {
  ------------------
  |  Branch (1521:13): [True: 951, False: 309k]
  ------------------
 1522|    951|            info->n_segments = (info->string_length + 251) / 252;
 1523|    951|        }
 1524|   310k|        info->index = ctx->var_count++;
 1525|   310k|        i += info->n_segments;
 1526|   310k|    }
 1527|  1.91k|    ctx->variables = readstat_calloc(ctx->var_count, sizeof(readstat_variable_t *));
 1528|  1.91k|    return READSTAT_OK;
 1529|  1.94k|}
readstat_sav_read.c:sav_parse_variable_display_parameter_record:
 1030|  1.88k|static readstat_error_t sav_parse_variable_display_parameter_record(sav_ctx_t *ctx) {
 1031|  1.88k|    if (!ctx->variable_display_values)
  ------------------
  |  Branch (1031:9): [True: 1.66k, False: 227]
  ------------------
 1032|  1.66k|        return READSTAT_OK;
 1033|       |
 1034|    227|    int i;
 1035|    227|    long count = ctx->variable_display_values_count;
 1036|    227|    if (count != 2 * ctx->var_index && count != 3 * ctx->var_index) {
  ------------------
  |  Branch (1036:9): [True: 158, False: 69]
  |  Branch (1036:40): [True: 36, False: 122]
  ------------------
 1037|     36|        return READSTAT_ERROR_PARSE;
 1038|     36|    }
 1039|    191|    int has_display_width = ctx->var_index > 0 && (count / ctx->var_index == 3);
  ------------------
  |  Branch (1039:29): [True: 191, False: 0]
  |  Branch (1039:51): [True: 122, False: 69]
  ------------------
 1040|    191|    int offset = 0;
 1041|  5.03k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1041:15): [True: 4.84k, False: 191]
  ------------------
 1042|  4.84k|        spss_varinfo_t *info = ctx->varinfo[i];
 1043|  4.84k|        offset = (2 + has_display_width)*i;
 1044|  4.84k|        info->measure = spss_measure_to_readstat_measure(ctx->variable_display_values[offset++]);
 1045|  4.84k|        if (has_display_width) {
  ------------------
  |  Branch (1045:13): [True: 2.26k, False: 2.57k]
  ------------------
 1046|  2.26k|            info->display_width = ctx->variable_display_values[offset++];
 1047|  2.26k|        }
 1048|  4.84k|        info->alignment = spss_alignment_to_readstat_alignment(ctx->variable_display_values[offset++]);
 1049|       |
 1050|  4.84k|        i += info->n_segments;
 1051|  4.84k|    }
 1052|    191|    return READSTAT_OK;
 1053|    227|}
readstat_sav_read.c:sav_handle_variables:
 1531|  1.85k|static readstat_error_t sav_handle_variables(sav_ctx_t *ctx) {
 1532|  1.85k|    int i;
 1533|  1.85k|    int index_after_skipping = 0;
 1534|  1.85k|    readstat_error_t retval = READSTAT_OK;
 1535|       |
 1536|  1.85k|    if (!ctx->handle.variable)
  ------------------
  |  Branch (1536:9): [True: 0, False: 1.85k]
  ------------------
 1537|      0|        return retval;
 1538|       |
 1539|   309k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1539:15): [True: 307k, False: 1.85k]
  ------------------
 1540|   307k|        char label_name_buf[256];
 1541|   307k|        spss_varinfo_t *info = ctx->varinfo[i];
 1542|   307k|        ctx->variables[info->index] = spss_init_variable_for_info(info, index_after_skipping, ctx->converter);
 1543|       |
 1544|   307k|        snprintf(label_name_buf, sizeof(label_name_buf), SAV_LABEL_NAME_PREFIX "%d", info->labels_index);
  ------------------
  |  |  117|   307k|#define SAV_LABEL_NAME_PREFIX         "labels"
  ------------------
 1545|       |
 1546|   307k|        int cb_retval = ctx->handle.variable(info->index, ctx->variables[info->index],
 1547|   307k|                info->labels_index == -1 ? NULL : label_name_buf,
  ------------------
  |  Branch (1547:17): [True: 307k, False: 134]
  ------------------
 1548|   307k|                ctx->user_ctx);
 1549|       |
 1550|   307k|        if (cb_retval == READSTAT_HANDLER_ABORT) {
  ------------------
  |  Branch (1550:13): [True: 0, False: 307k]
  ------------------
 1551|      0|            retval = READSTAT_ERROR_USER_ABORT;
 1552|      0|            goto cleanup;
 1553|      0|        }
 1554|       |
 1555|   307k|        if (cb_retval == READSTAT_HANDLER_SKIP_VARIABLE) {
  ------------------
  |  Branch (1555:13): [True: 0, False: 307k]
  ------------------
 1556|      0|            ctx->variables[info->index]->skip = 1;
 1557|   307k|        } else {
 1558|   307k|            index_after_skipping++;
 1559|   307k|        }
 1560|       |
 1561|   307k|        i += info->n_segments;
 1562|   307k|    }
 1563|  1.85k|cleanup:
 1564|  1.85k|    return retval;
 1565|  1.85k|}
readstat_sav_read.c:sav_handle_fweight:
 1567|  1.85k|static readstat_error_t sav_handle_fweight(sav_ctx_t *ctx) {
 1568|  1.85k|    readstat_error_t retval = READSTAT_OK;
 1569|  1.85k|    int i;
 1570|  1.85k|    if (ctx->handle.fweight && ctx->fweight_index >= 0) {
  ------------------
  |  Branch (1570:9): [True: 1.85k, False: 0]
  |  Branch (1570:32): [True: 1.34k, False: 507]
  ------------------
 1571|   301k|        for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (1571:19): [True: 299k, False: 1.31k]
  ------------------
 1572|   299k|            spss_varinfo_t *info = ctx->varinfo[i];
 1573|   299k|            if (info->offset == ctx->fweight_index - 1) {
  ------------------
  |  Branch (1573:17): [True: 27, False: 299k]
  ------------------
 1574|     27|                if (ctx->handle.fweight(ctx->variables[info->index], ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (1574:21): [True: 0, False: 27]
  ------------------
 1575|      0|                    retval = READSTAT_ERROR_USER_ABORT;
 1576|      0|                    goto cleanup;
 1577|      0|                }
 1578|     27|                break;
 1579|     27|            }
 1580|   299k|            i += info->n_segments;
 1581|   299k|        }
 1582|  1.34k|    }
 1583|  1.85k|cleanup:
 1584|  1.85k|    return retval;
 1585|  1.85k|}
readstat_sav_read.c:sav_read_data:
  795|  1.85k|static readstat_error_t sav_read_data(sav_ctx_t *ctx) {
  796|  1.85k|    readstat_error_t retval = READSTAT_OK;
  797|  1.85k|    size_t longest_string = 256;
  798|  1.85k|    int i;
  799|       |
  800|   309k|    for (i=0; i<ctx->var_index;) {
  ------------------
  |  Branch (800:15): [True: 307k, False: 1.85k]
  ------------------
  801|   307k|        spss_varinfo_t *info = ctx->varinfo[i];
  802|   307k|        if (info->string_length > longest_string) {
  ------------------
  |  Branch (802:13): [True: 181, False: 307k]
  ------------------
  803|    181|            longest_string = info->string_length;
  804|    181|        }
  805|   307k|        i += info->n_segments;
  806|   307k|    }
  807|       |
  808|  1.85k|    ctx->raw_string_len = longest_string + sizeof(SAV_EIGHT_SPACES)-2;
  ------------------
  |  |  143|  1.85k|#define SAV_EIGHT_SPACES              "        "
  ------------------
  809|  1.85k|    ctx->raw_string = readstat_malloc(ctx->raw_string_len);
  810|       |
  811|  1.85k|    ctx->utf8_string_len = 4*longest_string+1 + sizeof(SAV_EIGHT_SPACES)-2;
  ------------------
  |  |  143|  1.85k|#define SAV_EIGHT_SPACES              "        "
  ------------------
  812|  1.85k|    ctx->utf8_string = readstat_malloc(ctx->utf8_string_len);
  813|       |
  814|  1.85k|    if (ctx->raw_string == NULL || ctx->utf8_string == NULL) {
  ------------------
  |  Branch (814:9): [True: 31, False: 1.82k]
  |  Branch (814:36): [True: 4, False: 1.81k]
  ------------------
  815|     35|        retval = READSTAT_ERROR_MALLOC;
  816|     35|        goto done;
  817|     35|    }
  818|       |
  819|  1.81k|    if (ctx->compression == READSTAT_COMPRESS_ROWS) {
  ------------------
  |  Branch (819:9): [True: 379, False: 1.43k]
  ------------------
  820|    379|        retval = sav_read_compressed_data(ctx, &sav_process_row);
  821|  1.43k|    } else if (ctx->compression == READSTAT_COMPRESS_BINARY) {
  ------------------
  |  Branch (821:16): [True: 456, False: 982]
  ------------------
  822|    456|#if HAVE_ZLIB
  823|    456|        retval = zsav_read_compressed_data(ctx, &sav_process_row);
  824|       |#else
  825|       |        retval = READSTAT_ERROR_UNSUPPORTED_COMPRESSION;
  826|       |#endif
  827|    982|    } else {
  828|    982|        retval = sav_read_uncompressed_data(ctx, &sav_process_row);
  829|    982|    }
  830|  1.81k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (830:9): [True: 431, False: 1.38k]
  ------------------
  831|    431|        goto done;
  832|       |
  833|  1.38k|    if (ctx->record_count >= 0 && ctx->current_row != ctx->row_limit) {
  ------------------
  |  Branch (833:9): [True: 1.06k, False: 317]
  |  Branch (833:35): [True: 989, False: 80]
  ------------------
  834|    989|        retval = READSTAT_ERROR_ROW_COUNT_MISMATCH;
  835|    989|    }
  836|       |
  837|  1.85k|done:
  838|  1.85k|    return retval;
  839|  1.38k|}
readstat_sav_read.c:sav_read_compressed_data:
  879|    379|        readstat_error_t (*row_handler)(unsigned char *, size_t, sav_ctx_t *)) {
  880|    379|    readstat_error_t retval = READSTAT_OK;
  881|    379|    readstat_io_t *io = ctx->io;
  882|    379|    readstat_off_t data_offset = 0;
  883|    379|    unsigned char buffer[DATA_BUFFER_SIZE];
  884|    379|    int buffer_used = 0;
  885|       |
  886|    379|    size_t uncompressed_row_len = ctx->var_offset * 8;
  887|    379|    readstat_off_t uncompressed_offset = 0;
  888|    379|    unsigned char *uncompressed_row = NULL;
  889|       |
  890|    379|    struct sav_row_stream_s state = { 
  891|    379|        .missing_value = ctx->missing_double,
  892|    379|        .bias = ctx->bias,
  893|    379|        .bswap = ctx->bswap };
  894|       |
  895|    379|    if (uncompressed_row_len && (uncompressed_row = readstat_malloc(uncompressed_row_len)) == NULL) {
  ------------------
  |  Branch (895:9): [True: 379, False: 0]
  |  Branch (895:33): [True: 0, False: 379]
  ------------------
  896|      0|        retval = READSTAT_ERROR_MALLOC;
  897|      0|        goto done;
  898|      0|    }
  899|       |
  900|    710|    while (1) {
  ------------------
  |  Branch (900:12): [True: 710, Folded]
  ------------------
  901|    710|        retval = sav_update_progress(ctx);
  902|    710|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (902:13): [True: 0, False: 710]
  ------------------
  903|      0|            goto done;
  904|       |
  905|    710|        buffer_used = io->read(buffer, sizeof(buffer), io->io_ctx);
  906|    710|        if (buffer_used == -1 || buffer_used == 0 || (buffer_used % 8) != 0)
  ------------------
  |  Branch (906:13): [True: 0, False: 710]
  |  Branch (906:34): [True: 275, False: 435]
  |  Branch (906:54): [True: 70, False: 365]
  ------------------
  907|    345|            goto done;
  908|       |
  909|    365|        state.status = SAV_ROW_STREAM_HAVE_DATA;
  910|    365|        data_offset = 0;
  911|       |
  912|  2.25M|        while (state.status != SAV_ROW_STREAM_NEED_DATA) {
  ------------------
  |  Branch (912:16): [True: 2.25M, False: 331]
  ------------------
  913|  2.25M|            state.next_in = &buffer[data_offset];
  914|  2.25M|            state.avail_in = buffer_used - data_offset;
  915|       |
  916|  2.25M|            state.next_out = &uncompressed_row[uncompressed_offset];
  917|  2.25M|            state.avail_out = uncompressed_row_len - uncompressed_offset;
  918|       |
  919|  2.25M|            sav_decompress_row(&state);
  920|       |
  921|  2.25M|            uncompressed_offset = uncompressed_row_len - state.avail_out;
  922|  2.25M|            data_offset = buffer_used - state.avail_in;
  923|       |
  924|  2.25M|            if (state.status == SAV_ROW_STREAM_FINISHED_ROW) {
  ------------------
  |  Branch (924:17): [True: 2.25M, False: 347]
  ------------------
  925|  2.25M|                retval = row_handler(uncompressed_row, uncompressed_row_len, ctx);
  926|  2.25M|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (926:21): [True: 12, False: 2.25M]
  ------------------
  927|     12|                    goto done;
  928|       |
  929|  2.25M|                uncompressed_offset = 0;
  930|  2.25M|            }
  931|       |
  932|  2.25M|            if (state.status == SAV_ROW_STREAM_FINISHED_ALL)
  ------------------
  |  Branch (932:17): [True: 16, False: 2.25M]
  ------------------
  933|     16|                goto done;
  934|  2.25M|            if (ctx->row_limit > 0 && ctx->current_row == ctx->row_limit)
  ------------------
  |  Branch (934:17): [True: 256k, False: 1.99M]
  |  Branch (934:39): [True: 6, False: 256k]
  ------------------
  935|      6|                goto done;
  936|  2.25M|        }
  937|    365|    }
  938|       |
  939|    379|done:
  940|    379|    if (uncompressed_row)
  ------------------
  |  Branch (940:9): [True: 379, False: 0]
  ------------------
  941|    379|        free(uncompressed_row);
  942|       |
  943|    379|    return retval;
  944|    379|}
readstat_sav_read.c:sav_process_row:
  710|  2.25M|static readstat_error_t sav_process_row(unsigned char *buffer, size_t buffer_len, sav_ctx_t *ctx) {
  711|  2.25M|    if (ctx->row_offset) {
  ------------------
  |  Branch (711:9): [True: 0, False: 2.25M]
  ------------------
  712|      0|        ctx->row_offset--;
  713|      0|        return READSTAT_OK;
  714|      0|    }
  715|       |
  716|  2.25M|    readstat_error_t retval = READSTAT_OK;
  717|  2.25M|    double fp_value;
  718|  2.25M|    int offset = 0;
  719|  2.25M|    readstat_off_t data_offset = 0;
  720|  2.25M|    size_t raw_str_used = 0;
  721|  2.25M|    int segment_offset = 0;
  722|  2.25M|    int var_index = 0, col = 0;
  723|  2.25M|    int raw_str_is_utf8 = ctx->input_encoding && !strcmp(ctx->input_encoding, "UTF-8");
  ------------------
  |  Branch (723:27): [True: 823, False: 2.25M]
  |  Branch (723:50): [True: 748, False: 75]
  ------------------
  724|       |
  725|  4.53M|    while (data_offset < buffer_len && col < ctx->var_index && var_index < ctx->var_index) {
  ------------------
  |  Branch (725:12): [True: 2.59M, False: 1.94M]
  |  Branch (725:40): [True: 2.28M, False: 308k]
  |  Branch (725:64): [True: 2.28M, False: 68]
  ------------------
  726|  2.28M|        spss_varinfo_t *col_info = ctx->varinfo[col];
  727|  2.28M|        spss_varinfo_t *var_info = ctx->varinfo[var_index];
  728|  2.28M|        readstat_value_t value = { .type = var_info->type };
  729|  2.28M|        if (offset > 31) {
  ------------------
  |  Branch (729:13): [True: 1, False: 2.28M]
  ------------------
  730|      1|            retval = READSTAT_ERROR_PARSE;
  731|      1|            goto done;
  732|      1|        }
  733|  2.28M|        if (var_info->type == READSTAT_TYPE_STRING) {
  ------------------
  |  Branch (733:13): [True: 1.04M, False: 1.23M]
  ------------------
  734|       |            // If we're in the last column of a segment, only read 7 bytes
  735|       |            // (Segments contain 255 bytes but have room for 256)
  736|  1.04M|            size_t read_len = 8 - (offset == 31);
  737|  1.04M|            if (raw_str_used + read_len <= ctx->raw_string_len) {
  ------------------
  |  Branch (737:17): [True: 1.04M, False: 207]
  ------------------
  738|  1.04M|                if (raw_str_is_utf8) {
  ------------------
  |  Branch (738:21): [True: 1.07k, False: 1.04M]
  ------------------
  739|       |                    /* Skip null bytes, see https://github.com/tidyverse/haven/issues/560  */
  740|  1.07k|                    char c;
  741|  9.66k|                    for (int i=0; i<read_len; i++)
  ------------------
  |  Branch (741:35): [True: 8.59k, False: 1.07k]
  ------------------
  742|  8.59k|                        if ((c = buffer[data_offset+i]))
  ------------------
  |  Branch (742:29): [True: 4.86k, False: 3.73k]
  ------------------
  743|  4.86k|                            ctx->raw_string[raw_str_used++] = c;
  744|  1.04M|                } else {
  745|  1.04M|                    memcpy(ctx->raw_string + raw_str_used, &buffer[data_offset], read_len);
  746|  1.04M|                    raw_str_used += read_len;
  747|  1.04M|                }
  748|  1.04M|            }
  749|  1.04M|            if (++offset == col_info->width) {
  ------------------
  |  Branch (749:17): [True: 1.04M, False: 2.06k]
  ------------------
  750|  1.04M|                offset = 0;
  751|  1.04M|                col++;
  752|  1.04M|                segment_offset++;
  753|  1.04M|            }
  754|  1.04M|            if (segment_offset == var_info->n_segments) {
  ------------------
  |  Branch (754:17): [True: 1.04M, False: 2.44k]
  ------------------
  755|  1.04M|                if (!ctx->variables[var_info->index]->skip) {
  ------------------
  |  Branch (755:21): [True: 1.04M, False: 0]
  ------------------
  756|  1.04M|                    retval = readstat_convert(ctx->utf8_string, ctx->utf8_string_len, 
  757|  1.04M|                            ctx->raw_string, raw_str_used, ctx->converter);
  758|  1.04M|                    if (retval != READSTAT_OK)
  ------------------
  |  Branch (758:25): [True: 22, False: 1.04M]
  ------------------
  759|     22|                        goto done;
  760|  1.04M|                    value.v.string_value = ctx->utf8_string;
  761|  1.04M|                    if (ctx->handle.value(ctx->current_row, ctx->variables[var_info->index],
  ------------------
  |  Branch (761:25): [True: 0, False: 1.04M]
  ------------------
  762|  1.04M|                                value, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  763|      0|                        retval = READSTAT_ERROR_USER_ABORT;
  764|      0|                        goto done;
  765|      0|                    }
  766|  1.04M|                }
  767|  1.04M|                raw_str_used = 0;
  768|  1.04M|                segment_offset = 0;
  769|  1.04M|                var_index += var_info->n_segments;
  770|  1.04M|            }
  771|  1.23M|        } else if (var_info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (771:20): [True: 1.23M, False: 0]
  ------------------
  772|  1.23M|            if (!ctx->variables[var_info->index]->skip) {
  ------------------
  |  Branch (772:17): [True: 1.23M, False: 0]
  ------------------
  773|  1.23M|                memcpy(&fp_value, &buffer[data_offset], 8);
  774|  1.23M|                if (ctx->bswap) {
  ------------------
  |  Branch (774:21): [True: 3.09k, False: 1.23M]
  ------------------
  775|  3.09k|                    fp_value = byteswap_double(fp_value);
  776|  3.09k|                }
  777|  1.23M|                value.v.double_value = fp_value;
  778|  1.23M|                sav_tag_missing_double(&value, ctx);
  779|  1.23M|                if (ctx->handle.value(ctx->current_row, ctx->variables[var_info->index],
  ------------------
  |  Branch (779:21): [True: 0, False: 1.23M]
  ------------------
  780|  1.23M|                            value, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  781|      0|                    retval = READSTAT_ERROR_USER_ABORT;
  782|      0|                    goto done;
  783|      0|                }
  784|  1.23M|            }
  785|  1.23M|            var_index += var_info->n_segments;
  786|  1.23M|            col++;
  787|  1.23M|        }
  788|  2.28M|        data_offset += 8;
  789|  2.28M|    }
  790|  2.25M|    ctx->current_row++;
  791|  2.25M|done:
  792|  2.25M|    return retval;
  793|  2.25M|}
readstat_sav_read.c:sav_read_uncompressed_data:
  842|    982|        readstat_error_t (*row_handler)(unsigned char *, size_t, sav_ctx_t *)) {
  843|    982|    readstat_error_t retval = READSTAT_OK;
  844|    982|    readstat_io_t *io = ctx->io;
  845|    982|    unsigned char *buffer = NULL;
  846|    982|    size_t bytes_read = 0;
  847|    982|    size_t buffer_len = ctx->var_offset * 8;
  848|       |
  849|    982|    buffer = readstat_malloc(buffer_len);
  850|       |
  851|    982|    if (ctx->row_offset) {
  ------------------
  |  Branch (851:9): [True: 0, False: 982]
  ------------------
  852|      0|        if (io->seek(buffer_len * ctx->row_offset, READSTAT_SEEK_CUR, io->io_ctx) == -1) {
  ------------------
  |  Branch (852:13): [True: 0, False: 0]
  ------------------
  853|      0|            retval = READSTAT_ERROR_SEEK;
  854|      0|            goto done;
  855|      0|        }
  856|      0|        ctx->row_offset = 0;
  857|      0|    }
  858|       |
  859|  2.05k|    while (ctx->row_limit == -1 || ctx->current_row < ctx->row_limit) {
  ------------------
  |  Branch (859:12): [True: 0, False: 2.05k]
  |  Branch (859:36): [True: 1.77k, False: 288]
  ------------------
  860|  1.77k|        retval = sav_update_progress(ctx);
  861|  1.77k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (861:13): [True: 0, False: 1.77k]
  ------------------
  862|      0|            goto done;
  863|       |
  864|  1.77k|        if ((bytes_read = io->read(buffer, buffer_len, io->io_ctx)) != buffer_len)
  ------------------
  |  Branch (864:13): [True: 685, False: 1.08k]
  ------------------
  865|    685|            goto done;
  866|       |
  867|  1.08k|        retval = row_handler(buffer, buffer_len, ctx);
  868|  1.08k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (868:13): [True: 9, False: 1.07k]
  ------------------
  869|      9|            goto done;
  870|  1.08k|    }
  871|    982|done:
  872|    982|    if (buffer)
  ------------------
  |  Branch (872:9): [True: 982, False: 0]
  ------------------
  873|    982|        free(buffer);
  874|       |
  875|    982|    return retval;
  876|    982|}

spss_format:
   51|   307k|int spss_format(char *buffer, size_t len, spss_format_t *format) {
   52|   307k|    if (format->type < 0 
  ------------------
  |  Branch (52:9): [True: 0, False: 307k]
  ------------------
   53|   307k|            || format->type >= sizeof(spss_type_strings)/sizeof(spss_type_strings[0])
  ------------------
  |  Branch (53:16): [True: 6.57k, False: 301k]
  ------------------
   54|   301k|            || spss_type_strings[format->type][0] == '\0') {
  ------------------
  |  Branch (54:16): [True: 31.9k, False: 269k]
  ------------------
   55|  38.5k|        return 0;
   56|  38.5k|    }
   57|   269k|    char *string = spss_type_strings[format->type];
   58|       |
   59|   269k|    if (format->decimal_places || format->type == SPSS_FORMAT_TYPE_F) {
  ------------------
  |  |    6|   181k|#define SPSS_FORMAT_TYPE_F        5
  ------------------
  |  Branch (59:9): [True: 87.9k, False: 181k]
  |  Branch (59:35): [True: 706, False: 180k]
  ------------------
   60|  88.6k|        snprintf(buffer, len, "%s%d.%d", string, format->width, format->decimal_places);
   61|   180k|    } else if (format->width) {
  ------------------
  |  Branch (61:16): [True: 110k, False: 69.8k]
  ------------------
   62|   110k|        snprintf(buffer, len, "%s%d", string, format->width);
   63|   110k|    } else {
   64|  69.8k|        snprintf(buffer, len, "%s", string);
   65|  69.8k|    }
   66|       |
   67|   269k|    return 1;
   68|   307k|}
spss_varinfo_compare:
   70|   336k|int spss_varinfo_compare(const void *elem1, const void *elem2) {
   71|   336k|    int offset = *(int *)elem1;
   72|   336k|    const spss_varinfo_t *v = *(const spss_varinfo_t **)elem2;
   73|   336k|    if (offset < v->offset)
  ------------------
  |  Branch (73:9): [True: 159k, False: 177k]
  ------------------
   74|   159k|        return -1;
   75|   177k|    return (offset > v->offset);
   76|   336k|}
spss_varinfo_free:
   78|   468k|void spss_varinfo_free(spss_varinfo_t *info) {
   79|   468k|    if (info) {
  ------------------
  |  Branch (79:9): [True: 468k, False: 13]
  ------------------
   80|   468k|        if (info->label)
  ------------------
  |  Branch (80:13): [True: 1.10k, False: 467k]
  ------------------
   81|  1.10k|            free(info->label);
   82|   468k|        free(info);
   83|   468k|    }
   84|   468k|}
spss_missingness_for_info:
  127|   307k|readstat_missingness_t spss_missingness_for_info(spss_varinfo_t *info) {
  128|   307k|    readstat_missingness_t missingness;
  129|   307k|    memset(&missingness, '\0', sizeof(readstat_missingness_t));
  130|       |
  131|   307k|    if (info->missing_range) {
  ------------------
  |  Branch (131:9): [True: 2.24k, False: 305k]
  ------------------
  132|  2.24k|        missingness.missing_ranges_count++;
  133|  2.24k|        missingness.missing_ranges[0] = spss_boxed_missing_value(info, 0);
  134|  2.24k|        missingness.missing_ranges[1] = spss_boxed_missing_value(info, 1);
  135|       |
  136|  2.24k|        if (info->n_missing_values == 3) {
  ------------------
  |  Branch (136:13): [True: 760, False: 1.48k]
  ------------------
  137|    760|            missingness.missing_ranges_count++;
  138|    760|            missingness.missing_ranges[2] = missingness.missing_ranges[3] = spss_boxed_missing_value(info, 2);
  139|    760|        }
  140|   305k|    } else if (info->n_missing_values > 0) {
  ------------------
  |  Branch (140:16): [True: 1.81k, False: 303k]
  ------------------
  141|  1.81k|        missingness.missing_ranges_count = info->n_missing_values;
  142|  1.81k|        int i=0;
  143|  5.65k|        for (i=0; i<info->n_missing_values; i++) {
  ------------------
  |  Branch (143:19): [True: 3.84k, False: 1.81k]
  ------------------
  144|  3.84k|            missingness.missing_ranges[2*i] = missingness.missing_ranges[2*i+1] = spss_boxed_missing_value(info, i);
  145|  3.84k|        }
  146|  1.81k|    }
  147|   307k|    return missingness;
  148|   307k|}
spss_init_variable_for_info:
  151|   307k|        iconv_t converter) {
  152|   307k|    readstat_variable_t *variable = calloc(1, sizeof(readstat_variable_t));
  153|       |
  154|   307k|    variable->index = info->index;
  155|   307k|    variable->index_after_skipping = index_after_skipping;
  156|   307k|    variable->type = info->type;
  157|   307k|    if (info->string_length) {
  ------------------
  |  Branch (157:9): [True: 923, False: 306k]
  ------------------
  158|    923|        variable->storage_width = info->string_length;
  159|   306k|    } else {
  160|   306k|        variable->storage_width = 8 * info->width;
  161|   306k|    }
  162|       |
  163|   307k|    if (info->longname[0]) {
  ------------------
  |  Branch (163:9): [True: 304k, False: 3.26k]
  ------------------
  164|   304k|        readstat_convert(variable->name, sizeof(variable->name),
  165|   304k|                info->longname, sizeof(info->longname), converter);
  166|   304k|    } else {
  167|  3.26k|        readstat_convert(variable->name, sizeof(variable->name),
  168|  3.26k|                info->name, sizeof(info->name), converter);
  169|  3.26k|    }
  170|   307k|    if (info->label) {
  ------------------
  |  Branch (170:9): [True: 712, False: 306k]
  ------------------
  171|    712|        snprintf(variable->label, sizeof(variable->label), "%s", info->label);
  172|    712|    }
  173|       |
  174|   307k|    spss_format(variable->format, sizeof(variable->format), &info->print_format);
  175|       |
  176|   307k|    variable->missingness = spss_missingness_for_info(info);
  177|   307k|    variable->measure = info->measure;
  178|   307k|    if (info->display_width) {
  ------------------
  |  Branch (178:9): [True: 1.66k, False: 306k]
  ------------------
  179|  1.66k|        variable->display_width = info->display_width;
  180|   306k|    } else {
  181|   306k|        variable->display_width = info->print_format.width;
  182|   306k|    }
  183|       |
  184|   307k|    return variable;
  185|   307k|}
spss_measure_to_readstat_measure:
  199|  4.84k|readstat_measure_t spss_measure_to_readstat_measure(uint32_t sav_measure) {
  200|  4.84k|    if (sav_measure == SAV_MEASURE_NOMINAL)
  ------------------
  |  |   47|  4.84k|#define SAV_MEASURE_NOMINAL     1
  ------------------
  |  Branch (200:9): [True: 151, False: 4.69k]
  ------------------
  201|    151|        return READSTAT_MEASURE_NOMINAL;
  202|  4.69k|    if (sav_measure == SAV_MEASURE_ORDINAL)
  ------------------
  |  |   48|  4.69k|#define SAV_MEASURE_ORDINAL     2
  ------------------
  |  Branch (202:9): [True: 308, False: 4.38k]
  ------------------
  203|    308|        return READSTAT_MEASURE_ORDINAL;
  204|  4.38k|    if (sav_measure == SAV_MEASURE_SCALE)
  ------------------
  |  |   49|  4.38k|#define SAV_MEASURE_SCALE       3
  ------------------
  |  Branch (204:9): [True: 105, False: 4.28k]
  ------------------
  205|    105|        return READSTAT_MEASURE_SCALE;
  206|  4.28k|    return READSTAT_MEASURE_UNKNOWN;
  207|  4.38k|}
spss_alignment_to_readstat_alignment:
  221|  4.84k|readstat_alignment_t spss_alignment_to_readstat_alignment(uint32_t sav_alignment) {
  222|  4.84k|    if (sav_alignment == SAV_ALIGNMENT_LEFT)
  ------------------
  |  |   51|  4.84k|#define SAV_ALIGNMENT_LEFT      0
  ------------------
  |  Branch (222:9): [True: 1.36k, False: 3.47k]
  ------------------
  223|  1.36k|        return READSTAT_ALIGNMENT_LEFT;
  224|  3.47k|    if (sav_alignment == SAV_ALIGNMENT_CENTER)
  ------------------
  |  |   53|  3.47k|#define SAV_ALIGNMENT_CENTER    2
  ------------------
  |  Branch (224:9): [True: 363, False: 3.11k]
  ------------------
  225|    363|        return READSTAT_ALIGNMENT_CENTER;
  226|  3.11k|    if (sav_alignment == SAV_ALIGNMENT_RIGHT)
  ------------------
  |  |   52|  3.11k|#define SAV_ALIGNMENT_RIGHT     1
  ------------------
  |  Branch (226:9): [True: 111, False: 3.00k]
  ------------------
  227|    111|        return READSTAT_ALIGNMENT_RIGHT;
  228|  3.00k|    return READSTAT_ALIGNMENT_UNKNOWN;
  229|  3.11k|}
readstat_spss.c:spss_boxed_missing_value:
  120|  9.09k|static readstat_value_t spss_boxed_missing_value(spss_varinfo_t *info, int i) {
  121|  9.09k|    if (info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (121:9): [True: 5.34k, False: 3.75k]
  ------------------
  122|  5.34k|        return spss_boxed_double_value(info->missing_double_values[i]);
  123|  5.34k|    }
  124|  3.75k|    return spss_boxed_string_value(info->missing_string_values[i]);
  125|  9.09k|}
readstat_spss.c:spss_boxed_double_value:
  103|  5.34k|static readstat_value_t spss_boxed_double_value(double fp_value) {
  104|  5.34k|    readstat_value_t value = {
  105|  5.34k|        .type = READSTAT_TYPE_DOUBLE,
  106|  5.34k|        .v = { .double_value = fp_value },
  107|       |        .is_system_missing = isnan(fp_value)
  108|  5.34k|    };
  109|  5.34k|    return value;
  110|  5.34k|}
readstat_spss.c:spss_boxed_string_value:
  112|  3.75k|static readstat_value_t spss_boxed_string_value(const char *string) {
  113|  3.75k|    readstat_value_t value = {
  114|  3.75k|        .type = READSTAT_TYPE_STRING,
  115|  3.75k|        .v = { .string_value = string }
  116|  3.75k|    };
  117|  3.75k|    return value;
  118|  3.75k|}

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

rt_open_handler:
    8|  5.87k|int rt_open_handler(const char *path, void *io_ctx) {
    9|  5.87k|    return 0;
   10|  5.87k|}
rt_close_handler:
   12|  5.87k|int rt_close_handler(void *io_ctx) {
   13|  5.87k|    return 0;
   14|  5.87k|}
rt_seek_handler:
   17|   308k|        readstat_io_flags_t whence, void *io_ctx) {
   18|   308k|    rt_buffer_ctx_t *buffer_ctx = (rt_buffer_ctx_t *)io_ctx;
   19|   308k|    readstat_off_t newpos = -1;
   20|   308k|    if (whence == READSTAT_SEEK_SET) {
  ------------------
  |  Branch (20:9): [True: 11.0k, False: 297k]
  ------------------
   21|  11.0k|        newpos = offset;
   22|   297k|    } else if (whence == READSTAT_SEEK_CUR) {
  ------------------
  |  Branch (22:16): [True: 291k, False: 5.87k]
  ------------------
   23|   291k|        newpos = buffer_ctx->pos + offset;
   24|   291k|    } else if (whence == READSTAT_SEEK_END) {
  ------------------
  |  Branch (24:16): [True: 5.87k, False: 0]
  ------------------
   25|  5.87k|        newpos = buffer_ctx->buffer->used + offset;
   26|  5.87k|    }
   27|       |
   28|   308k|    if (newpos < 0)
  ------------------
  |  Branch (28:9): [True: 79, False: 307k]
  ------------------
   29|     79|        return -1;
   30|       |
   31|   307k|    if (newpos > buffer_ctx->buffer->used)
  ------------------
  |  Branch (31:9): [True: 266, False: 307k]
  ------------------
   32|    266|        return -1;
   33|       |
   34|   307k|    buffer_ctx->pos = newpos;
   35|   307k|    return newpos;
   36|   307k|}
rt_read_handler:
   38|  2.23M|ssize_t rt_read_handler(void *buf, size_t nbytes, void *io_ctx) {
   39|  2.23M|    rt_buffer_ctx_t *buffer_ctx = (rt_buffer_ctx_t *)io_ctx;
   40|  2.23M|    ssize_t bytes_copied = 0;
   41|  2.23M|    ssize_t bytes_left = buffer_ctx->buffer->used - buffer_ctx->pos;
   42|  2.23M|    if (nbytes <= bytes_left) {
  ------------------
  |  Branch (42:9): [True: 2.22M, False: 3.22k]
  ------------------
   43|  2.22M|        memcpy(buf, buffer_ctx->buffer->bytes + buffer_ctx->pos, nbytes);
   44|  2.22M|        bytes_copied = nbytes;
   45|  2.22M|    } else if (bytes_left > 0) {
  ------------------
  |  Branch (45:16): [True: 1.17k, False: 2.04k]
  ------------------
   46|  1.17k|        memcpy(buf, buffer_ctx->buffer->bytes + buffer_ctx->pos, bytes_left);
   47|  1.17k|        bytes_copied = bytes_left;
   48|  1.17k|    }
   49|  2.23M|    buffer_ctx->pos += bytes_copied;
   50|  2.23M|    return bytes_copied;
   51|  2.23M|}
rt_update_handler:
   54|  7.13k|        void *user_ctx, void *io_ctx) {
   55|  7.13k|    if (!progress_handler)
  ------------------
  |  Branch (55:9): [True: 7.13k, False: 0]
  ------------------
   56|  7.13k|        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|}

