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

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

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

readstat_convert:
   39|  24.0k|readstat_error_t readstat_convert(char *dst, size_t dst_len, const char *src, size_t src_len, iconv_t converter) {
   40|  24.0k|    return readstat_convert_impl(dst, dst_len, src, src_len, converter, 1);
   41|  24.0k|}
readstat_convert.c:readstat_convert_impl:
    8|  24.0k|        iconv_t converter, int trim_spaces) {
    9|       |    /* strip off spaces from the input because the programs use ASCII space
   10|       |     * padding even with non-ASCII encoding. */
   11|  87.6k|    while (src_len && ((trim_spaces && src[src_len-1] == ' ') || src[src_len-1] == '\0')) {
  ------------------
  |  Branch (11:12): [True: 79.1k, False: 8.48k]
  |  Branch (11:25): [True: 79.1k, False: 0]
  |  Branch (11:40): [True: 54.0k, False: 25.1k]
  |  Branch (11:66): [True: 9.58k, False: 15.5k]
  ------------------
   12|  63.6k|        src_len--;
   13|  63.6k|    }
   14|  24.0k|    if (dst_len == 0) {
  ------------------
  |  Branch (14:9): [True: 0, False: 24.0k]
  ------------------
   15|      0|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   16|  24.0k|    } else if (converter) {
  ------------------
  |  Branch (16:16): [True: 0, False: 24.0k]
  ------------------
   17|      0|        size_t dst_left = dst_len - 1;
   18|      0|        char *dst_end = dst;
   19|      0|        size_t status = iconv(converter, (readstat_iconv_inbuf_t)&src, &src_len, &dst_end, &dst_left);
   20|      0|        if (status == (size_t)-1) {
  ------------------
  |  Branch (20:13): [True: 0, False: 0]
  ------------------
   21|      0|            if (errno == E2BIG) {
  ------------------
  |  Branch (21:17): [True: 0, False: 0]
  ------------------
   22|      0|                return READSTAT_ERROR_CONVERT_LONG_STRING;
   23|      0|            } else if (errno == EILSEQ) {
  ------------------
  |  Branch (23:24): [True: 0, False: 0]
  ------------------
   24|      0|                return READSTAT_ERROR_CONVERT_BAD_STRING;
   25|      0|            } else if (errno != EINVAL) { /* EINVAL indicates improper truncation; accept it */
  ------------------
  |  Branch (25:24): [True: 0, False: 0]
  ------------------
   26|      0|                return READSTAT_ERROR_CONVERT;
   27|      0|            }
   28|      0|        }
   29|      0|        dst[dst_len - dst_left - 1] = '\0';
   30|  24.0k|    } else if (src_len + 1 > dst_len) {
  ------------------
  |  Branch (30:16): [True: 0, False: 24.0k]
  ------------------
   31|      0|        return READSTAT_ERROR_CONVERT_LONG_STRING;
   32|  24.0k|    } else {
   33|  24.0k|        memcpy(dst, src, src_len);
   34|  24.0k|        dst[src_len] = '\0';
   35|  24.0k|    }
   36|  24.0k|    return READSTAT_OK;
   37|  24.0k|}

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

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

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

por_ctx_init:
   75|  2.73k|por_ctx_t *por_ctx_init(void) {
   76|  2.73k|    por_ctx_t *ctx = calloc(1, sizeof(por_ctx_t));
   77|       |
   78|  2.73k|    ctx->space = ' ';
   79|  2.73k|    ctx->base30_precision = 20;
   80|  2.73k|    ctx->var_dict = ck_hash_table_init(1024, 8);
   81|  2.73k|    return ctx;
   82|  2.73k|}
por_ctx_free:
   84|  2.73k|void por_ctx_free(por_ctx_t *ctx) {
   85|  2.73k|    if (ctx->string_buffer)
  ------------------
  |  Branch (85:9): [True: 1.81k, False: 917]
  ------------------
   86|  1.81k|        free(ctx->string_buffer);
   87|  2.73k|    if (ctx->varinfo) {
  ------------------
  |  Branch (87:9): [True: 1.12k, False: 1.60k]
  ------------------
   88|  1.12k|        int i;
   89|  2.94M|        for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (89:19): [True: 2.94M, False: 1.12k]
  ------------------
   90|  2.94M|            if (ctx->varinfo[i].label)
  ------------------
  |  Branch (90:17): [True: 768, False: 2.94M]
  ------------------
   91|    768|                free(ctx->varinfo[i].label);
   92|  2.94M|        }
   93|  1.12k|        free(ctx->varinfo);
   94|  1.12k|    }
   95|  2.73k|    if (ctx->variables) {
  ------------------
  |  Branch (95:9): [True: 1.13k, False: 1.59k]
  ------------------
   96|  1.13k|        int i;
   97|  7.84M|        for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (97:19): [True: 7.84M, False: 1.13k]
  ------------------
   98|  7.84M|            if (ctx->variables[i])
  ------------------
  |  Branch (98:17): [True: 1.42k, False: 7.84M]
  ------------------
   99|  1.42k|                free(ctx->variables[i]);
  100|  7.84M|        }
  101|  1.13k|        free(ctx->variables);
  102|  1.13k|    }
  103|  2.73k|    if (ctx->var_dict)
  ------------------
  |  Branch (103:9): [True: 2.73k, False: 0]
  ------------------
  104|  2.73k|        ck_hash_table_free(ctx->var_dict);
  105|  2.73k|    if (ctx->converter)
  ------------------
  |  Branch (105:9): [True: 0, False: 2.73k]
  ------------------
  106|      0|        iconv_close(ctx->converter);
  107|  2.73k|    free(ctx);
  108|  2.73k|}
por_utf8_encode:
  168|   182k|        char *output, size_t output_len, uint16_t lookup[256]) {
  169|   182k|    size_t offset = 0;
  170|   182k|    size_t i;
  171|  2.66M|    for (i=0; i<input_len; i++) {
  ------------------
  |  Branch (171:15): [True: 2.48M, False: 178k]
  ------------------
  172|  2.48M|        uint16_t codepoint = lookup[input[i]];
  173|       |
  174|       |        /* Some software (SPSS?) uses an undefined character (zero) if a
  175|       |         * character can't be encoded. Use Unicode replacement character */
  176|  2.48M|        if (codepoint == 0) {
  ------------------
  |  Branch (176:13): [True: 20.4k, False: 2.46M]
  ------------------
  177|  20.4k|            codepoint = 0xFFFD;
  178|  20.4k|        }
  179|       |
  180|  2.48M|        if (codepoint < 0x20) {
  ------------------
  |  Branch (180:13): [True: 0, False: 2.48M]
  ------------------
  181|      0|            return -1;
  182|  2.48M|        } else if (codepoint <= 0x7F) {
  ------------------
  |  Branch (182:20): [True: 2.46M, False: 21.1k]
  ------------------
  183|  2.46M|            if (offset + 1 > output_len)
  ------------------
  |  Branch (183:17): [True: 1.89k, False: 2.45M]
  ------------------
  184|  1.89k|                return offset;
  185|       |
  186|  2.45M|            output[offset++] = codepoint;
  187|  2.45M|        } else if (codepoint <= 0x07FF) {
  ------------------
  |  Branch (187:20): [True: 597, False: 20.5k]
  ------------------
  188|    597|            if (offset + 2 > output_len)
  ------------------
  |  Branch (188:17): [True: 196, False: 401]
  ------------------
  189|    196|                return offset;
  190|       |
  191|    401|            output[offset++] = 0xC0 | (codepoint >> 6);
  192|    401|            output[offset++] = 0x80 | (codepoint & 0x3F);
  193|  20.5k|        } else {
  194|  20.5k|            if (offset + 3 > output_len)
  ------------------
  |  Branch (194:17): [True: 2.55k, False: 17.9k]
  ------------------
  195|  2.55k|                return offset;
  196|       |
  197|  17.9k|            output[offset++] = 0xE0 | (codepoint >> 12);
  198|  17.9k|            output[offset++] = 0x80 | ((codepoint >> 6) & 0x3F);
  199|  17.9k|            output[offset++] = 0x80 | (codepoint & 0x3F);
  200|  17.9k|        }
  201|  2.48M|    }
  202|   178k|    return offset;
  203|   182k|}
por_base30_to_double:
  399|   141k|double por_base30_to_double(const unsigned char *digits, size_t n_digits, long exponent) {
  400|   141k|    uint64_t mantissa = 0;
  401|   141k|    size_t mantissa_digits = 0;
  402|   141k|    long magnitude = 0;
  403|   141k|    long scale = 0;
  404|   141k|    double value = 0.0;
  405|   141k|    int iterations = 0;
  406|       |
  407|   141k|    while (n_digits > 0 && digits[0] == 0) {
  ------------------
  |  Branch (407:12): [True: 104k, False: 37.7k]
  |  Branch (407:28): [True: 0, False: 104k]
  ------------------
  408|      0|        digits++;
  409|      0|        n_digits--;
  410|      0|    }
  411|   207k|    while (n_digits > 0 && digits[n_digits-1] == 0) {
  ------------------
  |  Branch (411:12): [True: 169k, False: 37.7k]
  |  Branch (411:28): [True: 65.6k, False: 104k]
  ------------------
  412|  65.6k|        n_digits--;
  413|  65.6k|        exponent++;
  414|  65.6k|    }
  415|   141k|    if (n_digits == 0)
  ------------------
  |  Branch (415:9): [True: 37.7k, False: 104k]
  ------------------
  416|  37.7k|        return 0.0;
  417|       |
  418|       |    /* The value lies in [30^(magnitude-1), 30^magnitude) */
  419|   104k|    magnitude = (long)n_digits + exponent;
  420|   104k|    if (magnitude >= 210) /* 30^209 exceeds DBL_MAX */
  ------------------
  |  Branch (420:9): [True: 559, False: 103k]
  ------------------
  421|    559|        return HUGE_VAL;
  422|   103k|    if (magnitude <= -225) /* 30^-225 is below half the smallest denormal */
  ------------------
  |  Branch (422:9): [True: 1.13k, False: 102k]
  ------------------
  423|  1.13k|        return 0.0;
  424|       |
  425|       |    /* Initial approximation from the leading 13 digits (30^13 < 2^64) */
  426|   408k|    while (mantissa_digits < n_digits && mantissa_digits < 13) {
  ------------------
  |  Branch (426:12): [True: 315k, False: 93.0k]
  |  Branch (426:42): [True: 306k, False: 9.35k]
  ------------------
  427|   306k|        mantissa = mantissa * 30 + digits[mantissa_digits];
  428|   306k|        mantissa_digits++;
  429|   306k|    }
  430|   102k|    scale = exponent + (long)(n_digits - mantissa_digits);
  431|       |
  432|   102k|    if (mantissa <= (1ULL << 53) && scale >= -13 && scale <= 13) {
  ------------------
  |  Branch (432:9): [True: 87.8k, False: 14.5k]
  |  Branch (432:37): [True: 84.0k, False: 3.79k]
  |  Branch (432:53): [True: 82.9k, False: 1.10k]
  ------------------
  433|       |        /* Both operands are exact, so the single multiplication or division
  434|       |         * below is correctly rounded (30^13 = 2^13 * 15^13 and 15^13 < 2^53) */
  435|  82.9k|        double pow30 = 1.0;
  436|  82.9k|        long k = scale < 0 ? -scale : scale;
  ------------------
  |  Branch (436:18): [True: 504, False: 82.4k]
  ------------------
  437|  87.1k|        while (k-- > 0)
  ------------------
  |  Branch (437:16): [True: 4.23k, False: 82.9k]
  ------------------
  438|  4.23k|            pow30 *= 30.0;
  439|  82.9k|        return scale < 0 ? (double)mantissa / pow30 : (double)mantissa * pow30;
  ------------------
  |  Branch (439:16): [True: 504, False: 82.4k]
  ------------------
  440|  82.9k|    }
  441|       |
  442|  19.4k|    value = (double)mantissa;
  443|  29.5k|    while (scale > 0) {
  ------------------
  |  Branch (443:12): [True: 10.0k, False: 19.4k]
  ------------------
  444|  10.0k|        long step = scale > 200 ? 200 : scale;
  ------------------
  |  Branch (444:21): [True: 389, False: 9.69k]
  ------------------
  445|  10.0k|        value *= pow(30.0, (double)step);
  446|  10.0k|        scale -= step;
  447|  10.0k|    }
  448|  25.6k|    while (scale < 0) {
  ------------------
  |  Branch (448:12): [True: 6.22k, False: 19.4k]
  ------------------
  449|  6.22k|        long step = scale < -200 ? -200 : scale;
  ------------------
  |  Branch (449:21): [True: 485, False: 5.73k]
  ------------------
  450|  6.22k|        value *= pow(30.0, (double)step);
  451|  6.22k|        scale -= step;
  452|  6.22k|    }
  453|  19.4k|    if (isinf(value))
  ------------------
  |  Branch (453:9): [True: 446, False: 19.0k]
  ------------------
  454|    446|        value = DBL_MAX;
  455|       |
  456|       |    /* Correct the approximation by comparing the exact value against the
  457|       |     * midpoints between the candidate and its neighbors, moving one ulp at a
  458|       |     * time. Ties round to even. */
  459|  24.6k|    for (iterations=0; iterations<256; iterations++) {
  ------------------
  |  Branch (459:24): [True: 24.6k, False: 0]
  ------------------
  460|  24.6k|        uint64_t m = 0;
  461|  24.6k|        long e = -1074;
  462|  24.6k|        uint64_t midpoint_mantissa = 0;
  463|  24.6k|        long midpoint_exponent = 0;
  464|  24.6k|        int cmp = 0;
  465|       |
  466|  24.6k|        if (isinf(value))
  ------------------
  |  Branch (466:13): [True: 446, False: 24.2k]
  ------------------
  467|    446|            break;
  468|       |
  469|  24.2k|        if (value != 0.0) {
  ------------------
  |  Branch (469:13): [True: 24.0k, False: 203]
  ------------------
  470|  24.0k|            int exp2 = 0;
  471|  24.0k|            double significand = frexp(value, &exp2);
  472|  24.0k|            m = (uint64_t)ldexp(significand, 53);
  473|  24.0k|            e = exp2 - 53;
  474|  24.0k|            if (e < -1074) {
  ------------------
  |  Branch (474:17): [True: 260, False: 23.7k]
  ------------------
  475|       |                /* denormal: the spacing is fixed at 2^-1074 */
  476|    260|                m = (uint64_t)ldexp(value, 1074);
  477|    260|                e = -1074;
  478|    260|            }
  479|  24.0k|        }
  480|       |
  481|       |        /* midpoint above: (2m + 1) * 2^(e - 1) */
  482|  24.2k|        midpoint_mantissa = 2 * m + 1;
  483|  24.2k|        midpoint_exponent = e - 1;
  484|  24.2k|        cmp = por_compare_with_binary(digits, n_digits, exponent, midpoint_mantissa, midpoint_exponent);
  485|  24.2k|        if (cmp == 2)
  ------------------
  |  Branch (485:13): [True: 0, False: 24.2k]
  ------------------
  486|      0|            break;
  487|  24.2k|        if (cmp > 0) {
  ------------------
  |  Branch (487:13): [True: 3.51k, False: 20.7k]
  ------------------
  488|  3.51k|            value = nextafter(value, HUGE_VAL);
  489|  3.51k|            continue;
  490|  3.51k|        }
  491|  20.7k|        if (cmp == 0) {
  ------------------
  |  Branch (491:13): [True: 790, False: 19.9k]
  ------------------
  492|    790|            if (m & 1)
  ------------------
  |  Branch (492:17): [True: 194, False: 596]
  ------------------
  493|    194|                value = nextafter(value, HUGE_VAL);
  494|    790|            break;
  495|    790|        }
  496|  19.9k|        if (m == 0)
  ------------------
  |  Branch (496:13): [True: 203, False: 19.7k]
  ------------------
  497|    203|            break;
  498|       |
  499|       |        /* midpoint below: the spacing halves just below a power of two */
  500|  19.7k|        if (m == (1ULL << 52) && e > -1074) {
  ------------------
  |  Branch (500:13): [True: 205, False: 19.5k]
  |  Branch (500:34): [True: 205, False: 0]
  ------------------
  501|    205|            midpoint_mantissa = 4 * m - 1;
  502|    205|            midpoint_exponent = e - 2;
  503|  19.5k|        } else {
  504|  19.5k|            midpoint_mantissa = 2 * m - 1;
  505|  19.5k|            midpoint_exponent = e - 1;
  506|  19.5k|        }
  507|  19.7k|        cmp = por_compare_with_binary(digits, n_digits, exponent, midpoint_mantissa, midpoint_exponent);
  508|  19.7k|        if (cmp == 2)
  ------------------
  |  Branch (508:13): [True: 0, False: 19.7k]
  ------------------
  509|      0|            break;
  510|  19.7k|        if (cmp < 0) {
  ------------------
  |  Branch (510:13): [True: 1.70k, False: 18.0k]
  ------------------
  511|  1.70k|            value = nextafter(value, 0.0);
  512|  1.70k|            continue;
  513|  1.70k|        }
  514|  18.0k|        if (cmp == 0) {
  ------------------
  |  Branch (514:13): [True: 2.86k, False: 15.1k]
  ------------------
  515|       |            /* value's mantissa is 2m in the finer grid below a power of two,
  516|       |             * which is even, so only the ordinary case can move */
  517|  2.86k|            if (midpoint_mantissa == 2 * m - 1 && (m & 1))
  ------------------
  |  Branch (517:17): [True: 2.86k, False: 0]
  |  Branch (517:51): [True: 201, False: 2.66k]
  ------------------
  518|    201|                value = nextafter(value, 0.0);
  519|  2.86k|            break;
  520|  2.86k|        }
  521|  15.1k|        break;
  522|  18.0k|    }
  523|       |
  524|  19.4k|    return value;
  525|   102k|}
