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

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

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

readstat_convert:
    7|  16.6k|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|  96.8k|    while (src_len && (src[src_len-1] == ' ' || src[src_len-1] == '\0')) {
  ------------------
  |  Branch (10:12): [True: 81.3k, False: 15.5k]
  |  Branch (10:24): [True: 41.1k, False: 40.1k]
  |  Branch (10:49): [True: 39.0k, False: 1.12k]
  ------------------
   11|  80.1k|        src_len--;
   12|  80.1k|    }
   13|  16.6k|    if (dst_len == 0) {
  ------------------
  |  Branch (13:9): [True: 0, False: 16.6k]
  ------------------
   14|      0|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   15|  16.6k|    } else if (converter) {
  ------------------
  |  Branch (15:16): [True: 0, False: 16.6k]
  ------------------
   16|      0|        size_t dst_left = dst_len - 1;
   17|      0|        char *dst_end = dst;
   18|      0|        size_t status = iconv(converter, (readstat_iconv_inbuf_t)&src, &src_len, &dst_end, &dst_left);
   19|      0|        if (status == (size_t)-1) {
  ------------------
  |  Branch (19:13): [True: 0, False: 0]
  ------------------
   20|      0|            if (errno == E2BIG) {
  ------------------
  |  Branch (20:17): [True: 0, False: 0]
  ------------------
   21|      0|                return READSTAT_ERROR_CONVERT_LONG_STRING;
   22|      0|            } else if (errno == EILSEQ) {
  ------------------
  |  Branch (22:24): [True: 0, False: 0]
  ------------------
   23|      0|                return READSTAT_ERROR_CONVERT_BAD_STRING;
   24|      0|            } else if (errno != EINVAL) { /* EINVAL indicates improper truncation; accept it */
  ------------------
  |  Branch (24:24): [True: 0, False: 0]
  ------------------
   25|      0|                return READSTAT_ERROR_CONVERT;
   26|      0|            }
   27|      0|        }
   28|      0|        dst[dst_len - dst_left - 1] = '\0';
   29|  16.6k|    } else if (src_len + 1 > dst_len) {
  ------------------
  |  Branch (29:16): [True: 0, False: 16.6k]
  ------------------
   30|      0|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   31|  16.6k|    } else {
   32|  16.6k|        memcpy(dst, src, src_len);
   33|  16.6k|        dst[src_len] = '\0';
   34|  16.6k|    }
   35|  16.6k|    return READSTAT_OK;
   36|  16.6k|}

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

readstat_calloc:
   17|  2.31k|void *readstat_calloc(size_t count, size_t size) {
   18|  2.31k|    if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|  4.62k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
                  if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|  4.62k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
                  if (count > MAX_MALLOC_SIZE || size > MAX_MALLOC_SIZE || count * size > MAX_MALLOC_SIZE) {
  ------------------
  |  |    3|  2.31k|#define MAX_MALLOC_SIZE 0x1000000
  ------------------
  |  Branch (18:9): [True: 0, False: 2.31k]
  |  Branch (18:36): [True: 0, False: 2.31k]
  |  Branch (18:62): [True: 6, False: 2.30k]
  ------------------
   19|      6|        return NULL;
   20|      6|    }
   21|  2.30k|    if (count == 0 || size == 0) {
  ------------------
  |  Branch (21:9): [True: 2, False: 2.30k]
  |  Branch (21:23): [True: 0, False: 2.30k]
  ------------------
   22|      2|        return NULL;
   23|      2|    }
   24|  2.30k|    return calloc(count, size);
   25|  2.30k|}

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

por_ctx_init:
   67|  1.92k|por_ctx_t *por_ctx_init(void) {
   68|  1.92k|    por_ctx_t *ctx = calloc(1, sizeof(por_ctx_t));
   69|       |
   70|  1.92k|    ctx->space = ' ';
   71|  1.92k|    ctx->base30_precision = 20;
   72|  1.92k|    ctx->var_dict = ck_hash_table_init(1024, 8);
   73|  1.92k|    return ctx;
   74|  1.92k|}
por_ctx_free:
   76|  1.92k|void por_ctx_free(por_ctx_t *ctx) {
   77|  1.92k|    if (ctx->string_buffer)
  ------------------
  |  Branch (77:9): [True: 1.61k, False: 312]
  ------------------
   78|  1.61k|        free(ctx->string_buffer);
   79|  1.92k|    if (ctx->varinfo) {
  ------------------
  |  Branch (79:9): [True: 1.15k, False: 775]
  ------------------
   80|  1.15k|        int i;
   81|  3.81M|        for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (81:19): [True: 3.81M, False: 1.15k]
  ------------------
   82|  3.81M|            if (ctx->varinfo[i].label)
  ------------------
  |  Branch (82:17): [True: 8.46k, False: 3.80M]
  ------------------
   83|  8.46k|                free(ctx->varinfo[i].label);
   84|  3.81M|        }
   85|  1.15k|        free(ctx->varinfo);
   86|  1.15k|    }
   87|  1.92k|    if (ctx->variables) {
  ------------------
  |  Branch (87:9): [True: 1.15k, False: 769]
  ------------------
   88|  1.15k|        int i;
   89|  6.80M|        for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (89:19): [True: 6.80M, False: 1.15k]
  ------------------
   90|  6.80M|            if (ctx->variables[i])
  ------------------
  |  Branch (90:17): [True: 5.24k, False: 6.79M]
  ------------------
   91|  5.24k|                free(ctx->variables[i]);
   92|  6.80M|        }
   93|  1.15k|        free(ctx->variables);
   94|  1.15k|    }
   95|  1.92k|    if (ctx->var_dict)
  ------------------
  |  Branch (95:9): [True: 1.92k, False: 0]
  ------------------
   96|  1.92k|        ck_hash_table_free(ctx->var_dict);
   97|  1.92k|    if (ctx->converter)
  ------------------
  |  Branch (97:9): [True: 0, False: 1.92k]
  ------------------
   98|      0|        iconv_close(ctx->converter);
   99|  1.92k|    free(ctx);
  100|  1.92k|}
por_utf8_encode:
  103|  3.76M|        char *output, size_t output_len, uint16_t lookup[256]) {
  104|  3.76M|    int offset = 0;
  105|  3.76M|    int i;
  106|  16.2M|    for (i=0; i<input_len; i++) {
  ------------------
  |  Branch (106:15): [True: 12.5M, False: 3.70M]
  ------------------
  107|  12.5M|        uint16_t codepoint = lookup[input[i]];
  108|       |
  109|       |        /* Some software (SPSS?) uses an undefined character (zero) if a
  110|       |         * character can't be encoded. Use Unicode replacement character */
  111|  12.5M|        if (codepoint == 0) {
  ------------------
  |  Branch (111:13): [True: 24.9k, False: 12.5M]
  ------------------
  112|  24.9k|            codepoint = 0xFFFD;
  113|  24.9k|        }
  114|       |
  115|  12.5M|        if (codepoint < 0x20) {
  ------------------
  |  Branch (115:13): [True: 0, False: 12.5M]
  ------------------
  116|      0|            return -1;
  117|  12.5M|        } else if (codepoint <= 0x7F) {
  ------------------
  |  Branch (117:20): [True: 11.6M, False: 922k]
  ------------------
  118|  11.6M|            if (offset + 1 > output_len)
  ------------------
  |  Branch (118:17): [True: 46.3k, False: 11.6M]
  ------------------
  119|  46.3k|                return offset;
  120|       |            
  121|  11.6M|            output[offset++] = codepoint;
  122|  11.6M|        } else {
  123|   922k|            if (codepoint <= 0x07FF) {
  ------------------
  |  Branch (123:17): [True: 8.06k, False: 914k]
  ------------------
  124|  8.06k|                if (offset + 2 > output_len)
  ------------------
  |  Branch (124:21): [True: 196, False: 7.86k]
  ------------------
  125|    196|                    return offset;
  126|   914k|            } else /* if (codepoint <= 0xFFFF) */{
  127|   914k|                if (offset + 3 > output_len)
  ------------------
  |  Branch (127:21): [True: 17.7k, False: 896k]
  ------------------
  128|  17.7k|                    return offset;
  129|   914k|            }
  130|       |            /* TODO - For some reason that replacement character isn't recognized
  131|       |             * by some systems, so be prepared to insert an ASCII space instead */
  132|   904k|            int printed = snprintf(output + offset, output_len - offset, "%lc", codepoint);
  133|   904k|            if (printed > 0) {
  ------------------
  |  Branch (133:17): [True: 0, False: 904k]
  ------------------
  134|      0|                offset += printed;
  135|   904k|            } else {
  136|   904k|                output[offset++] = ' ';
  137|   904k|            }
  138|   904k|        }
  139|  12.5M|    }
  140|  3.70M|    return offset;
  141|  3.76M|}