readstat_por.c:por_big_set:
  249|  87.9k|static void por_big_set(por_bignum_t *big, uint64_t value) {
  250|  87.9k|    big->n = 0;
  251|  87.9k|    big->overflow = 0;
  252|   175k|    while (value) {
  ------------------
  |  Branch (252:12): [True: 87.3k, False: 87.9k]
  ------------------
  253|  87.3k|        big->limbs[big->n++] = (uint32_t)(value % POR_BIG_LIMB_BASE);
  ------------------
  |  |  239|  87.3k|#define POR_BIG_LIMB_BASE   729000000u  /* 30^6 */
  ------------------
  254|  87.3k|        value /= POR_BIG_LIMB_BASE;
  ------------------
  |  |  239|  87.3k|#define POR_BIG_LIMB_BASE   729000000u  /* 30^6 */
  ------------------
  255|  87.3k|    }
  256|  87.9k|}
readstat_por.c:por_big_mul_pow:
  279|  54.4k|static void por_big_mul_pow(por_bignum_t *big, uint32_t base, long exponent) {
  280|  54.4k|    uint32_t chunk_mult = 1;
  281|  54.4k|    long chunk = 0;
  282|  1.32M|    while ((uint64_t)chunk_mult * base <= 0xFFFFFFFFu) {
  ------------------
  |  Branch (282:12): [True: 1.27M, False: 54.4k]
  ------------------
  283|  1.27M|        chunk_mult *= base;
  284|  1.27M|        chunk++;
  285|  1.27M|    }
  286|   524k|    while (exponent >= chunk && !big->overflow) {
  ------------------
  |  Branch (286:12): [True: 469k, False: 54.4k]
  |  Branch (286:33): [True: 469k, False: 0]
  ------------------
  287|   469k|        por_big_mul_add(big, chunk_mult, 0);
  288|   469k|        exponent -= chunk;
  289|   469k|    }
  290|  54.4k|    if (exponent > 0) {
  ------------------
  |  Branch (290:9): [True: 50.6k, False: 3.80k]
  ------------------
  291|  50.6k|        uint32_t mult = 1;
  292|   671k|        while (exponent-- > 0)
  ------------------
  |  Branch (292:16): [True: 621k, False: 50.6k]
  ------------------
  293|   621k|            mult *= base;
  294|  50.6k|        por_big_mul_add(big, mult, 0);
  295|  50.6k|    }
  296|  54.4k|}
readstat_por.c:por_big_mul_add:
  259|   729k|static void por_big_mul_add(por_bignum_t *big, uint32_t mult, uint32_t add) {
  260|   729k|    uint64_t carry = add;
  261|   729k|    int i;
  262|  7.20M|    for (i=0; i<big->n; i++) {
  ------------------
  |  Branch (262:15): [True: 6.47M, False: 729k]
  ------------------
  263|  6.47M|        uint64_t product = (uint64_t)big->limbs[i] * mult + carry;
  264|  6.47M|        big->limbs[i] = (uint32_t)(product % POR_BIG_LIMB_BASE);
  ------------------
  |  |  239|  6.47M|#define POR_BIG_LIMB_BASE   729000000u  /* 30^6 */
  ------------------
  265|  6.47M|        carry = product / POR_BIG_LIMB_BASE;
  ------------------
  |  |  239|  6.47M|#define POR_BIG_LIMB_BASE   729000000u  /* 30^6 */
  ------------------
  266|  6.47M|    }
  267|  1.45M|    while (carry) {
  ------------------
  |  Branch (267:12): [True: 730k, False: 729k]
  ------------------
  268|   730k|        if (big->n == POR_BIG_LIMBS) {
  ------------------
  |  |  241|   730k|#define POR_BIG_LIMBS       200         /* 1200 trigesimals; a denormal needs ~870 */
  ------------------
  |  Branch (268:13): [True: 0, False: 730k]
  ------------------
  269|      0|            big->overflow = 1;
  270|      0|            return;
  271|      0|        }
  272|   730k|        big->limbs[big->n++] = (uint32_t)(carry % POR_BIG_LIMB_BASE);
  ------------------
  |  |  239|   730k|#define POR_BIG_LIMB_BASE   729000000u  /* 30^6 */
  ------------------
  273|   730k|        carry /= POR_BIG_LIMB_BASE;
  ------------------
  |  |  239|   730k|#define POR_BIG_LIMB_BASE   729000000u  /* 30^6 */
  ------------------
  274|   730k|    }
  275|   729k|}
readstat_por.c:por_compare_with_binary:
  362|  43.9k|        uint64_t mantissa, long exp2) {
  363|  43.9k|    por_bignum_t lhs, rhs;
  364|  43.9k|    size_t i;
  365|  43.9k|    uint32_t chunk = 0;
  366|  43.9k|    uint32_t chunk_mult = 1;
  367|       |
  368|  43.9k|    por_big_set(&lhs, 0);
  369|  1.19M|    for (i=0; i<n_digits; i++) {
  ------------------
  |  Branch (369:15): [True: 1.15M, False: 43.9k]
  ------------------
  370|  1.15M|        chunk = chunk * 30 + digits[i];
  371|  1.15M|        chunk_mult *= 30;
  372|  1.15M|        if (chunk_mult == POR_BIG_LIMB_BASE) {
  ------------------
  |  |  239|  1.15M|#define POR_BIG_LIMB_BASE   729000000u  /* 30^6 */
  ------------------
  |  Branch (372:13): [True: 173k, False: 980k]
  ------------------
  373|   173k|            por_big_mul_add(&lhs, chunk_mult, chunk);
  374|   173k|            chunk = 0;
  375|   173k|            chunk_mult = 1;
  376|   173k|        }
  377|  1.15M|    }
  378|  43.9k|    if (chunk_mult > 1)
  ------------------
  |  Branch (378:9): [True: 35.6k, False: 8.31k]
  ------------------
  379|  35.6k|        por_big_mul_add(&lhs, chunk_mult, chunk);
  380|       |
  381|  43.9k|    por_big_set(&rhs, mantissa);
  382|       |
  383|  43.9k|    if (exp30 > 0) {
  ------------------
  |  Branch (383:9): [True: 3.41k, False: 40.5k]
  ------------------
  384|  3.41k|        por_big_mul_pow(&lhs, 30, exp30);
  385|  40.5k|    } else if (exp30 < 0) {
  ------------------
  |  Branch (385:16): [True: 13.1k, False: 27.3k]
  ------------------
  386|  13.1k|        por_big_mul_pow(&rhs, 30, -exp30);
  387|  13.1k|    }
  388|  43.9k|    if (exp2 > 0) {
  ------------------
  |  Branch (388:9): [True: 25.0k, False: 18.9k]
  ------------------
  389|  25.0k|        por_big_mul_pow(&rhs, 2, exp2);
  390|  25.0k|    } else if (exp2 < 0) {
  ------------------
  |  Branch (390:16): [True: 12.8k, False: 6.10k]
  ------------------
  391|  12.8k|        por_big_mul_pow(&lhs, 2, -exp2);
  392|  12.8k|    }
  393|  43.9k|    if (lhs.overflow || rhs.overflow)
  ------------------
  |  Branch (393:9): [True: 0, False: 43.9k]
  |  Branch (393:25): [True: 0, False: 43.9k]
  ------------------
  394|      0|        return 2;
  395|       |
  396|  43.9k|    return por_big_compare(&lhs, &rhs);
  397|  43.9k|}
readstat_por.c:por_big_compare:
  298|  43.9k|static int por_big_compare(const por_bignum_t *a, const por_bignum_t *b) {
  299|  43.9k|    int i;
  300|  43.9k|    if (a->n != b->n)
  ------------------
  |  Branch (300:9): [True: 388, False: 43.5k]
  ------------------
  301|    388|        return a->n > b->n ? 1 : -1;
  ------------------
  |  Branch (301:16): [True: 180, False: 208]
  ------------------
  302|   117k|    for (i=a->n-1; i>=0; i--) {
  ------------------
  |  Branch (302:20): [True: 114k, False: 3.65k]
  ------------------
  303|   114k|        if (a->limbs[i] != b->limbs[i])
  ------------------
  |  Branch (303:13): [True: 39.9k, False: 74.1k]
  ------------------
  304|  39.9k|            return a->limbs[i] > b->limbs[i] ? 1 : -1;
  ------------------
  |  Branch (304:20): [True: 18.4k, False: 21.4k]
  ------------------
  305|   114k|    }
  306|  3.65k|    return 0;
  307|  43.5k|}

readstat_por_parse_double:
   79|   142k|readstat_error_handler error_cb, void *user_ctx) {
   80|   142k|	ssize_t retval = 0;
   81|   142k|	double val = 0.0;
   82|       |	
   83|       |	/* Significant digits of the mantissa, most significant first; leading
   84|       |	* zeros are dropped and digits beyond POR_PARSE_MAX_DIGITS are folded
   85|       |	* into the scale. */
   86|   142k|	unsigned char digits[POR_PARSE_MAX_DIGITS] = { 0 };
   87|   142k|	size_t n_digits = 0;
   88|   142k|	long scale = 0;
   89|   142k|	long exp = 0;
   90|       |	
   91|   142k|	const unsigned char *p = (const unsigned char *)data;
   92|   142k|	const unsigned char *pe = p + len;
   93|       |	
   94|   142k|	int cs;
   95|   142k|	int is_negative = 0, exp_is_negative = 0;
   96|   142k|	int got_dot = 0;
   97|   142k|	int is_missing = 0;
   98|   142k|	int success = 0;
   99|       |	
  100|       |	
  101|   142k|#line 102 "src/spss/readstat_por_parse.c"
  102|   142k|	{
  103|   142k|		cs = (int)por_field_parse_start;
  104|   142k|	}
  105|       |	
  106|   142k|#line 107 "src/spss/readstat_por_parse.c"
  107|   142k|	{
  108|   142k|		int _klen;
  109|   142k|		unsigned int _trans = 0;
  110|   142k|		const char * _keys;
  111|   142k|		const signed char * _acts;
  112|   142k|		unsigned int _nacts;
  113|  2.00M|		_resume: {}
  114|  2.00M|		if ( p == pe )
  ------------------
  |  Branch (114:8): [True: 0, False: 2.00M]
  ------------------
  115|      0|			goto _out;
  116|  2.00M|		_keys = ( _por_field_parse_trans_keys + (_por_field_parse_key_offsets[cs]));
  117|  2.00M|		_trans = (unsigned int)_por_field_parse_index_offsets[cs];
  118|       |		
  119|  2.00M|		_klen = (int)_por_field_parse_single_lengths[cs];
  120|  2.00M|		if ( _klen > 0 ) {
  ------------------
  |  Branch (120:8): [True: 1.99M, False: 8.25k]
  ------------------
  121|  1.99M|			const char *_lower = _keys;
  122|  1.99M|			const char *_upper = _keys + _klen - 1;
  123|  1.99M|			const char *_mid;
  124|  7.23M|			while ( 1 ) {
  ------------------
  |  Branch (124:12): [True: 7.23M, Folded]
  ------------------
  125|  7.23M|				if ( _upper < _lower ) {
  ------------------
  |  Branch (125:10): [True: 1.66M, False: 5.57M]
  ------------------
  126|  1.66M|					_keys += _klen;
  127|  1.66M|					_trans += (unsigned int)_klen;
  128|  1.66M|					break;
  129|  1.66M|				}
  130|       |				
  131|  5.57M|				_mid = _lower + ((_upper-_lower) >> 1);
  132|  5.57M|				if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (132:10): [True: 182k, False: 5.39M]
  ------------------
  133|   182k|					_upper = _mid - 1;
  134|  5.39M|				else if ( ( (*( p))) > (*( _mid)) )
  ------------------
  |  Branch (134:15): [True: 5.06M, False: 332k]
  ------------------
  135|  5.06M|					_lower = _mid + 1;
  136|   332k|				else {
  137|   332k|					_trans += (unsigned int)(_mid - _keys);
  138|   332k|					goto _match;
  139|   332k|				}
  140|  5.57M|			}
  141|  1.99M|		}
  142|       |		
  143|  1.66M|		_klen = (int)_por_field_parse_range_lengths[cs];
  144|  1.66M|		if ( _klen > 0 ) {
  ------------------
  |  Branch (144:8): [True: 1.66M, False: 2]
  ------------------
  145|  1.66M|			const char *_lower = _keys;
  146|  1.66M|			const char *_upper = _keys + (_klen<<1) - 2;
  147|  1.66M|			const char *_mid;
  148|  1.95M|			while ( 1 ) {
  ------------------
  |  Branch (148:12): [True: 1.95M, Folded]
  ------------------
  149|  1.95M|				if ( _upper < _lower ) {
  ------------------
  |  Branch (149:10): [True: 100, False: 1.95M]
  ------------------
  150|    100|					_trans += (unsigned int)_klen;
  151|    100|					break;
  152|    100|				}
  153|       |				
  154|  1.95M|				_mid = _lower + (((_upper-_lower) >> 1) & ~1);
  155|  1.95M|				if ( ( (*( p))) < (*( _mid)) )
  ------------------
  |  Branch (155:10): [True: 53, False: 1.95M]
  ------------------
  156|     53|					_upper = _mid - 2;
  157|  1.95M|				else if ( ( (*( p))) > (*( _mid + 1)) )
  ------------------
  |  Branch (157:15): [True: 287k, False: 1.66M]
  ------------------
  158|   287k|					_lower = _mid + 2;
  159|  1.66M|				else {
  160|  1.66M|					_trans += (unsigned int)((_mid - _keys)>>1);
  161|  1.66M|					break;
  162|  1.66M|				}
  163|  1.95M|			}
  164|  1.66M|		}
  165|       |		
  166|  2.00M|		_match: {}
  167|  2.00M|		cs = (int)_por_field_parse_cond_targs[_trans];
  168|       |		
  169|  2.00M|		if ( _por_field_parse_cond_actions[_trans] != 0 ) {
  ------------------
  |  Branch (169:8): [True: 1.81M, False: 182k]
  ------------------
  170|       |			
  171|  1.81M|			_acts = ( _por_field_parse_actions + (_por_field_parse_cond_actions[_trans]));
  172|  1.81M|			_nacts = (unsigned int)(*( _acts));
  173|  1.81M|			_acts += 1;
  174|  3.49M|			while ( _nacts > 0 ) {
  ------------------
  |  Branch (174:12): [True: 1.81M, False: 1.67M]
  ------------------
  175|  1.81M|				switch ( (*( _acts)) )
  ------------------
  |  Branch (175:14): [True: 1.81M, False: 0]
  ------------------
  176|  1.81M|				{
  177|  1.59M|					case 0:  {
  ------------------
  |  Branch (177:6): [True: 1.59M, False: 220k]
  ------------------
  178|  1.59M|						{
  179|  1.59M|#line 42 "src/spss/readstat_por_parse.rl"
  180|       |							
  181|  1.59M|							int digit = por_base30_digit_value((( (*( p)))));
  182|  1.59M|							if (n_digits == 0 && digit == 0) {
  ------------------
  |  Branch (182:12): [True: 1.07M, False: 521k]
  |  Branch (182:29): [True: 972k, False: 104k]
  ------------------
  183|   972k|								if (got_dot)
  ------------------
  |  Branch (183:13): [True: 780, False: 971k]
  ------------------
  184|    780|								scale--;
  185|   972k|							} else if (n_digits < POR_PARSE_MAX_DIGITS) {
  ------------------
  |  |    7|   625k|#define POR_PARSE_MAX_DIGITS 128
  ------------------
  |  Branch (185:19): [True: 625k, False: 0]
  ------------------
  186|   625k|								digits[n_digits++] = digit;
  187|   625k|								if (got_dot)
  ------------------
  |  Branch (187:13): [True: 64.3k, False: 560k]
  ------------------
  188|  64.3k|								scale--;
  189|   625k|							} else if (!got_dot) {
  ------------------
  |  Branch (189:19): [True: 0, False: 0]
  ------------------
  190|      0|								scale++;
  191|      0|							}
  192|  1.59M|						}
  193|       |						
  194|  1.59M|#line 195 "src/spss/readstat_por_parse.c"
  195|       |						
  196|  1.59M|						break; 
  197|      0|					}
  198|  70.2k|					case 1:  {
  ------------------
  |  Branch (198:6): [True: 70.2k, False: 1.74M]
  ------------------
  199|  70.2k|						{
  200|  70.2k|#line 56 "src/spss/readstat_por_parse.rl"
  201|       |							
  202|  70.2k|							if (exp < 100000)
  ------------------
  |  Branch (202:12): [True: 46.4k, False: 23.8k]
  ------------------
  203|  46.4k|							exp = 30 * exp + por_base30_digit_value((( (*( p)))));
  204|  70.2k|						}
  205|       |						
  206|  70.2k|#line 207 "src/spss/readstat_por_parse.c"
  207|       |						
  208|  70.2k|						break; 
  209|      0|					}
  210|  1.14k|					case 2:  {
  ------------------
  |  Branch (210:6): [True: 1.14k, False: 1.81M]
  ------------------
  211|  1.14k|						{
  212|  1.14k|#line 63 "src/spss/readstat_por_parse.rl"
  213|  1.14k|							got_dot = 1; }
  214|       |						
  215|  1.14k|#line 216 "src/spss/readstat_por_parse.c"
  216|       |						
  217|  1.14k|						break; 
  218|      0|					}
  219|  1.20k|					case 3:  {
  ------------------
  |  Branch (219:6): [True: 1.20k, False: 1.81M]
  ------------------
  220|  1.20k|						{
  221|  1.20k|#line 64 "src/spss/readstat_por_parse.rl"
  222|  1.20k|							got_dot = 1; }
  223|       |						
  224|  1.20k|#line 225 "src/spss/readstat_por_parse.c"
  225|       |						
  226|  1.20k|						break; 
  227|      0|					}
  228|  5.70k|					case 4:  {
  ------------------
  |  Branch (228:6): [True: 5.70k, False: 1.81M]
  ------------------
  229|  5.70k|						{
  230|  5.70k|#line 66 "src/spss/readstat_por_parse.rl"
  231|  5.70k|							exp_is_negative = 1; }
  232|       |						
  233|  5.70k|#line 234 "src/spss/readstat_por_parse.c"
  234|       |						
  235|  5.70k|						break; 
  236|      0|					}
  237|    370|					case 5:  {
  ------------------
  |  Branch (237:6): [True: 370, False: 1.81M]
  ------------------
  238|    370|						{
  239|    370|#line 68 "src/spss/readstat_por_parse.rl"
  240|    370|							is_negative = 1; }
  241|       |						
  242|    370|#line 243 "src/spss/readstat_por_parse.c"
  243|       |						
  244|    370|						break; 
  245|      0|					}
  246|    194|					case 6:  {
  ------------------
  |  Branch (246:6): [True: 194, False: 1.81M]
  ------------------
  247|    194|						{
  248|    194|#line 70 "src/spss/readstat_por_parse.rl"
  249|    194|							is_missing = 1; }
  250|       |						
  251|    194|#line 252 "src/spss/readstat_por_parse.c"
  252|       |						
  253|    194|						break; 
  254|      0|					}
  255|   141k|					case 7:  {
  ------------------
  |  Branch (255:6): [True: 141k, False: 1.67M]
  ------------------
  256|   141k|						{
  257|   141k|#line 72 "src/spss/readstat_por_parse.rl"
  258|   141k|							success = 1; {p += 1; goto _out; } }
  259|       |						
  260|      0|#line 261 "src/spss/readstat_por_parse.c"
  261|       |						
  262|      0|						break; 
  263|      0|					}
  264|  1.81M|				}
  265|  1.67M|				_nacts -= 1;
  266|  1.67M|				_acts += 1;
  267|  1.67M|			}
  268|       |			
  269|  1.81M|		}
  270|       |		
  271|  1.85M|		if ( cs != 0 ) {
  ------------------
  |  Branch (271:8): [True: 1.85M, False: 102]
  ------------------
  272|  1.85M|			p += 1;
  273|  1.85M|			goto _resume;
  274|  1.85M|		}
  275|   142k|		_out: {}
  276|   142k|	}
  277|       |	
  278|      0|#line 76 "src/spss/readstat_por_parse.rl"
  279|       |	
  280|       |	
  281|   142k|	if (is_missing) {
  ------------------
  |  Branch (281:6): [True: 194, False: 141k]
  ------------------
  282|    194|		val = NAN;
  283|   141k|	} else {
  284|   141k|		if (exp_is_negative)
  ------------------
  |  Branch (284:7): [True: 5.70k, False: 136k]
  ------------------
  285|  5.70k|			exp = -exp;
  286|   141k|		val = por_base30_to_double(digits, n_digits, scale + exp);
  287|   141k|		if (is_negative)
  ------------------
  |  Branch (287:7): [True: 370, False: 141k]
  ------------------
  288|    370|			val = -val;
  289|   141k|	}
  290|       |	
  291|   142k|	if (!success) {
  ------------------
  |  Branch (291:6): [True: 102, False: 141k]
  ------------------
  292|    102|		retval = -1;
  293|    102|		if (error_cb) {
  ------------------
  |  Branch (293:7): [True: 0, False: 102]
  ------------------
  294|      0|			char error_buf[1024];
  295|      0|			snprintf(error_buf, sizeof(error_buf), "Read bytes: %ld   String: %.*s  Ending state: %d",
  296|      0|			(long)(p - (const unsigned char *)data), (int)len, data, cs);
  297|      0|			error_cb(error_buf, user_ctx);
  298|      0|		}
  299|    102|	}
  300|       |	
  301|   142k|	if (retval == 0) {
  ------------------
  |  Branch (301:6): [True: 141k, False: 102]
  ------------------
  302|   141k|		if (result)
  ------------------
  |  Branch (302:7): [True: 141k, False: 0]
  ------------------
  303|   141k|			*result = val;
  304|       |		
  305|   141k|		retval = (p - (const unsigned char *)data);
  306|   141k|	}
  307|       |	
  308|       |	/* suppress warning */
  309|   142k|	(void)por_field_parse_en_main;
  310|       |	
  311|   142k|	return retval;
  312|  1.85M|}
readstat_por_parse.c:por_base30_digit_value:
   72|  1.64M|static int por_base30_digit_value(unsigned char c) {
   73|  1.64M|	if (c >= '0' && c <= '9')
  ------------------
  |  Branch (73:6): [True: 1.64M, False: 0]
  |  Branch (73:18): [True: 1.36M, False: 283k]
  ------------------
   74|  1.36M|		return c - '0';
   75|   283k|	return 10 + c - 'A';
   76|  1.64M|}