readstat_por_parse_double:
   78|  3.23M|readstat_error_handler error_cb, void *user_ctx) {
   79|  3.23M|	ssize_t retval = 0;
   80|  3.23M|	double val = 0.0;
   81|  3.23M|	double denom = 30.0;
   82|  3.23M|	double temp_frac = 0.0;
   83|  3.23M|	double num = 0.0;
   84|  3.23M|	double exp = 0.0;
   85|       |	
   86|  3.23M|	double temp_val = 0.0;
   87|       |	
   88|  3.23M|	const unsigned char *p = (const unsigned char *)data;
   89|  3.23M|	const unsigned char *pe = p + len;
   90|       |	
   91|  3.23M|	int cs;
   92|  3.23M|	int is_negative = 0, exp_is_negative = 0;
   93|  3.23M|	int success = 0;
   94|       |	
   95|       |	
   96|  3.23M|#line 97 "src/spss/readstat_por_parse.c"
   97|  3.23M|	{
   98|  3.23M|		cs = (int)por_field_parse_start;
   99|  3.23M|	}
  100|       |	
  101|  3.23M|#line 102 "src/spss/readstat_por_parse.c"
  102|  3.23M|	{
  103|  3.23M|		int _klen;
  104|  3.23M|		unsigned int _trans = 0;
  105|  3.23M|		const char * _keys;
  106|  3.23M|		const signed char * _acts;
  107|  3.23M|		unsigned int _nacts;
  108|  11.6M|		_resume: {}
  109|  11.6M|		if ( p == pe )
  ------------------
  |  Branch (109:8): [True: 0, False: 11.6M]
  ------------------
  110|      0|			goto _out;
  111|  11.6M|		_keys = ( _por_field_parse_trans_keys + (_por_field_parse_key_offsets[cs]));
  112|  11.6M|		_trans = (unsigned int)_por_field_parse_index_offsets[cs];
  113|       |		
  114|  11.6M|		_klen = (int)_por_field_parse_single_lengths[cs];
  115|  11.6M|		if ( _klen > 0 ) {
  ------------------
  |  Branch (115:8): [True: 11.6M, False: 1.00k]
  ------------------
  116|  11.6M|			const char *_lower = _keys;
  117|  11.6M|			const char *_upper = _keys + _klen - 1;
  118|  11.6M|			const char *_mid;
  119|  35.9M|			while ( 1 ) {
  ------------------
  |  Branch (119:12): [True: 35.9M, Folded]
  ------------------
  120|  35.9M|				if ( _upper < _lower ) {
  ------------------
  |  Branch (120:10): [True: 4.75M, False: 31.2M]
  ------------------
  121|  4.75M|					_keys += _klen;
  122|  4.75M|					_trans += (unsigned int)_klen;
  123|  4.75M|					break;
  124|  4.75M|				}
  125|       |				
  126|  31.2M|				_mid = _lower + ((_upper-_lower) >> 1);
  127|  31.2M|				if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (127:10): [True: 3.66M, False: 27.5M]
  ------------------
  128|  3.66M|					_upper = _mid - 1;
  129|  27.5M|				else if ( ( (*( p))) > (*( _mid)) )
  ------------------
  |  Branch (129:15): [True: 20.6M, False: 6.90M]
  ------------------
  130|  20.6M|					_lower = _mid + 1;
  131|  6.90M|				else {
  132|  6.90M|					_trans += (unsigned int)(_mid - _keys);
  133|  6.90M|					goto _match;
  134|  6.90M|				}
  135|  31.2M|			}
  136|  11.6M|		}
  137|       |		
  138|  4.75M|		_klen = (int)_por_field_parse_range_lengths[cs];
  139|  4.75M|		if ( _klen > 0 ) {
  ------------------
  |  Branch (139:8): [True: 4.75M, False: 9]
  ------------------
  140|  4.75M|			const char *_lower = _keys;
  141|  4.75M|			const char *_upper = _keys + (_klen<<1) - 2;
  142|  4.75M|			const char *_mid;
  143|  5.34M|			while ( 1 ) {
  ------------------
  |  Branch (143:12): [True: 5.34M, Folded]
  ------------------
  144|  5.34M|				if ( _upper < _lower ) {
  ------------------
  |  Branch (144:10): [True: 61, False: 5.34M]
  ------------------
  145|     61|					_trans += (unsigned int)_klen;
  146|     61|					break;
  147|     61|				}
  148|       |				
  149|  5.34M|				_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  150|  5.34M|				if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (150:10): [True: 55, False: 5.34M]
  ------------------
  151|     55|					_upper = _mid - 2;
  152|  5.34M|				else if ( ( (*( p))) > (*( _mid + 1)) )
  ------------------
  |  Branch (152:15): [True: 590k, False: 4.75M]
  ------------------
  153|   590k|					_lower = _mid + 2;
  154|  4.75M|				else {
  155|  4.75M|					_trans += (unsigned int)((_mid - _keys)>>1);
  156|  4.75M|					break;
  157|  4.75M|				}
  158|  5.34M|			}
  159|  4.75M|		}
  160|       |		
  161|  11.6M|		_match: {}
  162|  11.6M|		cs = (int)_por_field_parse_cond_targs[_trans];
  163|       |		
  164|  11.6M|		if ( _por_field_parse_cond_actions[_trans] != 0 ) {
  ------------------
  |  Branch (164:8): [True: 7.98M, False: 3.66M]
  ------------------
  165|       |			
  166|  7.98M|			_acts = ( _por_field_parse_actions + (_por_field_parse_cond_actions[_trans]));
  167|  7.98M|			_nacts = (unsigned int)(*( _acts));
  168|  7.98M|			_acts += 1;
  169|  19.2M|			while ( _nacts > 0 ) {
  ------------------
  |  Branch (169:12): [True: 14.4M, False: 4.75M]
  ------------------
  170|  14.4M|				switch ( (*( _acts)) )
  ------------------
  |  Branch (170:14): [True: 14.4M, False: 0]
  ------------------
  171|  14.4M|				{
  172|  4.72M|					case 0:  {
  ------------------
  |  Branch (172:6): [True: 4.72M, False: 9.73M]
  ------------------
  173|  4.72M|						{
  174|  4.72M|#line 30 "src/spss/readstat_por_parse.rl"
  175|       |							
  176|  4.72M|							if ((( (*( p)))) >= '0' && (( (*( p)))) <= '9') {
  ------------------
  |  Branch (176:12): [True: 4.72M, False: 0]
  |  Branch (176:35): [True: 4.13M, False: 589k]
  ------------------
  177|  4.13M|								temp_val = 30 * temp_val + ((( (*( p)))) - '0');
  178|  4.13M|							} else if ((( (*( p)))) >= 'A' && (( (*( p)))) <= 'T') {
  ------------------
  |  Branch (178:19): [True: 589k, False: 0]
  |  Branch (178:42): [True: 589k, False: 0]
  ------------------
  179|   589k|								temp_val = 30 * temp_val + (10 + (( (*( p)))) - 'A');
  180|   589k|							}
  181|  4.72M|						}
  182|       |						
  183|  4.72M|#line 184 "src/spss/readstat_por_parse.c"
  184|       |						
  185|  4.72M|						break; 
  186|      0|					}
  187|  28.1k|					case 1:  {
  ------------------
  |  Branch (187:6): [True: 28.1k, False: 14.4M]
  ------------------
  188|  28.1k|						{
  189|  28.1k|#line 38 "src/spss/readstat_por_parse.rl"
  190|       |							
  191|  28.1k|							if ((( (*( p)))) >= '0' && (( (*( p)))) <= '9') {
  ------------------
  |  Branch (191:12): [True: 28.1k, False: 0]
  |  Branch (191:35): [True: 27.6k, False: 506]
  ------------------
  192|  27.6k|								temp_frac += ((( (*( p)))) - '0') / denom;
  193|  27.6k|							} else if ((( (*( p)))) >= 'A' && (( (*( p)))) <= 'T') {
  ------------------
  |  Branch (193:19): [True: 506, False: 0]
  |  Branch (193:42): [True: 506, False: 0]
  ------------------
  194|    506|								temp_frac += (10 + (( (*( p)))) - 'A') / denom;
  195|    506|							}
  196|  28.1k|							denom *= 30.0;
  197|  28.1k|						}
  198|       |						
  199|  28.1k|#line 200 "src/spss/readstat_por_parse.c"
  200|       |						
  201|  28.1k|						break; 
  202|      0|					}
  203|  3.23M|					case 2:  {
  ------------------
  |  Branch (203:6): [True: 3.23M, False: 11.2M]
  ------------------
  204|  3.23M|						{
  205|  3.23M|#line 47 "src/spss/readstat_por_parse.rl"
  206|  3.23M|							temp_val = 0; }
  207|       |						
  208|  3.23M|#line 209 "src/spss/readstat_por_parse.c"
  209|       |						
  210|  3.23M|						break; 
  211|      0|					}
  212|    731|					case 3:  {
  ------------------
  |  Branch (212:6): [True: 731, False: 14.4M]
  ------------------
  213|    731|						{
  214|    731|#line 49 "src/spss/readstat_por_parse.rl"
  215|    731|							temp_frac = 0.0; }
  216|       |						
  217|    731|#line 218 "src/spss/readstat_por_parse.c"
  218|       |						
  219|    731|						break; 
  220|      0|					}
  221|    203|					case 4:  {
  ------------------
  |  Branch (221:6): [True: 203, False: 14.4M]
  ------------------
  222|    203|						{
  223|    203|#line 53 "src/spss/readstat_por_parse.rl"
  224|    203|							is_negative = 1; }
  225|       |						
  226|    203|#line 227 "src/spss/readstat_por_parse.c"
  227|       |						
  228|    203|						break; 
  229|      0|					}
  230|  3.23M|					case 5:  {
  ------------------
  |  Branch (230:6): [True: 3.23M, False: 11.2M]
  ------------------
  231|  3.23M|						{
  232|  3.23M|#line 53 "src/spss/readstat_por_parse.rl"
  233|  3.23M|							num = temp_val; }
  234|       |						
  235|  3.23M|#line 236 "src/spss/readstat_por_parse.c"
  236|       |						
  237|  3.23M|						break; 
  238|      0|					}
  239|    257|					case 6:  {
  ------------------
  |  Branch (239:6): [True: 257, False: 14.4M]
  ------------------
  240|    257|						{
  241|    257|#line 54 "src/spss/readstat_por_parse.rl"
  242|    257|							exp_is_negative = 1; }
  243|       |						
  244|    257|#line 245 "src/spss/readstat_por_parse.c"
  245|       |						
  246|    257|						break; 
  247|      0|					}
  248|    260|					case 7:  {
  ------------------
  |  Branch (248:6): [True: 260, False: 14.4M]
  ------------------
  249|    260|						{
  250|    260|#line 54 "src/spss/readstat_por_parse.rl"
  251|    260|							exp = temp_val; }
  252|       |						
  253|    260|#line 254 "src/spss/readstat_por_parse.c"
  254|       |						
  255|    260|						break; 
  256|      0|					}
  257|    194|					case 8:  {
  ------------------
  |  Branch (257:6): [True: 194, False: 14.4M]
  ------------------
  258|    194|						{
  259|    194|#line 56 "src/spss/readstat_por_parse.rl"
  260|    194|							is_negative = 1; }
  261|       |						
  262|    194|#line 263 "src/spss/readstat_por_parse.c"
  263|       |						
  264|    194|						break; 
  265|      0|					}
  266|    195|					case 9:  {
  ------------------
  |  Branch (266:6): [True: 195, False: 14.4M]
  ------------------
  267|    195|						{
  268|    195|#line 58 "src/spss/readstat_por_parse.rl"
  269|    195|							val = NAN; }
  270|       |						
  271|    195|#line 272 "src/spss/readstat_por_parse.c"
  272|       |						
  273|    195|						break; 
  274|      0|					}
  275|  3.23M|					case 10:  {
  ------------------
  |  Branch (275:6): [True: 3.23M, False: 11.2M]
  ------------------
  276|  3.23M|						{
  277|  3.23M|#line 60 "src/spss/readstat_por_parse.rl"
  278|  3.23M|							success = 1; {p += 1; goto _out; } }
  279|       |						
  280|      0|#line 281 "src/spss/readstat_por_parse.c"
  281|       |						
  282|      0|						break; 
  283|      0|					}
  284|  14.4M|				}
  285|  11.2M|				_nacts -= 1;
  286|  11.2M|				_acts += 1;
  287|  11.2M|			}
  288|       |			
  289|  7.98M|		}
  290|       |		
  291|  8.42M|		if ( cs != 0 ) {
  ------------------
  |  Branch (291:8): [True: 8.42M, False: 70]
  ------------------
  292|  8.42M|			p += 1;
  293|  8.42M|			goto _resume;
  294|  8.42M|		}
  295|  3.23M|		_out: {}
  296|  3.23M|	}
  297|       |	
  298|      0|#line 64 "src/spss/readstat_por_parse.rl"
  299|       |	
  300|       |	
  301|  3.23M|	if (!isnan(val)) {
  ------------------
  |  Branch (301:6): [True: 3.23M, False: 195]
  ------------------
  302|  3.23M|		val = 1.0 * num + temp_frac;
  303|  3.23M|		if (exp_is_negative)
  ------------------
  |  Branch (303:7): [True: 257, False: 3.23M]
  ------------------
  304|    257|			exp *= -1;
  305|  3.23M|		if (exp) {
  ------------------
  |  Branch (305:7): [True: 233, False: 3.23M]
  ------------------
  306|    233|			val *= pow(30.0, exp);
  307|    233|		}
  308|  3.23M|		if (is_negative)
  ------------------
  |  Branch (308:7): [True: 397, False: 3.23M]
  ------------------
  309|    397|			val *= -1;
  310|  3.23M|	}
  311|       |	
  312|  3.23M|	if (!success) {
  ------------------
  |  Branch (312:6): [True: 70, False: 3.23M]
  ------------------
  313|     70|		retval = -1;
  314|     70|		if (error_cb) {
  ------------------
  |  Branch (314:7): [True: 0, False: 70]
  ------------------
  315|      0|			char error_buf[1024];
  316|      0|			snprintf(error_buf, sizeof(error_buf), "Read bytes: %ld   String: %.*s  Ending state: %d",
  317|      0|			(long)(p - (const unsigned char *)data), (int)len, data, cs);
  318|      0|			error_cb(error_buf, user_ctx);
  319|      0|		}
  320|     70|	}
  321|       |	
  322|  3.23M|	if (retval == 0) {
  ------------------
  |  Branch (322:6): [True: 3.23M, False: 70]
  ------------------
  323|  3.23M|		if (result)
  ------------------
  |  Branch (323:7): [True: 3.23M, False: 0]
  ------------------
  324|  3.23M|			*result = val;
  325|       |		
  326|  3.23M|		retval = (p - (const unsigned char *)data);
  327|  3.23M|	}
  328|       |	
  329|       |	/* suppress warning */
  330|  3.23M|	(void)por_field_parse_en_main;
  331|       |	
  332|  3.23M|	return retval;
  333|  8.42M|}