read_version_and_timestamp:
  700|  2.40k|readstat_error_t read_version_and_timestamp(por_ctx_t *ctx) {
  701|  2.40k|    readstat_error_t retval = READSTAT_OK;
  702|  2.40k|    char string[256];
  703|  2.40k|    struct tm timestamp = { .tm_isdst = -1 };
  704|  2.40k|    unsigned char version;
  705|       |
  706|  2.40k|    if (read_bytes(ctx, &version, sizeof(version)) != sizeof(version)) {
  ------------------
  |  Branch (706:9): [True: 10, False: 2.39k]
  ------------------
  707|     10|        retval = READSTAT_ERROR_READ;
  708|     10|        goto cleanup;
  709|     10|    }
  710|  2.39k|    if ((retval = read_string(ctx, string, sizeof(string))) != READSTAT_OK) { /* creation date */
  ------------------
  |  Branch (710:9): [True: 465, False: 1.93k]
  ------------------
  711|    465|        goto cleanup;
  712|    465|    }
  713|  1.93k|    if (sscanf(string, "%04d%02d%02d", &timestamp.tm_year, &timestamp.tm_mon, &timestamp.tm_mday) != 3) {
  ------------------
  |  Branch (713:9): [True: 200, False: 1.73k]
  ------------------
  714|    200|        retval = READSTAT_ERROR_BAD_TIMESTAMP_STRING;
  715|    200|        goto cleanup;
  716|    200|    }
  717|  1.73k|    if ((retval = read_string(ctx, string, sizeof(string))) != READSTAT_OK) { /* creation time */
  ------------------
  |  Branch (717:9): [True: 36, False: 1.69k]
  ------------------
  718|     36|        goto cleanup;
  719|     36|    }
  720|  1.69k|    if (sscanf(string, "%02d%02d%02d", &timestamp.tm_hour, &timestamp.tm_min, &timestamp.tm_sec) != 3) {
  ------------------
  |  Branch (720:9): [True: 1.59k, False: 103]
  ------------------
  721|       |        /* optional */
  722|  1.59k|    }
  723|       |
  724|  1.69k|    timestamp.tm_year -= 1900;
  725|  1.69k|    timestamp.tm_mon--;
  726|       |
  727|  1.69k|    ctx->timestamp = mktime(&timestamp);
  728|  1.69k|    ctx->version = ctx->byte2unicode[version] - 'A';
  729|       |
  730|  2.40k|cleanup:
  731|  2.40k|    return retval;
  732|  1.69k|}
handle_variables:
  734|    375|readstat_error_t handle_variables(por_ctx_t *ctx) {
  735|    375|    readstat_error_t retval = READSTAT_OK;
  736|    375|    int i;
  737|    375|    int index_after_skipping = 0;
  738|  1.80k|    for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (738:15): [True: 1.42k, False: 375]
  ------------------
  739|  1.42k|        char label_name_buf[256];
  740|  1.42k|        spss_varinfo_t *info = &ctx->varinfo[i];
  741|  1.42k|        info->index = i;
  742|       |
  743|  1.42k|        ctx->variables[i] = spss_init_variable_for_info(info, index_after_skipping, ctx->converter);
  744|       |
  745|  1.42k|        snprintf(label_name_buf, sizeof(label_name_buf), POR_LABEL_NAME_PREFIX "%d", info->labels_index);
  ------------------
  |  |   25|  1.42k|#define POR_LABEL_NAME_PREFIX   "labels"
  ------------------
  746|       |
  747|  1.42k|        int cb_retval = READSTAT_HANDLER_OK;
  ------------------
  |  |   22|  1.42k|#define READSTAT_HANDLER_OK             0
  ------------------
  748|       |
  749|  1.42k|        if (ctx->handle.variable) {
  ------------------
  |  Branch (749:13): [True: 1.42k, False: 0]
  ------------------
  750|  1.42k|            cb_retval = ctx->handle.variable(i, ctx->variables[i],
  751|  1.42k|                    info->labels_index == -1 ? NULL : label_name_buf,
  ------------------
  |  Branch (751:21): [True: 1.40k, False: 21]
  ------------------
  752|  1.42k|                    ctx->user_ctx);
  753|  1.42k|        }
  754|       |
  755|  1.42k|        if (cb_retval == READSTAT_HANDLER_ABORT) {
  ------------------
  |  |   23|  1.42k|#define READSTAT_HANDLER_ABORT          1
  ------------------
  |  Branch (755:13): [True: 0, False: 1.42k]
  ------------------
  756|      0|            retval = READSTAT_ERROR_USER_ABORT;
  757|      0|            goto cleanup;
  758|      0|        }
  759|       |
  760|  1.42k|        if (cb_retval == READSTAT_HANDLER_SKIP_VARIABLE) {
  ------------------
  |  |   24|  1.42k|#define READSTAT_HANDLER_SKIP_VARIABLE  2
  ------------------
  |  Branch (760:13): [True: 0, False: 1.42k]
  ------------------
  761|      0|            ctx->variables[i]->skip = 1;
  762|  1.42k|        } else {
  763|  1.42k|            index_after_skipping++;
  764|  1.42k|        }
  765|  1.42k|    }
  766|    375|    if (ctx->handle.fweight && ctx->fweight_name[0]) {
  ------------------
  |  Branch (766:9): [True: 375, False: 0]
  |  Branch (766:32): [True: 92, False: 283]
  ------------------
  767|    405|        for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (767:19): [True: 316, False: 89]
  ------------------
  768|    316|            spss_varinfo_t *info = &ctx->varinfo[i];
  769|    316|            if (strcmp(info->name, ctx->fweight_name) == 0) {
  ------------------
  |  Branch (769:17): [True: 3, False: 313]
  ------------------
  770|      3|                if (ctx->handle.fweight(ctx->variables[i], ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|      3|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (770:21): [True: 0, False: 3]
  ------------------
  771|      0|                    retval = READSTAT_ERROR_USER_ABORT;
  772|      0|                    goto cleanup;
  773|      0|                }
  774|      3|                break;
  775|      3|            }
  776|    316|        }
  777|     92|    }
  778|    375|cleanup:
  779|    375|    return retval;
  780|    375|}
readstat_parse_por:
  782|  2.73k|readstat_error_t readstat_parse_por(readstat_parser_t *parser, const char *path, void *user_ctx) {
  783|  2.73k|    readstat_error_t retval = READSTAT_OK;
  784|  2.73k|    readstat_io_t *io = parser->io;
  785|  2.73k|    unsigned char reverse_lookup[256];
  786|  2.73k|    char vanity[5][40];
  787|  2.73k|    char error_buf[1024];
  788|       |
  789|  2.73k|    por_ctx_t *ctx = por_ctx_init();
  790|       |    
  791|  2.73k|    ctx->handle = parser->handlers;
  792|  2.73k|    ctx->user_ctx = user_ctx;
  793|  2.73k|    ctx->io = io;
  794|  2.73k|    ctx->row_limit = parser->row_limit;
  795|  2.73k|    if (parser->row_offset > 0)
  ------------------
  |  Branch (795:9): [True: 0, False: 2.73k]
  ------------------
  796|      0|        ctx->row_offset = parser->row_offset;
  797|       |
  798|  2.73k|    if (parser->output_encoding) {
  ------------------
  |  Branch (798:9): [True: 2.73k, False: 0]
  ------------------
  799|  2.73k|        if (strcmp(parser->output_encoding, "UTF-8") != 0)
  ------------------
  |  Branch (799:13): [True: 0, False: 2.73k]
  ------------------
  800|      0|            ctx->converter = iconv_open(parser->output_encoding, "UTF-8");
  801|       |
  802|  2.73k|        if (ctx->converter == (iconv_t)-1) {
  ------------------
  |  Branch (802:13): [True: 0, False: 2.73k]
  ------------------
  803|      0|            ctx->converter = NULL;
  804|      0|            retval = READSTAT_ERROR_UNSUPPORTED_CHARSET;
  805|      0|            goto cleanup;
  806|      0|        }
  807|  2.73k|    }
  808|       |    
  809|  2.73k|    if (io->open(path, io->io_ctx) == -1) {
  ------------------
  |  Branch (809:9): [True: 0, False: 2.73k]
  ------------------
  810|      0|        retval = READSTAT_ERROR_OPEN;
  811|      0|        goto cleanup;
  812|      0|    }
  813|       |
  814|  2.73k|    if ((ctx->file_size = io->seek(0, READSTAT_SEEK_END, io->io_ctx)) == -1) {
  ------------------
  |  Branch (814:9): [True: 0, False: 2.73k]
  ------------------
  815|      0|        retval = READSTAT_ERROR_SEEK;
  816|      0|        goto cleanup;
  817|      0|    }
  818|       |
  819|  2.73k|    if (io->seek(0, READSTAT_SEEK_SET, io->io_ctx) == -1) {
  ------------------
  |  Branch (819:9): [True: 0, False: 2.73k]
  ------------------
  820|      0|        retval = READSTAT_ERROR_SEEK;
  821|      0|        goto cleanup;
  822|      0|    }
  823|       |    
  824|  2.73k|    if (read_bytes(ctx, vanity, sizeof(vanity)) != sizeof(vanity)) {
  ------------------
  |  Branch (824:9): [True: 57, False: 2.67k]
  ------------------
  825|     57|        retval = READSTAT_ERROR_READ;
  826|     57|        goto cleanup;
  827|     57|    }
  828|       |
  829|  2.67k|    retval = readstat_convert(ctx->file_label, sizeof(ctx->file_label), vanity[1] + 20, 20, NULL);
  830|  2.67k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (830:9): [True: 0, False: 2.67k]
  ------------------
  831|      0|        goto cleanup;
  832|       |    
  833|  2.67k|    if (read_bytes(ctx, reverse_lookup, sizeof(reverse_lookup)) != sizeof(reverse_lookup)) {
  ------------------
  |  Branch (833:9): [True: 94, False: 2.58k]
  ------------------
  834|     94|        retval = READSTAT_ERROR_READ;
  835|     94|        goto cleanup;
  836|     94|    }
  837|       |    
  838|  2.58k|    ctx->space = reverse_lookup[126];
  839|       |
  840|  2.58k|    int i;
  841|       |
  842|       |    /* A byte that appears at several positions in the translation table
  843|       |     * keeps its first meaning, as in PSPP and R's foreign package. PSPP for
  844|       |     * instance maps the superscript digits (positions 167-176) to '0'-'9'
  845|       |     * as well, and last-writer-wins would turn every digit into a
  846|       |     * superscript. */
  847|   663k|    for (i=0; i<256; i++) {
  ------------------
  |  Branch (847:15): [True: 660k, False: 2.58k]
  ------------------
  848|   660k|        if (ctx->byte2unicode[reverse_lookup[i]])
  ------------------
  |  Branch (848:13): [True: 325k, False: 335k]
  ------------------
  849|   325k|            continue;
  850|   335k|        if (por_ascii_lookup[i]) {
  ------------------
  |  Branch (850:13): [True: 105k, False: 230k]
  ------------------
  851|   105k|            ctx->byte2unicode[reverse_lookup[i]] = por_ascii_lookup[i];
  852|   230k|        } else if (por_unicode_lookup[i]) {
  ------------------
  |  Branch (852:20): [True: 528, False: 230k]
  ------------------
  853|    528|            ctx->byte2unicode[reverse_lookup[i]] = por_unicode_lookup[i];
  854|    528|        }
  855|   335k|    }
  856|       |
  857|  2.58k|    ctx->byte2unicode[reverse_lookup[64]] = por_unicode_lookup[64];
  858|       |
  859|  2.58k|    unsigned char check[8];
  860|  2.58k|    char tr_check[8];
  861|       |    
  862|  2.58k|    if (read_bytes(ctx, check, sizeof(check)) != sizeof(check)) {
  ------------------
  |  Branch (862:9): [True: 29, False: 2.55k]
  ------------------
  863|     29|        retval = READSTAT_ERROR_READ;
  864|     29|        goto cleanup;
  865|     29|    }
  866|       |
  867|  2.55k|    ssize_t encoded_len;
  868|       |
  869|  2.55k|    if ((encoded_len = por_utf8_encode(check, sizeof(check), tr_check, sizeof(tr_check), ctx->byte2unicode)) == -1) {
  ------------------
  |  Branch (869:9): [True: 0, False: 2.55k]
  ------------------
  870|      0|        if (ctx->handle.error) {
  ------------------
  |  Branch (870:13): [True: 0, False: 0]
  ------------------
  871|      0|            snprintf(error_buf, sizeof(error_buf), "Error converting check string: %.*s", (int)sizeof(check), check);
  872|      0|            ctx->handle.error(error_buf, ctx->user_ctx);
  873|      0|        }
  874|      0|        retval = READSTAT_ERROR_CONVERT;
  875|      0|        goto cleanup;
  876|      0|    }
  877|       |
  878|  2.55k|    if (strncmp("SPSSPORT", tr_check, encoded_len) != 0) {
  ------------------
  |  Branch (878:9): [True: 144, False: 2.40k]
  ------------------
  879|    144|        retval = READSTAT_ERROR_PARSE;
  880|    144|        goto cleanup;
  881|    144|    }
  882|       |    
  883|  2.40k|    ctx->var_offset = -1;
  884|       |    
  885|  2.40k|    char string[256];
  886|       |
  887|  2.40k|    retval = read_version_and_timestamp(ctx);
  888|  2.40k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (888:9): [True: 711, False: 1.69k]
  ------------------
  889|    711|        goto cleanup;
  890|       |
  891|  27.7k|    while (1) {
  ------------------
  |  Branch (891:12): [True: 27.7k, Folded]
  ------------------
  892|  27.7k|        uint16_t tr_tag = read_tag(ctx);
  893|  27.7k|        switch (tr_tag) {
  894|    366|            case '1': /* product ID */
  ------------------
  |  Branch (894:13): [True: 366, False: 27.3k]
  ------------------
  895|    625|            case '2': /* author ID */
  ------------------
  |  Branch (895:13): [True: 259, False: 27.4k]
  ------------------
  896|    842|            case '3': /* sub-product ID */
  ------------------
  |  Branch (896:13): [True: 217, False: 27.5k]
  ------------------
  897|    842|                retval = read_string(ctx, string, sizeof(string));
  898|    842|                break;
  899|  1.17k|            case '4': /* variable count */
  ------------------
  |  Branch (899:13): [True: 1.17k, False: 26.5k]
  ------------------
  900|  1.17k|                retval = read_variable_count_record(ctx);
  901|  1.17k|                break;
  902|    467|            case '5': /* precision */
  ------------------
  |  Branch (902:13): [True: 467, False: 27.2k]
  ------------------
  903|    467|                retval = read_precision_record(ctx);
  904|    467|                break;
  905|  1.18k|            case '6': /* case weight */
  ------------------
  |  Branch (905:13): [True: 1.18k, False: 26.5k]
  ------------------
  906|  1.18k|                retval = read_case_weight_record(ctx);
  907|  1.18k|                break;
  908|  8.01k|            case '7': /* variable */
  ------------------
  |  Branch (908:13): [True: 8.01k, False: 19.7k]
  ------------------
  909|  8.01k|                retval = read_variable_record(ctx);
  910|  8.01k|                break;
  911|    656|            case '8': /* missing value */
  ------------------
  |  Branch (911:13): [True: 656, False: 27.0k]
  ------------------
  912|    656|                retval = read_missing_value_record(ctx);
  913|    656|                break;
  914|  3.77k|            case 'B': /* missing value range */
  ------------------
  |  Branch (914:13): [True: 3.77k, False: 23.9k]
  ------------------
  915|  3.77k|                retval = read_missing_value_range_record(ctx);
  916|  3.77k|                break;
  917|  1.95k|            case '9': /* LO THRU x */
  ------------------
  |  Branch (917:13): [True: 1.95k, False: 25.7k]
  ------------------
  918|  1.95k|                retval = read_missing_value_lo_range_record(ctx);
  919|  1.95k|                break;
  920|  1.49k|            case 'A': /* x THRU HI */
  ------------------
  |  Branch (920:13): [True: 1.49k, False: 26.2k]
  ------------------
  921|  1.49k|                retval = read_missing_value_hi_range_record(ctx);
  922|  1.49k|                break;
  923|  1.16k|            case 'C': /* variable label */
  ------------------
  |  Branch (923:13): [True: 1.16k, False: 26.5k]
  ------------------
  924|  1.16k|                retval = read_variable_label_record(ctx);
  925|  1.16k|                break;
  926|  5.59k|            case 'D': /* value label */
  ------------------
  |  Branch (926:13): [True: 5.59k, False: 22.1k]
  ------------------
  927|  5.59k|                retval = read_value_label_record(ctx);
  928|  5.59k|                break;
  929|    702|            case 'E': /* document record */
  ------------------
  |  Branch (929:13): [True: 702, False: 27.0k]
  ------------------
  930|    702|                retval = read_document_record(ctx);
  931|    702|                break;
  932|    407|            case 'F': /* file data */
  ------------------
  |  Branch (932:13): [True: 407, False: 27.3k]
  ------------------
  933|    407|                if (ctx->var_offset != ctx->var_count - 1) {
  ------------------
  |  Branch (933:21): [True: 32, False: 375]
  ------------------
  934|     32|                    retval = READSTAT_ERROR_COLUMN_COUNT_MISMATCH;
  935|     32|                    goto cleanup;
  936|     32|                }
  937|       |
  938|    375|                retval = handle_variables(ctx);
  939|    375|                if (retval != READSTAT_OK)
  ------------------
  |  Branch (939:21): [True: 0, False: 375]
  ------------------
  940|      0|                    goto cleanup;
  941|       |
  942|    375|                if (ctx->handle.value) {
  ------------------
  |  Branch (942:21): [True: 375, False: 0]
  ------------------
  943|    375|                    retval = read_por_file_data(ctx);
  944|    375|                }
  945|    375|                goto cleanup;
  946|    287|            default:
  ------------------
  |  Branch (946:13): [True: 287, False: 27.4k]
  ------------------
  947|    287|                retval = READSTAT_ERROR_PARSE;
  948|    287|                goto cleanup;
  949|  27.7k|        }
  950|  27.0k|        if (retval != READSTAT_OK)
  ------------------
  |  Branch (950:13): [True: 1.00k, False: 26.0k]
  ------------------
  951|  1.00k|            break;
  952|  27.0k|    }
  953|       |
  954|  2.73k|cleanup:
  955|  2.73k|    io->close(io->io_ctx);
  956|  2.73k|    por_ctx_free(ctx);
  957|       |    
  958|  2.73k|    return retval;
  959|  1.69k|}