read_version_and_timestamp:
  664|  1.72k|readstat_error_t read_version_and_timestamp(por_ctx_t *ctx) {
  665|  1.72k|    readstat_error_t retval = READSTAT_OK;
  666|  1.72k|    char string[256];
  667|  1.72k|    struct tm timestamp = { .tm_isdst = -1 };
  668|  1.72k|    unsigned char version;
  669|       |
  670|  1.72k|    if (read_bytes(ctx, &version, sizeof(version)) != sizeof(version)) {
  ------------------
  |  Branch (670:9): [True: 3, False: 1.71k]
  ------------------
  671|      3|        retval = READSTAT_ERROR_READ;
  672|      3|        goto cleanup;
  673|      3|    }
  674|  1.71k|    if ((retval = read_string(ctx, string, sizeof(string))) != READSTAT_OK) { /* creation date */
  ------------------
  |  Branch (674:9): [True: 80, False: 1.63k]
  ------------------
  675|     80|        goto cleanup;
  676|     80|    }
  677|  1.63k|    if (sscanf(string, "%04d%02d%02d", &timestamp.tm_year, &timestamp.tm_mon, &timestamp.tm_mday) != 3) {
  ------------------
  |  Branch (677:9): [True: 65, False: 1.57k]
  ------------------
  678|     65|        retval = READSTAT_ERROR_BAD_TIMESTAMP_STRING;
  679|     65|        goto cleanup;
  680|     65|    }
  681|  1.57k|    if ((retval = read_string(ctx, string, sizeof(string))) != READSTAT_OK) { /* creation time */
  ------------------
  |  Branch (681:9): [True: 19, False: 1.55k]
  ------------------
  682|     19|        goto cleanup;
  683|     19|    }
  684|  1.55k|    if (sscanf(string, "%02d%02d%02d", &timestamp.tm_hour, &timestamp.tm_min, &timestamp.tm_sec) != 3) {
  ------------------
  |  Branch (684:9): [True: 1.30k, False: 250]
  ------------------
  685|       |        /* optional */
  686|  1.30k|    }
  687|       |
  688|  1.55k|    timestamp.tm_year -= 1900;
  689|  1.55k|    timestamp.tm_mon--;
  690|       |
  691|  1.55k|    ctx->timestamp = mktime(&timestamp);
  692|  1.55k|    ctx->version = ctx->byte2unicode[version] - 'A';
  693|       |
  694|  1.72k|cleanup:
  695|  1.72k|    return retval;
  696|  1.55k|}
handle_variables:
  698|    314|readstat_error_t handle_variables(por_ctx_t *ctx) {
  699|    314|    readstat_error_t retval = READSTAT_OK;
  700|    314|    int i;
  701|    314|    int index_after_skipping = 0;
  702|  5.56k|    for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (702:15): [True: 5.24k, False: 314]
  ------------------
  703|  5.24k|        char label_name_buf[256];
  704|  5.24k|        spss_varinfo_t *info = &ctx->varinfo[i];
  705|  5.24k|        info->index = i;
  706|       |
  707|  5.24k|        ctx->variables[i] = spss_init_variable_for_info(info, index_after_skipping, ctx->converter);
  708|       |
  709|  5.24k|        snprintf(label_name_buf, sizeof(label_name_buf), POR_LABEL_NAME_PREFIX "%d", info->labels_index);
  ------------------
  |  |   25|  5.24k|#define POR_LABEL_NAME_PREFIX   "labels"
  ------------------
  710|       |
  711|  5.24k|        int cb_retval = READSTAT_HANDLER_OK;
  712|       |
  713|  5.24k|        if (ctx->handle.variable) {
  ------------------
  |  Branch (713:13): [True: 5.24k, False: 0]
  ------------------
  714|  5.24k|            cb_retval = ctx->handle.variable(i, ctx->variables[i],
  715|  5.24k|                    info->labels_index == -1 ? NULL : label_name_buf,
  ------------------
  |  Branch (715:21): [True: 5.19k, False: 54]
  ------------------
  716|  5.24k|                    ctx->user_ctx);
  717|  5.24k|        }
  718|       |
  719|  5.24k|        if (cb_retval == READSTAT_HANDLER_ABORT) {
  ------------------
  |  Branch (719:13): [True: 0, False: 5.24k]
  ------------------
  720|      0|            retval = READSTAT_ERROR_USER_ABORT;
  721|      0|            goto cleanup;
  722|      0|        }
  723|       |
  724|  5.24k|        if (cb_retval == READSTAT_HANDLER_SKIP_VARIABLE) {
  ------------------
  |  Branch (724:13): [True: 0, False: 5.24k]
  ------------------
  725|      0|            ctx->variables[i]->skip = 1;
  726|  5.24k|        } else {
  727|  5.24k|            index_after_skipping++;
  728|  5.24k|        }
  729|  5.24k|    }
  730|    314|    if (ctx->handle.fweight && ctx->fweight_name[0]) {
  ------------------
  |  Branch (730:9): [True: 314, False: 0]
  |  Branch (730:32): [True: 74, False: 240]
  ------------------
  731|    799|        for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (731:19): [True: 726, False: 73]
  ------------------
  732|    726|            spss_varinfo_t *info = &ctx->varinfo[i];
  733|    726|            if (strcmp(info->name, ctx->fweight_name) == 0) {
  ------------------
  |  Branch (733:17): [True: 1, False: 725]
  ------------------
  734|      1|                if (ctx->handle.fweight(ctx->variables[i], ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (734:21): [True: 0, False: 1]
  ------------------
  735|      0|                    retval = READSTAT_ERROR_USER_ABORT;
  736|      0|                    goto cleanup;
  737|      0|                }
  738|      1|                break;
  739|      1|            }
  740|    726|        }
  741|     74|    }
  742|    314|cleanup:
  743|    314|    return retval;
  744|    314|}