readstat_por_read.c:read_bytes:
   49|  2.09M|static ssize_t read_bytes(por_ctx_t *ctx, void *dst, size_t len) {
   50|  2.09M|    char *dst_pos = (char *)dst;
   51|  2.09M|    readstat_io_t *io = ctx->io;
   52|  2.09M|    char byte;
   53|       |
   54|  6.40M|    while (dst_pos < (char *)dst + len) {
  ------------------
  |  Branch (54:12): [True: 4.30M, False: 2.09M]
  ------------------
   55|  4.30M|        if (ctx->num_spaces) {
  ------------------
  |  Branch (55:13): [True: 2.63M, False: 1.67M]
  ------------------
   56|  2.63M|            *dst_pos++ = ctx->space;
   57|  2.63M|            ctx->num_spaces--;
   58|  2.63M|            continue;
   59|  2.63M|        }
   60|  1.67M|        ssize_t bytes_read = io->read(&byte, 1, io->io_ctx);
   61|  1.67M|        if (bytes_read == 0) {
  ------------------
  |  Branch (61:13): [True: 1.80k, False: 1.67M]
  ------------------
   62|  1.80k|            break;
   63|  1.80k|        }
   64|  1.67M|        if (bytes_read == -1) {
  ------------------
  |  Branch (64:13): [True: 0, False: 1.67M]
  ------------------
   65|      0|            return -1;
   66|      0|        }
   67|       |        /* Like PSPP: ignore carriage returns entirely; a line feed ends the
   68|       |         * line, and a line shorter than 80 characters is padded with spaces.
   69|       |         * Lines longer than 80 characters are read as-is. */
   70|  1.67M|        if (byte == '\r') {
  ------------------
  |  Branch (70:13): [True: 2.75k, False: 1.66M]
  ------------------
   71|  2.75k|            continue;
   72|  1.66M|        } else if (byte == '\n') {
  ------------------
  |  Branch (72:20): [True: 41.9k, False: 1.62M]
  ------------------
   73|  41.9k|            if (ctx->pos < POR_LINE_LENGTH)
  ------------------
  |  |   24|  41.9k|#define POR_LINE_LENGTH         80
  ------------------
  |  Branch (73:17): [True: 40.3k, False: 1.62k]
  ------------------
   74|  40.3k|                ctx->num_spaces = POR_LINE_LENGTH - ctx->pos;
  ------------------
  |  |   24|  40.3k|#define POR_LINE_LENGTH         80
  ------------------
   75|  41.9k|            ctx->pos = 0;
   76|  41.9k|            continue;
   77|  41.9k|        }
   78|  1.62M|        *dst_pos++ = byte;
   79|  1.62M|        ctx->pos++;
   80|  1.62M|    }
   81|       |    
   82|  2.09M|    return (int)(dst_pos - (char *)dst);
   83|  2.09M|}
readstat_por_read.c:read_string:
  248|  38.9k|static readstat_error_t read_string(por_ctx_t *ctx, char *data, size_t len) {
  249|  38.9k|    int finished = 0;
  250|  38.9k|    readstat_error_t retval = maybe_read_string(ctx, data, len, &finished);
  251|  38.9k|    if (retval == READSTAT_OK && finished) {
  ------------------
  |  Branch (251:9): [True: 37.9k, False: 992]
  |  Branch (251:34): [True: 9, False: 37.9k]
  ------------------
  252|      9|        return READSTAT_ERROR_PARSE;
  253|      9|    }
  254|  38.9k|    return retval;
  255|  38.9k|}
readstat_por_read.c:maybe_read_string:
  196|  39.4k|static readstat_error_t maybe_read_string(por_ctx_t *ctx, char *data, size_t len, int *out_finished) {
  197|  39.4k|    readstat_error_t retval = READSTAT_OK;
  198|  39.4k|    double value;
  199|  39.4k|    int finished = 0;
  200|  39.4k|    char error_buf[1024];
  201|  39.4k|    size_t string_length = 0;
  202|  39.4k|    retval = maybe_read_double(ctx, &value, &finished);
  203|  39.4k|    if (retval != READSTAT_OK || finished) {
  ------------------
  |  Branch (203:9): [True: 803, False: 38.6k]
  |  Branch (203:34): [True: 12, False: 38.6k]
  ------------------
  204|    815|        if (out_finished)
  ------------------
  |  Branch (204:13): [True: 815, False: 0]
  ------------------
  205|    815|            *out_finished = finished;
  206|       |
  207|    815|        return retval;
  208|    815|    }
  209|       |    
  210|  38.6k|    if (value < 0 || value > MAX_STRING_LENGTH || isnan(value)) {
  ------------------
  |  |   31|  77.3k|#define MAX_STRING_LENGTH   20000
  ------------------
  |  Branch (210:9): [True: 1, False: 38.6k]
  |  Branch (210:22): [True: 246, False: 38.4k]
  |  Branch (210:51): [True: 2, False: 38.4k]
  ------------------
  211|    249|        retval = READSTAT_ERROR_PARSE;
  212|    249|        goto cleanup;
  213|    249|    }
  214|  38.4k|    string_length = (size_t)value;
  215|       |    
  216|  38.4k|    if (string_length > ctx->string_buffer_len) {
  ------------------
  |  Branch (216:9): [True: 2.33k, False: 36.0k]
  ------------------
  217|  2.33k|        unsigned char *new_string_buf = realloc(ctx->string_buffer, string_length);
  218|  2.33k|        if (new_string_buf == NULL) { retval = READSTAT_ERROR_MALLOC; goto cleanup; }
  ------------------
  |  Branch (218:13): [True: 0, False: 2.33k]
  ------------------
  219|  2.33k|        ctx->string_buffer = new_string_buf;
  220|  2.33k|        ctx->string_buffer_len = string_length;
  221|  2.33k|        memset(ctx->string_buffer, 0, ctx->string_buffer_len);
  222|  2.33k|    }
  223|       |    
  224|  38.4k|    if (read_bytes(ctx, ctx->string_buffer, string_length) != string_length) {
  ------------------
  |  Branch (224:9): [True: 107, False: 38.3k]
  ------------------
  225|    107|        retval = READSTAT_ERROR_READ;
  226|    107|        goto cleanup;
  227|    107|    }
  228|  38.3k|    size_t bytes_encoded = por_utf8_encode(ctx->string_buffer, string_length, 
  229|  38.3k|            data, len - 1, ctx->byte2unicode);
  230|  38.3k|    if (bytes_encoded == -1) {
  ------------------
  |  Branch (230:9): [True: 0, False: 38.3k]
  ------------------
  231|      0|        if (ctx->handle.error) {
  ------------------
  |  Branch (231:13): [True: 0, False: 0]
  ------------------
  232|      0|            snprintf(error_buf, sizeof(error_buf), "Error converting string: %.*s", 
  233|      0|                    (int)string_length, ctx->string_buffer);
  234|      0|            ctx->handle.error(error_buf, ctx->user_ctx);
  235|      0|        }
  236|      0|        retval = READSTAT_ERROR_CONVERT;
  237|      0|        goto cleanup;
  238|      0|    }
  239|       |    
  240|  38.3k|    data[bytes_encoded] = '\0';
  241|  38.3k|    if (out_finished)
  ------------------
  |  Branch (241:9): [True: 38.3k, False: 0]
  ------------------
  242|  38.3k|        *out_finished = 0;
  243|       |
  244|  38.6k|cleanup:
  245|  38.6k|    return retval;
  246|  38.3k|}
readstat_por_read.c:maybe_read_double:
  176|  51.1k|static readstat_error_t maybe_read_double(por_ctx_t *ctx, double *out_double, int *out_finished) {
  177|  51.1k|    unsigned char peek;
  178|  51.1k|    size_t bytes_read = read_bytes(ctx, &peek, 1);
  179|  51.1k|    if (bytes_read != 1)
  ------------------
  |  Branch (179:9): [True: 571, False: 50.5k]
  ------------------
  180|    571|        return READSTAT_ERROR_PARSE;
  181|       |
  182|  50.5k|    if (ctx->byte2unicode[peek] == 'Z') {
  ------------------
  |  Branch (182:9): [True: 15, False: 50.5k]
  ------------------
  183|     15|        if (out_double)
  ------------------
  |  Branch (183:13): [True: 15, False: 0]
  ------------------
  184|     15|            *out_double = NAN;
  185|     15|        if (out_finished)
  ------------------
  |  Branch (185:13): [True: 15, False: 0]
  ------------------
  186|     15|            *out_finished = 1;
  187|     15|        return READSTAT_OK;
  188|     15|    }
  189|       |
  190|  50.5k|    if (out_finished)
  ------------------
  |  Branch (190:9): [True: 50.5k, False: 0]
  ------------------
  191|  50.5k|        *out_finished = 0;
  192|       |
  193|  50.5k|    return read_double_with_peek(ctx, out_double, peek);
  194|  50.5k|}