readstat_parse_por:
  746|  1.92k|readstat_error_t readstat_parse_por(readstat_parser_t *parser, const char *path, void *user_ctx) {
  747|  1.92k|    readstat_error_t retval = READSTAT_OK;
  748|  1.92k|    readstat_io_t *io = parser->io;
  749|  1.92k|    unsigned char reverse_lookup[256];
  750|  1.92k|    char vanity[5][40];
  751|  1.92k|    char error_buf[1024];
  752|       |
  753|  1.92k|    por_ctx_t *ctx = por_ctx_init();
  754|       |    
  755|  1.92k|    ctx->handle = parser->handlers;
  756|  1.92k|    ctx->user_ctx = user_ctx;
  757|  1.92k|    ctx->io = io;
  758|  1.92k|    ctx->row_limit = parser->row_limit;
  759|  1.92k|    if (parser->row_offset > 0)
  ------------------
  |  Branch (759:9): [True: 0, False: 1.92k]
  ------------------
  760|      0|        ctx->row_offset = parser->row_offset;
  761|       |
  762|  1.92k|    if (parser->output_encoding) {
  ------------------
  |  Branch (762:9): [True: 1.92k, False: 0]
  ------------------
  763|  1.92k|        if (strcmp(parser->output_encoding, "UTF-8") != 0)
  ------------------
  |  Branch (763:13): [True: 0, False: 1.92k]
  ------------------
  764|      0|            ctx->converter = iconv_open(parser->output_encoding, "UTF-8");
  765|       |
  766|  1.92k|        if (ctx->converter == (iconv_t)-1) {
  ------------------
  |  Branch (766:13): [True: 0, False: 1.92k]
  ------------------
  767|      0|            ctx->converter = NULL;
  768|      0|            retval = READSTAT_ERROR_UNSUPPORTED_CHARSET;
  769|      0|            goto cleanup;
  770|      0|        }
  771|  1.92k|    }
  772|       |    
  773|  1.92k|    if (io->open(path, io->io_ctx) == -1) {
  ------------------
  |  Branch (773:9): [True: 0, False: 1.92k]
  ------------------
  774|      0|        retval = READSTAT_ERROR_OPEN;
  775|      0|        goto cleanup;
  776|      0|    }
  777|       |
  778|  1.92k|    if ((ctx->file_size = io->seek(0, READSTAT_SEEK_END, io->io_ctx)) == -1) {
  ------------------
  |  Branch (778:9): [True: 0, False: 1.92k]
  ------------------
  779|      0|        retval = READSTAT_ERROR_SEEK;
  780|      0|        goto cleanup;
  781|      0|    }
  782|       |
  783|  1.92k|    if (io->seek(0, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (783:9): [True: 0, False: 1.92k]
  ------------------
  784|      0|        retval = READSTAT_ERROR_SEEK;
  785|      0|        goto cleanup;
  786|      0|    }
  787|       |    
  788|  1.92k|    if (read_bytes(ctx, vanity, sizeof(vanity)) != sizeof(vanity)) {
  ------------------
  |  Branch (788:9): [True: 57, False: 1.86k]
  ------------------
  789|     57|        retval = READSTAT_ERROR_READ;
  790|     57|        goto cleanup;
  791|     57|    }
  792|       |
  793|  1.86k|    retval = readstat_convert(ctx->file_label, sizeof(ctx->file_label), vanity[1] + 20, 20, NULL);
  794|  1.86k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (794:9): [True: 0, False: 1.86k]
  ------------------
  795|      0|        goto cleanup;
  796|       |    
  797|  1.86k|    if (read_bytes(ctx, reverse_lookup, sizeof(reverse_lookup)) != sizeof(reverse_lookup)) {
  ------------------
  |  Branch (797:9): [True: 56, False: 1.81k]
  ------------------
  798|     56|        retval = READSTAT_ERROR_READ;
  799|     56|        goto cleanup;
  800|     56|    }
  801|       |    
  802|  1.81k|    ctx->space = reverse_lookup[126];
  803|       |
  804|  1.81k|    int i;
  805|       |
  806|   465k|    for (i=0; i<256; i++) {
  ------------------
  |  Branch (806:15): [True: 463k, False: 1.81k]
  ------------------
  807|   463k|        if (por_ascii_lookup[i]) {
  ------------------
  |  Branch (807:13): [True: 173k, False: 289k]
  ------------------
  808|   173k|            ctx->byte2unicode[reverse_lookup[i]] = por_ascii_lookup[i];
  809|   289k|        } else if (por_unicode_lookup[i]) {
  ------------------
  |  Branch (809:20): [True: 52.5k, False: 237k]
  ------------------
  810|  52.5k|            ctx->byte2unicode[reverse_lookup[i]] = por_unicode_lookup[i];
  811|  52.5k|        }
  812|   463k|    }
  813|       |
  814|  1.81k|    ctx->byte2unicode[reverse_lookup[64]] = por_unicode_lookup[64];
  815|       |
  816|  1.81k|    unsigned char check[8];
  817|  1.81k|    char tr_check[8];
  818|       |    
  819|  1.81k|    if (read_bytes(ctx, check, sizeof(check)) != sizeof(check)) {
  ------------------
  |  Branch (819:9): [True: 7, False: 1.80k]
  ------------------
  820|      7|        retval = READSTAT_ERROR_READ;
  821|      7|        goto cleanup;
  822|      7|    }
  823|       |
  824|  1.80k|    ssize_t encoded_len;
  825|       |
  826|  1.80k|    if ((encoded_len = por_utf8_encode(check, sizeof(check), tr_check, sizeof(tr_check), ctx->byte2unicode)) == -1) {
  ------------------
  |  Branch (826:9): [True: 0, False: 1.80k]
  ------------------
  827|      0|        if (ctx->handle.error) {
  ------------------
  |  Branch (827:13): [True: 0, False: 0]
  ------------------
  828|      0|            snprintf(error_buf, sizeof(error_buf), "Error converting check string: %.*s", (int)sizeof(check), check);
  829|      0|            ctx->handle.error(error_buf, ctx->user_ctx);
  830|      0|        }
  831|      0|        retval = READSTAT_ERROR_CONVERT;
  832|      0|        goto cleanup;
  833|      0|    }
  834|       |
  835|  1.80k|    if (strncmp("SPSSPORT", tr_check, encoded_len) != 0) {
  ------------------
  |  Branch (835:9): [True: 85, False: 1.72k]
  ------------------
  836|     85|        retval = READSTAT_ERROR_PARSE;
  837|     85|        goto cleanup;
  838|     85|    }
  839|       |    
  840|  1.72k|    ctx->var_offset = -1;
  841|       |    
  842|  1.72k|    char string[256];
  843|       |
  844|  1.72k|    retval = read_version_and_timestamp(ctx);
  845|  1.72k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (845:9): [True: 167, False: 1.55k]
  ------------------
  846|    167|        goto cleanup;
  847|       |
  848|   546k|    while (1) {
  ------------------
  |  Branch (848:12): [True: 546k, Folded]
  ------------------
  849|   546k|        uint16_t tr_tag = read_tag(ctx);
  850|   546k|        switch (tr_tag) {
  851|    210|            case '1': /* product ID */
  ------------------
  |  Branch (851:13): [True: 210, False: 545k]
  ------------------
  852|    570|            case '2': /* author ID */
  ------------------
  |  Branch (852:13): [True: 360, False: 545k]
  ------------------
  853|    796|            case '3': /* sub-product ID */
  ------------------
  |  Branch (853:13): [True: 226, False: 545k]
  ------------------
  854|    796|                retval = read_string(ctx, string, sizeof(string));
  855|    796|                break;
  856|  1.17k|            case '4': /* variable count */
  ------------------
  |  Branch (856:13): [True: 1.17k, False: 544k]
  ------------------
  857|  1.17k|                retval = read_variable_count_record(ctx);
  858|  1.17k|                break;
  859|    732|            case '5': /* precision */
  ------------------
  |  Branch (859:13): [True: 732, False: 545k]
  ------------------
  860|    732|                retval = read_precision_record(ctx);
  861|    732|                break;
  862|    495|            case '6': /* case weight */
  ------------------
  |  Branch (862:13): [True: 495, False: 545k]
  ------------------
  863|    495|                retval = read_case_weight_record(ctx);
  864|    495|                break;
  865|   375k|            case '7': /* variable */
  ------------------
  |  Branch (865:13): [True: 375k, False: 170k]
  ------------------
  866|   375k|                retval = read_variable_record(ctx);
  867|   375k|                break;
  868|  1.62k|            case '8': /* missing value */
  ------------------
  |  Branch (868:13): [True: 1.62k, False: 544k]
  ------------------
  869|  1.62k|                retval = read_missing_value_record(ctx);
  870|  1.62k|                break;
  871|  1.55k|            case 'B': /* missing value range */
  ------------------
  |  Branch (871:13): [True: 1.55k, False: 544k]
  ------------------
  872|  1.55k|                retval = read_missing_value_range_record(ctx);
  873|  1.55k|                break;
  874|  30.0k|            case '9': /* LO THRU x */
  ------------------
  |  Branch (874:13): [True: 30.0k, False: 516k]
  ------------------
  875|  30.0k|                retval = read_missing_value_lo_range_record(ctx);
  876|  30.0k|                break;
  877|  88.6k|            case 'A': /* x THRU HI */
  ------------------
  |  Branch (877:13): [True: 88.6k, False: 457k]
  ------------------
  878|  88.6k|                retval = read_missing_value_hi_range_record(ctx);
  879|  88.6k|                break;
  880|  8.85k|            case 'C': /* variable label */
  ------------------
  |  Branch (880:13): [True: 8.85k, False: 537k]
  ------------------
  881|  8.85k|                retval = read_variable_label_record(ctx);
  882|  8.85k|                break;
  883|  34.6k|            case 'D': /* value label */
  ------------------
  |  Branch (883:13): [True: 34.6k, False: 511k]
  ------------------
  884|  34.6k|                retval = read_value_label_record(ctx);
  885|  34.6k|                break;
  886|  1.08k|            case 'E': /* document record */
  ------------------
  |  Branch (886:13): [True: 1.08k, False: 545k]
  ------------------
  887|  1.08k|                retval = read_document_record(ctx);
  888|  1.08k|                break;
  889|    347|            case 'F': /* file data */
  ------------------
  |  Branch (889:13): [True: 347, False: 545k]
  ------------------
  890|    347|                if (ctx->var_offset != ctx->var_count - 1) {
  ------------------
  |  Branch (890:21): [True: 33, False: 314]
  ------------------
  891|     33|                    retval = READSTAT_ERROR_COLUMN_COUNT_MISMATCH;
  892|     33|                    goto cleanup;
  893|     33|                }
  894|       |
  895|    314|                retval = handle_variables(ctx);
  896|    314|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (896:21): [True: 0, False: 314]
  ------------------
  897|      0|                    goto cleanup;
  898|       |
  899|    314|                if (ctx->handle.value) {
  ------------------
  |  Branch (899:21): [True: 314, False: 0]
  ------------------
  900|    314|                    retval = read_por_file_data(ctx);
  901|    314|                }
  902|    314|                goto cleanup;
  903|    226|            default:
  ------------------
  |  Branch (903:13): [True: 226, False: 545k]
  ------------------
  904|    226|                retval = READSTAT_ERROR_PARSE;
  905|    226|                goto cleanup;
  906|   546k|        }
  907|   545k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (907:13): [True: 980, False: 544k]
  ------------------
  908|    980|            break;
  909|   545k|    }
  910|       |
  911|  1.92k|cleanup:
  912|  1.92k|    io->close(io->io_ctx);
  913|  1.92k|    por_ctx_free(ctx);
  914|       |    
  915|  1.92k|    return retval;
  916|  1.55k|}
readstat_por_read.c:read_bytes:
   47|  12.7M|static ssize_t read_bytes(por_ctx_t *ctx, void *dst, size_t len) {
   48|  12.7M|    char *dst_pos = (char *)dst;
   49|  12.7M|    readstat_io_t *io = ctx->io;
   50|  12.7M|    char byte;
   51|       |
   52|  27.9M|    while (dst_pos < (char *)dst + len) {
  ------------------
  |  Branch (52:12): [True: 15.2M, False: 12.7M]
  ------------------
   53|  15.2M|        if (ctx->num_spaces) {
  ------------------
  |  Branch (53:13): [True: 7.54M, False: 7.69M]
  ------------------
   54|  7.54M|            *dst_pos++ = ctx->space;
   55|  7.54M|            ctx->num_spaces--;
   56|  7.54M|            continue;
   57|  7.54M|        }
   58|  7.69M|        ssize_t bytes_read = io->read(&byte, 1, io->io_ctx);
   59|  7.69M|        if (bytes_read == 0) {
  ------------------
  |  Branch (59:13): [True: 1.77k, False: 7.69M]
  ------------------
   60|  1.77k|            break;
   61|  1.77k|        }
   62|  7.69M|        if (bytes_read == -1) {
  ------------------
  |  Branch (62:13): [True: 0, False: 7.69M]
  ------------------
   63|      0|            return -1;
   64|      0|        }
   65|  7.69M|        if (byte == '\r' || byte == '\n') {
  ------------------
  |  Branch (65:13): [True: 276, False: 7.69M]
  |  Branch (65:29): [True: 187k, False: 7.50M]
  ------------------
   66|   188k|            if (byte == '\r') {
  ------------------
  |  Branch (66:17): [True: 276, False: 187k]
  ------------------
   67|    276|                bytes_read = io->read(&byte, 1, io->io_ctx);
   68|    276|                if (bytes_read == 0 || bytes_read == -1 || byte != '\n')
  ------------------
  |  Branch (68:21): [True: 43, False: 233]
  |  Branch (68:40): [True: 0, False: 233]
  |  Branch (68:60): [True: 14, False: 219]
  ------------------
   69|     57|                    return -1;
   70|    276|            }
   71|   187k|            ctx->num_spaces = POR_LINE_LENGTH - ctx->pos;
  ------------------
  |  |   24|   187k|#define POR_LINE_LENGTH         80
  ------------------
   72|   187k|            ctx->pos = 0;
   73|   187k|            continue;
   74|  7.50M|        } else if (ctx->pos == POR_LINE_LENGTH) {
  ------------------
  |  |   24|  7.50M|#define POR_LINE_LENGTH         80
  ------------------
  |  Branch (74:20): [True: 8, False: 7.50M]
  ------------------
   75|      8|            return -1;
   76|      8|        }
   77|  7.50M|        *dst_pos++ = byte;
   78|  7.50M|        ctx->pos++;
   79|  7.50M|    }
   80|       |    
   81|  12.7M|    return (int)(dst_pos - (char *)dst);
   82|  12.7M|}
readstat_por_read.c:read_string:
  245|   528k|static readstat_error_t read_string(por_ctx_t *ctx, char *data, size_t len) {
  246|   528k|    int finished = 0;
  247|   528k|    readstat_error_t retval = maybe_read_string(ctx, data, len, &finished);
  248|   528k|    if (retval == READSTAT_OK && finished) {
  ------------------
  |  Branch (248:9): [True: 527k, False: 528]
  |  Branch (248:34): [True: 16, False: 527k]
  ------------------
  249|     16|        return READSTAT_ERROR_PARSE;
  250|     16|    }
  251|   528k|    return retval;
  252|   528k|}
readstat_por_read.c:maybe_read_string:
  195|   529k|static readstat_error_t maybe_read_string(por_ctx_t *ctx, char *data, size_t len, int *out_finished) {
  196|   529k|    readstat_error_t retval = READSTAT_OK;
  197|   529k|    double value;
  198|   529k|    int finished = 0;
  199|   529k|    char error_buf[1024];
  200|   529k|    size_t string_length = 0;
  201|   529k|    retval = maybe_read_double(ctx, &value, &finished);
  202|   529k|    if (retval != READSTAT_OK || finished) {
  ------------------
  |  Branch (202:9): [True: 665, False: 528k]
  |  Branch (202:34): [True: 22, False: 528k]
  ------------------
  203|    687|        if (out_finished)
  ------------------
  |  Branch (203:13): [True: 687, False: 0]
  ------------------
  204|    687|            *out_finished = finished;
  205|       |
  206|    687|        return retval;
  207|    687|    }
  208|       |    
  209|   528k|    if (value < 0 || value > MAX_STRING_LENGTH || isnan(value)) {
  ------------------
  |  |   31|  1.05M|#define MAX_STRING_LENGTH   20000
  ------------------
  |  Branch (209:9): [True: 2, False: 528k]
  |  Branch (209:22): [True: 9, False: 528k]
  |  Branch (209:51): [True: 4, False: 528k]
  ------------------
  210|     15|        retval = READSTAT_ERROR_PARSE;
  211|     15|        goto cleanup;
  212|     15|    }
  213|   528k|    string_length = (size_t)value;
  214|       |    
  215|   528k|    if (string_length > ctx->string_buffer_len) {
  ------------------
  |  Branch (215:9): [True: 2.25k, False: 526k]
  ------------------
  216|  2.25k|        ctx->string_buffer_len = string_length;
  217|  2.25k|        ctx->string_buffer = realloc(ctx->string_buffer, ctx->string_buffer_len);
  218|  2.25k|        memset(ctx->string_buffer, 0, ctx->string_buffer_len);
  219|  2.25k|    }
  220|       |    
  221|   528k|    if (read_bytes(ctx, ctx->string_buffer, string_length) == -1) {
  ------------------
  |  Branch (221:9): [True: 22, False: 528k]
  ------------------
  222|     22|        retval = READSTAT_ERROR_READ;
  223|     22|        goto cleanup;
  224|     22|    }
  225|   528k|    size_t bytes_encoded = por_utf8_encode(ctx->string_buffer, string_length, 
  226|   528k|            data, len - 1, ctx->byte2unicode);
  227|   528k|    if (bytes_encoded == -1) {
  ------------------
  |  Branch (227:9): [True: 0, False: 528k]
  ------------------
  228|      0|        if (ctx->handle.error) {
  ------------------
  |  Branch (228:13): [True: 0, False: 0]
  ------------------
  229|      0|            snprintf(error_buf, sizeof(error_buf), "Error converting string: %.*s", 
  230|      0|                    (int)string_length, ctx->string_buffer);
  231|      0|            ctx->handle.error(error_buf, ctx->user_ctx);
  232|      0|        }
  233|      0|        retval = READSTAT_ERROR_CONVERT;
  234|      0|        goto cleanup;
  235|      0|    }
  236|       |    
  237|   528k|    data[bytes_encoded] = '\0';
  238|   528k|    if (out_finished)
  ------------------
  |  Branch (238:9): [True: 528k, False: 0]
  ------------------
  239|   528k|        *out_finished = 0;
  240|       |
  241|   528k|cleanup:
  242|   528k|    return retval;
  243|   528k|}
readstat_por_read.c:maybe_read_double:
  175|   530k|static readstat_error_t maybe_read_double(por_ctx_t *ctx, double *out_double, int *out_finished) {
  176|   530k|    unsigned char peek;
  177|   530k|    size_t bytes_read = read_bytes(ctx, &peek, 1);
  178|   530k|    if (bytes_read != 1)
  ------------------
  |  Branch (178:9): [True: 638, False: 529k]
  ------------------
  179|    638|        return READSTAT_ERROR_PARSE;
  180|       |
  181|   529k|    if (ctx->byte2unicode[peek] == 'Z') {
  ------------------
  |  Branch (181:9): [True: 28, False: 529k]
  ------------------
  182|     28|        if (out_double)
  ------------------
  |  Branch (182:13): [True: 28, False: 0]
  ------------------
  183|     28|            *out_double = NAN;
  184|     28|        if (out_finished)
  ------------------
  |  Branch (184:13): [True: 28, False: 0]
  ------------------
  185|     28|            *out_finished = 1;
  186|     28|        return READSTAT_OK;
  187|     28|    }
  188|       |
  189|   529k|    if (out_finished)
  ------------------
  |  Branch (189:9): [True: 529k, False: 0]
  ------------------
  190|   529k|        *out_finished = 0;
  191|       |
  192|   529k|    return read_double_with_peek(ctx, out_double, peek);
  193|   529k|}
readstat_por_read.c:read_double_with_peek:
   93|  3.23M|        unsigned char peek) {
   94|  3.23M|    readstat_error_t retval = READSTAT_OK;
   95|  3.23M|    double value = NAN;
   96|  3.23M|    unsigned char buffer[100];
   97|  3.23M|    char utf8_buffer[300];
   98|  3.23M|    char error_buf[1024];
   99|  3.23M|    int64_t len = 0;
  100|  3.23M|    ssize_t bytes_read = 0;
  101|       |
  102|  3.23M|    buffer[0] = peek;
  103|       |
  104|  3.23M|    bytes_read = read_bytes(ctx, &buffer[1], 1);
  105|  3.23M|    if (bytes_read != 1)
  ------------------
  |  Branch (105:9): [True: 103, False: 3.23M]
  ------------------
  106|    103|        return READSTAT_ERROR_PARSE;
  107|       |
  108|  3.23M|    if (ctx->byte2unicode[buffer[0]] == '*' && 
  ------------------
  |  Branch (108:9): [True: 235, False: 3.23M]
  ------------------
  109|    235|            ctx->byte2unicode[buffer[1]] == '.') {
  ------------------
  |  Branch (109:13): [True: 218, False: 17]
  ------------------
  110|    218|        if (out_double)
  ------------------
  |  Branch (110:13): [True: 218, False: 0]
  ------------------
  111|    218|            *out_double = NAN;
  112|    218|        return READSTAT_OK;
  113|    218|    }
  114|  3.23M|    int64_t i=2;
  115|  8.42M|    while (i<sizeof(buffer) && ctx->byte2unicode[buffer[i-1]] != '/') {
  ------------------
  |  Branch (115:12): [True: 8.42M, False: 4]
  |  Branch (115:32): [True: 5.19M, False: 3.23M]
  ------------------
  116|  5.19M|        bytes_read = read_bytes(ctx, &buffer[i], 1);
  117|  5.19M|        if (bytes_read != 1)
  ------------------
  |  Branch (117:13): [True: 111, False: 5.19M]
  ------------------
  118|    111|            return READSTAT_ERROR_PARSE;
  119|  5.19M|        i++;
  120|  5.19M|    }
  121|       |
  122|  3.23M|    if (i == sizeof(buffer)) {
  ------------------
  |  Branch (122:9): [True: 4, False: 3.23M]
  ------------------
  123|      4|        return READSTAT_ERROR_PARSE;
  124|      4|    }
  125|       |
  126|  3.23M|    len = por_utf8_encode(buffer, i, utf8_buffer, sizeof(utf8_buffer), ctx->byte2unicode);
  127|  3.23M|    if (len == -1) {
  ------------------
  |  Branch (127:9): [True: 0, False: 3.23M]
  ------------------
  128|      0|        if (ctx->handle.error) {
  ------------------
  |  Branch (128:13): [True: 0, False: 0]
  ------------------
  129|      0|            snprintf(error_buf, sizeof(error_buf), "Error converting double string (length=%" PRId64 "): %.*s", 
  130|      0|                    i, (int)i, buffer);
  131|      0|            ctx->handle.error(error_buf, ctx->user_ctx);
  132|      0|        }
  133|      0|        retval = READSTAT_ERROR_CONVERT;
  134|      0|        goto cleanup;
  135|      0|    }
  136|       |    
  137|  3.23M|    bytes_read = readstat_por_parse_double(utf8_buffer, len, &value, ctx->handle.error, ctx->user_ctx);
  138|  3.23M|    if (bytes_read == -1) {
  ------------------
  |  Branch (138:9): [True: 70, False: 3.23M]
  ------------------
  139|     70|        if (ctx->handle.error) {
  ------------------
  |  Branch (139:13): [True: 0, False: 70]
  ------------------
  140|      0|            snprintf(error_buf, sizeof(error_buf), "Error parsing double string (length=%" PRId64 "): %.*s [%s]", 
  141|      0|                    len, (int)len, utf8_buffer, buffer);
  142|      0|            ctx->handle.error(error_buf, ctx->user_ctx);
  143|      0|        }
  144|     70|        retval = READSTAT_ERROR_PARSE;
  145|     70|        goto cleanup;
  146|     70|    }
  147|       |    
  148|  3.23M|cleanup:
  149|  3.23M|    if (out_double)
  ------------------
  |  Branch (149:9): [True: 3.23M, False: 0]
  ------------------
  150|  3.23M|        *out_double = value;
  151|       |
  152|  3.23M|    return retval;
  153|  3.23M|}
readstat_por_read.c:read_tag:
   84|   546k|static uint16_t read_tag(por_ctx_t *ctx) {
   85|   546k|    unsigned char tag;
   86|   546k|    if (read_bytes(ctx, &tag, 1) != 1) {
  ------------------
  |  Branch (86:9): [True: 214, False: 545k]
  ------------------
   87|    214|        return -1;
   88|    214|    }
   89|   545k|    return ctx->byte2unicode[tag];
   90|   546k|}
readstat_por_read.c:read_variable_count_record:
  254|  1.17k|static readstat_error_t read_variable_count_record(por_ctx_t *ctx) {
  255|  1.17k|    int value;
  256|  1.17k|    readstat_error_t retval = READSTAT_OK;
  257|  1.17k|    if (ctx->var_count) {
  ------------------
  |  Branch (257:9): [True: 14, False: 1.16k]
  ------------------
  258|     14|        retval = READSTAT_ERROR_PARSE;
  259|     14|        goto cleanup;
  260|     14|    }
  261|  1.16k|    if ((retval = read_integer_in_range(ctx, 0, MAX_VARS, &value)) != READSTAT_OK) {
  ------------------
  |  |   33|  1.16k|#define MAX_VARS    1000000
  ------------------
  |  Branch (261:9): [True: 7, False: 1.15k]
  ------------------
  262|      7|        goto cleanup;
  263|      7|    }
  264|  1.15k|    ctx->var_count = value;
  265|  1.15k|    ctx->variables = readstat_calloc(ctx->var_count, sizeof(readstat_variable_t *));
  266|  1.15k|    ctx->varinfo = readstat_calloc(ctx->var_count, sizeof(spss_varinfo_t));
  267|  1.15k|    if (ctx->variables == NULL || ctx->varinfo == NULL) {
  ------------------
  |  Branch (267:9): [True: 1, False: 1.15k]
  |  Branch (267:35): [True: 6, False: 1.15k]
  ------------------
  268|      7|        retval = READSTAT_ERROR_MALLOC;
  269|      7|        goto cleanup;
  270|      7|    }
  271|       |
  272|  1.15k|    if (ctx->handle.metadata) {
  ------------------
  |  Branch (272:9): [True: 1.15k, False: 0]
  ------------------
  273|  1.15k|        readstat_metadata_t metadata = {
  274|  1.15k|            .row_count = -1,
  275|  1.15k|            .var_count = ctx->var_count,
  276|  1.15k|            .creation_time = ctx->timestamp,
  277|  1.15k|            .modified_time = ctx->timestamp,
  278|  1.15k|            .file_format_version = ctx->version,
  279|  1.15k|            .file_label = ctx->file_label
  280|  1.15k|        };
  281|  1.15k|        if (ctx->handle.metadata(&metadata, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (281:13): [True: 0, False: 1.15k]
  ------------------
  282|      0|            retval = READSTAT_ERROR_USER_ABORT;
  283|      0|            goto cleanup;
  284|      0|        }
  285|  1.15k|    }
  286|       |        
  287|  1.17k|cleanup:
  288|  1.17k|    return retval;
  289|  1.15k|}
readstat_por_read.c:read_integer_in_range:
  163|  2.70M|static readstat_error_t read_integer_in_range(por_ctx_t *ctx, int min, int max, int *out_integer) {
  164|  2.70M|    double dval = NAN;
  165|  2.70M|    readstat_error_t retval = read_double(ctx, &dval);
  166|  2.70M|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (166:9): [True: 320, False: 2.70M]
  ------------------
  167|    320|        return retval;
  168|  2.70M|    if (isnan(dval) || dval < min || dval > max)
  ------------------
  |  Branch (168:9): [True: 9, False: 2.70M]
  |  Branch (168:24): [True: 10, False: 2.70M]
  |  Branch (168:38): [True: 13, False: 2.70M]
  ------------------
  169|     32|        return READSTAT_ERROR_PARSE;
  170|  2.70M|    if (out_integer)
  ------------------
  |  Branch (170:9): [True: 2.70M, False: 0]
  ------------------
  171|  2.70M|        *out_integer = (int)dval;
  172|  2.70M|    return READSTAT_OK;
  173|  2.70M|}
readstat_por_read.c:read_double:
  155|  2.70M|static readstat_error_t read_double(por_ctx_t *ctx, double *out_double) {
  156|  2.70M|    unsigned char peek;
  157|  2.70M|    size_t bytes_read = read_bytes(ctx, &peek, 1);
  158|  2.70M|    if (bytes_read != 1)
  ------------------
  |  Branch (158:9): [True: 327, False: 2.70M]
  ------------------
  159|    327|        return READSTAT_ERROR_PARSE;
  160|  2.70M|    return read_double_with_peek(ctx, out_double, peek);
  161|  2.70M|}
readstat_por_read.c:read_precision_record:
  291|    732|static readstat_error_t read_precision_record(por_ctx_t *ctx) {
  292|    732|    int precision = 0;
  293|    732|    readstat_error_t error = read_integer_in_range(ctx, 0, 100, &precision);
  294|    732|    if (error == READSTAT_OK)
  ------------------
  |  Branch (294:9): [True: 709, False: 23]
  ------------------
  295|    709|        ctx->base30_precision = precision;
  296|    732|    return error;
  297|    732|}
readstat_por_read.c:read_case_weight_record:
  299|    495|static readstat_error_t read_case_weight_record(por_ctx_t *ctx) {
  300|    495|    return read_string(ctx, ctx->fweight_name, sizeof(ctx->fweight_name));
  301|    495|}
readstat_por_read.c:read_variable_record:
  303|   375k|static readstat_error_t read_variable_record(por_ctx_t *ctx) {
  304|   375k|    readstat_error_t retval = READSTAT_OK;
  305|   375k|    int value;
  306|   375k|    int i;
  307|   375k|    spss_varinfo_t *varinfo = NULL;
  308|   375k|    spss_format_t *formats[2];
  309|       |
  310|   375k|    ctx->var_offset++;
  311|       |
  312|   375k|    if (ctx->var_offset == ctx->var_count) {
  ------------------
  |  Branch (312:9): [True: 2, False: 375k]
  ------------------
  313|      2|        retval = READSTAT_ERROR_PARSE;
  314|      2|        goto cleanup;
  315|      2|    }
  316|       |
  317|   375k|    varinfo = &ctx->varinfo[ctx->var_offset];
  318|   375k|    formats[0] = &varinfo->print_format;
  319|   375k|    formats[1] = &varinfo->write_format;
  320|       |
  321|   375k|    varinfo->labels_index = -1;
  322|   375k|    if ((retval = read_integer_in_range(ctx, 0, MAX_WIDTH, &value)) != READSTAT_OK) {
  ------------------
  |  |   34|   375k|#define MAX_WIDTH   1000000
  ------------------
  |  Branch (322:9): [True: 31, False: 375k]
  ------------------
  323|     31|        goto cleanup;
  324|     31|    }
  325|   375k|    varinfo->width = value;
  326|   375k|    if (varinfo->width == 0) {
  ------------------
  |  Branch (326:9): [True: 93.9k, False: 281k]
  ------------------
  327|  93.9k|        varinfo->type = READSTAT_TYPE_DOUBLE;
  328|   281k|    } else {
  329|   281k|        varinfo->type = READSTAT_TYPE_STRING;
  330|   281k|    }
  331|   375k|    if ((retval = read_string(ctx, varinfo->name, sizeof(varinfo->name))) != READSTAT_OK) {
  ------------------
  |  Branch (331:9): [True: 39, False: 375k]
  ------------------
  332|     39|        goto cleanup;
  333|     39|    }
  334|   375k|    ck_str_hash_insert(varinfo->name, varinfo, ctx->var_dict);
  335|       |
  336|  1.12M|    for (i=0; i<sizeof(formats)/sizeof(spss_format_t *); i++) {
  ------------------
  |  Branch (336:15): [True: 751k, False: 375k]
  ------------------
  337|   751k|        spss_format_t *format = formats[i];
  338|   751k|        if ((retval = read_integer_in_range(ctx, 0, MAX_FORMAT_TYPE, &value)) != READSTAT_OK) {
  ------------------
  |  |   28|   751k|#define MAX_FORMAT_TYPE     (POR_FORMAT_SHIFT+SPSS_FORMAT_TYPE_YMDHMS)
  |  |  ------------------
  |  |  |  |   27|   751k|#define POR_FORMAT_SHIFT     82
  |  |  ------------------
  |  |               #define MAX_FORMAT_TYPE     (POR_FORMAT_SHIFT+SPSS_FORMAT_TYPE_YMDHMS)
  |  |  ------------------
  |  |  |  |   38|   751k|#define SPSS_FORMAT_TYPE_YMDHMS   41
  |  |  ------------------
  ------------------
  |  Branch (338:13): [True: 156, False: 751k]
  ------------------
  339|    156|            goto cleanup;
  340|    156|        }
  341|   751k|        if (value > POR_FORMAT_SHIFT) {
  ------------------
  |  |   27|   751k|#define POR_FORMAT_SHIFT     82
  ------------------
  |  Branch (341:13): [True: 830, False: 750k]
  ------------------
  342|       |            // Some files in the wild have their format types shifted by 82 for date/time values
  343|       |            // I have no idea why, but see test files linked from:
  344|       |            // https://github.com/WizardMac/ReadStat/issues/158
  345|    830|            format->type = value - POR_FORMAT_SHIFT;
  ------------------
  |  |   27|    830|#define POR_FORMAT_SHIFT     82
  ------------------
  346|   750k|        } else {
  347|   750k|            format->type = value;
  348|   750k|        }
  349|       |
  350|   751k|        if ((retval = read_integer_in_range(ctx, 0, MAX_FORMAT_WIDTH, &value)) != READSTAT_OK) {
  ------------------
  |  |   29|   751k|#define MAX_FORMAT_WIDTH    20000
  ------------------
  |  Branch (350:13): [True: 34, False: 751k]
  ------------------
  351|     34|            goto cleanup;
  352|     34|        }
  353|   751k|        format->width = value;
  354|       |
  355|   751k|        if ((retval = read_integer_in_range(ctx, 0, MAX_FORMAT_DECIMALS, &value)) != READSTAT_OK) {
  ------------------
  |  |   30|   751k|#define MAX_FORMAT_DECIMALS   100
  ------------------
  |  Branch (355:13): [True: 26, False: 751k]
  ------------------
  356|     26|            goto cleanup;
  357|     26|        }
  358|   751k|        format->decimal_places = value;
  359|   751k|    }
  360|       |
  361|   375k|cleanup:
  362|   375k|    return retval;
  363|   375k|}
readstat_por_read.c:read_missing_value_record:
  365|  1.62k|static readstat_error_t read_missing_value_record(por_ctx_t *ctx) {
  366|  1.62k|    readstat_error_t retval = READSTAT_OK;
  367|  1.62k|    spss_varinfo_t *varinfo = NULL;
  368|       |
  369|  1.62k|    if (ctx->var_offset < 0 || ctx->var_offset >= ctx->var_count) {
  ------------------
  |  Branch (369:9): [True: 2, False: 1.62k]
  |  Branch (369:32): [True: 0, False: 1.62k]
  ------------------
  370|      2|        retval = READSTAT_ERROR_PARSE;
  371|      2|        goto cleanup;
  372|      2|    }
  373|  1.62k|    varinfo = &ctx->varinfo[ctx->var_offset];
  374|       |
  375|  1.62k|    if (varinfo->n_missing_values >= 3) {
  ------------------
  |  Branch (375:9): [True: 7, False: 1.62k]
  ------------------
  376|      7|        retval = READSTAT_ERROR_PARSE;
  377|      7|        goto cleanup;
  378|      7|    }
  379|  1.62k|    if (varinfo->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (379:9): [True: 896, False: 724]
  ------------------
  380|    896|        if ((retval = read_double(ctx, &varinfo->missing_double_values[varinfo->n_missing_values])) != READSTAT_OK) {
  ------------------
  |  Branch (380:13): [True: 18, False: 878]
  ------------------
  381|     18|            goto cleanup;
  382|     18|        }
  383|    896|    } else {
  384|    724|        if ((retval = read_string(ctx, varinfo->missing_string_values[varinfo->n_missing_values],
  ------------------
  |  Branch (384:13): [True: 8, False: 716]
  ------------------
  385|    724|                        sizeof(varinfo->missing_string_values[varinfo->n_missing_values]))) != READSTAT_OK) {
  386|      8|            goto cleanup;
  387|      8|        }
  388|    724|    }
  389|  1.59k|    varinfo->n_missing_values++;
  390|       |
  391|  1.62k|cleanup:
  392|  1.62k|    return retval;
  393|  1.59k|}
readstat_por_read.c:read_missing_value_range_record:
  395|  1.55k|static readstat_error_t read_missing_value_range_record(por_ctx_t *ctx) {
  396|  1.55k|    readstat_error_t retval = READSTAT_OK;
  397|  1.55k|    spss_varinfo_t *varinfo = NULL;
  398|       |
  399|  1.55k|    if (ctx->var_offset < 0 || ctx->var_offset == ctx->var_count) {
  ------------------
  |  Branch (399:9): [True: 1, False: 1.55k]
  |  Branch (399:32): [True: 0, False: 1.55k]
  ------------------
  400|      1|        retval = READSTAT_ERROR_PARSE;
  401|      1|        goto cleanup;
  402|      1|    }
  403|  1.55k|    varinfo = &ctx->varinfo[ctx->var_offset];
  404|       |
  405|  1.55k|    varinfo->missing_range = 1;
  406|  1.55k|    varinfo->n_missing_values = 2;
  407|  1.55k|    if (varinfo->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (407:9): [True: 431, False: 1.12k]
  ------------------
  408|    431|        if ((retval = read_double(ctx, &varinfo->missing_double_values[0])) != READSTAT_OK) {
  ------------------
  |  Branch (408:13): [True: 26, False: 405]
  ------------------
  409|     26|            goto cleanup;
  410|     26|        }
  411|    405|        if ((retval = read_double(ctx, &varinfo->missing_double_values[1])) != READSTAT_OK) {
  ------------------
  |  Branch (411:13): [True: 11, False: 394]
  ------------------
  412|     11|            goto cleanup;
  413|     11|        }
  414|  1.12k|    } else {
  415|  1.12k|        if ((retval = read_string(ctx, varinfo->missing_string_values[0],
  ------------------
  |  Branch (415:13): [True: 15, False: 1.10k]
  ------------------
  416|  1.12k|                        sizeof(varinfo->missing_string_values[0]))) != READSTAT_OK) {
  417|     15|            goto cleanup;
  418|     15|        }
  419|  1.10k|        if ((retval = read_string(ctx, varinfo->missing_string_values[1],
  ------------------
  |  Branch (419:13): [True: 17, False: 1.09k]
  ------------------
  420|  1.10k|                        sizeof(varinfo->missing_string_values[1]))) != READSTAT_OK) {
  421|     17|            goto cleanup;
  422|     17|        }
  423|  1.10k|    }
  424|  1.55k|cleanup:
  425|  1.55k|    return retval;
  426|  1.55k|}
readstat_por_read.c:read_missing_value_lo_range_record:
  428|  30.0k|static readstat_error_t read_missing_value_lo_range_record(por_ctx_t *ctx) {
  429|  30.0k|    readstat_error_t retval = READSTAT_OK;
  430|  30.0k|    spss_varinfo_t *varinfo = NULL;
  431|       |
  432|  30.0k|    if (ctx->var_offset < 0 || ctx->var_offset == ctx->var_count) {
  ------------------
  |  Branch (432:9): [True: 1, False: 30.0k]
  |  Branch (432:32): [True: 0, False: 30.0k]
  ------------------
  433|      1|        retval = READSTAT_ERROR_PARSE;
  434|      1|        goto cleanup;
  435|      1|    }
  436|  30.0k|    varinfo = &ctx->varinfo[ctx->var_offset];
  437|       |
  438|  30.0k|    varinfo->missing_range = 1;
  439|  30.0k|    varinfo->n_missing_values = 2;
  440|  30.0k|    if (varinfo->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (440:9): [True: 899, False: 29.1k]
  ------------------
  441|    899|        varinfo->missing_double_values[0] = -HUGE_VAL;
  442|    899|        if ((retval = read_double(ctx, &varinfo->missing_double_values[1])) != READSTAT_OK) {
  ------------------
  |  Branch (442:13): [True: 32, False: 867]
  ------------------
  443|     32|            goto cleanup;
  444|     32|        }
  445|  29.1k|    } else {
  446|  29.1k|        varinfo->missing_string_values[0][0] = '\0';
  447|  29.1k|        if ((retval = read_string(ctx, varinfo->missing_string_values[1],
  ------------------
  |  Branch (447:13): [True: 10, False: 29.1k]
  ------------------
  448|  29.1k|                        sizeof(varinfo->missing_string_values[1]))) != READSTAT_OK) {
  449|     10|            goto cleanup;
  450|     10|        }
  451|  29.1k|    }
  452|  30.0k|cleanup:
  453|  30.0k|    return retval;
  454|  30.0k|}
readstat_por_read.c:read_missing_value_hi_range_record:
  456|  88.6k|static readstat_error_t read_missing_value_hi_range_record(por_ctx_t *ctx) {
  457|  88.6k|    readstat_error_t retval = READSTAT_OK;
  458|  88.6k|    spss_varinfo_t *varinfo = NULL;
  459|       |
  460|  88.6k|    if (ctx->var_offset < 0 || ctx->var_offset == ctx->var_count) {
  ------------------
  |  Branch (460:9): [True: 1, False: 88.6k]
  |  Branch (460:32): [True: 0, False: 88.6k]
  ------------------
  461|      1|        retval = READSTAT_ERROR_PARSE;
  462|      1|        goto cleanup;
  463|      1|    }
  464|  88.6k|    varinfo = &ctx->varinfo[ctx->var_offset];
  465|       |
  466|  88.6k|    varinfo->missing_range = 1;
  467|  88.6k|    varinfo->n_missing_values = 2;
  468|  88.6k|    if (varinfo->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (468:9): [True: 855, False: 87.8k]
  ------------------
  469|    855|        if ((retval = read_double(ctx, &varinfo->missing_double_values[0])) != READSTAT_OK) {
  ------------------
  |  Branch (469:13): [True: 20, False: 835]
  ------------------
  470|     20|            goto cleanup;
  471|     20|        }
  472|    835|        varinfo->missing_double_values[1] = HUGE_VAL;
  473|  87.8k|    } else {
  474|  87.8k|        if ((retval = read_string(ctx, varinfo->missing_string_values[0],
  ------------------
  |  Branch (474:13): [True: 9, False: 87.8k]
  ------------------
  475|  87.8k|                        sizeof(varinfo->missing_string_values[0]))) != READSTAT_OK) {
  476|      9|            goto cleanup;
  477|      9|        }
  478|  87.8k|        varinfo->missing_string_values[1][0] = '\0';
  479|  87.8k|    }
  480|  88.6k|cleanup:
  481|  88.6k|    return retval;
  482|  88.6k|}
readstat_por_read.c:read_variable_label_record:
  507|  8.85k|static readstat_error_t read_variable_label_record(por_ctx_t *ctx) {
  508|  8.85k|    readstat_error_t retval = READSTAT_OK;
  509|  8.85k|    char string[256];
  510|  8.85k|    spss_varinfo_t *varinfo = NULL;
  511|       |
  512|  8.85k|    if (ctx->var_offset < 0 || ctx->var_offset == ctx->var_count) {
  ------------------
  |  Branch (512:9): [True: 1, False: 8.84k]
  |  Branch (512:32): [True: 0, False: 8.84k]
  ------------------
  513|      1|        retval = READSTAT_ERROR_PARSE;
  514|      1|        goto cleanup;
  515|      1|    }
  516|  8.84k|    varinfo = &ctx->varinfo[ctx->var_offset];
  517|       |
  518|  8.84k|    if ((retval = read_string(ctx, string, sizeof(string))) != READSTAT_OK) {
  ------------------
  |  Branch (518:9): [True: 30, False: 8.81k]
  ------------------
  519|     30|        goto cleanup;
  520|     30|    }
  521|       |
  522|  8.81k|    varinfo->label = realloc(varinfo->label, 4*strlen(string) + 1);
  523|  8.81k|    retval = readstat_convert(varinfo->label, 4*strlen(string) + 1, string, strlen(string), ctx->converter);
  524|       |
  525|  8.85k|cleanup:
  526|  8.85k|    return retval;
  527|  8.81k|}
readstat_por_read.c:read_value_label_record:
  529|  34.6k|static readstat_error_t read_value_label_record(por_ctx_t *ctx) {
  530|  34.6k|    readstat_error_t retval = READSTAT_OK;
  531|  34.6k|    double dval;
  532|  34.6k|    int i;
  533|  34.6k|    char string[256];
  534|  34.6k|    int count = 0, label_count = 0;
  535|  34.6k|    char label_name_buf[256];
  536|  34.6k|    char label_buf[256];
  537|  34.6k|    snprintf(label_name_buf, sizeof(label_name_buf), POR_LABEL_NAME_PREFIX "%d", ctx->labels_offset);
  ------------------
  |  |   25|  34.6k|#define POR_LABEL_NAME_PREFIX   "labels"
  ------------------
  538|  34.6k|    readstat_type_t value_type = READSTAT_TYPE_DOUBLE;
  539|  34.6k|    if ((retval = read_integer_in_range(ctx, 0, MAX_STRINGS, &count)) != READSTAT_OK) {
  ------------------
  |  |   36|  34.6k|#define MAX_STRINGS 1000000
  ------------------
  |  Branch (539:9): [True: 19, False: 34.6k]
  ------------------
  540|     19|        goto cleanup;
  541|     19|    }
  542|  50.6k|    for (i=0; i<count; i++) {
  ------------------
  |  Branch (542:15): [True: 16.2k, False: 34.4k]
  ------------------
  543|  16.2k|        if ((retval = read_string(ctx, string, sizeof(string))) != READSTAT_OK) {
  ------------------
  |  Branch (543:13): [True: 195, False: 16.0k]
  ------------------
  544|    195|            goto cleanup;
  545|    195|        }
  546|  16.0k|        spss_varinfo_t *info = (spss_varinfo_t *)ck_str_hash_lookup(string, ctx->var_dict);
  547|  16.0k|        if (info) {
  ------------------
  |  Branch (547:13): [True: 8.70k, False: 7.29k]
  ------------------
  548|  8.70k|            value_type = info->type;
  549|  8.70k|            info->labels_index = ctx->labels_offset;
  550|  8.70k|        }
  551|  16.0k|    }
  552|  34.4k|    if ((retval = read_integer_in_range(ctx, 0, MAX_LABELS, &label_count)) != READSTAT_OK) {
  ------------------
  |  |   37|  34.4k|#define MAX_LABELS  1000000
  ------------------
  |  Branch (552:9): [True: 36, False: 34.4k]
  ------------------
  553|     36|        goto cleanup;
  554|     36|    }
  555|  35.6k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (555:15): [True: 1.33k, False: 34.3k]
  ------------------
  556|  1.33k|        readstat_value_t value = { .type = value_type };
  557|  1.33k|        if (value_type == READSTAT_TYPE_STRING) {
  ------------------
  |  Branch (557:13): [True: 407, False: 928]
  ------------------
  558|    407|            if ((retval = read_string(ctx, string, sizeof(string))) != READSTAT_OK) {
  ------------------
  |  Branch (558:17): [True: 10, False: 397]
  ------------------
  559|     10|                goto cleanup;
  560|     10|            }
  561|    397|            if ((retval = read_string(ctx, label_buf, sizeof(label_buf))) != READSTAT_OK) {
  ------------------
  |  Branch (561:17): [True: 11, False: 386]
  ------------------
  562|     11|                goto cleanup;
  563|     11|            }
  564|    386|            value.v.string_value = string;
  565|    928|        } else {
  566|    928|            if ((retval = read_double(ctx, &dval)) != READSTAT_OK) {
  ------------------
  |  Branch (566:17): [True: 40, False: 888]
  ------------------
  567|     40|                goto cleanup;
  568|     40|            }
  569|    888|            if ((retval = read_string(ctx, label_buf, sizeof(label_buf))) != READSTAT_OK) {
  ------------------
  |  Branch (569:17): [True: 13, False: 875]
  ------------------
  570|     13|                goto cleanup;
  571|     13|            }
  572|    875|            value.v.double_value = dval;
  573|    875|        }
  574|  1.26k|        if (ctx->handle.value_label) {
  ------------------
  |  Branch (574:13): [True: 1.26k, False: 0]
  ------------------
  575|  1.26k|            if (ctx->handle.value_label(label_name_buf, value, label_buf, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (575:17): [True: 0, False: 1.26k]
  ------------------
  576|      0|                retval = READSTAT_ERROR_USER_ABORT;
  577|      0|                goto cleanup;
  578|      0|            }
  579|  1.26k|        }
  580|  1.26k|    }
  581|  34.3k|    ctx->labels_offset++;
  582|       |
  583|  34.6k|cleanup:
  584|  34.6k|    return retval;
  585|  34.3k|}
readstat_por_read.c:read_document_record:
  484|  1.08k|static readstat_error_t read_document_record(por_ctx_t *ctx) {
  485|  1.08k|    readstat_error_t retval = READSTAT_OK;
  486|  1.08k|    char string[256];
  487|  1.08k|    int i;
  488|  1.08k|    int line_count = 0;
  489|  1.08k|    if ((retval = read_integer_in_range(ctx, 0, MAX_LINES, &line_count)) != READSTAT_OK) {
  ------------------
  |  |   35|  1.08k|#define MAX_LINES   1000000
  ------------------
  |  Branch (489:9): [True: 20, False: 1.06k]
  ------------------
  490|     20|        goto cleanup;
  491|     20|    }
  492|  2.10k|    for (i=0; i<line_count; i++) {
  ------------------
  |  Branch (492:15): [True: 1.08k, False: 1.02k]
  ------------------
  493|  1.08k|        if ((retval = read_string(ctx, string, sizeof(string))) != READSTAT_OK) {
  ------------------
  |  Branch (493:13): [True: 47, False: 1.04k]
  ------------------
  494|     47|            goto cleanup;
  495|     47|        }
  496|  1.04k|        if (ctx->handle.note) {
  ------------------
  |  Branch (496:13): [True: 1.04k, False: 0]
  ------------------
  497|  1.04k|            if (ctx->handle.note(i, string, ctx->user_ctx) != READSTAT_OK) {
  ------------------
  |  Branch (497:17): [True: 0, False: 1.04k]
  ------------------
  498|      0|                retval = READSTAT_ERROR_USER_ABORT;
  499|      0|                goto cleanup;
  500|      0|            }
  501|  1.04k|        }
  502|  1.04k|    }
  503|  1.08k|cleanup:
  504|  1.08k|    return retval;
  505|  1.06k|}
readstat_por_read.c:read_por_file_data:
  587|    314|static readstat_error_t read_por_file_data(por_ctx_t *ctx) {
  588|    314|    int i;
  589|    314|    char input_string[256];
  590|    314|    char output_string[4*256+1];
  591|    314|    char error_buf[1024];
  592|    314|    readstat_error_t rs_retval = READSTAT_OK;
  593|       |
  594|    314|    if (ctx->var_count == 0)
  ------------------
  |  Branch (594:9): [True: 7, False: 307]
  ------------------
  595|      7|        return READSTAT_OK;
  596|       |
  597|  1.57k|    while (1) {
  ------------------
  |  Branch (597:12): [True: 1.57k, Folded]
  ------------------
  598|  1.57k|        int finished = 0;
  599|  3.25k|        for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (599:19): [True: 1.99k, False: 1.26k]
  ------------------
  600|  1.99k|            spss_varinfo_t *info = &ctx->varinfo[i];
  601|  1.99k|            readstat_value_t value = { .type = info->type };
  602|       |
  603|  1.99k|            if (info->type == READSTAT_TYPE_STRING) {
  ------------------
  |  Branch (603:17): [True: 906, False: 1.08k]
  ------------------
  604|    906|                rs_retval = maybe_read_string(ctx, input_string, sizeof(input_string), &finished);
  605|    906|                if (rs_retval != READSTAT_OK) {
  ------------------
  |  Branch (605:21): [True: 174, False: 732]
  ------------------
  606|    174|                    if (ctx->handle.error) {
  ------------------
  |  Branch (606:25): [True: 0, False: 174]
  ------------------
  607|      0|                        snprintf(error_buf, sizeof(error_buf), "Error in %s (row=%d)", 
  608|      0|                                info->name, ctx->obs_count+1);
  609|      0|                        ctx->handle.error(error_buf, ctx->user_ctx);
  610|      0|                    }
  611|    174|                    goto cleanup;
  612|    732|                } else if (finished) {
  ------------------
  |  Branch (612:28): [True: 6, False: 726]
  ------------------
  613|      6|                    if (i != 0)
  ------------------
  |  Branch (613:25): [True: 5, False: 1]
  ------------------
  614|      5|                        rs_retval = READSTAT_ERROR_PARSE;
  615|      6|                    goto cleanup;
  616|      6|                }
  617|    726|                rs_retval = readstat_convert(output_string, sizeof(output_string),
  618|    726|                        input_string, strlen(input_string), ctx->converter);
  619|    726|                if (rs_retval != READSTAT_OK) {
  ------------------
  |  Branch (619:21): [True: 0, False: 726]
  ------------------
  620|      0|                    goto cleanup;
  621|      0|                }
  622|    726|                value.v.string_value = output_string;
  623|  1.08k|            } else if (info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (623:24): [True: 1.08k, False: 0]
  ------------------
  624|  1.08k|                rs_retval = maybe_read_double(ctx, &value.v.double_value, &finished);
  625|  1.08k|                if (rs_retval != READSTAT_OK) {
  ------------------
  |  Branch (625:21): [True: 121, False: 963]
  ------------------
  626|    121|                    if (ctx->handle.error) {
  ------------------
  |  Branch (626:25): [True: 0, False: 121]
  ------------------
  627|      0|                        snprintf(error_buf, sizeof(error_buf), "Error in %s (row=%d)", 
  628|      0|                                info->name, ctx->obs_count+1);
  629|      0|                        ctx->handle.error(error_buf, ctx->user_ctx);
  630|      0|                    }
  631|    121|                    goto cleanup;
  632|    963|                } else if (finished) {
  ------------------
  |  Branch (632:28): [True: 6, False: 957]
  ------------------
  633|      6|                    if (i != 0)
  ------------------
  |  Branch (633:25): [True: 5, False: 1]
  ------------------
  634|      5|                        rs_retval = READSTAT_ERROR_PARSE;
  635|      6|                    goto cleanup;
  636|      6|                }
  637|    957|                value.is_system_missing = isnan(value.v.double_value);
  638|    957|            }
  639|  1.68k|            if (ctx->handle.value && !ctx->variables[i]->skip && !ctx->row_offset) {
  ------------------
  |  Branch (639:17): [True: 1.68k, False: 0]
  |  Branch (639:38): [True: 1.68k, False: 0]
  |  Branch (639:66): [True: 1.68k, False: 0]
  ------------------
  640|  1.68k|                if (ctx->handle.value(ctx->obs_count, ctx->variables[i], value, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  Branch (640:21): [True: 0, False: 1.68k]
  ------------------
  641|      0|                    rs_retval = READSTAT_ERROR_USER_ABORT;
  642|      0|                    goto cleanup;
  643|      0|                }
  644|  1.68k|            }
  645|       |
  646|  1.68k|        }
  647|  1.26k|        if (ctx->row_offset) {
  ------------------
  |  Branch (647:13): [True: 0, False: 1.26k]
  ------------------
  648|      0|            ctx->row_offset--;
  649|  1.26k|        } else {
  650|  1.26k|            ctx->obs_count++;
  651|  1.26k|        }
  652|       |
  653|  1.26k|        rs_retval = por_update_progress(ctx);
  654|  1.26k|        if (rs_retval != READSTAT_OK)
  ------------------
  |  Branch (654:13): [True: 0, False: 1.26k]
  ------------------
  655|      0|            break;
  656|       |            
  657|  1.26k|        if (ctx->row_limit > 0 && ctx->obs_count == ctx->row_limit)
  ------------------
  |  Branch (657:13): [True: 0, False: 1.26k]
  |  Branch (657:35): [True: 0, False: 0]
  ------------------
  658|      0|            break;
  659|  1.26k|    }
  660|    307|cleanup:
  661|    307|    return rs_retval;
  662|    307|}
readstat_por_read.c:por_update_progress:
   42|  1.26k|static readstat_error_t por_update_progress(por_ctx_t *ctx) {
   43|  1.26k|    readstat_io_t *io = ctx->io;
   44|  1.26k|    return io->update(ctx->file_size, ctx->handle.progress, ctx->user_ctx, io->io_ctx);
   45|  1.26k|}

spss_format:
   51|  5.24k|int spss_format(char *buffer, size_t len, spss_format_t *format) {
   52|  5.24k|    if (format->type < 0 
  ------------------
  |  Branch (52:9): [True: 0, False: 5.24k]
  ------------------
   53|  5.24k|            || format->type >= sizeof(spss_type_strings)/sizeof(spss_type_strings[0])
  ------------------
  |  Branch (53:16): [True: 76, False: 5.17k]
  ------------------
   54|  5.17k|            || spss_type_strings[format->type][0] == '\0') {
  ------------------
  |  Branch (54:16): [True: 1.56k, False: 3.60k]
  ------------------
   55|  1.63k|        return 0;
   56|  1.63k|    }
   57|  3.60k|    char *string = spss_type_strings[format->type];
   58|       |
   59|  3.60k|    if (format->decimal_places || format->type == SPSS_FORMAT_TYPE_F) {
  ------------------
  |  |    6|  1.21k|#define SPSS_FORMAT_TYPE_F        5
  ------------------
  |  Branch (59:9): [True: 2.39k, False: 1.21k]
  |  Branch (59:35): [True: 178, False: 1.03k]
  ------------------
   60|  2.57k|        snprintf(buffer, len, "%s%d.%d", string, format->width, format->decimal_places);
   61|  2.57k|    } else if (format->width) {
  ------------------
  |  Branch (61:16): [True: 744, False: 294]
  ------------------
   62|    744|        snprintf(buffer, len, "%s%d", string, format->width);
   63|    744|    } else {
   64|    294|        snprintf(buffer, len, "%s", string);
   65|    294|    }
   66|       |
   67|  3.60k|    return 1;
   68|  5.24k|}
spss_missingness_for_info:
  127|  5.24k|readstat_missingness_t spss_missingness_for_info(spss_varinfo_t *info) {
  128|  5.24k|    readstat_missingness_t missingness;
  129|  5.24k|    memset(&missingness, '\0', sizeof(readstat_missingness_t));
  130|       |
  131|  5.24k|    if (info->missing_range) {
  ------------------
  |  Branch (131:9): [True: 762, False: 4.48k]
  ------------------
  132|    762|        missingness.missing_ranges_count++;
  133|    762|        missingness.missing_ranges[0] = spss_boxed_missing_value(info, 0);
  134|    762|        missingness.missing_ranges[1] = spss_boxed_missing_value(info, 1);
  135|       |
  136|    762|        if (info->n_missing_values == 3) {
  ------------------
  |  Branch (136:13): [True: 260, False: 502]
  ------------------
  137|    260|            missingness.missing_ranges_count++;
  138|    260|            missingness.missing_ranges[2] = missingness.missing_ranges[3] = spss_boxed_missing_value(info, 2);
  139|    260|        }
  140|  4.48k|    } else if (info->n_missing_values > 0) {
  ------------------
  |  Branch (140:16): [True: 436, False: 4.05k]
  ------------------
  141|    436|        missingness.missing_ranges_count = info->n_missing_values;
  142|    436|        int i=0;
  143|  1.00k|        for (i=0; i<info->n_missing_values; i++) {
  ------------------
  |  Branch (143:19): [True: 573, False: 436]
  ------------------
  144|    573|            missingness.missing_ranges[2*i] = missingness.missing_ranges[2*i+1] = spss_boxed_missing_value(info, i);
  145|    573|        }
  146|    436|    }
  147|  5.24k|    return missingness;
  148|  5.24k|}
spss_init_variable_for_info:
  151|  5.24k|        iconv_t converter) {
  152|  5.24k|    readstat_variable_t *variable = calloc(1, sizeof(readstat_variable_t));
  153|       |
  154|  5.24k|    variable->index = info->index;
  155|  5.24k|    variable->index_after_skipping = index_after_skipping;
  156|  5.24k|    variable->type = info->type;
  157|  5.24k|    if (info->string_length) {
  ------------------
  |  Branch (157:9): [True: 0, False: 5.24k]
  ------------------
  158|      0|        variable->storage_width = info->string_length;
  159|  5.24k|    } else {
  160|  5.24k|        variable->storage_width = 8 * info->width;
  161|  5.24k|    }
  162|       |
  163|  5.24k|    if (info->longname[0]) {
  ------------------
  |  Branch (163:9): [True: 0, False: 5.24k]
  ------------------
  164|      0|        readstat_convert(variable->name, sizeof(variable->name),
  165|      0|                info->longname, sizeof(info->longname), converter);
  166|  5.24k|    } else {
  167|  5.24k|        readstat_convert(variable->name, sizeof(variable->name),
  168|  5.24k|                info->name, sizeof(info->name), converter);
  169|  5.24k|    }
  170|  5.24k|    if (info->label) {
  ------------------
  |  Branch (170:9): [True: 203, False: 5.04k]
  ------------------
  171|    203|        snprintf(variable->label, sizeof(variable->label), "%s", info->label);
  172|    203|    }
  173|       |
  174|  5.24k|    spss_format(variable->format, sizeof(variable->format), &info->print_format);
  175|       |
  176|  5.24k|    variable->missingness = spss_missingness_for_info(info);
  177|  5.24k|    variable->measure = info->measure;
  178|  5.24k|    if (info->display_width) {
  ------------------
  |  Branch (178:9): [True: 0, False: 5.24k]
  ------------------
  179|      0|        variable->display_width = info->display_width;
  180|  5.24k|    } else {
  181|  5.24k|        variable->display_width = info->print_format.width;
  182|  5.24k|    }
  183|       |
  184|  5.24k|    return variable;
  185|  5.24k|}