readstat_por_read.c:read_double_with_peek:
   94|   142k|        unsigned char peek) {
   95|   142k|    readstat_error_t retval = READSTAT_OK;
   96|   142k|    double value = NAN;
   97|   142k|    unsigned char buffer[100];
   98|   142k|    char utf8_buffer[300];
   99|   142k|    char error_buf[1024];
  100|   142k|    int64_t len = 0;
  101|   142k|    ssize_t bytes_read = 0;
  102|       |
  103|   142k|    buffer[0] = peek;
  104|       |
  105|   142k|    bytes_read = read_bytes(ctx, &buffer[1], 1);
  106|   142k|    if (bytes_read != 1)
  ------------------
  |  Branch (106:9): [True: 99, False: 142k]
  ------------------
  107|     99|        return READSTAT_ERROR_PARSE;
  108|       |
  109|   142k|    if (ctx->byte2unicode[buffer[0]] == '*' && 
  ------------------
  |  Branch (109:9): [True: 278, False: 142k]
  ------------------
  110|    278|            ctx->byte2unicode[buffer[1]] == '.') {
  ------------------
  |  Branch (110:13): [True: 275, False: 3]
  ------------------
  111|    275|        if (out_double)
  ------------------
  |  Branch (111:13): [True: 275, False: 0]
  ------------------
  112|    275|            *out_double = NAN;
  113|    275|        return READSTAT_OK;
  114|    275|    }
  115|   142k|    int64_t i=2;
  116|  1.87M|    while (i<sizeof(buffer) && ctx->byte2unicode[buffer[i-1]] != '/') {
  ------------------
  |  Branch (116:12): [True: 1.87M, False: 21]
  |  Branch (116:32): [True: 1.73M, False: 142k]
  ------------------
  117|  1.73M|        bytes_read = read_bytes(ctx, &buffer[i], 1);
  118|  1.73M|        if (bytes_read != 1)
  ------------------
  |  Branch (118:13): [True: 352, False: 1.73M]
  ------------------
  119|    352|            return READSTAT_ERROR_PARSE;
  120|  1.73M|        i++;
  121|  1.73M|    }
  122|       |
  123|   142k|    if (i == sizeof(buffer)) {
  ------------------
  |  Branch (123:9): [True: 21, False: 142k]
  ------------------
  124|     21|        return READSTAT_ERROR_PARSE;
  125|     21|    }
  126|       |
  127|   142k|    len = por_utf8_encode(buffer, i, utf8_buffer, sizeof(utf8_buffer), ctx->byte2unicode);
  128|   142k|    if (len == -1) {
  ------------------
  |  Branch (128:9): [True: 0, False: 142k]
  ------------------
  129|      0|        if (ctx->handle.error) {
  ------------------
  |  Branch (129:13): [True: 0, False: 0]
  ------------------
  130|      0|            snprintf(error_buf, sizeof(error_buf), "Error converting double string (length=%" PRId64 "): %.*s", 
  131|      0|                    i, (int)i, buffer);
  132|      0|            ctx->handle.error(error_buf, ctx->user_ctx);
  133|      0|        }
  134|      0|        retval = READSTAT_ERROR_CONVERT;
  135|      0|        goto cleanup;
  136|      0|    }
  137|       |    
  138|   142k|    bytes_read = readstat_por_parse_double(utf8_buffer, len, &value, ctx->handle.error, ctx->user_ctx);
  139|   142k|    if (bytes_read == -1) {
  ------------------
  |  Branch (139:9): [True: 102, False: 141k]
  ------------------
  140|    102|        if (ctx->handle.error) {
  ------------------
  |  Branch (140:13): [True: 0, False: 102]
  ------------------
  141|      0|            snprintf(error_buf, sizeof(error_buf), "Error parsing double string (length=%" PRId64 "): %.*s [%s]", 
  142|      0|                    len, (int)len, utf8_buffer, buffer);
  143|      0|            ctx->handle.error(error_buf, ctx->user_ctx);
  144|      0|        }
  145|    102|        retval = READSTAT_ERROR_PARSE;
  146|    102|        goto cleanup;
  147|    102|    }
  148|       |    
  149|   142k|cleanup:
  150|   142k|    if (out_double)
  ------------------
  |  Branch (150:9): [True: 142k, False: 0]
  ------------------
  151|   142k|        *out_double = value;
  152|       |
  153|   142k|    return retval;
  154|   142k|}
readstat_por_read.c:read_tag:
   85|  27.7k|static uint16_t read_tag(por_ctx_t *ctx) {
   86|  27.7k|    unsigned char tag;
   87|  27.7k|    if (read_bytes(ctx, &tag, 1) != 1) {
  ------------------
  |  Branch (87:9): [True: 205, False: 27.5k]
  ------------------
   88|    205|        return -1;
   89|    205|    }
   90|  27.5k|    return ctx->byte2unicode[tag];
   91|  27.7k|}