readstat_spss.c:spss_boxed_missing_value:
  120|  2.35k|static readstat_value_t spss_boxed_missing_value(spss_varinfo_t *info, int i) {
  121|  2.35k|    if (info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (121:9): [True: 1.45k, False: 900]
  ------------------
  122|  1.45k|        return spss_boxed_double_value(info->missing_double_values[i]);
  123|  1.45k|    }
  124|    900|    return spss_boxed_string_value(info->missing_string_values[i]);
  125|  2.35k|}
readstat_spss.c:spss_boxed_double_value:
  103|  1.45k|static readstat_value_t spss_boxed_double_value(double fp_value) {
  104|  1.45k|    readstat_value_t value = {
  105|  1.45k|        .type = READSTAT_TYPE_DOUBLE,
  106|  1.45k|        .v = { .double_value = fp_value },
  107|       |        .is_system_missing = isnan(fp_value)
  108|  1.45k|    };
  109|  1.45k|    return value;
  110|  1.45k|}
readstat_spss.c:spss_boxed_string_value:
  112|    900|static readstat_value_t spss_boxed_string_value(const char *string) {
  113|    900|    readstat_value_t value = {
  114|    900|        .type = READSTAT_TYPE_STRING,
  115|    900|        .v = { .string_value = string }
  116|    900|    };
  117|    900|    return value;
  118|    900|}

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