readstat_por_read.c:read_variable_count_record:
  257|  1.17k|static readstat_error_t read_variable_count_record(por_ctx_t *ctx) {
  258|  1.17k|    int value;
  259|  1.17k|    readstat_error_t retval = READSTAT_OK;
  260|  1.17k|    if (ctx->var_count) {
  ------------------
  |  Branch (260:9): [True: 15, False: 1.15k]
  ------------------
  261|     15|        retval = READSTAT_ERROR_PARSE;
  262|     15|        goto cleanup;
  263|     15|    }
  264|  1.15k|    if ((retval = read_integer_in_range(ctx, 0, MAX_VARS, &value)) != READSTAT_OK) {
  ------------------
  |  |   35|  1.15k|#define MAX_VARS    1000000
  ------------------
  |  Branch (264:9): [True: 15, False: 1.14k]
  ------------------
  265|     15|        goto cleanup;
  266|     15|    }
  267|  1.14k|    ctx->var_count = value;
  268|  1.14k|    ctx->variables = readstat_calloc(ctx->var_count, sizeof(readstat_variable_t *));
  269|  1.14k|    ctx->varinfo = readstat_calloc(ctx->var_count, sizeof(spss_varinfo_t));
  270|  1.14k|    if (ctx->variables == NULL || ctx->varinfo == NULL) {
  ------------------
  |  Branch (270:9): [True: 3, False: 1.13k]
  |  Branch (270:35): [True: 9, False: 1.12k]
  ------------------
  271|     12|        retval = READSTAT_ERROR_MALLOC;
  272|     12|        goto cleanup;
  273|     12|    }
  274|       |
  275|  1.12k|    if (ctx->handle.metadata) {
  ------------------
  |  Branch (275:9): [True: 1.12k, False: 0]
  ------------------
  276|  1.12k|        readstat_metadata_t metadata = {
  277|  1.12k|            .row_count = -1,
  278|  1.12k|            .var_count = ctx->var_count,
  279|  1.12k|            .creation_time = ctx->timestamp,
  280|  1.12k|            .modified_time = ctx->timestamp,
  281|  1.12k|            .file_format_version = ctx->version,
  282|  1.12k|            .file_label = ctx->file_label
  283|  1.12k|        };
  284|  1.12k|        if (ctx->handle.metadata(&metadata, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|  1.12k|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (284:13): [True: 0, False: 1.12k]
  ------------------
  285|      0|            retval = READSTAT_ERROR_USER_ABORT;
  286|      0|            goto cleanup;
  287|      0|        }
  288|  1.12k|    }
  289|       |        
  290|  1.17k|cleanup:
  291|  1.17k|    return retval;
  292|  1.12k|}
readstat_por_read.c:read_integer_in_range:
  164|  68.3k|static readstat_error_t read_integer_in_range(por_ctx_t *ctx, int min, int max, int *out_integer) {
  165|  68.3k|    double dval = NAN;
  166|  68.3k|    readstat_error_t retval = read_double(ctx, &dval);
  167|  68.3k|    if (retval != READSTAT_OK)
  ------------------
  |  Branch (167:9): [True: 281, False: 68.0k]
  ------------------
  168|    281|        return retval;
  169|  68.0k|    if (isnan(dval) || dval < min || dval > max)
  ------------------
  |  Branch (169:9): [True: 11, False: 68.0k]
  |  Branch (169:24): [True: 9, False: 68.0k]
  |  Branch (169:38): [True: 13, False: 68.0k]
  ------------------
  170|     33|        return READSTAT_ERROR_PARSE;
  171|  68.0k|    if (out_integer)
  ------------------
  |  Branch (171:9): [True: 68.0k, False: 0]
  ------------------
  172|  68.0k|        *out_integer = (int)dval;
  173|  68.0k|    return READSTAT_OK;
  174|  68.0k|}
readstat_por_read.c:read_double:
  156|  92.4k|static readstat_error_t read_double(por_ctx_t *ctx, double *out_double) {
  157|  92.4k|    unsigned char peek;
  158|  92.4k|    size_t bytes_read = read_bytes(ctx, &peek, 1);
  159|  92.4k|    if (bytes_read != 1)
  ------------------
  |  Branch (159:9): [True: 281, False: 92.1k]
  ------------------
  160|    281|        return READSTAT_ERROR_PARSE;
  161|  92.1k|    return read_double_with_peek(ctx, out_double, peek);
  162|  92.4k|}
readstat_por_read.c:read_precision_record:
  294|    467|static readstat_error_t read_precision_record(por_ctx_t *ctx) {
  295|    467|    int precision = 0;
  296|    467|    readstat_error_t error = read_integer_in_range(ctx, 0, 100, &precision);
  297|    467|    if (error == READSTAT_OK)
  ------------------
  |  Branch (297:9): [True: 448, False: 19]
  ------------------
  298|    448|        ctx->base30_precision = precision;
  299|    467|    return error;
  300|    467|}
readstat_por_read.c:read_case_weight_record:
  302|  1.18k|static readstat_error_t read_case_weight_record(por_ctx_t *ctx) {
  303|  1.18k|    return read_string(ctx, ctx->fweight_name, sizeof(ctx->fweight_name));
  304|  1.18k|}
readstat_por_read.c:read_variable_record:
  306|  8.01k|static readstat_error_t read_variable_record(por_ctx_t *ctx) {
  307|  8.01k|    readstat_error_t retval = READSTAT_OK;
  308|  8.01k|    int value;
  309|  8.01k|    int i;
  310|  8.01k|    spss_varinfo_t *varinfo = NULL;
  311|  8.01k|    spss_format_t *formats[2];
  312|       |
  313|  8.01k|    ctx->var_offset++;
  314|       |
  315|  8.01k|    if (ctx->var_offset == ctx->var_count) {
  ------------------
  |  Branch (315:9): [True: 2, False: 8.01k]
  ------------------
  316|      2|        retval = READSTAT_ERROR_PARSE;
  317|      2|        goto cleanup;
  318|      2|    }
  319|       |
  320|  8.01k|    varinfo = &ctx->varinfo[ctx->var_offset];
  321|  8.01k|    formats[0] = &varinfo->print_format;
  322|  8.01k|    formats[1] = &varinfo->write_format;
  323|       |
  324|  8.01k|    varinfo->labels_index = -1;
  325|  8.01k|    if ((retval = read_integer_in_range(ctx, 0, MAX_WIDTH, &value)) != READSTAT_OK) {
  ------------------
  |  |   36|  8.01k|#define MAX_WIDTH   1000000
  ------------------
  |  Branch (325:9): [True: 22, False: 7.99k]
  ------------------
  326|     22|        goto cleanup;
  327|     22|    }
  328|  7.99k|    varinfo->width = value;
  329|  7.99k|    if (varinfo->width == 0) {
  ------------------
  |  Branch (329:9): [True: 3.40k, False: 4.59k]
  ------------------
  330|  3.40k|        varinfo->type = READSTAT_TYPE_DOUBLE;
  331|  3.40k|        varinfo->width = 1; /* one eight-byte slot, as in SAV files */
  332|  4.59k|    } else {
  333|  4.59k|        varinfo->type = READSTAT_TYPE_STRING;
  334|       |        /* The declared width is the string length in characters */
  335|  4.59k|        varinfo->string_length = value;
  336|  4.59k|    }
  337|  7.99k|    if ((retval = read_string(ctx, varinfo->name, sizeof(varinfo->name))) != READSTAT_OK) {
  ------------------
  |  Branch (337:9): [True: 37, False: 7.95k]
  ------------------
  338|     37|        goto cleanup;
  339|     37|    }
  340|  7.95k|    ck_str_hash_insert(varinfo->name, varinfo, ctx->var_dict);
  341|       |
  342|  23.5k|    for (i=0; i<sizeof(formats)/sizeof(spss_format_t *); i++) {
  ------------------
  |  Branch (342:15): [True: 15.7k, False: 7.78k]
  ------------------
  343|  15.7k|        spss_format_t *format = formats[i];
  344|  15.7k|        if ((retval = read_integer_in_range(ctx, 0, MAX_FORMAT_TYPE, &value)) != READSTAT_OK) {
  ------------------
  |  |   28|  15.7k|#define MAX_FORMAT_TYPE     (POR_FORMAT_SHIFT+SPSS_FORMAT_TYPE_YMDHMS)
  |  |  ------------------
  |  |  |  |   27|  15.7k|#define POR_FORMAT_SHIFT     82
  |  |  ------------------
  |  |               #define MAX_FORMAT_TYPE     (POR_FORMAT_SHIFT+SPSS_FORMAT_TYPE_YMDHMS)
  |  |  ------------------
  |  |  |  |   38|  15.7k|#define SPSS_FORMAT_TYPE_YMDHMS   41
  |  |  ------------------
  ------------------
  |  Branch (344:13): [True: 123, False: 15.6k]
  ------------------
  345|    123|            goto cleanup;
  346|    123|        }
  347|  15.6k|        if (value > POR_FORMAT_SHIFT) {
  ------------------
  |  |   27|  15.6k|#define POR_FORMAT_SHIFT     82
  ------------------
  |  Branch (347:13): [True: 217, False: 15.4k]
  ------------------
  348|       |            // Some files in the wild have their format types shifted by 82 for date/time values
  349|       |            // I have no idea why, but see test files linked from:
  350|       |            // https://github.com/WizardMac/ReadStat/issues/158
  351|    217|            format->type = value - POR_FORMAT_SHIFT;
  ------------------
  |  |   27|    217|#define POR_FORMAT_SHIFT     82
  ------------------
  352|  15.4k|        } else {
  353|  15.4k|            format->type = value;
  354|  15.4k|        }
  355|       |
  356|  15.6k|        if ((retval = read_integer_in_range(ctx, 0, MAX_FORMAT_WIDTH, &value)) != READSTAT_OK) {
  ------------------
  |  |   29|  15.6k|#define MAX_FORMAT_WIDTH    20000
  ------------------
  |  Branch (356:13): [True: 38, False: 15.6k]
  ------------------
  357|     38|            goto cleanup;
  358|     38|        }
  359|  15.6k|        format->width = value;
  360|       |
  361|  15.6k|        if ((retval = read_integer_in_range(ctx, 0, MAX_FORMAT_DECIMALS, &value)) != READSTAT_OK) {
  ------------------
  |  |   30|  15.6k|#define MAX_FORMAT_DECIMALS   100
  ------------------
  |  Branch (361:13): [True: 16, False: 15.5k]
  ------------------
  362|     16|            goto cleanup;
  363|     16|        }
  364|  15.5k|        format->decimal_places = value;
  365|  15.5k|    }
  366|       |
  367|  8.01k|cleanup:
  368|  8.01k|    return retval;
  369|  7.95k|}
readstat_por_read.c:read_missing_value_record:
  402|    656|static readstat_error_t read_missing_value_record(por_ctx_t *ctx) {
  403|    656|    readstat_error_t retval = READSTAT_OK;
  404|    656|    spss_varinfo_t *varinfo = NULL;
  405|       |
  406|    656|    if (ctx->var_offset < 0 || ctx->var_offset >= ctx->var_count) {
  ------------------
  |  Branch (406:9): [True: 1, False: 655]
  |  Branch (406:32): [True: 0, False: 655]
  ------------------
  407|      1|        retval = READSTAT_ERROR_PARSE;
  408|      1|        goto cleanup;
  409|      1|    }
  410|    655|    varinfo = &ctx->varinfo[ctx->var_offset];
  411|       |
  412|    655|    if (varinfo->n_missing_values >= 3) {
  ------------------
  |  Branch (412:9): [True: 5, False: 650]
  ------------------
  413|      5|        retval = READSTAT_ERROR_PARSE;
  414|      5|        goto cleanup;
  415|      5|    }
  416|    650|    if (varinfo->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (416:9): [True: 336, False: 314]
  ------------------
  417|    336|        if ((retval = read_double(ctx, &varinfo->missing_double_values[varinfo->n_missing_values])) != READSTAT_OK) {
  ------------------
  |  Branch (417:13): [True: 19, False: 317]
  ------------------
  418|     19|            goto cleanup;
  419|     19|        }
  420|    336|    } else {
  421|    314|        if ((retval = read_missing_string_value(ctx, varinfo, varinfo->n_missing_values)) != READSTAT_OK) {
  ------------------
  |  Branch (421:13): [True: 8, False: 306]
  ------------------
  422|      8|            goto cleanup;
  423|      8|        }
  424|    314|    }
  425|    623|    varinfo->n_missing_values++;
  426|       |
  427|    656|cleanup:
  428|    656|    return retval;
  429|    623|}
readstat_por_read.c:read_missing_string_value:
  397|  2.09k|static readstat_error_t read_missing_string_value(por_ctx_t *ctx, spss_varinfo_t *varinfo, int index) {
  398|  2.09k|    return read_converted_string(ctx, varinfo->missing_string_values[index],
  399|  2.09k|            sizeof(varinfo->missing_string_values[index]));
  400|  2.09k|}
readstat_por_read.c:read_converted_string:
  375|  18.6k|static readstat_error_t read_converted_string(por_ctx_t *ctx, char *dst, size_t dst_len) {
  376|  18.6k|    readstat_error_t retval = READSTAT_OK;
  377|  18.6k|    char string[POR_STRING_BUFFER_SIZE];
  378|  18.6k|    size_t len = 0;
  379|       |
  380|  18.6k|    if ((retval = read_string(ctx, string, sizeof(string))) != READSTAT_OK)
  ------------------
  |  Branch (380:9): [True: 201, False: 18.4k]
  ------------------
  381|    201|        goto cleanup;
  382|       |
  383|  18.4k|    len = strlen(string);
  384|  19.3k|    while (len > 0 && string[len-1] == ' ')
  ------------------
  |  Branch (384:12): [True: 15.0k, False: 4.24k]
  |  Branch (384:23): [True: 839, False: 14.2k]
  ------------------
  385|    839|        len--;
  386|  18.4k|    if (len + 1 > dst_len) {
  ------------------
  |  Branch (386:9): [True: 357, False: 18.1k]
  ------------------
  387|    357|        len = dst_len - 1;
  388|    640|        while (len > 0 && (string[len] & 0xC0) == 0x80)
  ------------------
  |  Branch (388:16): [True: 640, False: 0]
  |  Branch (388:27): [True: 283, False: 357]
  ------------------
  389|    283|            len--;
  390|    357|    }
  391|  18.4k|    retval = readstat_convert(dst, dst_len, string, len, ctx->converter);
  392|       |
  393|  18.6k|cleanup:
  394|  18.6k|    return retval;
  395|  18.4k|}
readstat_por_read.c:read_missing_value_range_record:
  431|  3.77k|static readstat_error_t read_missing_value_range_record(por_ctx_t *ctx) {
  432|  3.77k|    readstat_error_t retval = READSTAT_OK;
  433|  3.77k|    spss_varinfo_t *varinfo = NULL;
  434|       |
  435|  3.77k|    if (ctx->var_offset < 0 || ctx->var_offset == ctx->var_count) {
  ------------------
  |  Branch (435:9): [True: 3, False: 3.77k]
  |  Branch (435:32): [True: 0, False: 3.77k]
  ------------------
  436|      3|        retval = READSTAT_ERROR_PARSE;
  437|      3|        goto cleanup;
  438|      3|    }
  439|  3.77k|    varinfo = &ctx->varinfo[ctx->var_offset];
  440|       |
  441|  3.77k|    varinfo->missing_range = 1;
  442|  3.77k|    varinfo->n_missing_values = 2;
  443|  3.77k|    if (varinfo->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (443:9): [True: 3.23k, False: 543]
  ------------------
  444|  3.23k|        if ((retval = read_double(ctx, &varinfo->missing_double_values[0])) != READSTAT_OK) {
  ------------------
  |  Branch (444:13): [True: 20, False: 3.21k]
  ------------------
  445|     20|            goto cleanup;
  446|     20|        }
  447|  3.21k|        if ((retval = read_double(ctx, &varinfo->missing_double_values[1])) != READSTAT_OK) {
  ------------------
  |  Branch (447:13): [True: 16, False: 3.19k]
  ------------------
  448|     16|            goto cleanup;
  449|     16|        }
  450|  3.21k|    } else {
  451|    543|        if ((retval = read_missing_string_value(ctx, varinfo, 0)) != READSTAT_OK) {
  ------------------
  |  Branch (451:13): [True: 12, False: 531]
  ------------------
  452|     12|            goto cleanup;
  453|     12|        }
  454|    531|        if ((retval = read_missing_string_value(ctx, varinfo, 1)) != READSTAT_OK) {
  ------------------
  |  Branch (454:13): [True: 21, False: 510]
  ------------------
  455|     21|            goto cleanup;
  456|     21|        }
  457|    531|    }
  458|  3.77k|cleanup:
  459|  3.77k|    return retval;
  460|  3.77k|}
readstat_por_read.c:read_missing_value_lo_range_record:
  462|  1.95k|static readstat_error_t read_missing_value_lo_range_record(por_ctx_t *ctx) {
  463|  1.95k|    readstat_error_t retval = READSTAT_OK;
  464|  1.95k|    spss_varinfo_t *varinfo = NULL;
  465|       |
  466|  1.95k|    if (ctx->var_offset < 0 || ctx->var_offset == ctx->var_count) {
  ------------------
  |  Branch (466:9): [True: 2, False: 1.94k]
  |  Branch (466:32): [True: 0, False: 1.94k]
  ------------------
  467|      2|        retval = READSTAT_ERROR_PARSE;
  468|      2|        goto cleanup;
  469|      2|    }
  470|  1.94k|    varinfo = &ctx->varinfo[ctx->var_offset];
  471|       |
  472|  1.94k|    varinfo->missing_range = 1;
  473|  1.94k|    varinfo->n_missing_values = 2;
  474|  1.94k|    if (varinfo->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (474:9): [True: 1.62k, False: 324]
  ------------------
  475|  1.62k|        varinfo->missing_double_values[0] = -HUGE_VAL;
  476|  1.62k|        if ((retval = read_double(ctx, &varinfo->missing_double_values[1])) != READSTAT_OK) {
  ------------------
  |  Branch (476:13): [True: 20, False: 1.60k]
  ------------------
  477|     20|            goto cleanup;
  478|     20|        }
  479|  1.62k|    } else {
  480|    324|        varinfo->missing_string_values[0][0] = '\0';
  481|    324|        if ((retval = read_missing_string_value(ctx, varinfo, 1)) != READSTAT_OK) {
  ------------------
  |  Branch (481:13): [True: 17, False: 307]
  ------------------
  482|     17|            goto cleanup;
  483|     17|        }
  484|    324|    }
  485|  1.95k|cleanup:
  486|  1.95k|    return retval;
  487|  1.94k|}
readstat_por_read.c:read_missing_value_hi_range_record:
  489|  1.49k|static readstat_error_t read_missing_value_hi_range_record(por_ctx_t *ctx) {
  490|  1.49k|    readstat_error_t retval = READSTAT_OK;
  491|  1.49k|    spss_varinfo_t *varinfo = NULL;
  492|       |
  493|  1.49k|    if (ctx->var_offset < 0 || ctx->var_offset == ctx->var_count) {
  ------------------
  |  Branch (493:9): [True: 1, False: 1.49k]
  |  Branch (493:32): [True: 0, False: 1.49k]
  ------------------
  494|      1|        retval = READSTAT_ERROR_PARSE;
  495|      1|        goto cleanup;
  496|      1|    }
  497|  1.49k|    varinfo = &ctx->varinfo[ctx->var_offset];
  498|       |
  499|  1.49k|    varinfo->missing_range = 1;
  500|  1.49k|    varinfo->n_missing_values = 2;
  501|  1.49k|    if (varinfo->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (501:9): [True: 1.11k, False: 380]
  ------------------
  502|  1.11k|        if ((retval = read_double(ctx, &varinfo->missing_double_values[0])) != READSTAT_OK) {
  ------------------
  |  Branch (502:13): [True: 15, False: 1.10k]
  ------------------
  503|     15|            goto cleanup;
  504|     15|        }
  505|  1.10k|        varinfo->missing_double_values[1] = HUGE_VAL;
  506|  1.10k|    } else {
  507|    380|        if ((retval = read_missing_string_value(ctx, varinfo, 0)) != READSTAT_OK) {
  ------------------
  |  Branch (507:13): [True: 7, False: 373]
  ------------------
  508|      7|            goto cleanup;
  509|      7|        }
  510|    373|        varinfo->missing_string_values[1][0] = '\0';
  511|    373|    }
  512|  1.49k|cleanup:
  513|  1.49k|    return retval;
  514|  1.49k|}
readstat_por_read.c:read_variable_label_record:
  539|  1.16k|static readstat_error_t read_variable_label_record(por_ctx_t *ctx) {
  540|  1.16k|    readstat_error_t retval = READSTAT_OK;
  541|  1.16k|    char string[POR_STRING_BUFFER_SIZE];
  542|  1.16k|    spss_varinfo_t *varinfo = NULL;
  543|       |
  544|  1.16k|    if (ctx->var_offset < 0 || ctx->var_offset == ctx->var_count) {
  ------------------
  |  Branch (544:9): [True: 1, False: 1.16k]
  |  Branch (544:32): [True: 0, False: 1.16k]
  ------------------
  545|      1|        retval = READSTAT_ERROR_PARSE;
  546|      1|        goto cleanup;
  547|      1|    }
  548|  1.16k|    varinfo = &ctx->varinfo[ctx->var_offset];
  549|       |
  550|  1.16k|    if ((retval = read_string(ctx, string, sizeof(string))) != READSTAT_OK) {
  ------------------
  |  Branch (550:9): [True: 32, False: 1.13k]
  ------------------
  551|     32|        goto cleanup;
  552|     32|    }
  553|       |
  554|  1.13k|    size_t label_alloc_len = 4*strlen(string) + 1;
  555|  1.13k|    char *new_label = realloc(varinfo->label, label_alloc_len);
  556|  1.13k|    if (new_label == NULL) { retval = READSTAT_ERROR_MALLOC; goto cleanup; }
  ------------------
  |  Branch (556:9): [True: 0, False: 1.13k]
  ------------------
  557|  1.13k|    varinfo->label = new_label;
  558|  1.13k|    retval = readstat_convert(varinfo->label, label_alloc_len, string, strlen(string), ctx->converter);
  559|       |
  560|  1.16k|cleanup:
  561|  1.16k|    return retval;
  562|  1.13k|}
readstat_por_read.c:read_value_label_record:
  564|  5.59k|static readstat_error_t read_value_label_record(por_ctx_t *ctx) {
  565|  5.59k|    readstat_error_t retval = READSTAT_OK;
  566|  5.59k|    double dval;
  567|  5.59k|    int i;
  568|  5.59k|    char string[POR_STRING_BUFFER_SIZE];
  569|  5.59k|    int count = 0, label_count = 0;
  570|  5.59k|    char label_name_buf[256];
  571|  5.59k|    char key_buf[4*POR_STRING_BUFFER_SIZE+1];
  572|  5.59k|    char label_buf[4*POR_STRING_BUFFER_SIZE+1];
  573|  5.59k|    snprintf(label_name_buf, sizeof(label_name_buf), POR_LABEL_NAME_PREFIX "%d", ctx->labels_offset);
  ------------------
  |  |   25|  5.59k|#define POR_LABEL_NAME_PREFIX   "labels"
  ------------------
  574|  5.59k|    readstat_type_t value_type = READSTAT_TYPE_DOUBLE;
  575|  5.59k|    if ((retval = read_integer_in_range(ctx, 0, MAX_STRINGS, &count)) != READSTAT_OK) {
  ------------------
  |  |   38|  5.59k|#define MAX_STRINGS 1000000
  ------------------
  |  Branch (575:9): [True: 25, False: 5.57k]
  ------------------
  576|     25|        goto cleanup;
  577|     25|    }
  578|  10.3k|    for (i=0; i<count; i++) {
  ------------------
  |  Branch (578:15): [True: 4.98k, False: 5.40k]
  ------------------
  579|  4.98k|        if ((retval = read_string(ctx, string, sizeof(string))) != READSTAT_OK) {
  ------------------
  |  Branch (579:13): [True: 172, False: 4.81k]
  ------------------
  580|    172|            goto cleanup;
  581|    172|        }
  582|  4.81k|        spss_varinfo_t *info = (spss_varinfo_t *)ck_str_hash_lookup(string, ctx->var_dict);
  583|  4.81k|        if (info) {
  ------------------
  |  Branch (583:13): [True: 2.08k, False: 2.73k]
  ------------------
  584|  2.08k|            value_type = info->type;
  585|  2.08k|            info->labels_index = ctx->labels_offset;
  586|  2.08k|        }
  587|  4.81k|    }
  588|  5.40k|    if ((retval = read_integer_in_range(ctx, 0, MAX_LABELS, &label_count)) != READSTAT_OK) {
  ------------------
  |  |   39|  5.40k|#define MAX_LABELS  1000000
  ------------------
  |  Branch (588:9): [True: 44, False: 5.35k]
  ------------------
  589|     44|        goto cleanup;
  590|     44|    }
  591|  20.0k|    for (i=0; i<label_count; i++) {
  ------------------
  |  Branch (591:15): [True: 14.8k, False: 5.22k]
  ------------------
  592|  14.8k|        readstat_value_t value = { .type = value_type };
  593|  14.8k|        if (value_type == READSTAT_TYPE_STRING) {
  ------------------
  |  Branch (593:13): [True: 282, False: 14.5k]
  ------------------
  594|    282|            if ((retval = read_converted_string(ctx, key_buf, sizeof(key_buf))) != READSTAT_OK) {
  ------------------
  |  Branch (594:17): [True: 10, False: 272]
  ------------------
  595|     10|                goto cleanup;
  596|     10|            }
  597|    272|            if ((retval = read_converted_string(ctx, label_buf, sizeof(label_buf))) != READSTAT_OK) {
  ------------------
  |  Branch (597:17): [True: 1, False: 271]
  ------------------
  598|      1|                goto cleanup;
  599|      1|            }
  600|    271|            value.v.string_value = key_buf;
  601|  14.5k|        } else {
  602|  14.5k|            if ((retval = read_double(ctx, &dval)) != READSTAT_OK) {
  ------------------
  |  Branch (602:17): [True: 58, False: 14.5k]
  ------------------
  603|     58|                goto cleanup;
  604|     58|            }
  605|  14.5k|            if ((retval = read_converted_string(ctx, label_buf, sizeof(label_buf))) != READSTAT_OK) {
  ------------------
  |  Branch (605:17): [True: 62, False: 14.4k]
  ------------------
  606|     62|                goto cleanup;
  607|     62|            }
  608|  14.4k|            value.v.double_value = dval;
  609|  14.4k|        }
  610|  14.7k|        if (ctx->handle.value_label) {
  ------------------
  |  Branch (610:13): [True: 14.7k, False: 0]
  ------------------
  611|  14.7k|            if (ctx->handle.value_label(label_name_buf, value, label_buf, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|  14.7k|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (611:17): [True: 0, False: 14.7k]
  ------------------
  612|      0|                retval = READSTAT_ERROR_USER_ABORT;
  613|      0|                goto cleanup;
  614|      0|            }
  615|  14.7k|        }
  616|  14.7k|    }
  617|  5.22k|    ctx->labels_offset++;
  618|       |
  619|  5.59k|cleanup:
  620|  5.59k|    return retval;
  621|  5.22k|}
readstat_por_read.c:read_document_record:
  516|    702|static readstat_error_t read_document_record(por_ctx_t *ctx) {
  517|    702|    readstat_error_t retval = READSTAT_OK;
  518|    702|    char string[4*POR_STRING_BUFFER_SIZE+1];
  519|    702|    int i;
  520|    702|    int line_count = 0;
  521|    702|    if ((retval = read_integer_in_range(ctx, 0, MAX_LINES, &line_count)) != READSTAT_OK) {
  ------------------
  |  |   37|    702|#define MAX_LINES   1000000
  ------------------
  |  Branch (521:9): [True: 12, False: 690]
  ------------------
  522|     12|        goto cleanup;
  523|     12|    }
  524|  2.14k|    for (i=0; i<line_count; i++) {
  ------------------
  |  Branch (524:15): [True: 1.51k, False: 627]
  ------------------
  525|  1.51k|        if ((retval = read_converted_string(ctx, string, sizeof(string))) != READSTAT_OK) {
  ------------------
  |  Branch (525:13): [True: 63, False: 1.45k]
  ------------------
  526|     63|            goto cleanup;
  527|     63|        }
  528|  1.45k|        if (ctx->handle.note) {
  ------------------
  |  Branch (528:13): [True: 1.45k, False: 0]
  ------------------
  529|  1.45k|            if (ctx->handle.note(i, string, ctx->user_ctx) != READSTAT_OK) {
  ------------------
  |  Branch (529:17): [True: 0, False: 1.45k]
  ------------------
  530|      0|                retval = READSTAT_ERROR_USER_ABORT;
  531|      0|                goto cleanup;
  532|      0|            }
  533|  1.45k|        }
  534|  1.45k|    }
  535|    702|cleanup:
  536|    702|    return retval;
  537|    690|}
readstat_por_read.c:read_por_file_data:
  623|    375|static readstat_error_t read_por_file_data(por_ctx_t *ctx) {
  624|    375|    int i;
  625|    375|    char input_string[POR_STRING_BUFFER_SIZE];
  626|    375|    char output_string[4*POR_STRING_BUFFER_SIZE+1];
  627|    375|    char error_buf[1024];
  628|    375|    readstat_error_t rs_retval = READSTAT_OK;
  629|       |
  630|    375|    if (ctx->var_count == 0)
  ------------------
  |  Branch (630:9): [True: 8, False: 367]
  ------------------
  631|      8|        return READSTAT_OK;
  632|       |
  633|  8.42k|    while (1) {
  ------------------
  |  Branch (633:12): [True: 8.42k, Folded]
  ------------------
  634|  8.42k|        int finished = 0;
  635|  20.2k|        for (i=0; i<ctx->var_count; i++) {
  ------------------
  |  Branch (635:19): [True: 12.1k, False: 8.05k]
  ------------------
  636|  12.1k|            spss_varinfo_t *info = &ctx->varinfo[i];
  637|  12.1k|            readstat_value_t value = { .type = info->type };
  638|       |
  639|  12.1k|            if (info->type == READSTAT_TYPE_STRING) {
  ------------------
  |  Branch (639:17): [True: 482, False: 11.6k]
  ------------------
  640|    482|                rs_retval = maybe_read_string(ctx, input_string, sizeof(input_string), &finished);
  641|    482|                if (rs_retval != READSTAT_OK) {
  ------------------
  |  Branch (641:21): [True: 167, False: 315]
  ------------------
  642|    167|                    if (ctx->handle.error) {
  ------------------
  |  Branch (642:25): [True: 0, False: 167]
  ------------------
  643|      0|                        snprintf(error_buf, sizeof(error_buf), "Error in %s (row=%d)", 
  644|      0|                                info->name, ctx->obs_count+1);
  645|      0|                        ctx->handle.error(error_buf, ctx->user_ctx);
  646|      0|                    }
  647|    167|                    goto cleanup;
  648|    315|                } else if (finished) {
  ------------------
  |  Branch (648:28): [True: 3, False: 312]
  ------------------
  649|      3|                    if (i != 0)
  ------------------
  |  Branch (649:25): [True: 2, False: 1]
  ------------------
  650|      2|                        rs_retval = READSTAT_ERROR_PARSE;
  651|      3|                    goto cleanup;
  652|      3|                }
  653|    312|                rs_retval = readstat_convert(output_string, sizeof(output_string),
  654|    312|                        input_string, strlen(input_string), ctx->converter);
  655|    312|                if (rs_retval != READSTAT_OK) {
  ------------------
  |  Branch (655:21): [True: 0, False: 312]
  ------------------
  656|      0|                    goto cleanup;
  657|      0|                }
  658|    312|                value.v.string_value = output_string;
  659|  11.6k|            } else if (info->type == READSTAT_TYPE_DOUBLE) {
  ------------------
  |  Branch (659:24): [True: 11.6k, False: 0]
  ------------------
  660|  11.6k|                rs_retval = maybe_read_double(ctx, &value.v.double_value, &finished);
  661|  11.6k|                if (rs_retval != READSTAT_OK) {
  ------------------
  |  Branch (661:21): [True: 194, False: 11.4k]
  ------------------
  662|    194|                    if (ctx->handle.error) {
  ------------------
  |  Branch (662:25): [True: 0, False: 194]
  ------------------
  663|      0|                        snprintf(error_buf, sizeof(error_buf), "Error in %s (row=%d)", 
  664|      0|                                info->name, ctx->obs_count+1);
  665|      0|                        ctx->handle.error(error_buf, ctx->user_ctx);
  666|      0|                    }
  667|    194|                    goto cleanup;
  668|  11.4k|                } else if (finished) {
  ------------------
  |  Branch (668:28): [True: 3, False: 11.4k]
  ------------------
  669|      3|                    if (i != 0)
  ------------------
  |  Branch (669:25): [True: 2, False: 1]
  ------------------
  670|      2|                        rs_retval = READSTAT_ERROR_PARSE;
  671|      3|                    goto cleanup;
  672|      3|                }
  673|  11.4k|                value.is_system_missing = isnan(value.v.double_value);
  674|  11.4k|            }
  675|  11.8k|            if (ctx->handle.value && !ctx->variables[i]->skip && !ctx->row_offset) {
  ------------------
  |  Branch (675:17): [True: 11.8k, False: 0]
  |  Branch (675:38): [True: 11.8k, False: 0]
  |  Branch (675:66): [True: 11.8k, False: 0]
  ------------------
  676|  11.8k|                if (ctx->handle.value(ctx->obs_count, ctx->variables[i], value, ctx->user_ctx) != READSTAT_HANDLER_OK) {
  ------------------
  |  |   22|  11.8k|#define READSTAT_HANDLER_OK             0
  ------------------
  |  Branch (676:21): [True: 0, False: 11.8k]
  ------------------
  677|      0|                    rs_retval = READSTAT_ERROR_USER_ABORT;
  678|      0|                    goto cleanup;
  679|      0|                }
  680|  11.8k|            }
  681|       |
  682|  11.8k|        }
  683|  8.05k|        if (ctx->row_offset) {
  ------------------
  |  Branch (683:13): [True: 0, False: 8.05k]
  ------------------
  684|      0|            ctx->row_offset--;
  685|  8.05k|        } else {
  686|  8.05k|            ctx->obs_count++;
  687|  8.05k|        }
  688|       |
  689|  8.05k|        rs_retval = por_update_progress(ctx);
  690|  8.05k|        if (rs_retval != READSTAT_OK)
  ------------------
  |  Branch (690:13): [True: 0, False: 8.05k]
  ------------------
  691|      0|            break;
  692|       |            
  693|  8.05k|        if (ctx->row_limit > 0 && ctx->obs_count == ctx->row_limit)
  ------------------
  |  Branch (693:13): [True: 0, False: 8.05k]
  |  Branch (693:35): [True: 0, False: 0]
  ------------------
  694|      0|            break;
  695|  8.05k|    }
  696|    367|cleanup:
  697|    367|    return rs_retval;
  698|    367|}
readstat_por_read.c:por_update_progress:
   44|  8.05k|static readstat_error_t por_update_progress(por_ctx_t *ctx) {
   45|  8.05k|    readstat_io_t *io = ctx->io;
   46|  8.05k|    return io->update(ctx->file_size, ctx->handle.progress, ctx->user_ctx, io->io_ctx);
   47|  8.05k|}

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

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

