Coverage Report

Created: 2026-09-28 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/htslib/vcf.c
Line
Count
Source
1
/*  vcf.c -- VCF/BCF API functions.
2
3
    Copyright (C) 2012, 2013 Broad Institute.
4
    Copyright (C) 2012-2026 Genome Research Ltd.
5
    Portions copyright (C) 2014 Intel Corporation.
6
7
    Author: Heng Li <lh3@sanger.ac.uk>
8
9
Permission is hereby granted, free of charge, to any person obtaining a copy
10
of this software and associated documentation files (the "Software"), to deal
11
in the Software without restriction, including without limitation the rights
12
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
copies of the Software, and to permit persons to whom the Software is
14
furnished to do so, subject to the following conditions:
15
16
The above copyright notice and this permission notice shall be included in
17
all copies or substantial portions of the Software.
18
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
DEALINGS IN THE SOFTWARE.  */
26
27
#define HTS_BUILDING_LIBRARY // Enables HTSLIB_EXPORT, see htslib/hts_defs.h
28
#include <config.h>
29
30
#include <stdio.h>
31
#include <assert.h>
32
#include <string.h>
33
#include <strings.h>
34
#include <stdlib.h>
35
#include <limits.h>
36
#include <stdint.h>
37
#include <inttypes.h>
38
#include <errno.h>
39
40
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
41
#include "fuzz_settings.h"
42
#endif
43
44
#include "htslib/vcf.h"
45
#include "htslib/bgzf.h"
46
#include "htslib/tbx.h"
47
#include "htslib/hfile.h"
48
#include "hts_internal.h"
49
#include "htslib/hts_alloc.h"
50
#include "htslib/hts_endian.h"
51
#include "htslib/khash_str2int.h"
52
#include "htslib/kstring.h"
53
#include "htslib/sam.h"
54
#include "htslib/khash.h"
55
#include "bgzf_internal.h"
56
57
#if 0
58
// This helps on Intel a bit, often 6-7% faster VCF parsing.
59
// Conversely sometimes harms AMD Zen4 as ~9% slower.
60
// Possibly related to IPC differences.  However for now it's just a
61
// curiosity we ignore and stick with the simpler code.
62
//
63
// Left here as a hint for future explorers.
64
static inline int xstreq(const char *a, const char *b) {
65
    while (*a && *a == *b)
66
        a++, b++;
67
    return *a == *b;
68
}
69
70
#define KHASH_MAP_INIT_XSTR(name, khval_t) \
71
  KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, xstreq)
72
73
KHASH_MAP_INIT_XSTR(vdict, bcf_idinfo_t)
74
#else
75
0
KHASH_MAP_INIT_STR(vdict, bcf_idinfo_t)
76
0
#endif
77
0
78
0
typedef khash_t(vdict) vdict_t;
79
0
80
0
KHASH_MAP_INIT_STR(hdict, bcf_hrec_t*)
81
0
typedef khash_t(hdict) hdict_t;
82
0
83
0
84
0
#include "htslib/kseq.h"
85
0
HTSLIB_EXPORT
86
0
uint32_t bcf_float_missing    = 0x7F800001;
87
0
88
0
HTSLIB_EXPORT
89
0
uint32_t bcf_float_vector_end = 0x7F800002;
90
0
91
0
HTSLIB_EXPORT
92
0
uint8_t bcf_type_shift[] = { 0, 0, 1, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
93
0
94
0
static bcf_idinfo_t bcf_idinfo_def = { .info = { 15, 15, 15 }, .hrec = { NULL, NULL, NULL}, .id = -1 };
95
0
96
0
/*
97
0
    Partial support for 64-bit POS and Number=1 INFO tags.
98
0
    Notes:
99
0
     - the support for 64-bit values is motivated by POS and INFO/END for large genomes
100
0
     - the use of 64-bit values does not conform to the specification
101
0
     - cannot output 64-bit BCF and if it does, it is not compatible with anything
102
0
     - experimental, use at your risk
103
0
*/
104
0
#ifdef VCF_ALLOW_INT64
105
0
    #define BCF_MAX_BT_INT64 (0x7fffffffffffffff)       /* INT64_MAX, for internal use only */
106
0
    #define BCF_MIN_BT_INT64 -9223372036854775800LL     /* INT64_MIN + 8, for internal use only */
107
0
#endif
108
0
109
1.84k
#define BCF_IS_64BIT (1<<30)
110
111
112
// Opaque structure with auxiliary data which allows to extend bcf_hdr_t without breaking ABI.
113
// Note that this preserving API and ABI requires that the first element is vdict_t struct
114
// rather than a pointer, as user programs may (and in some cases do) access the dictionary
115
// directly as (vdict_t*)hdr->dict.
116
typedef struct
117
{
118
    vdict_t dict;   // bcf_hdr_t.dict[0] vdict_t dictionary which keeps bcf_idinfo_t for BCF_HL_FLT,BCF_HL_INFO,BCF_HL_FMT
119
    hdict_t *gen;   // hdict_t dictionary which keeps bcf_hrec_t* pointers for generic and structured fields
120
    size_t *key_len;// length of h->id[BCF_DT_ID] strings
121
    int version;    //cached version
122
    uint32_t ref_count; // reference count, low bit indicates bcf_hdr_destroy() has been called
123
}
124
bcf_hdr_aux_t;
125
126
static inline bcf_hdr_aux_t *get_hdr_aux(const bcf_hdr_t *hdr)
127
335k
{
128
335k
    return (bcf_hdr_aux_t *)hdr->dict[0];
129
335k
}
130
131
//version macros
132
177k
#define VCF_DEF 4002000
133
66.9k
#define VCF44   4004000
134
35.9k
#define VCF45   4005000
135
136
#define VCF_MAJOR_VER(x) ( (x) / 10000 / 100 )
137
#define VCF_MINOR_VER(x) ( ((x) % 1000000) / 1000 )
138
139
/**
140
 *  bcf_get_version - get the version as int
141
 *  @param hdr   - bcf header, to get version
142
 *  @param verstr- version string, which is already available
143
 *  Returns version on success and default version on failure
144
 *  version = major * 100 * 10000 + minor * 1000
145
 */
146
static int bcf_get_version(const bcf_hdr_t *hdr, const char *verstr)
147
27.4k
{
148
27.4k
    const char *version = NULL, vcf[] = "VCFv";
149
27.4k
    const char *major = NULL, *minor = NULL;
150
27.4k
    int ver = -1;
151
27.4k
    long tmp = 0;
152
27.4k
    bcf_hdr_aux_t *aux = NULL;
153
154
27.4k
    if (!hdr && !verstr) {  //invalid input
155
0
        goto fail;
156
0
    }
157
158
27.4k
    if (hdr) {
159
20.8k
        if ((aux = get_hdr_aux(hdr)) && aux->version != 0) {    //use cached version
160
19.5k
            return aux->version;
161
19.5k
        }
162
        //get from header
163
1.28k
        version = bcf_hdr_get_version(hdr);
164
6.58k
    } else {
165
        //get from version string
166
6.58k
        version = verstr;
167
6.58k
    }
168
7.87k
    if (!(major = strstr(version, vcf))) {  //bad format
169
5.44k
        goto fail;
170
5.44k
    }
171
2.42k
    major += sizeof(vcf) - 1;
172
2.42k
    if (!(minor = strchr(major, '.'))) {    //bad format
173
280
        goto fail;
174
280
    }
175
2.14k
    tmp = strtol(major, NULL, 10);
176
2.14k
    if ((!tmp && errno == EINVAL) || tmp < 0 || tmp >= 1000) {    //failed
177
355
        goto fail;
178
355
    }
179
1.79k
    ver = tmp * 100 * 10000;
180
1.79k
    tmp = strtol(++minor, NULL, 10);
181
1.79k
    if ((!tmp && errno == EINVAL) || tmp < 0 || tmp >= 1000) {    //failed
182
686
        goto fail;
183
686
    }
184
1.10k
    ver += tmp * 1000;
185
1.10k
    return ver;
186
187
6.76k
fail:
188
6.76k
    hts_log_warning("Couldn't get VCF version, considering as %d.%d",
189
6.76k
        VCF_MAJOR_VER(VCF_DEF), VCF_MINOR_VER(VCF_DEF));
190
6.76k
    return VCF_DEF;
191
1.79k
}
192
193
// Header reference counting
194
195
static void bcf_hdr_incr_ref(bcf_hdr_t *h)
196
2.77k
{
197
2.77k
    bcf_hdr_aux_t *aux = get_hdr_aux(h);
198
2.77k
    aux->ref_count += 2;
199
2.77k
}
200
201
static void bcf_hdr_decr_ref(bcf_hdr_t *h)
202
2.77k
{
203
2.77k
    bcf_hdr_aux_t *aux = get_hdr_aux(h);
204
2.77k
    if (aux->ref_count >= 2)
205
2.77k
        aux->ref_count -= 2;
206
207
2.77k
    if (aux->ref_count == 0)
208
2.51k
        bcf_hdr_destroy(h);
209
2.77k
}
210
211
static void hdr_bgzf_private_data_cleanup(void *data)
212
2.77k
{
213
2.77k
    bcf_hdr_t *h = (bcf_hdr_t *) data;
214
2.77k
    bcf_hdr_decr_ref(h);
215
2.77k
}
216
217
static char *find_chrom_header_line(char *s)
218
0
{
219
0
    char *nl;
220
0
    if (strncmp(s, "#CHROM\t", 7) == 0) return s;
221
0
    else if ((nl = strstr(s, "\n#CHROM\t")) != NULL) return nl+1;
222
0
    else return NULL;
223
0
}
224
225
static int64_t get_rlen(const bcf_hdr_t *h, bcf1_t *v);
226
227
/*************************
228
 *** VCF header parser ***
229
 *************************/
230
231
static int bcf_hdr_add_sample_len(bcf_hdr_t *h, const char *s, size_t len)
232
11.0k
{
233
11.0k
    const char *ss = s;
234
11.3k
    while ( *ss && isspace_c(*ss) && ss - s < len) ss++;
235
11.0k
    if ( !*ss || ss - s == len)
236
16
    {
237
16
        hts_log_error("Empty sample name: trailing spaces/tabs in the header line?");
238
16
        return -1;
239
16
    }
240
241
11.0k
    vdict_t *d = (vdict_t*)h->dict[BCF_DT_SAMPLE];
242
11.0k
    int ret;
243
11.0k
    char *sdup = malloc(len + 1);
244
11.0k
    if (!sdup) return -1;
245
11.0k
    memcpy(sdup, s, len);
246
11.0k
    sdup[len] = 0;
247
248
    // Ensure space is available in h->samples
249
11.0k
    size_t n = kh_size(d);
250
11.0k
    char **new_samples = hts_realloc_ps(h->samples, sizeof(*h->samples), n, 1);
251
11.0k
    if (!new_samples) {
252
0
        free(sdup);
253
0
        return -1;
254
0
    }
255
11.0k
    h->samples = new_samples;
256
257
11.0k
    int k = kh_put(vdict, d, sdup, &ret);
258
11.0k
    if (ret < 0) {
259
0
        free(sdup);
260
0
        return -1;
261
0
    }
262
11.0k
    if (ret) { // absent
263
10.9k
        kh_val(d, k) = bcf_idinfo_def;
264
10.9k
        kh_val(d, k).id = n;
265
10.9k
    } else {
266
6
        hts_log_error("Duplicated sample name '%s'", sdup);
267
6
        free(sdup);
268
6
        return -1;
269
6
    }
270
10.9k
    h->samples[n] = sdup;
271
10.9k
    h->dirty = 1;
272
10.9k
    return 0;
273
11.0k
}
274
275
int bcf_hdr_add_sample(bcf_hdr_t *h, const char *s)
276
0
{
277
0
    if (!s) {
278
        // Allowed for backwards-compatibility, calling with s == NULL
279
        // used to trigger bcf_hdr_sync(h);
280
0
        return 0;
281
0
    }
282
0
    return bcf_hdr_add_sample_len(h, s, strlen(s));
283
0
}
284
285
int HTS_RESULT_USED bcf_hdr_parse_sample_line(bcf_hdr_t *hdr, const char *str)
286
4.81k
{
287
4.81k
    const char *mandatory = "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO";
288
4.81k
    if ( strncmp(str,mandatory,strlen(mandatory)) )
289
290
    {
290
290
        hts_log_error("Could not parse the \"#CHROM..\" line, either the fields are incorrect or spaces are present instead of tabs:\n\t%s",str);
291
290
        return -1;
292
290
    }
293
294
4.52k
    const char *beg = str + strlen(mandatory), *end;
295
4.52k
    if ( !*beg || *beg=='\n' ) return 0;
296
2.45k
    if ( strncmp(beg,"\tFORMAT\t",8) )
297
6
    {
298
6
        hts_log_error("Could not parse the \"#CHROM..\" line, either FORMAT is missing or spaces are present instead of tabs:\n\t%s",str);
299
6
        return -1;
300
6
    }
301
2.44k
    beg += 8;
302
303
2.44k
    int ret = 0;
304
11.2k
    while ( *beg )
305
11.0k
    {
306
11.0k
        end = beg;
307
171M
        while ( *end && *end!='\t' && *end!='\n' ) end++;
308
11.0k
        if ( bcf_hdr_add_sample_len(hdr, beg, end-beg) < 0 ) ret = -1;
309
11.0k
        if ( !*end || *end=='\n' || ret<0 ) break;
310
8.76k
        beg = end + 1;
311
8.76k
    }
312
2.44k
    return ret;
313
2.45k
}
314
315
int bcf_hdr_sync(bcf_hdr_t *h)
316
48.8k
{
317
48.8k
    int i;
318
195k
    for (i = 0; i < 3; i++)
319
146k
    {
320
146k
        vdict_t *d = (vdict_t*)h->dict[i];
321
146k
        khint_t k;
322
146k
        if ( h->n[i] < kh_size(d) )
323
2.25k
        {
324
2.25k
            bcf_idpair_t *new_idpair;
325
            // this should be true only for i=2, BCF_DT_SAMPLE
326
2.25k
            new_idpair = hts_realloc_p(h->id[i], sizeof(bcf_idpair_t), kh_size(d));
327
2.25k
            if (!new_idpair) return -1;
328
2.25k
            h->n[i] = kh_size(d);
329
2.25k
            h->id[i] = new_idpair;
330
2.25k
        }
331
1.70G
        for (k=kh_begin(d); k<kh_end(d); k++)
332
1.69G
        {
333
1.69G
            if (!kh_exist(d,k)) continue;
334
1.43M
            h->id[i][kh_val(d,k).id].key = kh_key(d,k);
335
1.43M
            h->id[i][kh_val(d,k).id].val = &kh_val(d,k);
336
1.43M
        }
337
146k
    }
338
339
    // Invalidate key length cache
340
48.8k
    bcf_hdr_aux_t *aux = get_hdr_aux(h);
341
48.8k
    if (aux && aux->key_len) {
342
4.14k
        free(aux->key_len);
343
4.14k
        aux->key_len = NULL;
344
4.14k
    }
345
346
48.8k
    h->dirty = 0;
347
48.8k
    return 0;
348
48.8k
}
349
350
void bcf_hrec_destroy(bcf_hrec_t *hrec)
351
218k
{
352
218k
    if (!hrec) return;
353
211k
    free(hrec->key);
354
211k
    if ( hrec->value ) free(hrec->value);
355
211k
    int i;
356
524k
    for (i=0; i<hrec->nkeys; i++)
357
313k
    {
358
313k
        free(hrec->keys[i]);
359
313k
        free(hrec->vals[i]);
360
313k
    }
361
211k
    free(hrec->keys);
362
211k
    free(hrec->vals);
363
211k
    free(hrec);
364
211k
}
365
366
// Copies all fields except IDX.
367
bcf_hrec_t *bcf_hrec_dup(bcf_hrec_t *hrec)
368
0
{
369
0
    int save_errno;
370
0
    bcf_hrec_t *out = (bcf_hrec_t*) calloc(1,sizeof(bcf_hrec_t));
371
0
    if (!out) return NULL;
372
373
0
    out->type = hrec->type;
374
0
    if ( hrec->key ) {
375
0
        out->key = strdup(hrec->key);
376
0
        if (!out->key) goto fail;
377
0
    }
378
0
    if ( hrec->value ) {
379
0
        out->value = strdup(hrec->value);
380
0
        if (!out->value) goto fail;
381
0
    }
382
0
    out->nkeys = hrec->nkeys;
383
0
    out->keys = hts_malloc_p(sizeof(char*), hrec->nkeys);
384
0
    if (!out->keys) goto fail;
385
0
    out->vals = hts_malloc_p(sizeof(char*), hrec->nkeys);
386
0
    if (!out->vals) goto fail;
387
0
    int i, j = 0;
388
0
    for (i=0; i<hrec->nkeys; i++)
389
0
    {
390
0
        if ( hrec->keys[i] && !strcmp("IDX",hrec->keys[i]) ) continue;
391
0
        if ( hrec->keys[i] ) {
392
0
            out->keys[j] = strdup(hrec->keys[i]);
393
0
            if (!out->keys[j]) goto fail;
394
0
        }
395
0
        if ( hrec->vals[i] ) {
396
0
            out->vals[j] = strdup(hrec->vals[i]);
397
0
            if (!out->vals[j]) goto fail;
398
0
        }
399
0
        j++;
400
0
    }
401
0
    if ( i!=j ) out->nkeys -= i-j;   // IDX was omitted
402
0
    return out;
403
404
0
 fail:
405
0
    save_errno = errno;
406
0
    hts_log_error("%s", strerror(errno));
407
0
    bcf_hrec_destroy(out);
408
0
    errno = save_errno;
409
0
    return NULL;
410
0
}
411
412
void bcf_hrec_debug(FILE *fp, bcf_hrec_t *hrec)
413
0
{
414
0
    fprintf(fp, "key=[%s] value=[%s]", hrec->key, hrec->value?hrec->value:"");
415
0
    int i;
416
0
    for (i=0; i<hrec->nkeys; i++)
417
0
        fprintf(fp, "\t[%s]=[%s]", hrec->keys[i],hrec->vals[i]);
418
0
    fprintf(fp, "\n");
419
0
}
420
421
void bcf_header_debug(bcf_hdr_t *hdr)
422
0
{
423
0
    int i, j;
424
0
    for (i=0; i<hdr->nhrec; i++)
425
0
    {
426
0
        if ( !hdr->hrec[i]->value )
427
0
        {
428
0
            fprintf(stderr, "##%s=<", hdr->hrec[i]->key);
429
0
            fprintf(stderr,"%s=%s", hdr->hrec[i]->keys[0], hdr->hrec[i]->vals[0]);
430
0
            for (j=1; j<hdr->hrec[i]->nkeys; j++)
431
0
                fprintf(stderr,",%s=%s", hdr->hrec[i]->keys[j], hdr->hrec[i]->vals[j]);
432
0
            fprintf(stderr,">\n");
433
0
        }
434
0
        else
435
0
            fprintf(stderr,"##%s=%s\n", hdr->hrec[i]->key,hdr->hrec[i]->value);
436
0
    }
437
0
}
438
439
int bcf_hrec_add_key(bcf_hrec_t *hrec, const char *str, size_t len)
440
262k
{
441
262k
    char **tmp;
442
262k
    size_t n = hrec->nkeys + 1;
443
262k
    assert(len > 0 && len < SIZE_MAX);
444
262k
    tmp = hts_realloc_p(hrec->keys, sizeof(char*), n);
445
262k
    if (!tmp) return -1;
446
262k
    hrec->keys = tmp;
447
262k
    tmp = hts_realloc_p(hrec->vals, sizeof(char*), n);
448
262k
    if (!tmp) return -1;
449
262k
    hrec->vals = tmp;
450
451
262k
    hrec->keys[hrec->nkeys] = hts_malloc_ps(sizeof(char), len, 1);
452
262k
    if (!hrec->keys[hrec->nkeys]) return -1;
453
262k
    memcpy(hrec->keys[hrec->nkeys],str,len);
454
262k
    hrec->keys[hrec->nkeys][len] = 0;
455
262k
    hrec->vals[hrec->nkeys] = NULL;
456
262k
    hrec->nkeys = n;
457
262k
    return 0;
458
262k
}
459
460
int bcf_hrec_set_val(bcf_hrec_t *hrec, int i, const char *str, size_t len, int is_quoted)
461
262k
{
462
262k
    if ( hrec->vals[i] ) {
463
0
        free(hrec->vals[i]);
464
0
        hrec->vals[i] = NULL;
465
0
    }
466
262k
    if ( !str ) return 0;
467
262k
    if ( is_quoted )
468
54.4k
    {
469
54.4k
        if (len >= SIZE_MAX - 3) {
470
0
            errno = ENOMEM;
471
0
            return -1;
472
0
        }
473
54.4k
        hrec->vals[i] = hts_malloc_ps(sizeof(char), len, 3);
474
54.4k
        if (!hrec->vals[i]) return -1;
475
54.4k
        hrec->vals[i][0] = '"';
476
54.4k
        memcpy(&hrec->vals[i][1],str,len);
477
54.4k
        hrec->vals[i][len+1] = '"';
478
54.4k
        hrec->vals[i][len+2] = 0;
479
54.4k
    }
480
207k
    else
481
207k
    {
482
207k
        if (len == SIZE_MAX) {
483
0
            errno = ENOMEM;
484
0
            return -1;
485
0
        }
486
207k
        hrec->vals[i] = hts_malloc_ps(sizeof(char), len, 1);
487
207k
        if (!hrec->vals[i]) return -1;
488
207k
        memcpy(hrec->vals[i],str,len);
489
207k
        hrec->vals[i][len] = 0;
490
207k
    }
491
262k
    return 0;
492
262k
}
493
494
int hrec_add_idx(bcf_hrec_t *hrec, int idx)
495
50.8k
{
496
50.8k
    int n = hrec->nkeys + 1;
497
50.8k
    char **tmp = hts_realloc_p(hrec->keys, sizeof(char*), n);
498
50.8k
    if (!tmp) return -1;
499
50.8k
    hrec->keys = tmp;
500
501
50.8k
    tmp = hts_realloc_p(hrec->vals, sizeof(char*), n);
502
50.8k
    if (!tmp) return -1;
503
50.8k
    hrec->vals = tmp;
504
505
50.8k
    hrec->keys[hrec->nkeys] = strdup("IDX");
506
50.8k
    if (!hrec->keys[hrec->nkeys]) return -1;
507
508
50.8k
    kstring_t str = {0,0,0};
509
50.8k
    if (kputw(idx, &str) < 0) {
510
0
        free(hrec->keys[hrec->nkeys]);
511
0
        return -1;
512
0
    }
513
50.8k
    hrec->vals[hrec->nkeys] = str.s;
514
50.8k
    hrec->nkeys = n;
515
50.8k
    return 0;
516
50.8k
}
517
518
int bcf_hrec_find_key(bcf_hrec_t *hrec, const char *key)
519
117k
{
520
117k
    int i;
521
187k
    for (i=0; i<hrec->nkeys; i++)
522
113k
        if ( !strcasecmp(key,hrec->keys[i]) ) return i;
523
74.4k
    return -1;
524
117k
}
525
526
static void bcf_hrec_set_type(bcf_hrec_t *hrec)
527
311k
{
528
311k
    if ( !strcmp(hrec->key, "contig") ) hrec->type = BCF_HL_CTG;
529
295k
    else if ( !strcmp(hrec->key, "INFO") ) hrec->type = BCF_HL_INFO;
530
149k
    else if ( !strcmp(hrec->key, "FILTER") ) hrec->type = BCF_HL_FLT;
531
98.7k
    else if ( !strcmp(hrec->key, "FORMAT") ) hrec->type = BCF_HL_FMT;
532
78.6k
    else if ( hrec->nkeys>0 ) hrec->type = BCF_HL_STR;
533
68.7k
    else hrec->type = BCF_HL_GEN;
534
311k
}
535
536
537
/**
538
    The arrays were generated with
539
540
    valid_ctg:
541
        perl -le '@v = (split(//,q[!#$%&*+./:;=?@^_|~-]),"a"..."z","A"..."Z","0"..."9"); @a = (0) x 256; foreach $c (@v) { $a[ord($c)] = 1; } print join(", ",@a)' | fold -w 48
542
543
    valid_tag:
544
        perl -le '@v = (split(//,q[_.]),"a"..."z","A"..."Z","0"..."9"); @a = (0) x 256; foreach $c (@v) { $a[ord($c)] = 1; } print join(", ",@a)' | fold -w 48
545
*/
546
static const uint8_t valid_ctg[256] =
547
{
548
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
549
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
550
    0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1,
551
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
552
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
553
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
554
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
555
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
556
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
557
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
558
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
559
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
560
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
561
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
562
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
563
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
564
};
565
static const uint8_t valid_tag[256] =
566
{
567
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
568
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
569
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
570
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
571
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
572
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
573
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
574
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
575
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
576
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
577
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
578
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
579
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
580
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
581
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
582
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
583
};
584
585
/**
586
    bcf_hrec_check() - check the validity of structured header lines
587
588
    Returns 0 on success or negative value on error.
589
590
    Currently the return status is not checked by the caller
591
    and only a warning is printed on stderr. This should be improved
592
    to propagate the error all the way up to the caller and let it
593
    decide what to do: throw an error or proceed anyway.
594
 */
595
static int bcf_hrec_check(bcf_hrec_t *hrec)
596
155k
{
597
155k
    int i;
598
155k
    bcf_hrec_set_type(hrec);
599
600
155k
    if ( hrec->type==BCF_HL_CTG )
601
7.70k
    {
602
7.70k
        i = bcf_hrec_find_key(hrec,"ID");
603
7.70k
        if ( i<0 ) goto err_missing_id;
604
7.14k
        char *val = hrec->vals[i];
605
7.14k
        if ( val[0]=='*' || val[0]=='=' || !valid_ctg[(uint8_t)val[0]] ) goto err_invalid_ctg;
606
3.81k
        while ( *(++val) )
607
3.51k
            if ( !valid_ctg[(uint8_t)*val] ) goto err_invalid_ctg;
608
301
        return 0;
609
1.54k
    }
610
147k
    if ( hrec->type==BCF_HL_INFO )
611
72.8k
    {
612
72.8k
        i = bcf_hrec_find_key(hrec,"ID");
613
72.8k
        if ( i<0 ) goto err_missing_id;
614
16.1k
        char *val = hrec->vals[i];
615
16.1k
        if ( !strcmp(val,"1000G") ) return 0;
616
15.8k
        if ( val[0]=='.' || (val[0]>='0' && val[0]<='9') || !valid_tag[(uint8_t)val[0]] ) goto err_invalid_tag;
617
14.1k
        while ( *(++val) )
618
11.9k
            if ( !valid_tag[(uint8_t)*val] ) goto err_invalid_tag;
619
2.16k
        return 0;
620
4.29k
    }
621
74.9k
    if ( hrec->type==BCF_HL_FMT )
622
10.0k
    {
623
10.0k
        i = bcf_hrec_find_key(hrec,"ID");
624
10.0k
        if ( i<0 ) goto err_missing_id;
625
9.66k
        char *val = hrec->vals[i];
626
9.66k
        if ( val[0]=='.' || (val[0]>='0' && val[0]<='9') || !valid_tag[(uint8_t)val[0]] ) goto err_invalid_tag;
627
9.08k
        while ( *(++val) )
628
6.21k
            if ( !valid_tag[(uint8_t)*val] ) goto err_invalid_tag;
629
2.87k
        return 0;
630
4.00k
    }
631
64.9k
    return 0;
632
633
57.6k
  err_missing_id:
634
57.6k
    hts_log_warning("Missing ID attribute in one or more header lines");
635
57.6k
    return -1;
636
637
6.84k
  err_invalid_ctg:
638
6.84k
    hts_log_warning("Invalid contig name: \"%s\"", hrec->vals[i]);
639
6.84k
    return -1;
640
641
20.4k
  err_invalid_tag:
642
20.4k
    hts_log_warning("Invalid tag name: \"%s\"", hrec->vals[i]);
643
20.4k
    return -1;
644
74.9k
}
645
646
static inline int is_escaped(const char *min, const char *str)
647
53.7k
{
648
53.7k
    int n = 0;
649
54.4k
    while ( --str>=min && *str=='\\' ) n++;
650
53.7k
    return n%2;
651
53.7k
}
652
653
bcf_hrec_t *bcf_hdr_parse_line(const bcf_hdr_t *h, const char *line, int *len)
654
227k
{
655
227k
    bcf_hrec_t *hrec = NULL;
656
227k
    const char *p = line;
657
227k
    char *reason = "unknown";
658
227k
    if (p[0] != '#' || p[1] != '#') { *len = 0; return NULL; }
659
218k
    p += 2;
660
661
218k
    const char *q = p;
662
2.27M
    while ( *q && *q!='=' && *q != '\n' ) q++;
663
218k
    ptrdiff_t n = q-p;
664
218k
    if ( *q!='=' || !n ) {
665
        // wrong format
666
7.42k
        reason = "missing '='";
667
7.42k
        goto malformed_line;
668
7.42k
    }
669
670
211k
    hrec = (bcf_hrec_t*) calloc(1,sizeof(bcf_hrec_t));
671
211k
    if (!hrec) { *len = -1; return NULL; }
672
211k
    hrec->key = hts_malloc_ps(sizeof(char), n, 1);
673
211k
    if (!hrec->key) goto fail;
674
211k
    memcpy(hrec->key,p,n);
675
211k
    hrec->key[n] = 0;
676
211k
    hrec->type = -1;
677
678
211k
    p = ++q;
679
211k
    if ( *p!='<' ) // generic field, e.g. ##samtoolsVersion=0.1.18-r579
680
50.8k
    {
681
6.08M
        while ( *q && *q!='\n' ) q++;
682
50.8k
        hrec->value = hts_malloc_p(sizeof(char), (q-p+1));
683
50.8k
        if (!hrec->value) goto fail;
684
50.8k
        memcpy(hrec->value, p, q-p);
685
50.8k
        hrec->value[q-p] = 0;
686
50.8k
        *len = q - line + (*q ? 1 : 0); // Skip \n but not \0
687
50.8k
        return hrec;
688
50.8k
    }
689
690
    // structured line, e.g.
691
    // ##INFO=<ID=PV1,Number=1,Type=Float,Description="P-value for baseQ bias">
692
    // ##PEDIGREE=<Name_0=G0-ID,Name_1=G1-ID,Name_3=GN-ID>
693
160k
    int nopen = 1;
694
422k
    while ( *q && *q!='\n' && nopen>0 )
695
286k
    {
696
286k
        p = ++q;
697
288k
        while ( *q && *q==' ' ) { p++; q++; }
698
        // ^[A-Za-z_][0-9A-Za-z_.]*$
699
286k
        if (p==q && *q && (isalpha_c(*q) || *q=='_'))
700
276k
        {
701
276k
            q++;
702
1.46M
            while ( *q && (isalnum_c(*q) || *q=='_' || *q=='.') ) q++;
703
276k
        }
704
286k
        n = q-p;
705
286k
        int m = 0;
706
286k
        while ( *q && *q==' ' ) { q++; m++; }
707
286k
        if ( *q!='=' || !n ) {
708
23.9k
            reason = "missing '='";
709
23.9k
            goto malformed_line;
710
23.9k
        }
711
712
262k
        if (bcf_hrec_add_key(hrec, p, q-p-m) < 0) goto fail;
713
262k
        p = ++q;
714
264k
        while ( *q && *q==' ' ) { p++; q++; }
715
716
262k
        int quoted = 0;
717
262k
        char ending = '\0';
718
262k
        switch (*p) {
719
54.4k
        case '"':
720
54.4k
            quoted = 1;
721
54.4k
            ending = '"';
722
54.4k
            p++;
723
54.4k
            break;
724
318
        case '[':
725
318
            quoted = 1;
726
318
            ending = ']';
727
318
            break;
728
262k
        }
729
262k
        if ( quoted ) q++;
730
9.23M
        while ( *q && *q != '\n' )
731
9.20M
        {
732
9.20M
            if ( quoted ) { if ( *q==ending && !is_escaped(p,q) ) break; }
733
8.68M
            else
734
8.68M
            {
735
8.68M
                if ( *q=='<' ) nopen++;
736
8.68M
                if ( *q=='>' ) nopen--;
737
8.68M
                if ( !nopen ) break;
738
8.62M
                if ( *q==',' && nopen==1 ) break;
739
8.62M
            }
740
8.97M
            q++;
741
8.97M
        }
742
262k
        const char *r = q;
743
262k
        if (quoted && ending == ']') {
744
318
            if (*q == ending) {
745
235
                r++;
746
235
                q++;
747
235
                quoted = 0;
748
235
            } else {
749
83
                reason = "missing ']'";
750
83
                goto malformed_line;
751
83
            }
752
318
        }
753
263k
        while ( r > p && r[-1] == ' ' ) r--;
754
262k
        if (bcf_hrec_set_val(hrec, hrec->nkeys-1, p, r-p, quoted) < 0)
755
0
            goto fail;
756
262k
        if ( quoted && *q==ending ) q++;
757
262k
        if ( *q=='>' )
758
104k
        {
759
104k
            if (nopen) nopen--;     // this can happen with nested angle brackets <>
760
104k
            q++;
761
104k
        }
762
262k
    }
763
136k
    if ( nopen ) {
764
31.6k
        reason = "incomplete";
765
31.6k
        goto malformed_line;
766
31.6k
    }
767
768
    // Skip to end of line
769
104k
    int nonspace = 0;
770
104k
    p = q;
771
1.02M
    while ( *q && *q!='\n' ) { nonspace |= !isspace_c(*q); q++; }
772
104k
    if (nonspace) {
773
30.5k
        char buffer[320];
774
30.5k
        hts_log_warning("Dropped trailing junk from header line '%s'",
775
30.5k
                        hts_strprint(buffer, sizeof(buffer),
776
30.5k
                                     '"', line, q - line));
777
30.5k
    }
778
779
104k
    *len = q - line + (*q ? 1 : 0);
780
104k
    return hrec;
781
782
0
 fail:
783
0
    *len = -1;
784
0
    bcf_hrec_destroy(hrec);
785
0
    return NULL;
786
787
63.1k
 malformed_line:
788
63.1k
    {
789
63.1k
        char buffer[320];
790
477k
        while ( *q && *q!='\n' ) q++;  // Ensure *len includes full line
791
63.1k
        hts_log_error("Could not parse the header line (%s): %s", reason,
792
63.1k
                      hts_strprint(buffer, sizeof(buffer),
793
63.1k
                                   '"', line, q - line));
794
63.1k
        *len = q - line + (*q ? 1 : 0);
795
63.1k
        bcf_hrec_destroy(hrec);
796
63.1k
        return NULL;
797
136k
    }
798
136k
}
799
800
static int bcf_hdr_set_idx(bcf_hdr_t *hdr, int dict_type, const char *tag, bcf_idinfo_t *idinfo)
801
48.5k
{
802
48.5k
    size_t new_n;
803
804
    // If available, preserve existing IDX
805
48.5k
    if ( idinfo->id==-1 )
806
48.3k
        idinfo->id = hdr->n[dict_type];
807
213
    else if ( idinfo->id < hdr->n[dict_type] && hdr->id[dict_type][idinfo->id].key )
808
3
    {
809
3
        hts_log_error("Conflicting IDX=%d lines in the header dictionary, the new tag is %s",
810
3
            idinfo->id, tag);
811
3
        errno = EINVAL;
812
3
        return -1;
813
3
    }
814
815
48.5k
    new_n = idinfo->id >= hdr->n[dict_type] ? idinfo->id+1 : hdr->n[dict_type];
816
48.5k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
817
    // hts_resize() can attempt to allocate up to 2 * requested items
818
48.5k
    if (new_n > FUZZ_ALLOC_LIMIT/(2 * sizeof(bcf_idpair_t)))
819
10
        return -1;
820
48.5k
#endif
821
48.5k
    if (hts_resize(bcf_idpair_t, new_n, &hdr->m[dict_type],
822
48.5k
                   &hdr->id[dict_type], HTS_RESIZE_CLEAR)) {
823
0
        return -1;
824
0
    }
825
48.5k
    hdr->n[dict_type] = new_n;
826
827
    // NB: the next kh_put call can invalidate the idinfo pointer, therefore
828
    // we leave it unassigned here. It must be set explicitly in bcf_hdr_sync.
829
48.5k
    hdr->id[dict_type][idinfo->id].key = tag;
830
831
48.5k
    return 0;
832
48.5k
}
833
834
// Sub-function of bcf_hdr_register_hrec for type==BCF_HL_CTG
835
// Returns 1 when hdr needs to be synced, -1 on error, 0 otherwise
836
7.70k
static int bcf_hdr_register_hrec_ctg(bcf_hdr_t *hdr, bcf_hrec_t *hrec) {
837
7.70k
    char *id_copy = NULL;
838
7.70k
    hts_pos_t len = 0;
839
7.70k
    int ret, replacing = 0;
840
841
    // Get the contig ID and length
842
7.70k
    int id_i = bcf_hrec_find_key(hrec,"ID");
843
7.70k
    if ( id_i<0 ) return 0;
844
7.14k
    const char *id = hrec->vals[id_i];
845
7.14k
    int len_i = bcf_hrec_find_key(hrec,"length");
846
7.14k
    if ( len_i >= 0 ) {
847
0
        const char *length = hrec->vals[len_i];
848
0
        const char *start = length + (*length == '"');
849
0
        char *end;
850
0
        len = strtoll(start, &end, 10);
851
0
        if (start == end || len < 0) {
852
0
            hts_log_warning("Could not parse the length attribute of "
853
0
                            "contig \"%s\": \"%s\". Using zero.",
854
0
                            id, length);
855
0
            len = 0;
856
0
        }
857
7.14k
    } else {
858
7.14k
        len = 0;
859
7.14k
    }
860
861
7.14k
    id_copy = strdup(id);
862
7.14k
    if (!id_copy) return -1;
863
864
    // Register in the dictionary
865
7.14k
    vdict_t *d = (vdict_t*)hdr->dict[BCF_DT_CTG];
866
7.14k
    khint_t k = kh_get(vdict, d, id_copy);
867
7.14k
    if ( k != kh_end(d) ) { // already present
868
489
        free(id_copy); id_copy=NULL;
869
489
        if (kh_val(d, k).hrec[0] != NULL) // and not removed
870
489
            return 0;
871
0
        replacing = 1;
872
6.65k
    } else {
873
6.65k
        k = kh_put(vdict, d, id_copy, &ret);
874
6.65k
        if (ret < 0) { free(id_copy); return -1; }
875
6.65k
    }
876
877
6.65k
    int idx = bcf_hrec_find_key(hrec,"IDX");
878
6.65k
    if ( idx!=-1 )
879
1.61k
    {
880
1.61k
        char *tmp = hrec->vals[idx];
881
1.61k
        idx = strtol(hrec->vals[idx], &tmp, 10);
882
1.61k
        if ( *tmp || idx < 0 || idx >= INT_MAX - 1)
883
1.59k
        {
884
1.59k
            if (!replacing) {
885
1.59k
                kh_del(vdict, d, k);
886
1.59k
                free(id_copy);
887
1.59k
            }
888
1.59k
            hts_log_warning("Error parsing the IDX tag, skipping");
889
1.59k
            return 0;
890
1.59k
        }
891
1.61k
    }
892
893
5.06k
    kh_val(d, k) = bcf_idinfo_def;
894
5.06k
    kh_val(d, k).id = idx;
895
5.06k
    kh_val(d, k).info[0] = len;
896
5.06k
    kh_val(d, k).hrec[0] = hrec;
897
5.06k
    if (bcf_hdr_set_idx(hdr, BCF_DT_CTG, kh_key(d,k), &kh_val(d,k)) < 0) {
898
9
        if (!replacing) {
899
9
            kh_del(vdict, d, k);
900
9
            free(id_copy);
901
9
        }
902
9
        return -1;
903
9
    }
904
5.05k
    if ( idx==-1 ) {
905
5.03k
        if (hrec_add_idx(hrec, kh_val(d,k).id) < 0) {
906
0
            return -1;
907
0
        }
908
5.03k
    }
909
910
5.05k
    return 1;
911
5.05k
}
912
913
// Sub-function of bcf_hdr_register_hrec for type is BCF_HL_INFO,
914
// BCF_HL_FLT or BCF_HL_FMT.
915
// Returns 1 when hdr needs to be synced, -1 on error, 0 otherwise
916
108k
static int bcf_hdr_register_hrec_info(bcf_hdr_t *hdr, bcf_hrec_t *hrec) {
917
108k
    int i, ret;
918
108k
    khint_t k;
919
108k
    char *id_copy = NULL;
920
108k
    char *id = NULL;
921
108k
    uint32_t type = UINT32_MAX, var = UINT32_MAX;
922
108k
    int num = -1, idx = -1;
923
924
292k
    for (i=0; i<hrec->nkeys; i++)
925
183k
    {
926
183k
        if ( !strcmp(hrec->keys[i], "ID") ) id = hrec->vals[i];
927
132k
        else if ( !strcmp(hrec->keys[i], "IDX") )
928
19.4k
        {
929
19.4k
            char *tmp = hrec->vals[i];
930
19.4k
            idx = strtol(hrec->vals[i], &tmp, 10);
931
19.4k
            if ( *tmp || idx < 0 || idx >= INT_MAX - 1)
932
128
            {
933
128
                hts_log_warning("Error parsing the IDX tag, skipping");
934
128
                return 0;
935
128
            }
936
19.4k
        }
937
113k
        else if ( !strcmp(hrec->keys[i], "Type") )
938
25.0k
        {
939
25.0k
            if ( !strcmp(hrec->vals[i], "Integer") ) type = BCF_HT_INT;
940
20.3k
            else if ( !strcmp(hrec->vals[i], "Float") ) type = BCF_HT_REAL;
941
20.2k
            else if ( !strcmp(hrec->vals[i], "String") ) type = BCF_HT_STR;
942
177
            else if ( !strcmp(hrec->vals[i], "Character") ) type = BCF_HT_STR;
943
177
            else if ( !strcmp(hrec->vals[i], "Flag") ) type = BCF_HT_FLAG;
944
156
            else
945
156
            {
946
156
                hts_log_warning("The type \"%s\" is not supported, assuming \"String\"", hrec->vals[i]);
947
156
                type = BCF_HT_STR;
948
156
            }
949
25.0k
        }
950
88.1k
        else if ( !strcmp(hrec->keys[i], "Number") )
951
37.6k
        {
952
37.6k
            int is_fmt = hrec->type == BCF_HL_FMT;
953
37.6k
            if ( !strcmp(hrec->vals[i],"A") ) var = BCF_VL_A;
954
24.7k
            else if ( !strcmp(hrec->vals[i],"R") ) var = BCF_VL_R;
955
24.5k
            else if ( !strcmp(hrec->vals[i],"G") ) var = BCF_VL_G;
956
20.6k
            else if ( !strcmp(hrec->vals[i],".") ) var = BCF_VL_VAR;
957
20.5k
            else if ( is_fmt && !strcmp(hrec->vals[i],"P") )  var = BCF_VL_P;
958
20.5k
            else if ( is_fmt && !strcmp(hrec->vals[i],"LA") ) var = BCF_VL_LA;
959
20.5k
            else if ( is_fmt && !strcmp(hrec->vals[i],"LR") ) var = BCF_VL_LR;
960
20.5k
            else if ( is_fmt && !strcmp(hrec->vals[i],"LG") ) var = BCF_VL_LG;
961
20.5k
            else if ( is_fmt && !strcmp(hrec->vals[i],"M") )  var = BCF_VL_M;
962
20.5k
            else
963
20.5k
            {
964
20.5k
                if (sscanf(hrec->vals[i],"%d",&num) == 1)
965
20.1k
                    var = BCF_VL_FIXED;
966
20.5k
            }
967
37.6k
            if (var != BCF_VL_FIXED) num = 0xfffff;
968
37.6k
        }
969
183k
    }
970
108k
    if (hrec->type == BCF_HL_INFO || hrec->type == BCF_HL_FMT) {
971
82.7k
        if (type == -1) {
972
57.7k
            hts_log_warning("%s %s field has no Type defined. Assuming String",
973
57.7k
                *hrec->key == 'I' ? "An" : "A", hrec->key);
974
57.7k
            type = BCF_HT_STR;
975
57.7k
        }
976
82.7k
        if (var == UINT32_MAX) {
977
45.5k
            hts_log_warning("%s %s field has no Number defined. Assuming '.'",
978
45.5k
                *hrec->key == 'I' ? "An" : "A", hrec->key);
979
45.5k
            var = BCF_VL_VAR;
980
45.5k
        }
981
82.7k
        if ( type==BCF_HT_FLAG && (var!=BCF_VL_FIXED || num!=0) )
982
16
        {
983
16
            hts_log_warning("The definition of Flag \"%s/%s\" is invalid, forcing Number=0", hrec->key,id);
984
16
            var = BCF_VL_FIXED;
985
16
            num = 0;
986
16
        }
987
82.7k
    }
988
108k
    uint32_t info = ((((uint32_t)num) & 0xfffff)<<12 |
989
108k
                     (var & 0xf) << 8 |
990
108k
                     (type & 0xf) << 4 |
991
108k
                     (((uint32_t) hrec->type) & 0xf));
992
993
108k
    if ( !id ) return 0;
994
51.3k
    id_copy = strdup(id);
995
51.3k
    if (!id_copy) return -1;
996
997
51.3k
    vdict_t *d = (vdict_t*)hdr->dict[BCF_DT_ID];
998
51.3k
    k = kh_get(vdict, d, id_copy);
999
51.3k
    if ( k != kh_end(d) )
1000
7.83k
    {
1001
        // already present
1002
7.83k
        int is_pass = strcmp(id_copy, "PASS")==0;
1003
7.83k
        free(id_copy);
1004
7.83k
        if ( kh_val(d, k).hrec[info&0xf] ) {
1005
            // Handle a duplicate ##FILTER=<ID=PASS,...> is possible as the
1006
            // user is permitted to add one, but we always interject our own
1007
            // after the ##fileformat line.
1008
            //
1009
            // I'm certain hdr->hrec[1] will always be our automatic
1010
            // PASS, but check anyway just incase.
1011
5.28k
            if (is_pass && (info & 0xf) == BCF_HL_FLT &&
1012
0
                hdr->nhrec > 1 && hdr->hrec[1]->type == BCF_HL_FLT) {
1013
0
                if (idx == -1 && hrec_add_idx(hrec, kh_val(d, k).id) < 0) {
1014
0
                    return -1;
1015
0
                }
1016
0
                bcf_hrec_t hrec_pass = *hdr->hrec[1];
1017
0
                *hdr->hrec[1] = *hrec;
1018
0
                *hrec = hrec_pass;
1019
0
            }
1020
5.28k
            return 0;
1021
5.28k
        }
1022
1023
2.54k
        kh_val(d, k).info[info&0xf] = info;
1024
2.54k
        kh_val(d, k).hrec[info&0xf] = hrec;
1025
2.54k
        if ( idx==-1 ) {
1026
2.54k
            if (hrec_add_idx(hrec, kh_val(d, k).id) < 0) {
1027
0
                return -1;
1028
0
            }
1029
2.54k
        }
1030
2.54k
        return 1;
1031
2.54k
    }
1032
43.5k
    k = kh_put(vdict, d, id_copy, &ret);
1033
43.5k
    if (ret < 0) {
1034
0
        free(id_copy);
1035
0
        return -1;
1036
0
    }
1037
43.5k
    kh_val(d, k) = bcf_idinfo_def;
1038
43.5k
    kh_val(d, k).info[info&0xf] = info;
1039
43.5k
    kh_val(d, k).hrec[info&0xf] = hrec;
1040
43.5k
    kh_val(d, k).id = idx;
1041
43.5k
    if (bcf_hdr_set_idx(hdr, BCF_DT_ID, kh_key(d,k), &kh_val(d,k)) < 0) {
1042
4
        kh_del(vdict, d, k);
1043
4
        free(id_copy);
1044
4
        return -1;
1045
4
    }
1046
43.4k
    if ( idx==-1 ) {
1047
43.3k
        if (hrec_add_idx(hrec, kh_val(d,k).id) < 0) {
1048
0
            return -1;
1049
0
        }
1050
43.3k
    }
1051
1052
43.4k
    return 1;
1053
43.4k
}
1054
1055
// returns: 1 when hdr needs to be synced, -1 on error, 0 otherwise
1056
static int bcf_hdr_register_hrec(bcf_hdr_t *hdr, bcf_hrec_t *hrec)
1057
155k
{
1058
155k
    bcf_hrec_set_type(hrec);
1059
1060
155k
    switch (hrec->type) {
1061
7.70k
    case BCF_HL_CTG:
1062
7.70k
        return bcf_hdr_register_hrec_ctg(hdr, hrec);
1063
1064
72.8k
    case BCF_HL_INFO:
1065
98.4k
    case BCF_HL_FLT:
1066
108k
    case BCF_HL_FMT:
1067
108k
        return bcf_hdr_register_hrec_info(hdr, hrec);
1068
1069
4.94k
    case BCF_HL_STR:
1070
4.94k
        return 1;
1071
1072
34.3k
    default:
1073
34.3k
        return 0;
1074
155k
    }
1075
155k
}
1076
1077
static void bcf_hdr_unregister_hrec(bcf_hdr_t *hdr, bcf_hrec_t *hrec)
1078
0
{
1079
0
    if (hrec->type == BCF_HL_FLT ||
1080
0
        hrec->type == BCF_HL_INFO ||
1081
0
        hrec->type == BCF_HL_FMT ||
1082
0
        hrec->type == BCF_HL_CTG) {
1083
0
        int id = bcf_hrec_find_key(hrec, "ID");
1084
0
        if (id < 0 || !hrec->vals[id])
1085
0
            return;
1086
0
        vdict_t *dict = (hrec->type == BCF_HL_CTG
1087
0
                         ? (vdict_t*)hdr->dict[BCF_DT_CTG]
1088
0
                         : (vdict_t*)hdr->dict[BCF_DT_ID]);
1089
0
        khint_t k = kh_get(vdict, dict, hrec->vals[id]);
1090
0
        if (k != kh_end(dict))
1091
0
            kh_val(dict, k).hrec[hrec->type==BCF_HL_CTG ? 0 : hrec->type] = NULL;
1092
0
    }
1093
0
}
1094
1095
static void bcf_hdr_remove_from_hdict(bcf_hdr_t *hdr, bcf_hrec_t *hrec)
1096
0
{
1097
0
    kstring_t str = KS_INITIALIZE;
1098
0
    bcf_hdr_aux_t *aux = get_hdr_aux(hdr);
1099
0
    khint_t k;
1100
0
    int id;
1101
1102
0
    switch (hrec->type) {
1103
0
    case BCF_HL_GEN:
1104
0
        if (ksprintf(&str, "##%s=%s", hrec->key,hrec->value) < 0)
1105
0
            str.l = 0;
1106
0
        break;
1107
0
    case BCF_HL_STR:
1108
0
        id = bcf_hrec_find_key(hrec, "ID");
1109
0
        if (id < 0)
1110
0
            return;
1111
0
        if (!hrec->vals[id] ||
1112
0
            ksprintf(&str, "##%s=<ID=%s>", hrec->key, hrec->vals[id]) < 0)
1113
0
            str.l = 0;
1114
0
        break;
1115
0
    default:
1116
0
        return;
1117
0
    }
1118
0
    if (str.l) {
1119
0
        k = kh_get(hdict, aux->gen, str.s);
1120
0
    } else {
1121
        // Couldn't get a string for some reason, so try the hard way...
1122
0
        for (k = kh_begin(aux->gen); k < kh_end(aux->gen); k++) {
1123
0
            if (kh_exist(aux->gen, k) && kh_val(aux->gen, k) == hrec)
1124
0
                break;
1125
0
        }
1126
0
    }
1127
0
    if (k != kh_end(aux->gen) && kh_val(aux->gen, k) == hrec) {
1128
0
        kh_val(aux->gen, k) = NULL;
1129
0
        free((char *) kh_key(aux->gen, k));
1130
0
        kh_key(aux->gen, k) = NULL;
1131
0
        kh_del(hdict, aux->gen, k);
1132
0
    }
1133
0
    free(str.s);
1134
0
}
1135
1136
int bcf_hdr_update_hrec(bcf_hdr_t *hdr, bcf_hrec_t *hrec, const bcf_hrec_t *tmp)
1137
0
{
1138
0
    assert( hrec->type==BCF_HL_GEN );
1139
0
    int ret;
1140
0
    khint_t k;
1141
0
    bcf_hdr_aux_t *aux = get_hdr_aux(hdr);
1142
0
    for (k=kh_begin(aux->gen); k<kh_end(aux->gen); k++)
1143
0
    {
1144
0
        if ( !kh_exist(aux->gen,k) ) continue;
1145
0
        if ( hrec!=(bcf_hrec_t*)kh_val(aux->gen,k) ) continue;
1146
0
        break;
1147
0
    }
1148
0
    assert( k<kh_end(aux->gen) );   // something went wrong, should never happen
1149
1150
0
    kstring_t str = {0,0,NULL};
1151
0
    char *val = NULL;
1152
1153
0
    if ( ksprintf(&str, "##%s=%s", tmp->key,tmp->value) < 0 )
1154
0
        goto fail;
1155
0
    val = strdup(tmp->value);
1156
0
    if (!val)
1157
0
        goto fail;
1158
1159
    // Remove old entry
1160
0
    free((char*)kh_key(aux->gen,k));
1161
0
    kh_del(hdict,aux->gen,k);
1162
1163
    // Add new one (should succeed as we just cleared out a slot)
1164
0
    k = kh_put(hdict, aux->gen, str.s, &ret);
1165
0
    if ( ret<0 )
1166
0
        goto fail;
1167
1168
    // str.s is now owned by the hash table
1169
0
    free(hrec->value);
1170
0
    hrec->value = val;
1171
0
    kh_val(aux->gen,k) = hrec;
1172
1173
0
    if (!strcmp(hrec->key,"fileformat")) {
1174
        //update version
1175
0
        get_hdr_aux(hdr)->version = bcf_get_version(NULL, hrec->value);
1176
0
    }
1177
0
    return 0;
1178
1179
0
 fail:
1180
0
    ks_free(&str);
1181
0
    free(val);
1182
0
    return -1;
1183
0
}
1184
1185
int bcf_hdr_add_hrec(bcf_hdr_t *hdr, bcf_hrec_t *hrec)
1186
156k
{
1187
156k
    kstring_t str = {0,0,0};
1188
156k
    bcf_hdr_aux_t *aux = get_hdr_aux(hdr);
1189
1190
156k
    int res;
1191
156k
    if ( !hrec ) return 0;
1192
1193
155k
    bcf_hrec_check(hrec);   // todo: check return status and propagate errors up
1194
1195
155k
    res = bcf_hdr_register_hrec(hdr,hrec);
1196
155k
    if (res < 0) return -1;
1197
155k
    if ( !res )
1198
99.4k
    {
1199
        // If one of the hashed field, then it is already present
1200
99.4k
        if ( hrec->type != BCF_HL_GEN )
1201
65.0k
        {
1202
65.0k
            bcf_hrec_destroy(hrec);
1203
65.0k
            return 0;
1204
65.0k
        }
1205
        // Is one of the generic fields and already present?
1206
34.3k
        if ( ksprintf(&str, "##%s=%s", hrec->key,hrec->value) < 0 )
1207
0
        {
1208
0
            free(str.s);
1209
0
            return -1;
1210
0
        }
1211
34.3k
        khint_t k = kh_get(hdict, aux->gen, str.s);
1212
34.3k
        if ( k != kh_end(aux->gen) )
1213
22.3k
        {
1214
            // duplicate record
1215
22.3k
            bcf_hrec_destroy(hrec);
1216
22.3k
            free(str.s);
1217
22.3k
            return 0;
1218
22.3k
        }
1219
12.0k
        if (!strcmp(hrec->key, "fileformat")) {
1220
6.58k
            aux->version = bcf_get_version(NULL, hrec->value);
1221
6.58k
        }
1222
12.0k
    }
1223
1224
68.0k
    int i;
1225
68.0k
    if ( hrec->type==BCF_HL_STR && (i=bcf_hrec_find_key(hrec,"ID"))>=0 )
1226
872
    {
1227
872
        if ( ksprintf(&str, "##%s=<ID=%s>", hrec->key,hrec->vals[i]) < 0 )
1228
0
        {
1229
0
            free(str.s);
1230
0
            return -1;
1231
0
        }
1232
872
        khint_t k = kh_get(hdict, aux->gen, str.s);
1233
872
        if ( k != kh_end(aux->gen) )
1234
682
        {
1235
            // duplicate record
1236
682
            bcf_hrec_destroy(hrec);
1237
682
            free(str.s);
1238
682
            return 0;
1239
682
        }
1240
872
    }
1241
1242
    // New record, needs to be added
1243
67.3k
    int n = hdr->nhrec + 1;
1244
67.3k
    bcf_hrec_t **new_hrec = hts_realloc_p(hdr->hrec, sizeof(bcf_hrec_t*), n);
1245
67.3k
    if (!new_hrec) {
1246
0
        free(str.s);
1247
0
        bcf_hdr_unregister_hrec(hdr, hrec);
1248
0
        return -1;
1249
0
    }
1250
67.3k
    hdr->hrec = new_hrec;
1251
1252
67.3k
    if ( str.s )
1253
12.2k
    {
1254
12.2k
        khint_t k = kh_put(hdict, aux->gen, str.s, &res);
1255
12.2k
        if ( res<0 )
1256
0
        {
1257
0
            free(str.s);
1258
0
            return -1;
1259
0
        }
1260
12.2k
        kh_val(aux->gen,k) = hrec;
1261
12.2k
    }
1262
1263
67.3k
    hdr->hrec[hdr->nhrec] = hrec;
1264
67.3k
    hdr->dirty = 1;
1265
67.3k
    hdr->nhrec = n;
1266
1267
67.3k
    return hrec->type==BCF_HL_GEN ? 0 : 1;
1268
67.3k
}
1269
1270
bcf_hrec_t *bcf_hdr_get_hrec(const bcf_hdr_t *hdr, int type, const char *key, const char *value, const char *str_class)
1271
1.28k
{
1272
1.28k
    int i;
1273
1.28k
    if ( type==BCF_HL_GEN )
1274
1.28k
    {
1275
        // e.g. ##fileformat=VCFv4.2
1276
        //      ##source=GenomicsDBImport
1277
        //      ##bcftools_viewVersion=1.16-80-gdfdb0923+htslib-1.16-34-g215d364
1278
1.28k
        if ( value )
1279
0
        {
1280
0
            kstring_t str = {0,0,0};
1281
0
            ksprintf(&str, "##%s=%s", key,value);
1282
0
            bcf_hdr_aux_t *aux = get_hdr_aux(hdr);
1283
0
            khint_t k = kh_get(hdict, aux->gen, str.s);
1284
0
            free(str.s);
1285
0
            if ( k == kh_end(aux->gen) ) return NULL;
1286
0
            return kh_val(aux->gen, k);
1287
0
        }
1288
2.45k
        for (i=0; i<hdr->nhrec; i++)
1289
1.46k
        {
1290
1.46k
            if ( hdr->hrec[i]->type!=type ) continue;
1291
413
            if ( strcmp(hdr->hrec[i]->key,key) ) continue;
1292
295
            return hdr->hrec[i];
1293
413
        }
1294
992
        return NULL;
1295
1.28k
    }
1296
0
    else if ( type==BCF_HL_STR )
1297
0
    {
1298
        // e.g. ##GATKCommandLine=<ID=GenomicsDBImport,CommandLine="GenomicsDBImport....">
1299
        //      ##ALT=<ID=NON_REF,Description="Represents any possible alternative allele not already represented at this location by REF and ALT">
1300
0
        if (!str_class) return NULL;
1301
0
        if ( !strcmp("ID",key) )
1302
0
        {
1303
0
            kstring_t str = {0,0,0};
1304
0
            ksprintf(&str, "##%s=<%s=%s>",str_class,key,value);
1305
0
            bcf_hdr_aux_t *aux = get_hdr_aux(hdr);
1306
0
            khint_t k = kh_get(hdict, aux->gen, str.s);
1307
0
            free(str.s);
1308
0
            if ( k == kh_end(aux->gen) ) return NULL;
1309
0
            return kh_val(aux->gen, k);
1310
0
        }
1311
0
        for (i=0; i<hdr->nhrec; i++)
1312
0
        {
1313
0
            if ( hdr->hrec[i]->type!=type ) continue;
1314
0
            if ( strcmp(hdr->hrec[i]->key,str_class) ) continue;
1315
0
            int j = bcf_hrec_find_key(hdr->hrec[i],key);
1316
0
            if ( j>=0 && !strcmp(hdr->hrec[i]->vals[j],value) ) return hdr->hrec[i];
1317
0
        }
1318
0
        return NULL;
1319
0
    }
1320
0
    vdict_t *d = type==BCF_HL_CTG ? (vdict_t*)hdr->dict[BCF_DT_CTG] : (vdict_t*)hdr->dict[BCF_DT_ID];
1321
0
    khint_t k = kh_get(vdict, d, value);
1322
0
    if ( k == kh_end(d) ) return NULL;
1323
0
    return kh_val(d, k).hrec[type==BCF_HL_CTG?0:type];
1324
0
}
1325
1326
// Check the VCF header is correctly formatted as per the specification.
1327
// Note the code that calls this doesn't bother to check return values and
1328
// we have so many broken VCFs in the wild that for now we just reprt a
1329
// warning and continue anyway.  So currently this is a void function.
1330
void bcf_hdr_check_sanity(bcf_hdr_t *hdr)
1331
4.49k
{
1332
4.49k
    int version = bcf_get_version(hdr, NULL);
1333
1334
4.49k
    struct tag {
1335
4.49k
        char name[10];
1336
4.49k
        char number_str[3];
1337
4.49k
        int number;
1338
4.49k
        int version;
1339
4.49k
        int type;
1340
4.49k
    };
1341
1342
4.49k
    char type_str[][8] = {"Flag", "Integer", "Float", "String"};
1343
1344
4.49k
    struct tag info_tags[] = {
1345
4.49k
        {"AD",        "R",  BCF_VL_R,     VCF_DEF, BCF_HT_INT},
1346
4.49k
        {"ADF",       "R",  BCF_VL_R,     VCF_DEF, BCF_HT_INT},
1347
4.49k
        {"ADR",       "R",  BCF_VL_R,     VCF_DEF, BCF_HT_INT},
1348
4.49k
        {"AC",        "A",  BCF_VL_A,     VCF_DEF, BCF_HT_INT},
1349
4.49k
        {"AF",        "A",  BCF_VL_A,     VCF_DEF, BCF_HT_REAL},
1350
4.49k
        {"CIGAR",     "A",  BCF_VL_A,     VCF_DEF, BCF_HT_STR},
1351
4.49k
        {"AA",        "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_STR},
1352
4.49k
        {"AN",        "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1353
4.49k
        {"BQ",        "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_REAL},
1354
4.49k
        {"DB",        "0",  BCF_VL_FIXED, VCF_DEF, BCF_HT_FLAG},
1355
4.49k
        {"DP",        "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1356
4.49k
        {"END",       "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1357
4.49k
        {"H2",        "0",  BCF_VL_FIXED, VCF_DEF, BCF_HT_FLAG},
1358
4.49k
        {"H3",        "0",  BCF_VL_FIXED, VCF_DEF, BCF_HT_FLAG},
1359
4.49k
        {"MQ",        "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_REAL},
1360
4.49k
        {"MQ0",       "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1361
4.49k
        {"NS",        "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1362
4.49k
        {"SB",        "4",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1363
4.49k
        {"SOMATIC",   "0",  BCF_VL_FIXED, VCF_DEF, BCF_HT_FLAG},
1364
4.49k
        {"VALIDATED", "0",  BCF_VL_FIXED, VCF_DEF, BCF_HT_FLAG},
1365
4.49k
        {"1000G",     "0",  BCF_VL_FIXED, VCF_DEF, BCF_HT_FLAG},
1366
4.49k
    };
1367
4.49k
    static int info_warned[sizeof(info_tags)/sizeof(*info_tags)] = {0};
1368
1369
4.49k
    struct tag fmt_tags[] = {
1370
4.49k
        {"AD",   "R",  BCF_VL_R,     VCF_DEF, BCF_HT_INT},
1371
4.49k
        {"ADF",  "R",  BCF_VL_R,     VCF_DEF, BCF_HT_INT},
1372
4.49k
        {"ADR",  "R",  BCF_VL_R,     VCF_DEF, BCF_HT_INT},
1373
4.49k
        {"EC",   "A",  BCF_VL_A,     VCF_DEF, BCF_HT_INT},
1374
4.49k
        {"GL",   "G",  BCF_VL_G,     VCF_DEF, BCF_HT_REAL},
1375
4.49k
        {"GP",   "G",  BCF_VL_G,     VCF_DEF, BCF_HT_REAL},
1376
4.49k
        {"PL",   "G",  BCF_VL_G,     VCF_DEF, BCF_HT_INT},
1377
4.49k
        {"PP",   "G",  BCF_VL_G,     VCF_DEF, BCF_HT_INT},
1378
4.49k
        {"DP",   "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1379
4.49k
        {"LEN",  "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1380
4.49k
        {"FT",   "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_STR},
1381
4.49k
        {"GQ",   "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1382
4.49k
        {"GT",   "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_STR},
1383
4.49k
        {"HQ",   "2",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1384
4.49k
        {"MQ",   "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1385
4.49k
        {"PQ",   "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1386
4.49k
        {"PS",   "1",  BCF_VL_FIXED, VCF_DEF, BCF_HT_INT},
1387
4.49k
        {"PSL",  "P",  BCF_VL_P,     VCF44,   BCF_HT_STR},
1388
4.49k
        {"PSO",  "P",  BCF_VL_P,     VCF44,   BCF_HT_INT},
1389
4.49k
        {"PSQ",  "P",  BCF_VL_P,     VCF44,   BCF_HT_INT},
1390
4.49k
        {"LGL",  "LG", BCF_VL_LG,    VCF45,   BCF_HT_INT},
1391
4.49k
        {"LGP",  "LG", BCF_VL_LG,    VCF45,   BCF_HT_INT},
1392
4.49k
        {"LPL",  "LG", BCF_VL_LG,    VCF45,   BCF_HT_INT},
1393
4.49k
        {"LPP",  "LG", BCF_VL_LG,    VCF45,   BCF_HT_INT},
1394
4.49k
        {"LEC",  "LA", BCF_VL_LA,    VCF45,   BCF_HT_INT},
1395
4.49k
        {"LAD",  "LR", BCF_VL_LR,    VCF45,   BCF_HT_INT},
1396
4.49k
        {"LADF", "LR", BCF_VL_LR,    VCF45,   BCF_HT_INT},
1397
4.49k
        {"LADR", "LR", BCF_VL_LR,    VCF45,   BCF_HT_INT},
1398
4.49k
    };
1399
4.49k
    static int fmt_warned[sizeof(fmt_tags)/sizeof(*fmt_tags)] = {0};
1400
1401
    // Check INFO tag numbers.  We shouldn't really permit ".", but it's
1402
    // commonly misused so we let it slide unless it's a new tag and the
1403
    // file format claims to be new also.  We also cannot distinguish between
1404
    // Number=1 and Number=2, but we at least report the correct term if we
1405
    // get, say, Number=G in its place.
1406
    // Also check the types.
1407
4.49k
    int i;
1408
98.9k
    for (i = 0; i < sizeof(info_tags)/sizeof(*info_tags); i++) {
1409
94.4k
        if (info_warned[i])
1410
2.66k
            continue;
1411
91.7k
        int id = bcf_hdr_id2int(hdr, BCF_DT_ID, info_tags[i].name);
1412
91.7k
        if (bcf_hdr_idinfo_exists(hdr, BCF_HL_INFO, id)) {
1413
1
            if (bcf_hdr_id2length(hdr, BCF_HL_INFO, id) != info_tags[i].number &&
1414
1
                bcf_hdr_id2length(hdr, BCF_HL_INFO, id) != BCF_VL_VAR) {
1415
0
                info_warned[i] = 1;
1416
1
            } else if (bcf_hdr_id2length(hdr, BCF_HL_INFO, id) == BCF_VL_FIXED &&
1417
0
                       bcf_hdr_id2number(hdr, BCF_HL_INFO, id) != atoi(info_tags[i].number_str)) {
1418
0
                info_warned[i] = 1;
1419
0
            }
1420
1421
1
            if (info_warned[i]) {
1422
0
                hts_log_warning("%s should be declared as Number=%s",
1423
0
                                info_tags[i].name, info_tags[i].number_str);
1424
0
            }
1425
1426
1
            if (bcf_hdr_id2type(hdr, BCF_HL_INFO, id) != info_tags[i].type) {
1427
1
                hts_log_warning("%s should be declared as Type=%s",
1428
1
                                info_tags[i].name, type_str[info_tags[i].type]);
1429
1
                info_warned[i] = 1;
1430
1
            }
1431
1
        }
1432
91.7k
    }
1433
1434
    // Check FORMAT tag numbers and types.
1435
130k
    for (i = 0; i < sizeof(fmt_tags)/sizeof(*fmt_tags); i++) {
1436
125k
        if (fmt_warned[i])
1437
0
            continue;
1438
125k
        int id = bcf_hdr_id2int(hdr, BCF_DT_ID, fmt_tags[i].name);
1439
125k
        if (bcf_hdr_idinfo_exists(hdr, BCF_HL_FMT, id)) {
1440
0
            if (bcf_hdr_id2length(hdr, BCF_HL_FMT, id) != fmt_tags[i].number) {
1441
                // Permit "Number=." if this tag predates the vcf version it is
1442
                // defined within.  This is a common tactic for callers to use
1443
                // new tags with older formats in order to avoid parsing failures
1444
                // with some software.
1445
                // We don't care for 4.3 and earlier as that's more of a wild-west
1446
                // and it's not abnormal to see incorrect usage of Number=. there.
1447
0
                if ((version < VCF44 &&
1448
0
                     bcf_hdr_id2length(hdr, BCF_HL_FMT, id) != BCF_VL_VAR) ||
1449
0
                    (version >= VCF44 && version >= fmt_tags[i].version)) {
1450
0
                    fmt_warned[i] = 1;
1451
0
                }
1452
0
            } else if (bcf_hdr_id2length(hdr, BCF_HL_FMT, id) == BCF_VL_FIXED &&
1453
0
                       bcf_hdr_id2number(hdr, BCF_HL_FMT, id) != atoi(fmt_tags[i].number_str)) {
1454
0
                fmt_warned[i] = 1;
1455
0
            }
1456
1457
0
            if (fmt_warned[i]) {
1458
0
                hts_log_warning("%s should be declared as Number=%s",
1459
0
                                fmt_tags[i].name, fmt_tags[i].number_str);
1460
0
            }
1461
1462
0
            if (bcf_hdr_id2type(hdr, BCF_HL_FMT, id) != fmt_tags[i].type) {
1463
0
                hts_log_warning("%s should be declared as Type=%s",
1464
0
                                fmt_tags[i].name, type_str[fmt_tags[i].type]);
1465
0
                fmt_warned[i] = 1;
1466
0
            }
1467
0
        }
1468
125k
    }
1469
4.49k
}
1470
1471
int bcf_hdr_parse(bcf_hdr_t *hdr, char *htxt)
1472
6.30k
{
1473
6.30k
    int len, done = 0;
1474
6.30k
    char *p = htxt;
1475
1476
    // Check sanity: "fileformat" string must come as first
1477
6.30k
    bcf_hrec_t *hrec = bcf_hdr_parse_line(hdr,p,&len);
1478
6.30k
    if ( !hrec || !hrec->key || strcasecmp(hrec->key,"fileformat") )
1479
724
        hts_log_warning("The first line should be ##fileformat; is the VCF/BCF header broken?");
1480
6.30k
    if (bcf_hdr_add_hrec(hdr, hrec) < 0) {
1481
0
        bcf_hrec_destroy(hrec);
1482
0
        return -1;
1483
0
    }
1484
1485
    // The filter PASS must appear first in the dictionary
1486
6.30k
    hrec = bcf_hdr_parse_line(hdr,"##FILTER=<ID=PASS,Description=\"All filters passed\">",&len);
1487
6.30k
    if (!hrec || bcf_hdr_add_hrec(hdr, hrec) < 0) {
1488
0
        bcf_hrec_destroy(hrec);
1489
0
        return -1;
1490
0
    }
1491
1492
    // Parse the whole header
1493
70.6k
    do {
1494
169k
        while (NULL != (hrec = bcf_hdr_parse_line(hdr, p, &len))) {
1495
99.2k
            if (bcf_hdr_add_hrec(hdr, hrec) < 0) {
1496
12
                bcf_hrec_destroy(hrec);
1497
12
                return -1;
1498
12
            }
1499
99.2k
            p += len;
1500
99.2k
        }
1501
70.6k
        assert(hrec == NULL);
1502
70.6k
        if (len < 0) {
1503
            // len < 0 indicates out-of-memory, or similar error
1504
0
            hts_log_error("Could not parse header line: %s", strerror(errno));
1505
0
            return -1;
1506
70.6k
        } else if (len > 0) {
1507
            // Bad header line.  bcf_hdr_parse_line() will have logged it.
1508
            // Skip and try again on the next line (p + len will be the start
1509
            // of the next one).
1510
62.9k
            p += len;
1511
62.9k
            continue;
1512
62.9k
        }
1513
1514
        // Next should be the sample line.  If not, it was a malformed
1515
        // header, in which case print a warning and skip (many VCF
1516
        // operations do not really care about a few malformed lines).
1517
        // In the future we may want to add a strict mode that errors in
1518
        // this case.
1519
7.74k
        if ( strncmp("#CHROM\t",p,7) && strncmp("#CHROM ",p,7) ) {
1520
2.92k
            char *eol = strchr(p, '\n');
1521
2.92k
            if (*p != '\0') {
1522
1.55k
                char buffer[320];
1523
1.55k
                hts_log_warning("Could not parse header line: %s",
1524
1.55k
                                hts_strprint(buffer, sizeof(buffer),
1525
1.55k
                                               '"', p,
1526
1.55k
                                               eol ? (eol - p) : SIZE_MAX));
1527
1.55k
            }
1528
2.92k
            if (eol) {
1529
1.45k
                p = eol + 1; // Try from the next line.
1530
1.47k
            } else {
1531
1.47k
                done = -1; // No more lines left, give up.
1532
1.47k
            }
1533
4.81k
        } else {
1534
4.81k
            done = 1; // Sample line found
1535
4.81k
        }
1536
70.6k
    } while (!done);
1537
1538
6.29k
    if (done < 0) {
1539
        // No sample line is fatal.
1540
1.47k
        hts_log_error("Could not parse the header, sample line not found");
1541
1.47k
        return -1;
1542
1.47k
    }
1543
1544
4.81k
    if (bcf_hdr_parse_sample_line(hdr,p) < 0)
1545
318
        return -1;
1546
4.49k
    if (bcf_hdr_sync(hdr) < 0)
1547
0
        return -1;
1548
4.49k
    bcf_hdr_check_sanity(hdr);
1549
4.49k
    return 0;
1550
4.49k
}
1551
1552
int bcf_hdr_append(bcf_hdr_t *hdr, const char *line)
1553
0
{
1554
0
    int len;
1555
0
    bcf_hrec_t *hrec = bcf_hdr_parse_line(hdr, (char*) line, &len);
1556
0
    if ( !hrec ) return -1;
1557
0
    if (bcf_hdr_add_hrec(hdr, hrec) < 0)
1558
0
        return -1;
1559
0
    return 0;
1560
0
}
1561
1562
void bcf_hdr_remove(bcf_hdr_t *hdr, int type, const char *key)
1563
0
{
1564
0
    int i = 0;
1565
0
    bcf_hrec_t *hrec;
1566
0
    if ( !key )
1567
0
    {
1568
        // no key, remove all entries of this type
1569
0
        while ( i<hdr->nhrec )
1570
0
        {
1571
0
            if ( hdr->hrec[i]->type!=type ) { i++; continue; }
1572
0
            hrec = hdr->hrec[i];
1573
0
            bcf_hdr_unregister_hrec(hdr, hrec);
1574
0
            bcf_hdr_remove_from_hdict(hdr, hrec);
1575
0
            hdr->dirty = 1;
1576
0
            hdr->nhrec--;
1577
0
            if ( i < hdr->nhrec )
1578
0
                memmove(&hdr->hrec[i],&hdr->hrec[i+1],(hdr->nhrec-i)*sizeof(bcf_hrec_t*));
1579
0
            bcf_hrec_destroy(hrec);
1580
0
        }
1581
0
        return;
1582
0
    }
1583
0
    while (1)
1584
0
    {
1585
0
        if ( type==BCF_HL_FLT || type==BCF_HL_INFO || type==BCF_HL_FMT || type== BCF_HL_CTG )
1586
0
        {
1587
0
            hrec = bcf_hdr_get_hrec(hdr, type, "ID", key, NULL);
1588
0
            if ( !hrec ) return;
1589
1590
0
            for (i=0; i<hdr->nhrec; i++)
1591
0
                if ( hdr->hrec[i]==hrec ) break;
1592
0
            assert( i<hdr->nhrec );
1593
1594
0
            vdict_t *d = type==BCF_HL_CTG ? (vdict_t*)hdr->dict[BCF_DT_CTG] : (vdict_t*)hdr->dict[BCF_DT_ID];
1595
0
            khint_t k = kh_get(vdict, d, key);
1596
0
            kh_val(d, k).hrec[type==BCF_HL_CTG?0:type] = NULL;
1597
0
        }
1598
0
        else
1599
0
        {
1600
0
            for (i=0; i<hdr->nhrec; i++)
1601
0
            {
1602
0
                if ( hdr->hrec[i]->type!=type ) continue;
1603
0
                if ( type==BCF_HL_GEN )
1604
0
                {
1605
0
                    if ( !strcmp(hdr->hrec[i]->key,key) ) break;
1606
0
                }
1607
0
                else
1608
0
                {
1609
                    // not all structured lines have ID, we could be more sophisticated as in bcf_hdr_get_hrec()
1610
0
                    int j = bcf_hrec_find_key(hdr->hrec[i], "ID");
1611
0
                    if ( j>=0 && !strcmp(hdr->hrec[i]->vals[j],key) ) break;
1612
0
                }
1613
0
            }
1614
0
            if ( i==hdr->nhrec ) return;
1615
0
            hrec = hdr->hrec[i];
1616
0
            bcf_hdr_remove_from_hdict(hdr, hrec);
1617
0
        }
1618
1619
0
        hdr->nhrec--;
1620
0
        if ( i < hdr->nhrec )
1621
0
            memmove(&hdr->hrec[i],&hdr->hrec[i+1],(hdr->nhrec-i)*sizeof(bcf_hrec_t*));
1622
0
        bcf_hrec_destroy(hrec);
1623
0
        hdr->dirty = 1;
1624
0
    }
1625
0
}
1626
1627
int bcf_hdr_printf(bcf_hdr_t *hdr, const char *fmt, ...)
1628
0
{
1629
0
    char tmp[256], *line = tmp;
1630
0
    va_list ap;
1631
0
    va_start(ap, fmt);
1632
0
    int n = vsnprintf(line, sizeof(tmp), fmt, ap);
1633
0
    va_end(ap);
1634
1635
0
    if (n >= sizeof(tmp)) {
1636
0
        n++; // For trailing NUL
1637
0
        line = (char*)malloc(n);
1638
0
        if (!line)
1639
0
            return -1;
1640
1641
0
        va_start(ap, fmt);
1642
0
        vsnprintf(line, n, fmt, ap);
1643
0
        va_end(ap);
1644
0
    }
1645
1646
0
    int ret = bcf_hdr_append(hdr, line);
1647
1648
0
    if (line != tmp) free(line);
1649
0
    return ret;
1650
0
}
1651
1652
1653
/**********************
1654
 *** BCF header I/O ***
1655
 **********************/
1656
1657
const char *bcf_hdr_get_version(const bcf_hdr_t *hdr)
1658
1.28k
{
1659
1.28k
    bcf_hrec_t *hrec = bcf_hdr_get_hrec(hdr, BCF_HL_GEN, "fileformat", NULL, NULL);
1660
1.28k
    if ( !hrec )
1661
992
    {
1662
992
        hts_log_warning("No version string found, assuming VCFv4.2");
1663
992
        return "VCFv4.2";
1664
992
    }
1665
295
    return hrec->value;
1666
1.28k
}
1667
1668
int bcf_hdr_set_version(bcf_hdr_t *hdr, const char *version)
1669
0
{
1670
0
    bcf_hrec_t *hrec = bcf_hdr_get_hrec(hdr, BCF_HL_GEN, "fileformat", NULL, NULL);
1671
0
    if ( !hrec )
1672
0
    {
1673
0
        int len;
1674
0
        kstring_t str = {0,0,0};
1675
0
        if ( ksprintf(&str,"##fileformat=%s", version) < 0 ) return -1;
1676
0
        hrec = bcf_hdr_parse_line(hdr, str.s, &len);
1677
0
        free(str.s);
1678
0
        if (!hrec)
1679
0
            return -1;
1680
1681
0
        get_hdr_aux(hdr)->version = bcf_get_version(NULL, hrec->value);
1682
0
    }
1683
0
    else
1684
0
    {
1685
0
        bcf_hrec_t *tmp = bcf_hrec_dup(hrec);
1686
0
        if ( !tmp ) return -1;
1687
0
        free(tmp->value);
1688
0
        tmp->value = strdup(version);
1689
0
        if ( !tmp->value ) return -1;
1690
0
        bcf_hdr_update_hrec(hdr, hrec, tmp);
1691
0
        bcf_hrec_destroy(tmp);
1692
0
    }
1693
0
    hdr->dirty = 1;
1694
    //TODO rlen may change, deal with it
1695
0
    return 0;
1696
0
}
1697
1698
bcf_hdr_t *bcf_hdr_init(const char *mode)
1699
6.43k
{
1700
6.43k
    int i;
1701
6.43k
    bcf_hdr_t *h;
1702
6.43k
    h = (bcf_hdr_t*)calloc(1, sizeof(bcf_hdr_t));
1703
6.43k
    if (!h) return NULL;
1704
25.7k
    for (i = 0; i < 3; ++i) {
1705
19.3k
        if ((h->dict[i] = kh_init(vdict)) == NULL) goto fail;
1706
        // Supersize the hash to make collisions very unlikely
1707
19.3k
        static int dsize[3] = {16384,16384,2048}; // info, contig, format
1708
19.3k
        if (kh_resize(vdict, h->dict[i], dsize[i]) < 0) goto fail;
1709
19.3k
    }
1710
1711
6.43k
    bcf_hdr_aux_t *aux = (bcf_hdr_aux_t*)calloc(1,sizeof(bcf_hdr_aux_t));
1712
6.43k
    if ( !aux ) goto fail;
1713
6.43k
    if ( (aux->gen = kh_init(hdict))==NULL ) { free(aux); goto fail; }
1714
6.43k
    aux->key_len = NULL;
1715
6.43k
    aux->dict = *((vdict_t*)h->dict[0]);
1716
6.43k
    aux->version = 0;
1717
6.43k
    aux->ref_count = 1;
1718
6.43k
    free(h->dict[0]);
1719
6.43k
    h->dict[0] = aux;
1720
1721
6.43k
    if ( strchr(mode,'w') )
1722
0
    {
1723
0
        bcf_hdr_append(h, "##fileformat=VCFv4.2");
1724
        // The filter PASS must appear first in the dictionary
1725
0
        bcf_hdr_append(h, "##FILTER=<ID=PASS,Description=\"All filters passed\">");
1726
0
        aux->version = VCF_DEF;
1727
0
    }
1728
6.43k
    return h;
1729
1730
0
 fail:
1731
0
    for (i = 0; i < 3; ++i)
1732
0
        kh_destroy(vdict, h->dict[i]);
1733
0
    free(h);
1734
0
    return NULL;
1735
6.43k
}
1736
1737
void bcf_hdr_destroy(bcf_hdr_t *h)
1738
8.95k
{
1739
8.95k
    int i;
1740
8.95k
    khint_t k;
1741
8.95k
    if (!h) return;
1742
8.95k
    bcf_hdr_aux_t *aux = get_hdr_aux(h);
1743
8.95k
    if (aux->ref_count > 1) // Refs still held, so delay destruction
1744
2.51k
    {
1745
2.51k
        aux->ref_count &= ~1;
1746
2.51k
        return;
1747
2.51k
    }
1748
25.7k
    for (i = 0; i < 3; ++i) {
1749
19.3k
        vdict_t *d = (vdict_t*)h->dict[i];
1750
19.3k
        if (d == 0) continue;
1751
224M
        for (k = kh_begin(d); k != kh_end(d); ++k)
1752
224M
            if (kh_exist(d, k)) free((char*)kh_key(d, k));
1753
19.3k
        if ( i==0 )
1754
6.43k
        {
1755
37.6k
            for (k=kh_begin(aux->gen); k<kh_end(aux->gen); k++)
1756
31.2k
                if ( kh_exist(aux->gen,k) ) free((char*)kh_key(aux->gen,k));
1757
6.43k
            kh_destroy(hdict, aux->gen);
1758
6.43k
            free(aux->key_len); // may exist for dict[0] only
1759
6.43k
        }
1760
19.3k
        kh_destroy(vdict, d);
1761
19.3k
        free(h->id[i]);
1762
19.3k
    }
1763
73.8k
    for (i=0; i<h->nhrec; i++)
1764
67.3k
        bcf_hrec_destroy(h->hrec[i]);
1765
6.43k
    if (h->nhrec) free(h->hrec);
1766
6.43k
    if (h->samples) free(h->samples);
1767
6.43k
    free(h->keep_samples);
1768
6.43k
    free(h->transl[0]); free(h->transl[1]);
1769
6.43k
    free(h->mem.s);
1770
6.43k
    free(h);
1771
6.43k
}
1772
1773
bcf_hdr_t *bcf_hdr_read(htsFile *hfp)
1774
6.43k
{
1775
6.43k
    if (hfp->format.format == vcf)
1776
5.62k
        return vcf_hdr_read(hfp);
1777
812
    if (hfp->format.format != bcf) {
1778
0
        hts_log_error("Input is not detected as bcf or vcf format");
1779
0
        return NULL;
1780
0
    }
1781
1782
812
    assert(hfp->is_bgzf);
1783
1784
812
    BGZF *fp = hfp->fp.bgzf;
1785
812
    uint8_t magic[5];
1786
812
    bcf_hdr_t *h;
1787
812
    h = bcf_hdr_init("r");
1788
812
    if (!h) {
1789
0
        hts_log_error("Failed to allocate bcf header");
1790
0
        return NULL;
1791
0
    }
1792
812
    if (bgzf_read(fp, magic, 5) != 5)
1793
8
    {
1794
8
        hts_log_error("Failed to read the header (reading BCF in text mode?)");
1795
8
        bcf_hdr_destroy(h);
1796
8
        return NULL;
1797
8
    }
1798
804
    if (strncmp((char*)magic, "BCF\2\2", 5) != 0)
1799
10
    {
1800
10
        if (!strncmp((char*)magic, "BCF", 3))
1801
10
            hts_log_error("Invalid BCF2 magic string: only BCFv2.2 is supported");
1802
0
        else
1803
0
            hts_log_error("Invalid BCF2 magic string");
1804
10
        bcf_hdr_destroy(h);
1805
10
        return NULL;
1806
10
    }
1807
794
    uint8_t buf[4];
1808
794
    size_t hlen;
1809
794
    char *htxt = NULL;
1810
794
    if (bgzf_read(fp, buf, 4) != 4) goto fail;
1811
790
    hlen = buf[0] | (buf[1] << 8) | (buf[2] << 16) | ((size_t) buf[3] << 24);
1812
790
    if (hlen >= SIZE_MAX) { errno = ENOMEM; goto fail; }
1813
790
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1814
790
    if (hlen > FUZZ_ALLOC_LIMIT/2) { errno = ENOMEM; goto fail; }
1815
786
#endif
1816
786
    htxt = (char*)malloc(hlen + 1);
1817
786
    if (!htxt) goto fail;
1818
786
    if (bgzf_read(fp, htxt, hlen) != hlen) goto fail;
1819
724
    htxt[hlen] = '\0'; // Ensure htxt is terminated
1820
724
    if ( bcf_hdr_parse(h, htxt) < 0 ) goto fail;
1821
530
    free(htxt);
1822
1823
530
    bcf_hdr_incr_ref(h);
1824
530
    bgzf_set_private_data(fp, h, hdr_bgzf_private_data_cleanup);
1825
1826
530
    return h;
1827
264
 fail:
1828
264
    hts_log_error("Failed to read BCF header");
1829
264
    free(htxt);
1830
264
    bcf_hdr_destroy(h);
1831
264
    return NULL;
1832
724
}
1833
1834
int bcf_hdr_write(htsFile *hfp, bcf_hdr_t *h)
1835
4.49k
{
1836
4.49k
    if (!h) {
1837
0
        errno = EINVAL;
1838
0
        return -1;
1839
0
    }
1840
4.49k
    if ( h->dirty ) {
1841
0
        if (bcf_hdr_sync(h) < 0) return -1;
1842
0
    }
1843
4.49k
    hfp->format.category = variant_data;
1844
4.49k
    if (hfp->format.format == vcf || hfp->format.format == text_format) {
1845
2.24k
        hfp->format.format = vcf;
1846
2.24k
        return vcf_hdr_write(hfp, h);
1847
2.24k
    }
1848
1849
2.24k
    if (hfp->format.format == binary_format)
1850
2.24k
        hfp->format.format = bcf;
1851
1852
2.24k
    kstring_t htxt = {0,0,0};
1853
2.24k
    if (bcf_hdr_format(h, 1, &htxt) < 0) {
1854
0
        free(htxt.s);
1855
0
        return -1;
1856
0
    }
1857
2.24k
    kputc('\0', &htxt); // include the \0 byte
1858
1859
2.24k
    BGZF *fp = hfp->fp.bgzf;
1860
2.24k
    if ( bgzf_write(fp, "BCF\2\2", 5) !=5 ) return -1;
1861
2.24k
    uint8_t hlen[4];
1862
2.24k
    u32_to_le(htxt.l, hlen);
1863
2.24k
    if ( bgzf_write(fp, hlen, 4) !=4 ) return -1;
1864
2.24k
    if ( bgzf_write(fp, htxt.s, htxt.l) != htxt.l ) return -1;
1865
2.24k
    if ( bgzf_flush(fp) < 0) return -1;
1866
1867
2.24k
    bcf_hdr_incr_ref(h);
1868
2.24k
    bgzf_set_private_data(fp, h, hdr_bgzf_private_data_cleanup);
1869
1870
2.24k
    free(htxt.s);
1871
2.24k
    return 0;
1872
2.24k
}
1873
1874
/********************
1875
 *** BCF site I/O ***
1876
 ********************/
1877
1878
bcf1_t *bcf_init(void)
1879
4.49k
{
1880
4.49k
    bcf1_t *v;
1881
4.49k
    v = (bcf1_t*)calloc(1, sizeof(bcf1_t));
1882
4.49k
    return v;
1883
4.49k
}
1884
1885
void bcf_clear(bcf1_t *v)
1886
65.6k
{
1887
65.6k
    int i;
1888
65.6k
    for (i=0; i<v->d.m_info; i++)
1889
0
    {
1890
0
        if ( v->d.info[i].vptr_free )
1891
0
        {
1892
0
            free(v->d.info[i].vptr - v->d.info[i].vptr_off);
1893
0
            v->d.info[i].vptr_free = 0;
1894
0
        }
1895
0
    }
1896
65.6k
    for (i=0; i<v->d.m_fmt; i++)
1897
0
    {
1898
0
        if ( v->d.fmt[i].p_free )
1899
0
        {
1900
0
            free(v->d.fmt[i].p - v->d.fmt[i].p_off);
1901
0
            v->d.fmt[i].p_free = 0;
1902
0
        }
1903
0
    }
1904
65.6k
    v->rid = v->pos = v->rlen = v->unpacked = 0;
1905
65.6k
    bcf_float_set_missing(v->qual);
1906
65.6k
    v->n_info = v->n_allele = v->n_fmt = v->n_sample = 0;
1907
65.6k
    v->shared.l = v->indiv.l = 0;
1908
65.6k
    v->d.var_type = -1;
1909
65.6k
    v->d.shared_dirty = 0;
1910
65.6k
    v->d.indiv_dirty  = 0;
1911
65.6k
    v->d.n_flt = 0;
1912
65.6k
    v->errcode = 0;
1913
65.6k
    if (v->d.m_als) v->d.als[0] = 0;
1914
65.6k
    if (v->d.m_id) v->d.id[0] = 0;
1915
65.6k
}
1916
1917
void bcf_empty(bcf1_t *v)
1918
4.49k
{
1919
4.49k
    bcf_clear1(v);
1920
4.49k
    free(v->d.id);
1921
4.49k
    free(v->d.als);
1922
4.49k
    free(v->d.allele); free(v->d.flt); free(v->d.info); free(v->d.fmt);
1923
4.49k
    if (v->d.var ) free(v->d.var);
1924
4.49k
    free(v->shared.s); free(v->indiv.s);
1925
4.49k
    memset(&v->d,0,sizeof(v->d));
1926
4.49k
    memset(&v->shared,0,sizeof(v->shared));
1927
4.49k
    memset(&v->indiv,0,sizeof(v->indiv));
1928
4.49k
}
1929
1930
void bcf_destroy(bcf1_t *v)
1931
4.49k
{
1932
4.49k
    if (!v) return;
1933
4.49k
    bcf_empty1(v);
1934
4.49k
    free(v);
1935
4.49k
}
1936
1937
static inline int bcf_read1_core(BGZF *fp, bcf1_t *v)
1938
540
{
1939
540
    uint8_t x[32];
1940
540
    ssize_t ret;
1941
540
    uint32_t shared_len, indiv_len;
1942
540
    if ((ret = bgzf_read(fp, x, 32)) != 32) {
1943
18
        if (ret == 0) return -1;
1944
10
        return -2;
1945
18
    }
1946
522
    bcf_clear1(v);
1947
522
    shared_len = le_to_u32(x);
1948
522
    if (shared_len < 24) return -2;
1949
520
    shared_len -= 24; // to exclude six 32-bit integers
1950
520
    indiv_len = le_to_u32(x + 4);
1951
520
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1952
    // ks_resize() normally allocates 1.5 * requested size to allow for growth
1953
520
    if ((uint64_t) shared_len + indiv_len > FUZZ_ALLOC_LIMIT / 3 * 2) return -2;
1954
504
#endif
1955
504
    if (ks_resize(&v->shared, shared_len ? shared_len : 1) != 0) return -2;
1956
504
    if (ks_resize(&v->indiv, indiv_len ? indiv_len : 1) != 0) return -2;
1957
504
    v->rid  = le_to_i32(x + 8);
1958
504
    v->pos  = le_to_u32(x + 12);
1959
504
    if ( v->pos==UINT32_MAX ) v->pos = -1;  // this is for telomere coordinate, e.g. MT:0
1960
504
    v->rlen = le_to_i32(x + 16);
1961
504
    v->qual = le_to_float(x + 20);
1962
504
    v->n_info = le_to_u16(x + 24);
1963
504
    v->n_allele = le_to_u16(x + 26);
1964
504
    v->n_sample = le_to_u32(x + 28) & 0xffffff;
1965
504
    v->n_fmt = x[31];
1966
504
    v->shared.l = shared_len;
1967
504
    v->indiv.l = indiv_len;
1968
    // silent fix of broken BCFs produced by earlier versions of bcf_subset, prior to and including bd6ed8b4
1969
504
    if ( (!v->indiv.l || !v->n_sample) && v->n_fmt ) v->n_fmt = 0;
1970
1971
504
    if (bgzf_read(fp, v->shared.s, v->shared.l) != v->shared.l) return -2;
1972
470
    if (bgzf_read(fp, v->indiv.s, v->indiv.l) != v->indiv.l) return -2;
1973
462
    return 0;
1974
470
}
1975
1976
0
#define bit_array_size(n) ((n)/8+1)
1977
0
#define bit_array_set(a,i)   ((a)[(i)/8] |=   1 << ((i)%8))
1978
0
#define bit_array_clear(a,i) ((a)[(i)/8] &= ~(1 << ((i)%8)))
1979
0
#define bit_array_test(a,i)  ((a)[(i)/8] &   (1 << ((i)%8)))
1980
1981
static int bcf_dec_typed_int1_safe(uint8_t *p, uint8_t *end, uint8_t **q,
1982
7.42k
                                   int32_t *val) {
1983
7.42k
    uint32_t t;
1984
7.42k
    if (end - p < 2) return -1;
1985
7.39k
    t = *p++ & 0xf;
1986
    /* Use if .. else if ... else instead of switch to force order.  Assumption
1987
       is that small integers are more frequent than big ones. */
1988
7.39k
    if (t == BCF_BT_INT8) {
1989
2.89k
        *val = *(int8_t *) p++;
1990
4.50k
    } else {
1991
4.50k
        if (end - p < (1<<bcf_type_shift[t])) return -1;
1992
4.47k
        if (t == BCF_BT_INT16) {
1993
2.98k
            *val = le_to_i16(p);
1994
2.98k
            p += 2;
1995
2.98k
        } else if (t == BCF_BT_INT32) {
1996
1.31k
            *val = le_to_i32(p);
1997
1.31k
            p += 4;
1998
#ifdef VCF_ALLOW_INT64
1999
        } else if (t == BCF_BT_INT64) {
2000
            // This case should never happen because there should be no
2001
            // 64-bit BCFs at all, definitely not coming from htslib
2002
            *val = le_to_i64(p);
2003
            p += 8;
2004
#endif
2005
1.31k
        } else {
2006
168
            return -1;
2007
168
        }
2008
4.47k
    }
2009
7.20k
    *q = p;
2010
7.20k
    return 0;
2011
7.39k
}
2012
2013
static int bcf_dec_size_safe(uint8_t *p, uint8_t *end, uint8_t **q,
2014
18.8k
                             int *num, int *type) {
2015
18.8k
    int r;
2016
18.8k
    if (p >= end) return -1;
2017
18.7k
    *type = *p & 0xf;
2018
18.7k
    if (*p>>4 != 15) {
2019
18.2k
        *q = p + 1;
2020
18.2k
        *num = *p >> 4;
2021
18.2k
        return 0;
2022
18.2k
    }
2023
542
    r = bcf_dec_typed_int1_safe(p + 1, end, q, num);
2024
542
    if (r) return r;
2025
460
    return *num >= 0 ? 0 : -1;
2026
542
}
2027
2028
692
static const char *get_type_name(int type) {
2029
692
    const char *types[9] = {
2030
692
        "null", "int (8-bit)", "int (16 bit)", "int (32 bit)",
2031
692
        "unknown", "float", "unknown", "char", "unknown"
2032
692
    };
2033
692
    int t = (type >= 0 && type < 8) ? type : 8;
2034
692
    return types[t];
2035
692
}
2036
2037
/**
2038
 *  updatephasing - updates 1st phasing based on other phasing status
2039
 *  @param p - pointer to phase value array
2040
 *  @param end - end of array
2041
 *  @param q - pointer to consumed data
2042
 *  @param samples - no. of samples in array
2043
 *  @param ploidy - no. of phasing values per sample
2044
 *  @param type - value type (one of BCF_BT_...)
2045
 *  Returns 0 on success and 1 on failure
2046
 *  Update for haploids made only if it is not unknown (.)
2047
 */
2048
static int updatephasing(uint8_t *p, uint8_t *end, uint8_t **q, int samples, int ploidy, int type)
2049
0
{
2050
0
    int j, k;
2051
0
    unsigned int inc = 1 << bcf_type_shift[type];
2052
0
    ptrdiff_t bytes = samples * ploidy * inc;
2053
2054
0
    if (samples < 0 || ploidy < 0 || end - p < bytes)
2055
0
        return 1;
2056
2057
    /*
2058
     * This works because phasing is stored in the least-significant bit
2059
     * of the GT encoding, and the data is always stored little-endian.
2060
     * Thus it's possible to get the desired result by doing bit operations
2061
     * on the least-significant byte of each value and ignoring the
2062
     * higher bytes (for 16-bit and 32-bit values).
2063
     */
2064
2065
0
    switch (ploidy) {
2066
0
    case 1:
2067
        // Trivial case - haploid data is phased by default
2068
0
        for (j = 0; j < samples; ++j) {
2069
0
            if (*p) *p |= 1;    //only if not unknown (.)
2070
0
            p += inc;
2071
0
        }
2072
0
        break;
2073
0
    case 2:
2074
        // Mostly trivial case - first is phased if second is.
2075
0
        for (j = 0; j < samples; ++j) {
2076
0
            *p |= (p[inc] & 1);
2077
0
            p += 2 * inc;
2078
0
        }
2079
0
        break;
2080
0
    default:
2081
        // Generic case - first is phased if all other alleles are.
2082
0
        for (j = 0; j < samples; ++j) {
2083
0
            uint8_t allphased = 1;
2084
0
            for (k = 1; k < ploidy; ++k)
2085
0
                allphased &= (p[inc * k]);
2086
0
            *p |= allphased;
2087
0
            p += ploidy * inc;
2088
0
        }
2089
0
    }
2090
0
    *q = p;
2091
0
    return 0;
2092
0
}
2093
2094
static void bcf_record_check_err(const bcf_hdr_t *hdr, bcf1_t *rec,
2095
4.28k
                                 char *type, uint32_t *reports, int i) {
2096
4.28k
    if (*reports == 0 || hts_verbose >= HTS_LOG_DEBUG)
2097
120
        hts_log_warning("Bad BCF record at %s:%"PRIhts_pos
2098
4.28k
                        ": Invalid FORMAT %s %d",
2099
4.28k
                        bcf_seqname_safe(hdr,rec), rec->pos+1, type, i);
2100
4.28k
    (*reports)++;
2101
4.28k
}
2102
2103
462
static int bcf_record_check(const bcf_hdr_t *hdr, bcf1_t *rec) {
2104
462
    uint8_t *ptr, *end;
2105
462
    size_t bytes;
2106
462
    uint32_t err = 0;
2107
462
    int type = 0;
2108
462
    int num  = 0;
2109
462
    uint32_t i, reports;
2110
462
    const uint32_t is_integer = ((1 << BCF_BT_INT8)  |
2111
462
                                 (1 << BCF_BT_INT16) |
2112
#ifdef VCF_ALLOW_INT64
2113
                                 (1 << BCF_BT_INT64) |
2114
#endif
2115
462
                                 (1 << BCF_BT_INT32));
2116
462
    const uint32_t is_valid_type = (is_integer          |
2117
462
                                    (1 << BCF_BT_NULL)  |
2118
462
                                    (1 << BCF_BT_FLOAT) |
2119
462
                                    (1 << BCF_BT_CHAR));
2120
462
    int32_t max_id = hdr ? hdr->n[BCF_DT_ID] : 0;
2121
    /* set phasing for 1st allele as in v44 for versions upto v43, to have
2122
    consistent binary values irrespective of version; not run for v >= v44,
2123
    to retain explicit phasing in v44 and higher */
2124
462
    int idgt = hdr ?
2125
462
                    bcf_get_version(hdr, NULL) < VCF44 ?
2126
462
                        bcf_hdr_id2int(hdr, BCF_DT_ID, "GT") : -1 :
2127
462
                    -1;
2128
2129
    // Check for valid contig ID
2130
462
    if (rec->rid < 0
2131
328
        || (hdr && (rec->rid >= hdr->n[BCF_DT_CTG]
2132
436
                    || hdr->id[BCF_DT_CTG][rec->rid].key == NULL))) {
2133
436
        hts_log_warning("Bad BCF record at %"PRIhts_pos": Invalid %s id %d", rec->pos+1, "CONTIG", rec->rid);
2134
436
        err |= BCF_ERR_CTG_INVALID;
2135
436
    }
2136
2137
    // Check ID
2138
462
    ptr = (uint8_t *) rec->shared.s;
2139
462
    end = ptr + rec->shared.l;
2140
462
    if (bcf_dec_size_safe(ptr, end, &ptr, &num, &type) != 0) goto bad_shared;
2141
448
    if (type != BCF_BT_CHAR) {
2142
408
        hts_log_warning("Bad BCF record at %s:%"PRIhts_pos": Invalid %s type %d (%s)", bcf_seqname_safe(hdr,rec), rec->pos+1, "ID", type, get_type_name(type));
2143
408
        err |= BCF_ERR_TAG_INVALID;
2144
408
    }
2145
448
    bytes = (size_t) num << bcf_type_shift[type];
2146
448
    if (end - ptr < bytes) goto bad_shared;
2147
432
    ptr += bytes;
2148
2149
    // Check REF and ALT
2150
432
    if (rec->n_allele < 1) {
2151
238
        hts_log_warning("Bad BCF record at %s:%"PRIhts_pos": No REF allele",
2152
238
                        bcf_seqname_safe(hdr,rec), rec->pos+1);
2153
238
        err |= BCF_ERR_TAG_UNDEF;
2154
238
    }
2155
2156
432
    reports = 0;
2157
11.6k
    for (i = 0; i < rec->n_allele; i++) {
2158
11.2k
        if (bcf_dec_size_safe(ptr, end, &ptr, &num, &type) != 0) goto bad_shared;
2159
11.2k
        if (type != BCF_BT_CHAR) {
2160
10.8k
            if (!reports++ || hts_verbose >= HTS_LOG_DEBUG)
2161
162
                hts_log_warning("Bad BCF record at %s:%"PRIhts_pos": Invalid %s type %d (%s)", bcf_seqname_safe(hdr,rec), rec->pos+1, "REF/ALT", type, get_type_name(type));
2162
10.8k
            err |= BCF_ERR_CHAR;
2163
10.8k
        }
2164
11.2k
        bytes = (size_t) num << bcf_type_shift[type];
2165
11.2k
        if (end - ptr < bytes) goto bad_shared;
2166
11.1k
        ptr += bytes;
2167
11.1k
    }
2168
2169
    // Check FILTER
2170
346
    reports = 0;
2171
346
    if (bcf_dec_size_safe(ptr, end, &ptr, &num, &type) != 0) goto bad_shared;
2172
332
    if (num > 0) {
2173
194
        bytes = (size_t) num << bcf_type_shift[type];
2174
194
        if (((1 << type) & is_integer) == 0) {
2175
104
            hts_log_warning("Bad BCF record at %s:%"PRIhts_pos": Invalid %s type %d (%s)", bcf_seqname_safe(hdr,rec), rec->pos+1, "FILTER", type, get_type_name(type));
2176
104
            err |= BCF_ERR_TAG_INVALID;
2177
104
            if (end - ptr < bytes) goto bad_shared;
2178
94
            ptr += bytes;
2179
94
        } else {
2180
90
            if (end - ptr < bytes) goto bad_shared;
2181
2.75k
            for (i = 0; i < num; i++) {
2182
2.66k
                int32_t key = bcf_dec_int1(ptr, type, &ptr);
2183
2.66k
                if (key < 0
2184
2.08k
                    || (hdr && (key >= max_id
2185
1.70k
                                || hdr->id[BCF_DT_ID][key].key == NULL))) {
2186
1.70k
                    if (!reports++ || hts_verbose >= HTS_LOG_DEBUG)
2187
84
                        hts_log_warning("Bad BCF record at %s:%"PRIhts_pos": Invalid %s id %d", bcf_seqname_safe(hdr,rec), rec->pos+1, "FILTER", key);
2188
1.70k
                    err |= BCF_ERR_TAG_UNDEF;
2189
1.70k
                }
2190
2.66k
            }
2191
84
        }
2192
194
    }
2193
2194
    // Check INFO
2195
316
    reports = 0;
2196
316
    bcf_idpair_t *id_tmp = hdr ? hdr->id[BCF_DT_ID] : NULL;
2197
2.93k
    for (i = 0; i < rec->n_info; i++) {
2198
2.77k
        int32_t key = -1;
2199
2.77k
        if (bcf_dec_typed_int1_safe(ptr, end, &ptr, &key) != 0) goto bad_shared;
2200
2.67k
        if (key < 0 || (hdr && (key >= max_id
2201
2.63k
                                || id_tmp[key].key == NULL))) {
2202
2.63k
            if (!reports++ || hts_verbose >= HTS_LOG_DEBUG)
2203
118
                hts_log_warning("Bad BCF record at %s:%"PRIhts_pos": Invalid %s id %d", bcf_seqname_safe(hdr,rec), rec->pos+1, "INFO", key);
2204
2.63k
            err |= BCF_ERR_TAG_UNDEF;
2205
2.63k
        }
2206
2.67k
        if (bcf_dec_size_safe(ptr, end, &ptr, &num, &type) != 0) goto bad_shared;
2207
2.63k
        if (((1 << type) & is_valid_type) == 0
2208
2.51k
            || (type == BCF_BT_NULL && num > 0)) {
2209
220
            if (!reports++ || hts_verbose >= HTS_LOG_DEBUG)
2210
18
                hts_log_warning("Bad BCF record at %s:%"PRIhts_pos": Invalid %s type %d (%s)", bcf_seqname_safe(hdr,rec), rec->pos+1, "INFO", type, get_type_name(type));
2211
220
            err |= BCF_ERR_TAG_INVALID;
2212
220
        }
2213
2.63k
        bytes = (size_t) num << bcf_type_shift[type];
2214
2.63k
        if (end - ptr < bytes) goto bad_shared;
2215
2.61k
        ptr += bytes;
2216
2.61k
    }
2217
2218
    // Check FORMAT and individual information
2219
158
    ptr = (uint8_t *) rec->indiv.s;
2220
158
    end = ptr + rec->indiv.l;
2221
158
    reports = 0;
2222
4.13k
    for (i = 0; i < rec->n_fmt; i++) {
2223
4.11k
        int32_t key = -1;
2224
4.11k
        if (bcf_dec_typed_int1_safe(ptr, end, &ptr, &key) != 0) goto bad_indiv;
2225
4.07k
        if (key < 0
2226
3.87k
            || (hdr && (key >= max_id
2227
4.05k
                        || id_tmp[key].key == NULL))) {
2228
4.05k
            bcf_record_check_err(hdr, rec, "id", &reports, key);
2229
4.05k
            err |= BCF_ERR_TAG_UNDEF;
2230
4.05k
        }
2231
4.07k
        if (bcf_dec_size_safe(ptr, end, &ptr, &num, &type) != 0) goto bad_indiv;
2232
4.03k
        if (((1 << type) & is_valid_type) == 0
2233
3.88k
            || (type == BCF_BT_NULL && num > 0)) {
2234
234
            bcf_record_check_err(hdr, rec, "type", &reports, type);
2235
234
            err |= BCF_ERR_TAG_INVALID;
2236
234
        }
2237
        // Enforce the same 2GiB limit on FORMAT data items as VCF does,
2238
        // to prevent issues where multiplications might overflow.
2239
        // There's already a limit of 4GiB for all FORMAT items due to
2240
        // the type of l_indiv in the BCF format, so this limits data for each
2241
        // key to half the maximum possible.
2242
4.03k
        uint64_t ndata = (uint64_t) num * (uint64_t) rec->n_sample;
2243
4.03k
        if (ndata > (INT_MAX >> bcf_type_shift[type])) goto too_many_indiv;
2244
4.02k
        bytes = (size_t) ndata << bcf_type_shift[type]; // Now safe
2245
4.02k
        if (end - ptr < bytes) goto bad_indiv;
2246
2247
3.97k
        if (idgt >= 0 && idgt == key) {
2248
            // check first GT phasing bit and fix up if necessary
2249
0
            if (updatephasing(ptr, end, &ptr, rec->n_sample, num, type)) {
2250
0
                err |= BCF_ERR_TAG_INVALID;
2251
0
            }
2252
3.97k
        } else {
2253
3.97k
            ptr += bytes;
2254
3.97k
        }
2255
3.97k
    }
2256
2257
26
    if (!err && rec->rlen < 0) {
2258
        // Treat bad rlen as a warning instead of an error, and try to
2259
        // fix up by using the length of the stored REF allele.
2260
6
        static int warned = 0;
2261
6
        if (!warned) {
2262
1
            hts_log_warning("BCF record at %s:%"PRIhts_pos" has invalid RLEN (%"PRIhts_pos"). "
2263
1
                            "Only one invalid RLEN will be reported.",
2264
1
                            bcf_seqname_safe(hdr,rec), rec->pos+1, rec->rlen);
2265
1
            warned = 1;
2266
1
        }
2267
        //find rlen considering reflen, END, SVLEN, fmt LEN
2268
6
        hts_pos_t len = get_rlen(hdr, rec);
2269
6
        rec->rlen = len >= 0 ? len : 0;
2270
6
    }
2271
2272
26
    rec->errcode |= err;
2273
2274
26
    return err ? -2 : 0; // Return -2 so bcf_read() reports an error
2275
2276
304
 bad_shared:
2277
304
    hts_log_error("Bad BCF record at %s:%"PRIhts_pos" - shared section malformed or too short", bcf_seqname_safe(hdr,rec), rec->pos+1);
2278
304
    return -2;
2279
2280
124
 bad_indiv:
2281
124
    hts_log_error("Bad BCF record at %s:%"PRIhts_pos" - individuals section malformed or too short", bcf_seqname_safe(hdr,rec), rec->pos+1);
2282
124
    return -2;
2283
2284
8
 too_many_indiv:
2285
8
    hts_log_error("Bad BCF record at %s:%"PRIhts_pos" - individuals section data too large", bcf_seqname_safe(hdr,rec), rec->pos+1);
2286
8
    return -2;
2287
158
}
2288
2289
static inline uint8_t *bcf_unpack_fmt_core1(uint8_t *ptr, int n_sample, bcf_fmt_t *fmt);
2290
int bcf_subset_format(const bcf_hdr_t *hdr, bcf1_t *rec)
2291
0
{
2292
0
    if ( !hdr->keep_samples ) return 0;
2293
0
    if ( !bcf_hdr_nsamples(hdr) )
2294
0
    {
2295
0
        rec->indiv.l = rec->n_sample = 0;
2296
0
        return 0;
2297
0
    }
2298
2299
0
    int i, j;
2300
0
    uint8_t *ptr = (uint8_t*)rec->indiv.s, *dst = NULL, *src;
2301
0
    bcf_dec_t *dec = &rec->d;
2302
0
    hts_expand(bcf_fmt_t, rec->n_fmt, dec->m_fmt, dec->fmt);
2303
0
    for (i=0; i<dec->m_fmt; ++i) dec->fmt[i].p_free = 0;
2304
2305
0
    for (i=0; i<rec->n_fmt; i++)
2306
0
    {
2307
0
        ptr = bcf_unpack_fmt_core1(ptr, rec->n_sample, &dec->fmt[i]);
2308
0
        src = dec->fmt[i].p - dec->fmt[i].size;
2309
0
        if ( dst )
2310
0
        {
2311
0
            memmove(dec->fmt[i-1].p + dec->fmt[i-1].p_len, dec->fmt[i].p - dec->fmt[i].p_off, dec->fmt[i].p_off);
2312
0
            dec->fmt[i].p = dec->fmt[i-1].p + dec->fmt[i-1].p_len + dec->fmt[i].p_off;
2313
0
        }
2314
0
        dst = dec->fmt[i].p;
2315
0
        for (j=0; j<hdr->nsamples_ori; j++)
2316
0
        {
2317
0
            src += dec->fmt[i].size;
2318
0
            if ( !bit_array_test(hdr->keep_samples,j) ) continue;
2319
0
            memmove(dst, src, dec->fmt[i].size);
2320
0
            dst += dec->fmt[i].size;
2321
0
        }
2322
0
        rec->indiv.l -= dec->fmt[i].p_len - (dst - dec->fmt[i].p);
2323
0
        dec->fmt[i].p_len = dst - dec->fmt[i].p;
2324
0
    }
2325
0
    rec->unpacked |= BCF_UN_FMT;
2326
2327
0
    rec->n_sample = bcf_hdr_nsamples(hdr);
2328
0
    return 0;
2329
0
}
2330
2331
int bcf_read(htsFile *fp, const bcf_hdr_t *h, bcf1_t *v)
2332
61.9k
{
2333
61.9k
    if (fp->format.format == vcf) return vcf_read(fp, h, v);
2334
540
    if (!h)
2335
0
        h = (const bcf_hdr_t *) bgzf_get_private_data(fp->fp.bgzf);
2336
540
    int ret = bcf_read1_core(fp->fp.bgzf, v);
2337
540
    if (ret == 0) ret = bcf_record_check(h, v);
2338
540
    if ( ret!=0 || !h->keep_samples ) return ret;
2339
0
    return bcf_subset_format(h,v);
2340
540
}
2341
2342
int bcf_readrec(BGZF *fp, void *null, void *vv, int *tid, hts_pos_t *beg, hts_pos_t *end)
2343
0
{
2344
0
    bcf1_t *v = (bcf1_t *) vv;
2345
0
    const bcf_hdr_t *hdr = (const bcf_hdr_t *) bgzf_get_private_data(fp);
2346
0
    int ret = bcf_read1_core(fp, v);
2347
0
    if (ret == 0) ret = bcf_record_check(hdr, v);
2348
0
    if (ret  >= 0)
2349
0
        *tid = v->rid, *beg = v->pos, *end = v->pos + v->rlen;
2350
0
    return ret;
2351
0
}
2352
2353
static inline int bcf1_sync_id(bcf1_t *line, kstring_t *str)
2354
0
{
2355
    // single typed string
2356
0
    if ( line->d.id && strcmp(line->d.id, ".") ) {
2357
0
        return bcf_enc_vchar(str, strlen(line->d.id), line->d.id);
2358
0
    } else {
2359
0
        return bcf_enc_size(str, 0, BCF_BT_CHAR);
2360
0
    }
2361
0
}
2362
static inline int bcf1_sync_alleles(bcf1_t *line, kstring_t *str)
2363
0
{
2364
    // list of typed strings
2365
0
    int i;
2366
0
    for (i=0; i<line->n_allele; i++) {
2367
0
        if (bcf_enc_vchar(str, strlen(line->d.allele[i]), line->d.allele[i]) < 0)
2368
0
            return -1;
2369
0
    }
2370
0
    if ( !line->rlen && line->n_allele ) line->rlen = strlen(line->d.allele[0]);
2371
0
    return 0;
2372
0
}
2373
static inline int bcf1_sync_filter(bcf1_t *line, kstring_t *str)
2374
0
{
2375
    // typed vector of integers
2376
0
    if ( line->d.n_flt ) {
2377
0
        return bcf_enc_vint(str, line->d.n_flt, line->d.flt, -1);
2378
0
    } else {
2379
0
        return bcf_enc_vint(str, 0, 0, -1);
2380
0
    }
2381
0
}
2382
2383
static inline int bcf1_sync_info(bcf1_t *line, kstring_t *str)
2384
0
{
2385
    // pairs of typed vectors
2386
0
    int i, irm = -1, e = 0;
2387
0
    for (i=0; i<line->n_info; i++)
2388
0
    {
2389
0
        bcf_info_t *info = &line->d.info[i];
2390
0
        if ( !info->vptr )
2391
0
        {
2392
            // marked for removal
2393
0
            if ( irm < 0 ) irm = i;
2394
0
            continue;
2395
0
        }
2396
0
        e |= kputsn_(info->vptr - info->vptr_off, info->vptr_len + info->vptr_off, str) < 0;
2397
0
        if ( irm >=0 )
2398
0
        {
2399
0
            bcf_info_t tmp = line->d.info[irm]; line->d.info[irm] = line->d.info[i]; line->d.info[i] = tmp;
2400
0
            while ( irm<=i && line->d.info[irm].vptr ) irm++;
2401
0
        }
2402
0
    }
2403
0
    if ( irm>=0 ) line->n_info = irm;
2404
0
    return e == 0 ? 0 : -1;
2405
0
}
2406
2407
static int bcf1_sync(bcf1_t *line)
2408
10
{
2409
10
    char *shared_ori = line->shared.s;
2410
10
    size_t prev_len;
2411
2412
10
    kstring_t tmp = {0,0,0};
2413
10
    if ( !line->shared.l )
2414
0
    {
2415
        // New line created via API, BCF data blocks do not exist. Get it ready for BCF output
2416
0
        tmp = line->shared;
2417
0
        bcf1_sync_id(line, &tmp);
2418
0
        line->unpack_size[0] = tmp.l; prev_len = tmp.l;
2419
2420
0
        bcf1_sync_alleles(line, &tmp);
2421
0
        line->unpack_size[1] = tmp.l - prev_len; prev_len = tmp.l;
2422
2423
0
        bcf1_sync_filter(line, &tmp);
2424
0
        line->unpack_size[2] = tmp.l - prev_len;
2425
2426
0
        bcf1_sync_info(line, &tmp);
2427
0
        line->shared = tmp;
2428
0
    }
2429
10
    else if ( line->d.shared_dirty )
2430
0
    {
2431
        // The line was edited, update the BCF data block.
2432
2433
0
        if ( !(line->unpacked & BCF_UN_STR) ) bcf_unpack(line,BCF_UN_STR);
2434
2435
        // ptr_ori points to the original unchanged BCF data.
2436
0
        uint8_t *ptr_ori = (uint8_t *) line->shared.s;
2437
2438
        // ID: single typed string
2439
0
        if ( line->d.shared_dirty & BCF1_DIRTY_ID )
2440
0
            bcf1_sync_id(line, &tmp);
2441
0
        else
2442
0
            kputsn_(ptr_ori, line->unpack_size[0], &tmp);
2443
0
        ptr_ori += line->unpack_size[0];
2444
0
        line->unpack_size[0] = tmp.l; prev_len = tmp.l;
2445
2446
        // REF+ALT: list of typed strings
2447
0
        if ( line->d.shared_dirty & BCF1_DIRTY_ALS )
2448
0
            bcf1_sync_alleles(line, &tmp);
2449
0
        else
2450
0
        {
2451
0
            kputsn_(ptr_ori, line->unpack_size[1], &tmp);
2452
0
            if ( !line->rlen && line->n_allele ) line->rlen = strlen(line->d.allele[0]);
2453
0
        }
2454
0
        ptr_ori += line->unpack_size[1];
2455
0
        line->unpack_size[1] = tmp.l - prev_len; prev_len = tmp.l;
2456
2457
0
        if ( line->unpacked & BCF_UN_FLT )
2458
0
        {
2459
            // FILTER: typed vector of integers
2460
0
            if ( line->d.shared_dirty & BCF1_DIRTY_FLT )
2461
0
                bcf1_sync_filter(line, &tmp);
2462
0
            else if ( line->d.n_flt )
2463
0
                kputsn_(ptr_ori, line->unpack_size[2], &tmp);
2464
0
            else
2465
0
                bcf_enc_vint(&tmp, 0, 0, -1);
2466
0
            ptr_ori += line->unpack_size[2];
2467
0
            line->unpack_size[2] = tmp.l - prev_len;
2468
2469
0
            if ( line->unpacked & BCF_UN_INFO )
2470
0
            {
2471
                // INFO: pairs of typed vectors
2472
0
                if ( line->d.shared_dirty & BCF1_DIRTY_INF )
2473
0
                {
2474
0
                    bcf1_sync_info(line, &tmp);
2475
0
                    ptr_ori = (uint8_t*)line->shared.s + line->shared.l;
2476
0
                }
2477
0
            }
2478
0
        }
2479
2480
0
        int size = line->shared.l - (size_t)ptr_ori + (size_t)line->shared.s;
2481
0
        if ( size ) kputsn_(ptr_ori, size, &tmp);
2482
2483
0
        free(line->shared.s);
2484
0
        line->shared = tmp;
2485
0
    }
2486
10
    if ( line->shared.s != shared_ori && line->unpacked & BCF_UN_INFO )
2487
0
    {
2488
        // Reallocated line->shared.s block invalidated line->d.info[].vptr pointers
2489
0
        size_t off_new = line->unpack_size[0] + line->unpack_size[1] + line->unpack_size[2];
2490
0
        int i;
2491
0
        for (i=0; i<line->n_info; i++)
2492
0
        {
2493
0
            uint8_t *vptr_free = line->d.info[i].vptr_free ? line->d.info[i].vptr - line->d.info[i].vptr_off : NULL;
2494
0
            line->d.info[i].vptr = (uint8_t*) line->shared.s + off_new + line->d.info[i].vptr_off;
2495
0
            off_new += line->d.info[i].vptr_len + line->d.info[i].vptr_off;
2496
0
            if ( vptr_free )
2497
0
            {
2498
0
                free(vptr_free);
2499
0
                line->d.info[i].vptr_free = 0;
2500
0
            }
2501
0
        }
2502
0
    }
2503
2504
10
    if ( line->n_sample && line->n_fmt && (!line->indiv.l || line->d.indiv_dirty) )
2505
0
    {
2506
        // The genotype fields changed or are not present
2507
0
        tmp.l = tmp.m = 0; tmp.s = NULL;
2508
0
        int i, irm = -1;
2509
0
        for (i=0; i<line->n_fmt; i++)
2510
0
        {
2511
0
            bcf_fmt_t *fmt = &line->d.fmt[i];
2512
0
            if ( !fmt->p )
2513
0
            {
2514
                // marked for removal
2515
0
                if ( irm < 0 ) irm = i;
2516
0
                continue;
2517
0
            }
2518
0
            kputsn_(fmt->p - fmt->p_off, fmt->p_len + fmt->p_off, &tmp);
2519
0
            if ( irm >=0 )
2520
0
            {
2521
0
                bcf_fmt_t tfmt = line->d.fmt[irm]; line->d.fmt[irm] = line->d.fmt[i]; line->d.fmt[i] = tfmt;
2522
0
                while ( irm<=i && line->d.fmt[irm].p ) irm++;
2523
0
            }
2524
2525
0
        }
2526
0
        if ( irm>=0 ) line->n_fmt = irm;
2527
0
        free(line->indiv.s);
2528
0
        line->indiv = tmp;
2529
2530
        // Reallocated line->indiv.s block invalidated line->d.fmt[].p pointers
2531
0
        size_t off_new = 0;
2532
0
        for (i=0; i<line->n_fmt; i++)
2533
0
        {
2534
0
            uint8_t *p_free = line->d.fmt[i].p_free ? line->d.fmt[i].p - line->d.fmt[i].p_off : NULL;
2535
0
            line->d.fmt[i].p = (uint8_t*) line->indiv.s + off_new + line->d.fmt[i].p_off;
2536
0
            off_new += line->d.fmt[i].p_len + line->d.fmt[i].p_off;
2537
0
            if ( p_free )
2538
0
            {
2539
0
                free(p_free);
2540
0
                line->d.fmt[i].p_free = 0;
2541
0
            }
2542
0
        }
2543
0
    }
2544
10
    if ( !line->n_sample ) line->n_fmt = 0;
2545
10
    line->d.shared_dirty = line->d.indiv_dirty = 0;
2546
10
    return 0;
2547
10
}
2548
2549
bcf1_t *bcf_copy(bcf1_t *dst, bcf1_t *src)
2550
0
{
2551
0
    bcf1_sync(src);
2552
2553
0
    bcf_clear(dst);
2554
0
    dst->rid  = src->rid;
2555
0
    dst->pos  = src->pos;
2556
0
    dst->rlen = src->rlen;
2557
0
    dst->qual = src->qual;
2558
0
    dst->n_info = src->n_info; dst->n_allele = src->n_allele;
2559
0
    dst->n_fmt = src->n_fmt; dst->n_sample = src->n_sample;
2560
2561
0
    if ( dst->shared.m < src->shared.l )
2562
0
    {
2563
0
        dst->shared.s = (char*) realloc(dst->shared.s, src->shared.l);
2564
0
        dst->shared.m = src->shared.l;
2565
0
    }
2566
0
    dst->shared.l = src->shared.l;
2567
0
    memcpy(dst->shared.s,src->shared.s,dst->shared.l);
2568
2569
0
    if ( dst->indiv.m < src->indiv.l )
2570
0
    {
2571
0
        dst->indiv.s = (char*) realloc(dst->indiv.s, src->indiv.l);
2572
0
        dst->indiv.m = src->indiv.l;
2573
0
    }
2574
0
    dst->indiv.l = src->indiv.l;
2575
0
    memcpy(dst->indiv.s,src->indiv.s,dst->indiv.l);
2576
2577
0
    return dst;
2578
0
}
2579
bcf1_t *bcf_dup(bcf1_t *src)
2580
0
{
2581
0
    bcf1_t *out = bcf_init1();
2582
0
    return bcf_copy(out, src);
2583
0
}
2584
2585
int bcf_write(htsFile *hfp, bcf_hdr_t *h, bcf1_t *v)
2586
59.1k
{
2587
59.1k
    if ( h->dirty ) {
2588
0
        if (bcf_hdr_sync(h) < 0) return -1;
2589
0
    }
2590
59.1k
    if ( bcf_hdr_nsamples(h)!=v->n_sample )
2591
119
    {
2592
119
        hts_log_error("Broken VCF record, the number of columns at %s:%"PRIhts_pos" does not match the number of samples (%d vs %d)",
2593
119
            bcf_seqname_safe(h,v), v->pos+1, v->n_sample, bcf_hdr_nsamples(h));
2594
119
        return -1;
2595
119
    }
2596
2597
59.0k
    if ( hfp->format.format == vcf || hfp->format.format == text_format )
2598
57.4k
        return vcf_write(hfp,h,v);
2599
2600
1.63k
    if ( v->errcode & ~BCF_ERR_LIMITS ) // todo: unsure about the other BCF_ERR_LIMITS branches in vcf_parse_format_alloc4()
2601
1.62k
    {
2602
        // vcf_parse1() encountered a new contig or tag, undeclared in the
2603
        // header.  At this point, the header must have been printed,
2604
        // proceeding would lead to a broken BCF file. Errors must be checked
2605
        // and cleared by the caller before we can proceed.
2606
1.62k
        char errdescription[1024] = "";
2607
1.62k
        hts_log_error("Unchecked error (%d %s) at %s:%"PRIhts_pos, v->errcode, bcf_strerror(v->errcode, errdescription, sizeof(errdescription)), bcf_seqname_safe(h,v), v->pos+1);
2608
1.62k
        return -1;
2609
1.62k
    }
2610
10
    bcf1_sync(v);   // check if the BCF record was modified
2611
2612
10
    if ( v->unpacked & BCF_IS_64BIT )
2613
0
    {
2614
0
        hts_log_error("Data at %s:%"PRIhts_pos" contains 64-bit values not representable in BCF. Please use VCF instead", bcf_seqname_safe(h,v), v->pos+1);
2615
0
        return -1;
2616
0
    }
2617
2618
10
    BGZF *fp = hfp->fp.bgzf;
2619
10
    uint8_t x[32];
2620
10
    u32_to_le(v->shared.l + 24, x); // to include six 32-bit integers
2621
10
    u32_to_le(v->indiv.l, x + 4);
2622
10
    i32_to_le(v->rid, x + 8);
2623
10
    u32_to_le(v->pos, x + 12);
2624
10
    u32_to_le(v->rlen, x + 16);
2625
10
    float_to_le(v->qual, x + 20);
2626
10
    u16_to_le(v->n_info, x + 24);
2627
10
    u16_to_le(v->n_allele, x + 26);
2628
10
    u32_to_le((uint32_t)v->n_fmt<<24 | (v->n_sample & 0xffffff), x + 28);
2629
10
    if ( bgzf_write(fp, x, 32) != 32 ) return -1;
2630
10
    if ( bgzf_write(fp, v->shared.s, v->shared.l) != v->shared.l ) return -1;
2631
10
    if ( bgzf_write(fp, v->indiv.s, v->indiv.l) != v->indiv.l ) return -1;
2632
2633
10
    if (hfp->idx) {
2634
0
        if (bgzf_idx_push(fp, hfp->idx, v->rid, v->pos, v->pos + v->rlen,
2635
0
                          bgzf_tell(fp), 1) < 0)
2636
0
            return -1;
2637
0
    }
2638
2639
10
    return 0;
2640
10
}
2641
2642
/**********************
2643
 *** VCF header I/O ***
2644
 **********************/
2645
2646
0
static int add_missing_contig_hrec(bcf_hdr_t *h, const char *name) {
2647
0
    bcf_hrec_t *hrec = calloc(1, sizeof(bcf_hrec_t));
2648
0
    int save_errno;
2649
0
    if (!hrec) goto fail;
2650
2651
0
    hrec->key = strdup("contig");
2652
0
    if (!hrec->key) goto fail;
2653
2654
0
    if (bcf_hrec_add_key(hrec, "ID", strlen("ID")) < 0) goto fail;
2655
0
    if (bcf_hrec_set_val(hrec, hrec->nkeys-1, name, strlen(name), 0) < 0)
2656
0
        goto fail;
2657
0
    if (bcf_hdr_add_hrec(h, hrec) < 0)
2658
0
        goto fail;
2659
0
    return 0;
2660
2661
0
 fail:
2662
0
    save_errno = errno;
2663
0
    hts_log_error("%s", strerror(errno));
2664
0
    if (hrec) bcf_hrec_destroy(hrec);
2665
0
    errno = save_errno;
2666
0
    return -1;
2667
0
}
2668
2669
bcf_hdr_t *vcf_hdr_read(htsFile *fp)
2670
5.62k
{
2671
5.62k
    kstring_t txt, *s = &fp->line;
2672
5.62k
    int ret;
2673
5.62k
    bcf_hdr_t *h;
2674
5.62k
    tbx_t *idx = NULL;
2675
5.62k
    const char **names = NULL;
2676
5.62k
    h = bcf_hdr_init("r");
2677
5.62k
    if (!h) {
2678
0
        hts_log_error("Failed to allocate bcf header");
2679
0
        return NULL;
2680
0
    }
2681
5.62k
    txt.l = txt.m = 0; txt.s = 0;
2682
173k
    while ((ret = hts_getline(fp, KS_SEP_LINE, s)) >= 0) {
2683
172k
        int e = 0;
2684
172k
        if (s->l == 0) continue;
2685
171k
        if (s->s[0] != '#') {
2686
24
            hts_log_error("No sample line");
2687
24
            goto error;
2688
24
        }
2689
171k
        if (s->s[1] != '#' && fp->fn_aux) { // insert contigs here
2690
0
            kstring_t tmp = { 0, 0, NULL };
2691
0
            hFILE *f = hopen(fp->fn_aux, "r");
2692
0
            if (f == NULL) {
2693
0
                hts_log_error("Couldn't open \"%s\"", fp->fn_aux);
2694
0
                goto error;
2695
0
            }
2696
0
            while (tmp.l = 0, khgetline(&tmp, f) >= 0) {
2697
0
                char *tab = strchr(tmp.s, '\t');
2698
0
                if (tab == NULL) continue;
2699
0
                e |= (kputs("##contig=<ID=", &txt) < 0);
2700
0
                e |= (kputsn(tmp.s, tab - tmp.s, &txt) < 0);
2701
0
                e |= (kputs(",length=", &txt) < 0);
2702
0
                e |= (kputl(atol(tab), &txt) < 0);
2703
0
                e |= (kputsn(">\n", 2, &txt) < 0);
2704
0
            }
2705
0
            free(tmp.s);
2706
0
            if (hclose(f) != 0) {
2707
0
                hts_log_error("Error on closing %s", fp->fn_aux);
2708
0
                goto error;
2709
0
            }
2710
0
            if (e) goto error;
2711
0
        }
2712
171k
        if (kputsn(s->s, s->l, &txt) < 0) goto error;
2713
171k
        if (kputc('\n', &txt) < 0) goto error;
2714
171k
        if (s->s[1] != '#') break;
2715
171k
    }
2716
5.60k
    if ( ret < -1 ) goto error;
2717
5.57k
    if ( !txt.s )
2718
0
    {
2719
0
        hts_log_error("Could not read the header");
2720
0
        goto error;
2721
0
    }
2722
5.57k
    if ( bcf_hdr_parse(h, txt.s) < 0 ) goto error;
2723
2724
    // check tabix index, are all contigs listed in the header? add the missing ones
2725
3.96k
    idx = tbx_index_load3(fp->fn, NULL, HTS_IDX_SILENT_FAIL);
2726
3.96k
    if ( idx )
2727
0
    {
2728
0
        int i, n, need_sync = 0;
2729
0
        names = tbx_seqnames(idx, &n);
2730
0
        if (!names) goto error;
2731
0
        for (i=0; i<n; i++)
2732
0
        {
2733
0
            bcf_hrec_t *hrec = bcf_hdr_get_hrec(h, BCF_HL_CTG, "ID", (char*) names[i], NULL);
2734
0
            if ( hrec ) continue;
2735
0
            if (add_missing_contig_hrec(h, names[i]) < 0) goto error;
2736
0
            need_sync = 1;
2737
0
        }
2738
0
        if ( need_sync ) {
2739
0
            if (bcf_hdr_sync(h) < 0) goto error;
2740
0
        }
2741
0
        free(names);
2742
0
        tbx_destroy(idx);
2743
0
    }
2744
3.96k
    free(txt.s);
2745
3.96k
    return h;
2746
2747
1.65k
 error:
2748
1.65k
    if (idx) tbx_destroy(idx);
2749
1.65k
    free(names);
2750
1.65k
    free(txt.s);
2751
1.65k
    if (h) bcf_hdr_destroy(h);
2752
1.65k
    return NULL;
2753
3.96k
}
2754
2755
int bcf_hdr_set(bcf_hdr_t *hdr, const char *fname)
2756
0
{
2757
0
    int i = 0, n = 0, save_errno;
2758
0
    char **lines = hts_readlines(fname, &n);
2759
0
    if ( !lines ) return 1;
2760
0
    for (i=0; i<n-1; i++)
2761
0
    {
2762
0
        int k;
2763
0
        bcf_hrec_t *hrec = bcf_hdr_parse_line(hdr,lines[i],&k);
2764
0
        if (!hrec) goto fail;
2765
0
        if (bcf_hdr_add_hrec(hdr, hrec) < 0) {
2766
0
            bcf_hrec_destroy(hrec);
2767
0
            goto fail;
2768
0
        }
2769
0
        free(lines[i]);
2770
0
        lines[i] = NULL;
2771
0
    }
2772
0
    if (bcf_hdr_parse_sample_line(hdr, lines[n-1]) < 0) goto fail;
2773
0
    if (bcf_hdr_sync(hdr) < 0) goto fail;
2774
0
    free(lines[n-1]);
2775
0
    free(lines);
2776
0
    return 0;
2777
2778
0
 fail:
2779
0
    save_errno = errno;
2780
0
    for (; i < n; i++)
2781
0
        free(lines[i]);
2782
0
    free(lines);
2783
0
    errno = save_errno;
2784
0
    return 1;
2785
0
}
2786
2787
static int _bcf_hrec_format(const bcf_hrec_t *hrec, int is_bcf, kstring_t *str)
2788
11.0k
{
2789
11.0k
    uint32_t e = 0;
2790
11.0k
    if ( !hrec->value )
2791
5.48k
    {
2792
5.48k
        int j, nout = 0;
2793
5.48k
        e |= ksprintf(str, "##%s=<", hrec->key) < 0;
2794
20.2k
        for (j=0; j<hrec->nkeys; j++)
2795
14.7k
        {
2796
            // do not output IDX if output is VCF
2797
14.7k
            if ( !is_bcf && !strcmp("IDX",hrec->keys[j]) ) continue;
2798
12.4k
            if ( nout ) e |= kputc(',',str) < 0;
2799
12.4k
            e |= ksprintf(str,"%s=%s", hrec->keys[j], hrec->vals[j]) < 0;
2800
12.4k
            nout++;
2801
12.4k
        }
2802
5.48k
        e |= ksprintf(str,">\n") < 0;
2803
5.48k
    }
2804
5.53k
    else
2805
5.53k
        e |= ksprintf(str,"##%s=%s\n", hrec->key,hrec->value) < 0;
2806
2807
11.0k
    return e == 0 ? 0 : -1;
2808
11.0k
}
2809
2810
int bcf_hrec_format(const bcf_hrec_t *hrec, kstring_t *str)
2811
0
{
2812
0
    return _bcf_hrec_format(hrec,0,str);
2813
0
}
2814
2815
int bcf_hdr_format(const bcf_hdr_t *hdr, int is_bcf, kstring_t *str)
2816
4.49k
{
2817
4.49k
    int i, r = 0;
2818
15.5k
    for (i=0; i<hdr->nhrec; i++)
2819
11.0k
        r |= _bcf_hrec_format(hdr->hrec[i], is_bcf, str) < 0;
2820
2821
4.49k
    r |= ksprintf(str, "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO") < 0;
2822
4.49k
    if ( bcf_hdr_nsamples(hdr) )
2823
2.25k
    {
2824
2.25k
        r |= ksprintf(str, "\tFORMAT") < 0;
2825
13.1k
        for (i=0; i<bcf_hdr_nsamples(hdr); i++)
2826
10.9k
            r |= ksprintf(str, "\t%s", hdr->samples[i]) < 0;
2827
2.25k
    }
2828
4.49k
    r |= ksprintf(str, "\n") < 0;
2829
2830
4.49k
    return r ? -1 : 0;
2831
4.49k
}
2832
2833
char *bcf_hdr_fmt_text(const bcf_hdr_t *hdr, int is_bcf, int *len)
2834
0
{
2835
0
    kstring_t txt = {0,0,0};
2836
0
    if (bcf_hdr_format(hdr, is_bcf, &txt) < 0)
2837
0
        return NULL;
2838
0
    if ( len ) *len = txt.l;
2839
0
    return txt.s;
2840
0
}
2841
2842
const char **bcf_hdr_seqnames(const bcf_hdr_t *h, int *n)
2843
0
{
2844
0
    vdict_t *d = (vdict_t*)h->dict[BCF_DT_CTG];
2845
0
    int i, tid, m = kh_size(d);
2846
0
    const char **names = (const char**) calloc(m,sizeof(const char*));
2847
0
    if ( !names )
2848
0
    {
2849
0
        hts_log_error("Failed to allocate memory");
2850
0
        *n = 0;
2851
0
        return NULL;
2852
0
    }
2853
0
    khint_t k;
2854
0
    for (k=kh_begin(d); k<kh_end(d); k++)
2855
0
    {
2856
0
        if ( !kh_exist(d,k) ) continue;
2857
0
        if ( !kh_val(d, k).hrec[0] ) continue;  // removed via bcf_hdr_remove
2858
0
        tid = kh_val(d,k).id;
2859
0
        if ( tid >= m )
2860
0
        {
2861
            // This can happen after a contig has been removed from BCF header via bcf_hdr_remove()
2862
0
            if ( hts_resize(const char*, tid + 1, &m, &names, HTS_RESIZE_CLEAR)<0 )
2863
0
            {
2864
0
                hts_log_error("Failed to allocate memory");
2865
0
                *n = 0;
2866
0
                free(names);
2867
0
                return NULL;
2868
0
            }
2869
0
            m = tid + 1;
2870
0
        }
2871
0
        names[tid] = kh_key(d,k);
2872
0
    }
2873
    // ensure there are no gaps
2874
0
    for (i=0,tid=0; tid<m; i++,tid++)
2875
0
    {
2876
0
        while ( tid<m && !names[tid] ) tid++;
2877
0
        if ( tid==m ) break;
2878
0
        if ( i==tid ) continue;
2879
0
        names[i] = names[tid];
2880
0
        names[tid] = 0;
2881
0
    }
2882
0
    *n = i;
2883
0
    return names;
2884
0
}
2885
2886
int vcf_hdr_write(htsFile *fp, const bcf_hdr_t *h)
2887
2.24k
{
2888
2.24k
    kstring_t htxt = {0,0,0};
2889
2.24k
    if (bcf_hdr_format(h, 0, &htxt) < 0) {
2890
0
        free(htxt.s);
2891
0
        return -1;
2892
0
    }
2893
2.24k
    while (htxt.l && htxt.s[htxt.l-1] == '\0') --htxt.l; // kill trailing zeros
2894
2.24k
    int ret;
2895
2.24k
    if ( fp->format.compression!=no_compression ) {
2896
0
        ret = bgzf_write(fp->fp.bgzf, htxt.s, htxt.l);
2897
0
        if (bgzf_flush(fp->fp.bgzf) != 0) return -1;
2898
2.24k
    } else {
2899
2.24k
        ret = hwrite(fp->fp.hfile, htxt.s, htxt.l);
2900
2.24k
    }
2901
2.24k
    free(htxt.s);
2902
2.24k
    return ret<0 ? -1 : 0;
2903
2.24k
}
2904
2905
/***********************
2906
 *** Typed value I/O ***
2907
 ***********************/
2908
2909
int bcf_enc_vint(kstring_t *s, int n, int32_t *a, int wsize)
2910
68.4k
{
2911
68.4k
    int32_t max = INT32_MIN, min = INT32_MAX;
2912
68.4k
    int i;
2913
68.4k
    if (n <= 0) {
2914
8.57k
        return bcf_enc_size(s, 0, BCF_BT_NULL);
2915
59.8k
    } else if (n == 1) {
2916
50.8k
        return bcf_enc_int1(s, a[0]);
2917
50.8k
    } else {
2918
8.96k
        if (wsize <= 0) wsize = n;
2919
2920
        // Equivalent to:
2921
        // for (i = 0; i < n; ++i) {
2922
        //     if (a[i] == bcf_int32_missing || a[i] == bcf_int32_vector_end )
2923
        //         continue;
2924
        //     if (max < a[i]) max = a[i];
2925
        //     if (min > a[i]) min = a[i];
2926
        // }
2927
8.96k
        int max4[4] = {INT32_MIN, INT32_MIN, INT32_MIN, INT32_MIN};
2928
8.96k
        int min4[4] = {INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX};
2929
53.5k
        for (i = 0; i < (n&~3); i+=4) {
2930
            // bcf_int32_missing    == INT32_MIN and
2931
            // bcf_int32_vector_end == INT32_MIN+1.
2932
            // We skip these, but can mostly avoid explicit checking
2933
44.6k
            if (max4[0] < a[i+0]) max4[0] = a[i+0];
2934
44.6k
            if (max4[1] < a[i+1]) max4[1] = a[i+1];
2935
44.6k
            if (max4[2] < a[i+2]) max4[2] = a[i+2];
2936
44.6k
            if (max4[3] < a[i+3]) max4[3] = a[i+3];
2937
44.6k
            if (min4[0] > a[i+0] && a[i+0] > INT32_MIN+1) min4[0] = a[i+0];
2938
44.6k
            if (min4[1] > a[i+1] && a[i+1] > INT32_MIN+1) min4[1] = a[i+1];
2939
44.6k
            if (min4[2] > a[i+2] && a[i+2] > INT32_MIN+1) min4[2] = a[i+2];
2940
44.6k
            if (min4[3] > a[i+3] && a[i+3] > INT32_MIN+1) min4[3] = a[i+3];
2941
44.6k
        }
2942
8.96k
        min = min4[0];
2943
8.96k
        if (min > min4[1]) min = min4[1];
2944
8.96k
        if (min > min4[2]) min = min4[2];
2945
8.96k
        if (min > min4[3]) min = min4[3];
2946
8.96k
        max = max4[0];
2947
8.96k
        if (max < max4[1]) max = max4[1];
2948
8.96k
        if (max < max4[2]) max = max4[2];
2949
8.96k
        if (max < max4[3]) max = max4[3];
2950
21.5k
        for (; i < n; ++i) {
2951
12.5k
            if (max < a[i]) max = a[i];
2952
12.5k
            if (min > a[i] && a[i] > INT32_MIN+1) min = a[i];
2953
12.5k
        }
2954
2955
8.96k
        if (max <= BCF_MAX_BT_INT8 && min >= BCF_MIN_BT_INT8) {
2956
5.39k
            if (bcf_enc_size(s, wsize, BCF_BT_INT8) < 0 ||
2957
5.39k
                ks_resize(s, s->l + n) < 0)
2958
0
                return -1;
2959
5.39k
            uint8_t *p = (uint8_t *) s->s + s->l;
2960
126k
            for (i = 0; i < n; ++i, p++) {
2961
121k
                if ( a[i]==bcf_int32_vector_end )   *p = bcf_int8_vector_end;
2962
96.5k
                else if ( a[i]==bcf_int32_missing ) *p = bcf_int8_missing;
2963
83.9k
                else *p = a[i];
2964
121k
            }
2965
5.39k
            s->l += n;
2966
5.39k
        } else if (max <= BCF_MAX_BT_INT16 && min >= BCF_MIN_BT_INT16) {
2967
1.67k
            uint8_t *p;
2968
1.67k
            if (bcf_enc_size(s, wsize, BCF_BT_INT16) < 0 ||
2969
1.67k
                ks_resize(s, s->l + n * sizeof(int16_t)) < 0)
2970
0
                return -1;
2971
1.67k
            p = (uint8_t *) s->s + s->l;
2972
50.3k
            for (i = 0; i < n; ++i)
2973
48.6k
            {
2974
48.6k
                int16_t x;
2975
48.6k
                if ( a[i]==bcf_int32_vector_end ) x = bcf_int16_vector_end;
2976
19.8k
                else if ( a[i]==bcf_int32_missing ) x = bcf_int16_missing;
2977
12.4k
                else x = a[i];
2978
48.6k
                i16_to_le(x, p);
2979
48.6k
                p += sizeof(int16_t);
2980
48.6k
            }
2981
1.67k
            s->l += n * sizeof(int16_t);
2982
1.89k
        } else {
2983
1.89k
            uint8_t *p;
2984
1.89k
            if (bcf_enc_size(s, wsize, BCF_BT_INT32) < 0 ||
2985
1.89k
                ks_resize(s, s->l + n * sizeof(int32_t)) < 0)
2986
0
                return -1;
2987
1.89k
            p = (uint8_t *) s->s + s->l;
2988
22.7k
            for (i = 0; i < n; ++i) {
2989
20.8k
                i32_to_le(a[i], p);
2990
20.8k
                p += sizeof(int32_t);
2991
20.8k
            }
2992
1.89k
            s->l += n * sizeof(int32_t);
2993
1.89k
        }
2994
8.96k
    }
2995
2996
8.96k
    return 0;
2997
68.4k
}
2998
2999
#ifdef VCF_ALLOW_INT64
3000
static int bcf_enc_long1(kstring_t *s, int64_t x) {
3001
    uint32_t e = 0;
3002
    if (x <= BCF_MAX_BT_INT32 && x >= BCF_MIN_BT_INT32)
3003
        return bcf_enc_int1(s, x);
3004
    if (x == bcf_int64_vector_end) {
3005
        e |= bcf_enc_size(s, 1, BCF_BT_INT8);
3006
        e |= kputc(bcf_int8_vector_end, s) < 0;
3007
    } else if (x == bcf_int64_missing) {
3008
        e |= bcf_enc_size(s, 1, BCF_BT_INT8);
3009
        e |= kputc(bcf_int8_missing, s) < 0;
3010
    } else {
3011
        e |= bcf_enc_size(s, 1, BCF_BT_INT64);
3012
        e |= ks_expand(s, 8);
3013
        if (e == 0) { u64_to_le(x, (uint8_t *) s->s + s->l); s->l += 8; }
3014
    }
3015
    return e == 0 ? 0 : -1;
3016
}
3017
#endif
3018
3019
0
static inline int serialize_float_array(kstring_t *s, size_t n, const float *a) {
3020
0
    uint8_t *p;
3021
0
    size_t i;
3022
0
    size_t bytes = n * sizeof(float);
3023
3024
0
    if (bytes / sizeof(float) != n) return -1;
3025
0
    if (ks_resize(s, s->l + bytes) < 0) return -1;
3026
3027
0
    p = (uint8_t *) s->s + s->l;
3028
0
    for (i = 0; i < n; i++) {
3029
0
        float_to_le(a[i], p);
3030
0
        p += sizeof(float);
3031
0
    }
3032
0
    s->l += bytes;
3033
3034
0
    return 0;
3035
0
}
3036
3037
int bcf_enc_vfloat(kstring_t *s, int n, float *a)
3038
0
{
3039
0
    assert(n >= 0);
3040
0
    bcf_enc_size(s, n, BCF_BT_FLOAT);
3041
0
    serialize_float_array(s, n, a);
3042
0
    return 0; // FIXME: check for errs in this function
3043
0
}
3044
3045
int bcf_enc_vchar(kstring_t *s, int l, const char *a)
3046
2.75M
{
3047
2.75M
    bcf_enc_size(s, l, BCF_BT_CHAR);
3048
2.75M
    kputsn(a, l, s);
3049
2.75M
    return 0; // FIXME: check for errs in this function
3050
2.75M
}
3051
3052
// Special case of n==1 as it also occurs quite often in FORMAT data.
3053
// This version is also small enough to get inlined.
3054
15.2k
static inline int bcf_fmt_array1(kstring_t *s, int type, void *data) {
3055
15.2k
    uint32_t e = 0;
3056
15.2k
    uint8_t *p = (uint8_t *)data;
3057
15.2k
    int32_t v;
3058
3059
    // helps gcc more than clang here. In billions of cycles:
3060
    //          bcf_fmt_array1  bcf_fmt_array
3061
    // gcc7:    23.2            24.3
3062
    // gcc13:   21.6            23.0
3063
    // clang13: 27.1            27.8
3064
15.2k
    switch (type) {
3065
15.2k
    case BCF_BT_CHAR:
3066
15.2k
        e |= kputc_(*p == bcf_str_missing ? '.' : *p, s) < 0;
3067
15.2k
        break;
3068
3069
0
    case BCF_BT_INT8:
3070
0
        if (*(int8_t *)p != bcf_int8_vector_end) {
3071
0
            e |= ((*(int8_t *)p == bcf_int8_missing)
3072
0
                  ? kputc_('.', s)
3073
0
                  : kputw(*(int8_t *)p, s)) < 0;
3074
0
        }
3075
0
        break;
3076
0
    case BCF_BT_INT16:
3077
0
        v = le_to_i16(p);
3078
0
        if (v != bcf_int16_vector_end) {
3079
0
            e |= (v == bcf_int16_missing
3080
0
                  ? kputc_('.', s)
3081
0
                  : kputw(v, s)) < 0;
3082
0
        }
3083
0
        break;
3084
3085
0
    case BCF_BT_INT32:
3086
0
        v = le_to_i32(p);
3087
0
        if (v != bcf_int32_vector_end) {
3088
0
            e |= (v == bcf_int32_missing
3089
0
                  ? kputc_('.', s)
3090
0
                  : kputw(v, s)) < 0;
3091
0
        }
3092
0
        break;
3093
3094
0
    case BCF_BT_FLOAT:
3095
0
        v = le_to_u32(p);
3096
0
        if (v != bcf_float_vector_end) {
3097
0
            e |= (v == bcf_float_missing
3098
0
                  ? kputc_('.', s)
3099
0
                  : kputd(le_to_float(p), s)) < 0;
3100
0
        }
3101
0
        break;
3102
3103
0
    default:
3104
0
        hts_log_error("Unexpected type %d", type);
3105
0
        return -1;
3106
15.2k
    }
3107
3108
15.2k
    return e == 0 ? 0 : -1;
3109
15.2k
}
3110
3111
int bcf_fmt_array(kstring_t *s, int n, int type, void *data)
3112
1.67M
{
3113
1.67M
    int j = 0;
3114
1.67M
    uint32_t e = 0;
3115
1.67M
    if (n == 0) {
3116
1.35M
        return kputc_('.', s) >= 0 ? 0 : -1;
3117
1.35M
    }
3118
3119
320k
    if (type == BCF_BT_CHAR)
3120
320k
    {
3121
320k
        char *p = (char *)data;
3122
3123
        // Note bcf_str_missing is already accounted for in n==0 above.
3124
320k
        if (n >= 8) {
3125
55.0k
            char *p_end = memchr(p, 0, n);
3126
55.0k
            e |= kputsn(p, p_end ? p_end-p : n, s) < 0;
3127
265k
        } else {
3128
833k
            for (j = 0; j < n && *p; ++j, ++p)
3129
567k
               e |= kputc(*p, s) < 0;
3130
265k
        }
3131
320k
    }
3132
0
    else
3133
0
    {
3134
0
        #define BRANCH(type_t, convert, is_missing, is_vector_end, kprint) { \
3135
0
            uint8_t *p = (uint8_t *) data; \
3136
0
            for (j=0; j<n; j++, p += sizeof(type_t))    \
3137
0
            { \
3138
0
                type_t v = convert(p); \
3139
0
                if ( is_vector_end ) break; \
3140
0
                if ( j ) e |= kputc_(',', s) < 0; \
3141
0
                e |= (is_missing ? kputc('.', s) : kprint) < 0; \
3142
0
            } \
3143
0
        }
3144
0
        switch (type) {
3145
0
            case BCF_BT_INT8:  BRANCH(int8_t,  le_to_i8, v==bcf_int8_missing,  v==bcf_int8_vector_end,  kputw(v, s)); break;
3146
0
            case BCF_BT_INT16: BRANCH(int16_t, le_to_i16, v==bcf_int16_missing, v==bcf_int16_vector_end, kputw(v, s)); break;
3147
0
            case BCF_BT_INT32: BRANCH(int32_t, le_to_i32, v==bcf_int32_missing, v==bcf_int32_vector_end, kputw(v, s)); break;
3148
0
            case BCF_BT_FLOAT: BRANCH(uint32_t, le_to_u32, v==bcf_float_missing, v==bcf_float_vector_end, kputd(le_to_float(p), s)); break;
3149
0
            default: hts_log_error("Unexpected type %d", type); exit(1); break;
3150
0
        }
3151
0
        #undef BRANCH
3152
0
    }
3153
320k
    return e == 0 ? 0 : -1;
3154
320k
}
3155
3156
uint8_t *bcf_fmt_sized_array(kstring_t *s, uint8_t *ptr)
3157
1.52M
{
3158
1.52M
    int x, type;
3159
1.52M
    x = bcf_dec_size(ptr, &ptr, &type);
3160
1.52M
    bcf_fmt_array(s, x, type, ptr);
3161
1.52M
    return ptr + (x << bcf_type_shift[type]);
3162
1.52M
}
3163
3164
/********************
3165
 *** VCF site I/O ***
3166
 ********************/
3167
3168
typedef struct {
3169
    int key;            // Key for h->id[BCF_DT_ID][key] vdict
3170
    int max_m;          // number of elements in field array (ie commas)
3171
    int size;           // field size (max_l or max_g*4 if is_gt)
3172
    int offset;         // offset of buf into h->mem
3173
    uint32_t is_gt:1,   // is genotype
3174
             max_g:31;  // maximum number of genotypes
3175
    uint32_t max_l;     // length of field
3176
    uint32_t y;         // h->id[0][fmt[j].key].val->info[BCF_HL_FMT]
3177
    uint8_t *buf;       // Pointer into h->mem
3178
} fmt_aux_t;
3179
3180
// fmt_aux_t field notes:
3181
// max_* are biggest sizes of the various FORMAT fields across all samples.
3182
// We use these after pivoting the data to ensure easy random access
3183
// of a specific sample.
3184
//
3185
// max_m is only used for type BCF_HT_REAL or BCF_HT_INT
3186
// max_g is only used for is_gt == 1 (will be BCF_HT_STR)
3187
// max_l is only used for is_gt == 0 (will be BCF_HT_STR)
3188
//
3189
// These are computed in vcf_parse_format_max3 and used in
3190
// vcf_parse_format_alloc4 to get the size.
3191
//
3192
// size is computed from max_g, max_l, max_m and is_gt.  Once computed
3193
// the max values are never accessed again.
3194
//
3195
// In theory all 4 vars could be coalesced into a single variable, but this
3196
// significantly harms speed (even if done via a union).  It's about 25-30%
3197
// slower.
3198
3199
static inline int align_mem(kstring_t *s)
3200
105k
{
3201
105k
    int e = 0;
3202
105k
    if (s->l&7) {
3203
15.3k
        uint64_t zero = 0;
3204
15.3k
        e = kputsn((char*)&zero, 8 - (s->l&7), s) < 0;
3205
15.3k
    }
3206
105k
    return e == 0 ? 0 : -1;
3207
105k
}
3208
3209
106k
#define MAX_N_FMT 255   /* Limited by size of bcf1_t n_fmt field */
3210
3211
// detect FORMAT "."
3212
static int vcf_parse_format_empty1(kstring_t *s, const bcf_hdr_t *h, bcf1_t *v,
3213
16.6k
                                   const char *p, const char *q) {
3214
16.6k
    const char *end = s->s + s->l;
3215
16.6k
    if ( q>=end )
3216
62
    {
3217
62
        hts_log_error("FORMAT column with no sample columns starting at %s:%"PRIhts_pos"", bcf_seqname_safe(h,v), v->pos+1);
3218
62
        v->errcode |= BCF_ERR_NCOLS;
3219
62
        return -1;
3220
62
    }
3221
3222
16.5k
    v->n_fmt = 0;
3223
16.5k
    if ( p[0]=='.' && p[1]==0 ) // FORMAT field is empty "."
3224
598
    {
3225
598
        v->n_sample = bcf_hdr_nsamples(h);
3226
598
        return 1;
3227
598
    }
3228
3229
15.9k
    return 0;
3230
16.5k
}
3231
3232
// get format information from the dictionary
3233
static int vcf_parse_format_dict2(kstring_t *s, const bcf_hdr_t *h, bcf1_t *v,
3234
15.9k
                                  const char *p, const char *q, fmt_aux_t *fmt) {
3235
15.9k
    const vdict_t *d = (vdict_t*)h->dict[BCF_DT_ID];
3236
15.9k
    char *t;
3237
15.9k
    int j;
3238
15.9k
    ks_tokaux_t aux1;
3239
3240
122k
    for (j = 0, t = kstrtok(p, ":", &aux1); t; t = kstrtok(0, 0, &aux1), ++j) {
3241
106k
        if (j >= MAX_N_FMT) {
3242
3
            v->errcode |= BCF_ERR_LIMITS;
3243
3
            hts_log_error("FORMAT column at %s:%"PRIhts_pos" lists more identifiers than htslib can handle",
3244
3
                bcf_seqname_safe(h,v), v->pos+1);
3245
3
            return -1;
3246
3
        }
3247
3248
106k
        *(char*)aux1.p = 0;
3249
106k
        khint_t k = kh_get(vdict, d, t);
3250
106k
        if (k == kh_end(d) || kh_val(d, k).info[BCF_HL_FMT] == 15) {
3251
9.67k
            if ( t[0]=='.' && t[1]==0 )
3252
3
            {
3253
3
                hts_log_error("Invalid FORMAT tag name '.' at %s:%"PRIhts_pos, bcf_seqname_safe(h,v), v->pos+1);
3254
3
                v->errcode |= BCF_ERR_TAG_INVALID;
3255
3
                return -1;
3256
3
            }
3257
9.67k
            hts_log_warning("FORMAT '%s' at %s:%"PRIhts_pos" is not defined in the header, assuming Type=String", t, bcf_seqname_safe(h,v), v->pos+1);
3258
9.67k
            if ((v->errcode & (BCF_ERR_TAG_UNDEF|BCF_ERR_CTG_UNDEF)) == 0)
3259
731
                hts_log_warning("Missing headers may cause later processing to fail");
3260
9.67k
            kstring_t tmp = {0,0,0};
3261
9.67k
            int l;
3262
9.67k
            ksprintf(&tmp, "##FORMAT=<ID=%s,Number=1,Type=String,Description=\"Dummy\">", t);
3263
9.67k
            bcf_hrec_t *hrec = bcf_hdr_parse_line(h,tmp.s,&l);
3264
9.67k
            free(tmp.s);
3265
9.67k
            int res = hrec ? bcf_hdr_add_hrec((bcf_hdr_t*)h, hrec) : -1;
3266
9.67k
            if (res < 0) bcf_hrec_destroy(hrec);
3267
9.67k
            if (res > 0) res = bcf_hdr_sync((bcf_hdr_t*)h);
3268
3269
9.67k
            k = kh_get(vdict, d, t);
3270
9.67k
            v->errcode |= BCF_ERR_TAG_UNDEF;
3271
9.67k
            if (res || k == kh_end(d)) {
3272
21
                hts_log_error("Could not add dummy header for FORMAT '%s' at %s:%"PRIhts_pos, t, bcf_seqname_safe(h,v), v->pos+1);
3273
21
                v->errcode |= BCF_ERR_TAG_INVALID;
3274
21
                return -1;
3275
21
            }
3276
9.67k
        }
3277
106k
        fmt[j].max_l = fmt[j].max_m = fmt[j].max_g = 0;
3278
106k
        fmt[j].key = kh_val(d, k).id;
3279
106k
        fmt[j].is_gt = (t[0] == 'G' && t[1] == 'T' && !t[2]);
3280
106k
        fmt[j].y = h->id[0][fmt[j].key].val->info[BCF_HL_FMT];
3281
106k
        v->n_fmt++;
3282
106k
    }
3283
15.9k
    return 0;
3284
15.9k
}
3285
3286
// compute max
3287
static int vcf_parse_format_max3(kstring_t *s, const bcf_hdr_t *h, bcf1_t *v,
3288
15.9k
                                 char *p, char *q, fmt_aux_t *fmt) {
3289
15.9k
    int n_sample_ori = -1;
3290
15.9k
    char *r = q + 1;  // r: position in the format string
3291
15.9k
    int l = 0, m = 1, g = 1, j;
3292
15.9k
    v->n_sample = 0;  // m: max vector size, l: max field len, g: max number of alleles
3293
15.9k
    const char *end = s->s + s->l;
3294
3295
57.5k
    while ( r<end )
3296
57.4k
    {
3297
        // can we skip some samples?
3298
57.4k
        if ( h->keep_samples )
3299
0
        {
3300
0
            n_sample_ori++;
3301
0
            if ( !bit_array_test(h->keep_samples,n_sample_ori) )
3302
0
            {
3303
0
                while ( *r!='\t' && r<end ) r++;
3304
0
                if ( *r=='\t' ) { *r = 0; r++; }
3305
0
                continue;
3306
0
            }
3307
0
        }
3308
3309
        // collect fmt stats: max vector size, length, number of alleles
3310
57.4k
        j = 0;  // j-th format field
3311
57.4k
        fmt_aux_t *f = fmt;
3312
57.4k
        static char meta[256] = {
3313
            // \0 \t , / : |
3314
57.4k
            1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3315
57.4k
            0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1, 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,
3316
57.4k
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3317
57.4k
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
3318
57.4k
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3319
57.4k
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3320
57.4k
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3321
57.4k
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3322
57.4k
        };
3323
3324
57.4k
        char *r_start = r;
3325
6.11M
        for (;;) {
3326
            // Quickly skip ahead to an appropriate meta-character
3327
7.06M
            while (!meta[(unsigned char)*r]) r++;
3328
3329
6.11M
            switch (*r) {
3330
5.99M
            case ',':
3331
5.99M
                m++;
3332
5.99M
                break;
3333
3334
1.71k
            case '|':
3335
43.0k
            case '/':
3336
43.0k
                if (f->is_gt) g++;
3337
43.0k
                break;
3338
3339
18.1k
            case '\t':
3340
18.1k
                *r = 0; // fall through
3341
3342
18.1k
            default: // valid due to while loop above.
3343
57.3k
            case '\0':
3344
76.5k
            case ':':
3345
76.5k
                l = r - r_start; r_start = r;
3346
76.5k
                if (f->max_m < m) f->max_m = m;
3347
76.5k
                if (f->max_l < l) f->max_l = l;
3348
76.5k
                if (f->is_gt && f->max_g < g) f->max_g = g;
3349
76.5k
                l = 0, m = g = 1;
3350
76.5k
                if ( *r==':' ) {
3351
19.1k
                    j++; f++;
3352
19.1k
                    if ( j>=v->n_fmt ) {
3353
40
                        hts_log_error("Incorrect number of FORMAT fields at %s:%"PRIhts_pos"",
3354
40
                                      h->id[BCF_DT_CTG][v->rid].key, v->pos+1);
3355
40
                        v->errcode |= BCF_ERR_NCOLS;
3356
40
                        return -1;
3357
40
                    }
3358
57.3k
                } else goto end_for;
3359
19.1k
                break;
3360
6.11M
            }
3361
6.05M
            if ( r>=end ) break;
3362
6.05M
            r++;
3363
6.05M
        }
3364
57.3k
    end_for:
3365
57.3k
        v->n_sample++;
3366
57.3k
        if ( v->n_sample == bcf_hdr_nsamples(h) ) break;
3367
41.6k
        r++;
3368
41.6k
    }
3369
3370
15.8k
    return 0;
3371
15.9k
}
3372
3373
// allocate memory for arrays
3374
static int vcf_parse_format_alloc4(kstring_t *s, const bcf_hdr_t *h, bcf1_t *v,
3375
                                   const char *p, const char *q,
3376
15.8k
                                   fmt_aux_t *fmt) {
3377
15.8k
    kstring_t *mem = (kstring_t*)&h->mem;
3378
3379
15.8k
    int j;
3380
121k
    for (j = 0; j < v->n_fmt; ++j) {
3381
105k
        fmt_aux_t *f = &fmt[j];
3382
105k
        if ( !f->max_m ) f->max_m = 1;  // omitted trailing format field
3383
3384
105k
        if ((f->y>>4&0xf) == BCF_HT_STR) {
3385
105k
            f->size = f->is_gt? f->max_g << 2 : f->max_l;
3386
105k
        } else if ((f->y>>4&0xf) == BCF_HT_REAL || (f->y>>4&0xf) == BCF_HT_INT) {
3387
0
            f->size = f->max_m << 2;
3388
0
        } else {
3389
0
            hts_log_error("The format type %d at %s:%"PRIhts_pos" is currently not supported", f->y>>4&0xf, bcf_seqname_safe(h,v), v->pos+1);
3390
0
            v->errcode |= BCF_ERR_TAG_INVALID;
3391
0
            return -1;
3392
0
        }
3393
3394
105k
        if (align_mem(mem) < 0) {
3395
0
            hts_log_error("Memory allocation failure at %s:%"PRIhts_pos, bcf_seqname_safe(h,v), v->pos+1);
3396
0
            v->errcode |= BCF_ERR_LIMITS;
3397
0
            return -1;
3398
0
        }
3399
3400
        // Limit the total memory to ~2Gb per VCF row.  This should mean
3401
        // malformed VCF data is less likely to take excessive memory and/or
3402
        // time.
3403
105k
        if ((uint64_t) mem->l + v->n_sample * (uint64_t)f->size > INT_MAX) {
3404
0
            static int warned = 0;
3405
0
            if ( !warned ) hts_log_warning("Excessive memory required by FORMAT fields at %s:%"PRIhts_pos, bcf_seqname_safe(h,v), v->pos+1);
3406
0
            warned = 1;
3407
0
            v->errcode |= BCF_ERR_LIMITS;
3408
0
            f->size = -1;
3409
0
            f->offset = 0;
3410
0
            continue;
3411
0
        }
3412
3413
105k
        f->offset = mem->l;
3414
105k
        if (ks_resize(mem, mem->l + v->n_sample * (size_t)f->size) < 0) {
3415
0
            hts_log_error("Memory allocation failure at %s:%"PRIhts_pos, bcf_seqname_safe(h,v), v->pos+1);
3416
0
            v->errcode |= BCF_ERR_LIMITS;
3417
0
            return -1;
3418
0
        }
3419
105k
        mem->l += v->n_sample * f->size;
3420
105k
    }
3421
3422
15.8k
    {
3423
15.8k
        int j;
3424
121k
        for (j = 0; j < v->n_fmt; ++j)
3425
105k
            fmt[j].buf = (uint8_t*)mem->s + fmt[j].offset;
3426
15.8k
    }
3427
3428
    // check for duplicate tags
3429
15.8k
    int i;
3430
105k
    for (i=1; i<v->n_fmt; i++)
3431
90.1k
    {
3432
90.1k
        fmt_aux_t *ifmt = &fmt[i];
3433
90.1k
        if ( ifmt->size==-1 ) continue; // already marked for removal
3434
548k
        for (j=0; j<i; j++)
3435
515k
        {
3436
515k
            fmt_aux_t *jfmt = &fmt[j];
3437
515k
            if ( jfmt->size==-1 ) continue; // already marked for removal
3438
252k
            if ( ifmt->key!=jfmt->key ) continue;
3439
57.6k
            static int warned = 0;
3440
57.6k
            if ( !warned ) hts_log_warning("Duplicate FORMAT tag %s at %s:%"PRIhts_pos, bcf_hdr_int2id(h,BCF_DT_ID,ifmt->key), bcf_seqname_safe(h,v), v->pos+1);
3441
57.6k
            warned = 1;
3442
57.6k
            v->errcode |= BCF_ERR_TAG_INVALID;
3443
57.6k
            ifmt->size = -1;
3444
57.6k
            ifmt->offset = 0;
3445
57.6k
            break;
3446
252k
        }
3447
90.1k
    }
3448
15.8k
    return 0;
3449
15.8k
}
3450
3451
// Fill the sample fields
3452
static int vcf_parse_format_fill5(kstring_t *s, const bcf_hdr_t *h, bcf1_t *v,
3453
15.8k
                                  const char *p, const char *q, fmt_aux_t *fmt) {
3454
15.8k
    static int extreme_val_warned = 0;
3455
15.8k
    int n_sample_ori = -1;
3456
    // At beginning of the loop t points to the first char of a format
3457
15.8k
    const char *t = q + 1;
3458
15.8k
    int m = 0;   // m: sample id
3459
15.8k
    const int nsamples = bcf_hdr_nsamples(h);
3460
15.8k
    const char *end = s->s + s->l;
3461
3462
15.8k
    int ver = bcf_get_version(h, NULL);
3463
3464
72.3k
    while ( t<end )
3465
69.6k
    {
3466
        // can we skip some samples?
3467
69.6k
        if ( h->keep_samples )
3468
0
        {
3469
0
            n_sample_ori++;
3470
0
            if ( !bit_array_test(h->keep_samples,n_sample_ori) )
3471
0
            {
3472
0
                while ( *t && t<end ) t++;
3473
0
                t++;
3474
0
                continue;
3475
0
            }
3476
0
        }
3477
69.6k
        if ( m == nsamples ) break;
3478
3479
56.7k
        int j = 0; // j-th format field, m-th sample
3480
75.7k
        while ( t < end )
3481
74.5k
        {
3482
74.5k
            fmt_aux_t *z = &fmt[j++];
3483
74.5k
            const int htype = z->y>>4&0xf;
3484
74.5k
            if (!z->buf) {
3485
11
                hts_log_error("Memory allocation failure for FORMAT field type %d at %s:%"PRIhts_pos,
3486
11
                              z->y>>4&0xf, bcf_seqname_safe(h,v), v->pos+1);
3487
11
                v->errcode |= BCF_ERR_LIMITS;
3488
11
                return -1;
3489
11
            }
3490
3491
74.5k
            if ( z->size==-1 )
3492
6.07k
            {
3493
                // this field is to be ignored, it's either too big or a duplicate
3494
97.6k
                while ( *t != ':' && *t ) t++;
3495
6.07k
            }
3496
68.5k
            else if (htype == BCF_HT_STR) {
3497
68.5k
                int l;
3498
68.5k
                if (z->is_gt) {
3499
                    // Genotypes.
3500
                    //([/|])?<val>)([|/]<val>)+... where <val> is [0-9]+ or ".".
3501
7.75k
                    int32_t is_phased = 0;
3502
7.75k
                    uint32_t *x = (uint32_t*)(z->buf + z->size * (size_t)m);
3503
7.75k
                    uint32_t unreadable = 0;
3504
7.75k
                    uint32_t max = 0;
3505
7.75k
                    int overflow = 0, ploidy = 0, anyunphased = 0, \
3506
7.75k
                        phasingprfx = 0, unknown1 = 0;
3507
3508
                    /* with prefixed phasing, it is explicitly given for 1st one
3509
                    with non-prefixed, set based on ploidy and phasing of other
3510
                    alleles. */
3511
7.75k
                    if (ver >= VCF44 && (*t == '|' || *t == '/')) {
3512
                        // cache prefix and phasing status
3513
178
                        is_phased = *t++ == '|';
3514
178
                        phasingprfx = 1;
3515
178
                    }
3516
3517
34.5k
                    for (l = 0;; ++t) {
3518
34.5k
                        ploidy++;
3519
34.5k
                        if (*t == '.') {
3520
12.6k
                            ++t, x[l++] = is_phased;
3521
12.6k
                            if (l==1) {   //for 1st allele only
3522
3.54k
                                unknown1 = 1;
3523
3.54k
                            }
3524
21.9k
                        } else {
3525
21.9k
                            const char *tt = t;
3526
21.9k
                            uint32_t val;
3527
                            // Or "v->n_allele < 10", but it doesn't
3528
                            // seem to be any faster and this feels safer.
3529
21.9k
                            if (*t >= '0' && *t <= '9' &&
3530
20.5k
                                !(t[1] >= '0' && t[1] <= '9')) {
3531
11.3k
                                val = *t++ - '0';
3532
11.3k
                            } else {
3533
10.5k
                                val = hts_str2uint(t, (char **)&t,
3534
10.5k
                                                   sizeof(val) * CHAR_MAX - 2,
3535
10.5k
                                                   &overflow);
3536
10.5k
                                unreadable |= tt == t;
3537
10.5k
                            }
3538
21.9k
                            if (max < val) max = val;
3539
21.9k
                            x[l++] = (val + 1) << 1 | is_phased;
3540
21.9k
                        }
3541
34.5k
                        anyunphased |= (ploidy != 1) && !is_phased;
3542
34.5k
                        is_phased = (*t == '|');
3543
34.5k
                        if (*t != '|' && *t != '/') break;
3544
34.5k
                    }
3545
7.75k
                    if (!phasingprfx) { //get GT in v44 way when no prefixed phasing
3546
                        /* no explicit phasing for 1st allele, set based on
3547
                         other alleles and ploidy */
3548
7.57k
                        if (ploidy == 1) {  //implicitly phased
3549
1.11k
                            if (!unknown1) {
3550
834
                                x[0] |= 1;
3551
834
                            }
3552
6.46k
                        } else {            //set by other unphased alleles
3553
6.46k
                            x[0] |= (anyunphased)? 0 : 1;
3554
6.46k
                        }
3555
7.57k
                    }
3556
                    // Possibly check max against v->n_allele instead?
3557
7.75k
                    if (overflow || max > (INT32_MAX >> 1) - 1) {
3558
97
                        hts_log_error("Couldn't read GT data: value too large at %s:%"PRIhts_pos, bcf_seqname_safe(h,v), v->pos+1);
3559
97
                        return -1;
3560
97
                    }
3561
7.65k
                    if (unreadable) {
3562
171
                        hts_log_error("Couldn't read GT data: value not a number or '.' at %s:%"PRIhts_pos, bcf_seqname_safe(h,v), v->pos+1);
3563
171
                        return -1;
3564
171
                    }
3565
7.48k
                    if ( !l ) x[l++] = 0;   // An empty field, insert missing value
3566
9.05k
                    for (; l < z->size>>2; ++l)
3567
1.56k
                        x[l] = bcf_int32_vector_end;
3568
3569
60.7k
                } else {
3570
                    // Otherwise arbitrary strings
3571
60.7k
                    char *x = (char*)z->buf + z->size * (size_t)m;
3572
6.48M
                    for (l = 0; *t != ':' && *t; ++t)
3573
6.42M
                        x[l++] = *t;
3574
60.7k
                    if (z->size > l)
3575
42.1k
                        memset(&x[l], 0, (z->size-l) * sizeof(*x));
3576
60.7k
                }
3577
3578
68.5k
            } else if (htype == BCF_HT_INT) {
3579
                // One or more integers in an array
3580
0
                int32_t *x = (int32_t*)(z->buf + z->size * (size_t)m);
3581
0
                int l;
3582
0
                for (l = 0;; ++t) {
3583
0
                    if (*t == '.') {
3584
0
                        x[l++] = bcf_int32_missing, ++t; // ++t to skip "."
3585
0
                    } else {
3586
0
                        int overflow = 0;
3587
0
                        char *te;
3588
0
                        long int tmp_val = hts_str2int(t, &te, sizeof(tmp_val)*CHAR_BIT, &overflow);
3589
0
                        if ( te==t || overflow || tmp_val<BCF_MIN_BT_INT32 || tmp_val>BCF_MAX_BT_INT32 )
3590
0
                        {
3591
0
                            if ( !extreme_val_warned )
3592
0
                            {
3593
0
                                hts_log_warning("Extreme FORMAT/%s value encountered and set to missing at %s:%"PRIhts_pos,
3594
0
                                                h->id[BCF_DT_ID][fmt[j-1].key].key, bcf_seqname_safe(h,v), v->pos+1);
3595
0
                                extreme_val_warned = 1;
3596
0
                            }
3597
0
                            tmp_val = bcf_int32_missing;
3598
0
                        }
3599
0
                        x[l++] = tmp_val;
3600
0
                        t = te;
3601
0
                    }
3602
0
                    if (*t != ',') break;
3603
0
                }
3604
0
                if ( !l )
3605
0
                    x[l++] = bcf_int32_missing;
3606
0
                for (; l < z->size>>2; ++l)
3607
0
                    x[l] = bcf_int32_vector_end;
3608
3609
0
            } else if (htype == BCF_HT_REAL) {
3610
                // One of more floating point values in an array
3611
0
                float *x = (float*)(z->buf + z->size * (size_t)m);
3612
0
                int l;
3613
0
                for (l = 0;; ++t) {
3614
0
                    if (*t == '.' && !isdigit_c(t[1])) {
3615
0
                        bcf_float_set_missing(x[l++]), ++t; // ++t to skip "."
3616
0
                    } else {
3617
0
                        int overflow = 0;
3618
0
                        char *te;
3619
0
                        float tmp_val = hts_str2dbl(t, &te, &overflow);
3620
0
                        if ( (te==t || overflow) && !extreme_val_warned )
3621
0
                        {
3622
0
                            hts_log_warning("Extreme FORMAT/%s value encountered at %s:%"PRIhts_pos, h->id[BCF_DT_ID][fmt[j-1].key].key, bcf_seqname(h,v), v->pos+1);
3623
0
                            extreme_val_warned = 1;
3624
0
                        }
3625
0
                        x[l++] = tmp_val;
3626
0
                        t = te;
3627
0
                    }
3628
0
                    if (*t != ',') break;
3629
0
                }
3630
0
                if ( !l )
3631
                    // An empty field, insert missing value
3632
0
                    bcf_float_set_missing(x[l++]);
3633
0
                for (; l < z->size>>2; ++l)
3634
0
                    bcf_float_set_vector_end(x[l]);
3635
0
            } else {
3636
0
                hts_log_error("Unknown FORMAT field type %d at %s:%"PRIhts_pos, htype, bcf_seqname_safe(h,v), v->pos+1);
3637
0
                v->errcode |= BCF_ERR_TAG_INVALID;
3638
0
                return -1;
3639
0
            }
3640
3641
74.3k
            if (*t == '\0') {
3642
55.3k
                break;
3643
55.3k
            }
3644
18.9k
            else if (*t == ':') {
3645
18.9k
                t++;
3646
18.9k
            }
3647
32
            else {
3648
32
                char buffer[8];
3649
32
                hts_log_error("Invalid character %s in '%s' FORMAT field at %s:%"PRIhts_pos"",
3650
32
                    hts_strprint(buffer, sizeof buffer, '\'', t, 1),
3651
32
                    h->id[BCF_DT_ID][z->key].key, bcf_seqname_safe(h,v), v->pos+1);
3652
32
                v->errcode |= BCF_ERR_CHAR;
3653
32
                return -1;
3654
32
            }
3655
74.3k
        }
3656
3657
        // fill end-of-vector values
3658
632k
        for (; j < v->n_fmt; ++j) {
3659
576k
            fmt_aux_t *z = &fmt[j];
3660
576k
            const int htype = z->y>>4&0xf;
3661
576k
            int l;
3662
3663
576k
            if (z->size == -1) // this field is to be ignored
3664
404k
                continue;
3665
3666
171k
            if (htype == BCF_HT_STR) {
3667
171k
                if (z->is_gt) {
3668
32.1k
                    int32_t *x = (int32_t*)(z->buf + z->size * (size_t)m);
3669
32.1k
                    if (z->size) x[0] = bcf_int32_missing;
3670
96.0k
                    for (l = 1; l < z->size>>2; ++l) x[l] = bcf_int32_vector_end;
3671
139k
                } else {
3672
139k
                    char *x = (char*)z->buf + z->size * (size_t)m;
3673
139k
                    if ( z->size ) {
3674
13.8k
                        x[0] = '.';
3675
13.8k
                        memset(&x[1], 0, (z->size-1) * sizeof(*x));
3676
13.8k
                    }
3677
139k
                }
3678
171k
            } else if (htype == BCF_HT_INT) {
3679
0
                int32_t *x = (int32_t*)(z->buf + z->size * (size_t)m);
3680
0
                x[0] = bcf_int32_missing;
3681
0
                for (l = 1; l < z->size>>2; ++l) x[l] = bcf_int32_vector_end;
3682
0
            } else if (htype == BCF_HT_REAL) {
3683
0
                float *x = (float*)(z->buf + z->size * (size_t)m);
3684
0
                bcf_float_set_missing(x[0]);
3685
0
                for (l = 1; l < z->size>>2; ++l) bcf_float_set_vector_end(x[l]);
3686
0
            }
3687
171k
        }
3688
3689
56.4k
        m++; t++;
3690
56.4k
    }
3691
3692
15.5k
    return 0;
3693
15.8k
}
3694
3695
// write individual genotype information
3696
static int vcf_parse_format_gt6(kstring_t *s, const bcf_hdr_t *h, bcf1_t *v,
3697
15.5k
                                const char *p, const char *q, fmt_aux_t *fmt) {
3698
15.5k
    kstring_t *str = &v->indiv;
3699
15.5k
    int i, need_downsize = 0;
3700
15.5k
    if (v->n_sample > 0) {
3701
115k
        for (i = 0; i < v->n_fmt; ++i) {
3702
100k
            fmt_aux_t *z = &fmt[i];
3703
100k
            if ( z->size==-1 ) {
3704
53.1k
                need_downsize = 1;
3705
53.1k
                continue;
3706
53.1k
            }
3707
47.2k
            bcf_enc_int1(str, z->key);
3708
47.2k
            if ((z->y>>4&0xf) == BCF_HT_STR && !z->is_gt) {
3709
38.7k
                bcf_enc_size(str, z->size, BCF_BT_CHAR);
3710
38.7k
                kputsn((char*)z->buf, z->size * (size_t)v->n_sample, str);
3711
38.7k
            } else if ((z->y>>4&0xf) == BCF_HT_INT || z->is_gt) {
3712
8.48k
                bcf_enc_vint(str, (z->size>>2) * v->n_sample, (int32_t*)z->buf, z->size>>2);
3713
8.48k
            } else {
3714
0
                bcf_enc_size(str, z->size>>2, BCF_BT_FLOAT);
3715
0
                if (serialize_float_array(str, (z->size>>2) * (size_t)v->n_sample,
3716
0
                                          (float *) z->buf) != 0) {
3717
0
                    v->errcode |= BCF_ERR_LIMITS;
3718
0
                    hts_log_error("Out of memory at %s:%"PRIhts_pos, bcf_seqname_safe(h,v), v->pos+1);
3719
0
                    return -1;
3720
0
                }
3721
0
            }
3722
47.2k
        }
3723
3724
15.5k
    }
3725
15.5k
    if ( need_downsize ) {
3726
3.59k
        i = 0;
3727
72.5k
        while ( i < v->n_fmt ) {
3728
68.9k
            if ( fmt[i].size==-1 )
3729
53.1k
            {
3730
53.1k
                v->n_fmt--;
3731
53.1k
                if ( i < v->n_fmt ) memmove(&fmt[i],&fmt[i+1],sizeof(*fmt)*(v->n_fmt-i));
3732
53.1k
            }
3733
15.8k
            else
3734
15.8k
                i++;
3735
68.9k
        }
3736
3.59k
    }
3737
15.5k
    return 0;
3738
15.5k
}
3739
3740
// validity checking
3741
15.5k
static int vcf_parse_format_check7(const bcf_hdr_t *h, bcf1_t *v) {
3742
15.5k
    if ( v->n_sample!=bcf_hdr_nsamples(h) )
3743
130
    {
3744
130
        hts_log_error("Number of columns at %s:%"PRIhts_pos" does not match the number of samples (%d vs %d)",
3745
130
            bcf_seqname_safe(h,v), v->pos+1, v->n_sample, bcf_hdr_nsamples(h));
3746
130
        v->errcode |= BCF_ERR_NCOLS;
3747
130
        return -1;
3748
130
    }
3749
15.4k
    if ( v->indiv.l > 0xffffffff )
3750
0
    {
3751
0
        hts_log_error("The FORMAT at %s:%"PRIhts_pos" is too long", bcf_seqname_safe(h,v), v->pos+1);
3752
0
        v->errcode |= BCF_ERR_LIMITS;
3753
3754
        // Error recovery: return -1 if this is a critical error or 0 if we want to ignore the FORMAT and proceed
3755
0
        v->n_fmt = 0;
3756
0
        return -1;
3757
0
    }
3758
3759
15.4k
    return 0;
3760
15.4k
}
3761
3762
// p,q is the start and the end of the FORMAT field
3763
static int vcf_parse_format(kstring_t *s, const bcf_hdr_t *h, bcf1_t *v,
3764
                            char *p, char *q)
3765
54.2k
{
3766
54.2k
    if ( !bcf_hdr_nsamples(h) ) return 0;
3767
16.6k
    kstring_t *mem = (kstring_t*)&h->mem;
3768
16.6k
    mem->l = 0;
3769
3770
16.6k
    fmt_aux_t fmt[MAX_N_FMT];
3771
3772
    // detect FORMAT "."
3773
16.6k
    int ret; // +ve = ok, -ve = err
3774
16.6k
    if ((ret = vcf_parse_format_empty1(s, h, v, p, q)))
3775
660
        return ret ? 0 : -1;
3776
3777
    // get format information from the dictionary
3778
15.9k
    if (vcf_parse_format_dict2(s, h, v, p, q, fmt) < 0)
3779
27
        return -1;
3780
3781
    // FORMAT data is per-sample A:B:C A:B:C A:B:C ... but in memory it is
3782
    // stored as per-type arrays AAA... BBB... CCC...  This is basically
3783
    // a data rotation or pivot.
3784
3785
    // The size of elements in the array grow to their maximum needed,
3786
    // permitting fast random access.  This means however we have to first
3787
    // scan the whole FORMAT line to find the maximum of each type, and
3788
    // then scan it again to find the store the data.
3789
    // We break this down into compute-max, allocate, fill-out-buffers
3790
3791
    // TODO: ?
3792
    // The alternative would be to pivot on the first pass, with fixed
3793
    // size entries for numerics and concatenated strings otherwise, also
3794
    // tracking maximum sizes.  Then on a second pass we reallocate and
3795
    // copy the data again to a uniformly sized array.  Two passes through
3796
    // memory, but without doubling string parsing.
3797
3798
    // compute max
3799
15.9k
    if (vcf_parse_format_max3(s, h, v, p, q, fmt) < 0)
3800
40
        return -1;
3801
3802
    // allocate memory for arrays
3803
15.8k
    if (vcf_parse_format_alloc4(s, h, v, p, q, fmt) < 0)
3804
0
        return -1;
3805
3806
    // fill the sample fields; at beginning of the loop
3807
15.8k
    if (vcf_parse_format_fill5(s, h, v, p, q, fmt) < 0)
3808
311
        return -1;
3809
3810
    // write individual genotype information
3811
15.5k
    if (vcf_parse_format_gt6(s, h, v, p, q, fmt) < 0)
3812
0
        return -1;
3813
3814
    // validity checking
3815
15.5k
    if (vcf_parse_format_check7(h, v) < 0)
3816
130
        return -1;
3817
3818
15.4k
    return 0;
3819
15.5k
}
3820
3821
4.99k
static khint_t fix_chromosome(const bcf_hdr_t *h, vdict_t *d, const char *p) {
3822
    // Simple error recovery for chromosomes not defined in the header. It will not help when VCF header has
3823
    // been already printed, but will enable tools like vcfcheck to proceed.
3824
3825
4.99k
    kstring_t tmp = {0,0,0};
3826
4.99k
    khint_t k;
3827
4.99k
    int l;
3828
4.99k
    if (ksprintf(&tmp, "##contig=<ID=%s>", p) < 0)
3829
0
        return kh_end(d);
3830
4.99k
    bcf_hrec_t *hrec = bcf_hdr_parse_line(h,tmp.s,&l);
3831
4.99k
    free(tmp.s);
3832
4.99k
    int res = hrec ? bcf_hdr_add_hrec((bcf_hdr_t*)h, hrec) : -1;
3833
4.99k
    if (res < 0) bcf_hrec_destroy(hrec);
3834
4.99k
    if (res > 0) res = bcf_hdr_sync((bcf_hdr_t*)h);
3835
4.99k
    k = kh_get(vdict, d, p);
3836
3837
4.99k
    return k;
3838
4.99k
}
3839
3840
53.0k
static int vcf_parse_filter(kstring_t *str, const bcf_hdr_t *h, bcf1_t *v, char *p, char *q) {
3841
53.0k
    int i, n_flt = 1, max_n_flt = 0;
3842
53.0k
    char *r, *t;
3843
53.0k
    int32_t *a_flt = NULL;
3844
53.0k
    ks_tokaux_t aux1;
3845
53.0k
    khint_t k;
3846
53.0k
    vdict_t *d = (vdict_t*)h->dict[BCF_DT_ID];
3847
    // count the number of filters
3848
53.0k
    if (*(q-1) == ';') *(q-1) = 0;
3849
21.8M
    for (r = p; *r; ++r)
3850
21.7M
        if (*r == ';') ++n_flt;
3851
53.0k
    if (n_flt > max_n_flt) {
3852
53.0k
        a_flt = hts_malloc_p(sizeof(*a_flt), n_flt);
3853
53.0k
        if (!a_flt) {
3854
0
            hts_log_error("Could not allocate memory at %s:%"PRIhts_pos, bcf_seqname_safe(h,v), v->pos+1);
3855
0
            v->errcode |= BCF_ERR_LIMITS; // No appropriate code?
3856
0
            return -1;
3857
0
        }
3858
53.0k
        max_n_flt = n_flt;
3859
53.0k
    }
3860
    // add filters
3861
287k
    for (t = kstrtok(p, ";", &aux1), i = 0; t; t = kstrtok(0, 0, &aux1)) {
3862
234k
        *(char*)aux1.p = 0;
3863
234k
        k = kh_get(vdict, d, t);
3864
234k
        if (k == kh_end(d))
3865
19.3k
        {
3866
            // Simple error recovery for FILTERs not defined in the header. It will not help when VCF header has
3867
            // been already printed, but will enable tools like vcfcheck to proceed.
3868
19.3k
            hts_log_warning("FILTER '%s' at %s:%"PRIhts_pos" is not defined in the header",
3869
19.3k
                            t, bcf_seqname_safe(h,v), v->pos+1);
3870
19.3k
            if ((v->errcode & (BCF_ERR_TAG_UNDEF|BCF_ERR_CTG_UNDEF)) == 0)
3871
1.46k
                hts_log_warning("Missing headers may cause later processing to fail");
3872
19.3k
            kstring_t tmp = {0,0,0};
3873
19.3k
            int l;
3874
19.3k
            ksprintf(&tmp, "##FILTER=<ID=%s,Description=\"Dummy\">", t);
3875
19.3k
            bcf_hrec_t *hrec = bcf_hdr_parse_line(h,tmp.s,&l);
3876
19.3k
            free(tmp.s);
3877
19.3k
            int res = hrec ? bcf_hdr_add_hrec((bcf_hdr_t*)h, hrec) : -1;
3878
19.3k
            if (res < 0) bcf_hrec_destroy(hrec);
3879
19.3k
            if (res > 0) res = bcf_hdr_sync((bcf_hdr_t*)h);
3880
19.3k
            k = kh_get(vdict, d, t);
3881
19.3k
            v->errcode |= BCF_ERR_TAG_UNDEF;
3882
19.3k
            if (res || k == kh_end(d)) {
3883
50
                hts_log_error("Could not add dummy header for FILTER '%s' at %s:%"PRIhts_pos, t, bcf_seqname_safe(h,v), v->pos+1);
3884
50
                v->errcode |= BCF_ERR_TAG_INVALID;
3885
50
                free(a_flt);
3886
50
                return -1;
3887
50
            }
3888
19.3k
        }
3889
234k
        a_flt[i++] = kh_val(d, k).id;
3890
234k
    }
3891
3892
52.9k
    bcf_enc_vint(str, n_flt, a_flt, -1);
3893
52.9k
    free(a_flt);
3894
3895
52.9k
    return 0;
3896
53.0k
}
3897
3898
58.1k
static int vcf_parse_info(kstring_t *str, const bcf_hdr_t *h, bcf1_t *v, char *p, char *q) {
3899
58.1k
    static int extreme_int_warned = 0, negative_rlen_warned = 0;
3900
58.1k
    int max_n_val = 0, overflow = 0;
3901
58.1k
    char *r, *key;
3902
58.1k
    khint_t k;
3903
58.1k
    vdict_t *d = (vdict_t*)h->dict[BCF_DT_ID];
3904
58.1k
    int32_t *a_val = NULL;
3905
3906
58.1k
    v->n_info = 0;
3907
58.1k
    if (*(q-1) == ';') *(q-1) = 0;
3908
95.9k
    for (r = key = p;; ++r) {
3909
95.9k
        int c;
3910
95.9k
        char *val, *end;
3911
3.02M
        while (*r > '=' || (*r != ';' && *r != '=' && *r != 0)) r++;
3912
95.9k
        if (v->n_info == UINT16_MAX) {
3913
0
            hts_log_error("Too many INFO entries at %s:%"PRIhts_pos,
3914
0
                          bcf_seqname_safe(h,v), v->pos+1);
3915
0
            v->errcode |= BCF_ERR_LIMITS;
3916
0
            goto fail;
3917
0
        }
3918
95.9k
        val = end = NULL;
3919
95.9k
        c = *r; *r = 0;
3920
95.9k
        if (c == '=') {
3921
6.74k
            val = r + 1;
3922
3923
1.90M
            for (end = val; *end != ';' && *end != 0; ++end);
3924
6.74k
            c = *end; *end = 0;
3925
89.1k
        } else end = r;
3926
95.9k
        if ( !*key ) { if (c==0) break; r = end; key = r + 1; continue; }  // faulty VCF, ";;" in the INFO
3927
58.9k
        k = kh_get(vdict, d, key);
3928
58.9k
        if (k == kh_end(d) || kh_val(d, k).info[BCF_HL_INFO] == 15)
3929
10.5k
        {
3930
10.5k
            hts_log_warning("INFO '%s' at %s:%"PRIhts_pos" is not defined in the header, assuming Type=String",
3931
10.5k
                            key, bcf_seqname_safe(h,v), v->pos+1);
3932
10.5k
            if ((v->errcode & (BCF_ERR_TAG_UNDEF|BCF_ERR_CTG_UNDEF)) == 0)
3933
910
                hts_log_warning("Missing headers may cause later processing to fail");
3934
10.5k
            kstring_t tmp = {0,0,0};
3935
10.5k
            int l;
3936
10.5k
            ksprintf(&tmp, "##INFO=<ID=%s,Number=1,Type=String,Description=\"Dummy\">", key);
3937
10.5k
            bcf_hrec_t *hrec = bcf_hdr_parse_line(h,tmp.s,&l);
3938
10.5k
            free(tmp.s);
3939
10.5k
            int res = hrec ? bcf_hdr_add_hrec((bcf_hdr_t*)h, hrec) : -1;
3940
10.5k
            if (res < 0) bcf_hrec_destroy(hrec);
3941
10.5k
            if (res > 0) res = bcf_hdr_sync((bcf_hdr_t*)h);
3942
10.5k
            k = kh_get(vdict, d, key);
3943
10.5k
            v->errcode |= BCF_ERR_TAG_UNDEF;
3944
10.5k
            if (res || k == kh_end(d)) {
3945
117
                hts_log_error("Could not add dummy header for INFO '%s' at %s:%"PRIhts_pos, key, bcf_seqname_safe(h,v), v->pos+1);
3946
117
                v->errcode |= BCF_ERR_TAG_INVALID;
3947
117
                goto fail;
3948
117
            }
3949
10.5k
        }
3950
58.8k
        uint32_t y = kh_val(d, k).info[BCF_HL_INFO];
3951
58.8k
        ++v->n_info;
3952
58.8k
        bcf_enc_int1(str, kh_val(d, k).id);
3953
58.8k
        if (val == 0) {
3954
52.3k
            bcf_enc_size(str, 0, BCF_BT_NULL);
3955
52.3k
        } else if ((y>>4&0xf) == BCF_HT_FLAG || (y>>4&0xf) == BCF_HT_STR) { // if Flag has a value, treat it as a string
3956
6.44k
            bcf_enc_vchar(str, end - val, val);
3957
6.44k
        } else { // int/float value/array
3958
0
            int i, n_val;
3959
0
            char *t, *te;
3960
0
            for (t = val, n_val = 1; *t; ++t) // count the number of values
3961
0
                if (*t == ',') ++n_val;
3962
            // Check both int and float size in one step for simplicity
3963
0
            if (n_val > max_n_val) {
3964
0
                int32_t *a_tmp = hts_realloc_p(a_val, sizeof(*a_val), n_val);
3965
0
                if (!a_tmp) {
3966
0
                    hts_log_error("Could not allocate memory at %s:%"PRIhts_pos, bcf_seqname_safe(h,v), v->pos+1);
3967
0
                    v->errcode |= BCF_ERR_LIMITS; // No appropriate code?
3968
0
                    goto fail;
3969
0
                }
3970
0
                a_val = a_tmp;
3971
0
                max_n_val = n_val;
3972
0
            }
3973
0
            if ((y>>4&0xf) == BCF_HT_INT) {
3974
0
                i = 0, t = val;
3975
0
                int64_t val1;
3976
0
                int is_int64 = 0;
3977
#ifdef VCF_ALLOW_INT64
3978
                if ( n_val==1 )
3979
                {
3980
                    overflow = 0;
3981
                    long long int tmp_val = hts_str2int(val, &te, sizeof(tmp_val)*CHAR_BIT, &overflow);
3982
                    if ( te==val ) tmp_val = bcf_int32_missing;
3983
                    else if ( overflow || tmp_val<BCF_MIN_BT_INT64 || tmp_val>BCF_MAX_BT_INT64 )
3984
                    {
3985
                        if ( !extreme_int_warned )
3986
                        {
3987
                            hts_log_warning("Extreme INFO/%s value encountered and set to missing at %s:%"PRIhts_pos,key,bcf_seqname_safe(h,v), v->pos+1);
3988
                            extreme_int_warned = 1;
3989
                        }
3990
                        tmp_val = bcf_int32_missing;
3991
                    }
3992
                    else
3993
                        is_int64 = 1;
3994
                    val1 = tmp_val;
3995
                    t = te;
3996
                    i = 1;  // this is just to avoid adding another nested block...
3997
                }
3998
#endif
3999
0
                for (; i < n_val; ++i, ++t)
4000
0
                {
4001
0
                    overflow = 0;
4002
0
                    long int tmp_val = hts_str2int(t, &te, sizeof(tmp_val)*CHAR_BIT, &overflow);
4003
0
                    if ( te==t ) tmp_val = bcf_int32_missing;
4004
0
                    else if ( overflow || tmp_val<BCF_MIN_BT_INT32 || tmp_val>BCF_MAX_BT_INT32 )
4005
0
                    {
4006
0
                        if ( !extreme_int_warned )
4007
0
                        {
4008
0
                            hts_log_warning("Extreme INFO/%s value encountered and set to missing at %s:%"PRIhts_pos,key,bcf_seqname_safe(h,v), v->pos+1);
4009
0
                            extreme_int_warned = 1;
4010
0
                        }
4011
0
                        tmp_val = bcf_int32_missing;
4012
0
                    }
4013
0
                    a_val[i] = tmp_val;
4014
0
                    for (t = te; *t && *t != ','; t++);
4015
0
                }
4016
0
                if (n_val == 1) {
4017
#ifdef VCF_ALLOW_INT64
4018
                    if ( is_int64 )
4019
                    {
4020
                        v->unpacked |= BCF_IS_64BIT;
4021
                        bcf_enc_long1(str, val1);
4022
                    }
4023
                    else
4024
                        bcf_enc_int1(str, (int32_t)val1);
4025
#else
4026
0
                    val1 = a_val[0];
4027
0
                    bcf_enc_int1(str, (int32_t)val1);
4028
0
#endif
4029
0
                } else {
4030
0
                    bcf_enc_vint(str, n_val, a_val, -1);
4031
0
                }
4032
0
                if (n_val==1 && (val1!=bcf_int32_missing || is_int64)
4033
0
                    && memcmp(key, "END", 4) == 0)
4034
0
                {
4035
0
                    if ( val1 <= v->pos )
4036
0
                    {
4037
0
                        if ( !negative_rlen_warned )
4038
0
                        {
4039
0
                            hts_log_warning("INFO/END=%"PRIhts_pos" is smaller than POS at %s:%"PRIhts_pos,val1,bcf_seqname_safe(h,v),v->pos+1);
4040
0
                            negative_rlen_warned = 1;
4041
0
                        }
4042
0
                    }
4043
0
                }
4044
0
            } else if ((y>>4&0xf) == BCF_HT_REAL) {
4045
0
                float *val_f = (float *)a_val;
4046
0
                for (i = 0, t = val; i < n_val; ++i, ++t)
4047
0
                {
4048
0
                    overflow = 0;
4049
0
                    val_f[i] = hts_str2dbl(t, &te, &overflow);
4050
0
                    if ( te==t || overflow ) // conversion failed
4051
0
                        bcf_float_set_missing(val_f[i]);
4052
0
                    for (t = te; *t && *t != ','; t++);
4053
0
                }
4054
0
                bcf_enc_vfloat(str, n_val, val_f);
4055
0
            }
4056
0
        }
4057
58.8k
        if (c == 0) break;
4058
30.0k
        r = end;
4059
30.0k
        key = r + 1;
4060
30.0k
    }
4061
4062
58.0k
    free(a_val);
4063
58.0k
    return 0;
4064
4065
117
 fail:
4066
117
    free(a_val);
4067
117
    return -1;
4068
58.1k
}
4069
4070
int vcf_parse(kstring_t *s, const bcf_hdr_t *h, bcf1_t *v)
4071
60.6k
{
4072
60.6k
    int ret = -2, overflow = 0;
4073
60.6k
    char *p, *q, *r, *t;
4074
60.6k
    kstring_t *str;
4075
60.6k
    khint_t k;
4076
60.6k
    ks_tokaux_t aux;
4077
4078
//#define NOT_DOT(p) strcmp((p), ".")
4079
//#define NOT_DOT(p) (!(*p == '.' && !p[1]))
4080
//#define NOT_DOT(p) ((*p) != '.' || (p)[1])
4081
//#define NOT_DOT(p) (q-p != 1 || memcmp(p, ".\0", 2))
4082
300k
#define NOT_DOT(p) (memcmp(p, ".\0", 2))
4083
4084
60.6k
    if (!s || !h || !v || !(s->s))
4085
0
        return ret;
4086
4087
    // Assumed in lots of places, but we may as well spot this early
4088
60.6k
    assert(sizeof(float) == sizeof(int32_t));
4089
4090
    // Ensure string we parse has space to permit some over-flow when during
4091
    // parsing.  Eg to do memcmp(key, "END", 4) in vcf_parse_info over
4092
    // the more straight forward looking strcmp, giving a speed advantage.
4093
60.6k
    if (ks_resize(s, s->l+4) < 0)
4094
0
        return -2;
4095
4096
    // Force our memory to be initialised so we avoid the technicality of
4097
    // undefined behaviour in using a 4-byte memcmp.  (The reality is this
4098
    // almost certainly is never detected by the compiler so has no impact,
4099
    // but equally so this code has minimal (often beneficial) impact on
4100
    // performance too.)
4101
60.6k
    s->s[s->l+0] = 0;
4102
60.6k
    s->s[s->l+1] = 0;
4103
60.6k
    s->s[s->l+2] = 0;
4104
60.6k
    s->s[s->l+3] = 0;
4105
4106
60.6k
    bcf_clear1(v);
4107
60.6k
    str = &v->shared;
4108
60.6k
    memset(&aux, 0, sizeof(ks_tokaux_t));
4109
4110
    // CHROM
4111
60.6k
    if (!(p = kstrtok(s->s, "\t", &aux)))
4112
0
        goto err;
4113
60.6k
    *(q = (char*)aux.p) = 0;
4114
4115
60.6k
    vdict_t *d = (vdict_t*)h->dict[BCF_DT_CTG];
4116
60.6k
    k = kh_get(vdict, d, p);
4117
60.6k
    if (k == kh_end(d)) {
4118
4.99k
        hts_log_warning("Contig '%s' is not defined in the header. (Quick workaround: index the file with tabix.)", p);
4119
4.99k
            if ((v->errcode & (BCF_ERR_TAG_UNDEF|BCF_ERR_CTG_UNDEF)) == 0)
4120
4.99k
                hts_log_warning("Missing headers may cause later processing to fail");
4121
4.99k
        v->errcode = BCF_ERR_CTG_UNDEF;
4122
4.99k
        if ((k = fix_chromosome(h, d, p)) == kh_end(d)) {
4123
53
            hts_log_error("Could not add dummy header for contig '%s'", p);
4124
53
            v->errcode |= BCF_ERR_CTG_INVALID;
4125
53
            goto err;
4126
53
        }
4127
4.99k
    }
4128
60.5k
    v->rid = kh_val(d, k).id;
4129
4130
    // POS
4131
60.5k
    if (!(p = kstrtok(0, 0, &aux)))
4132
100
        goto err;
4133
60.4k
    *(q = (char*)aux.p) = 0;
4134
4135
60.4k
    overflow = 0;
4136
60.4k
    char *tmp = p;
4137
60.4k
    v->pos = hts_str2uint(p, &p, 62, &overflow);
4138
60.4k
    if (overflow) {
4139
45
        hts_log_error("Position value '%s' is too large", tmp);
4140
45
        goto err;
4141
60.4k
    } else if ( *p ) {
4142
114
        hts_log_error("Could not parse the position '%s'", tmp);
4143
114
        goto err;
4144
60.2k
    } else {
4145
60.2k
        v->pos -= 1;
4146
60.2k
    }
4147
60.2k
    if (v->pos >= INT32_MAX)
4148
1.83k
        v->unpacked |= BCF_IS_64BIT;
4149
4150
    // ID
4151
60.2k
    if (!(p = kstrtok(0, 0, &aux)))
4152
56
        goto err;
4153
60.2k
    *(q = (char*)aux.p) = 0;
4154
4155
60.2k
    if (NOT_DOT(p)) bcf_enc_vchar(str, q - p, p);
4156
588
    else bcf_enc_size(str, 0, BCF_BT_CHAR);
4157
4158
    // REF
4159
60.2k
    if (!(p = kstrtok(0, 0, &aux)))
4160
45
        goto err;
4161
60.1k
    *(q = (char*)aux.p) = 0;
4162
4163
60.1k
    bcf_enc_vchar(str, q - p, p);
4164
60.1k
    v->n_allele = 1, v->rlen = q - p;
4165
4166
    // ALT
4167
60.1k
    if (!(p = kstrtok(0, 0, &aux)))
4168
40
        goto err;
4169
60.1k
    *(q = (char*)aux.p) = 0;
4170
4171
60.1k
    if (NOT_DOT(p)) {
4172
5.51M
        for (r = t = p;; ++r) {
4173
5.51M
            if (*r == ',' || *r == 0) {
4174
2.63M
                if (v->n_allele == UINT16_MAX) {
4175
2
                    hts_log_error("Too many ALT alleles at %s:%"PRIhts_pos,
4176
2
                                  bcf_seqname_safe(h,v), v->pos+1);
4177
2
                    v->errcode |= BCF_ERR_LIMITS;
4178
2
                    goto err;
4179
2
                }
4180
2.63M
                bcf_enc_vchar(str, r - t, t);
4181
2.63M
                t = r + 1;
4182
2.63M
                ++v->n_allele;
4183
2.63M
            }
4184
5.51M
            if (r == q) break;
4185
5.51M
        }
4186
59.1k
    }
4187
4188
    // QUAL
4189
60.1k
    if (!(p = kstrtok(0, 0, &aux)))
4190
97
        goto err;
4191
60.0k
    *(q = (char*)aux.p) = 0;
4192
4193
60.0k
    if (NOT_DOT(p)) v->qual = atof(p);
4194
1.31k
    else bcf_float_set_missing(v->qual);
4195
60.0k
    if ( v->max_unpack && !(v->max_unpack>>1) ) goto end; // BCF_UN_STR
4196
4197
    // FILTER
4198
60.0k
    if (!(p = kstrtok(0, 0, &aux)))
4199
66
        goto err;
4200
59.9k
    *(q = (char*)aux.p) = 0;
4201
4202
59.9k
    if (NOT_DOT(p)) {
4203
53.0k
        if (vcf_parse_filter(str, h, v, p, q)) {
4204
50
            goto err;
4205
50
        }
4206
53.0k
    } else bcf_enc_vint(str, 0, 0, -1);
4207
59.9k
    if ( v->max_unpack && !(v->max_unpack>>2) ) goto end; // BCF_UN_FLT
4208
4209
    // INFO
4210
59.9k
    if (!(p = kstrtok(0, 0, &aux)))
4211
120
        goto err;
4212
59.8k
    *(q = (char*)aux.p) = 0;
4213
4214
59.8k
    if (NOT_DOT(p)) {
4215
58.1k
        if (vcf_parse_info(str, h, v, p, q)) {
4216
117
            goto err;
4217
117
        }
4218
58.1k
    }
4219
59.6k
    if ( v->max_unpack && !(v->max_unpack>>3) ) goto end;
4220
4221
    // FORMAT; optional
4222
59.6k
    p = kstrtok(0, 0, &aux);
4223
59.6k
    if (p) {
4224
54.2k
        *(q = (char*)aux.p) = 0;
4225
4226
54.2k
        if (vcf_parse_format(s, h, v, p, q)) {
4227
508
            goto err;
4228
508
        }
4229
54.2k
    }
4230
4231
59.1k
 end:
4232
59.1k
    v->rlen = get_rlen(h, v);    //set rlen based on version
4233
59.1k
    ret = 0;
4234
4235
60.6k
 err:
4236
60.6k
    return ret;
4237
59.1k
}
4238
4239
int vcf_open_mode(char *mode, const char *fn, const char *format)
4240
0
{
4241
0
    if (format == NULL) {
4242
        // Try to pick a format based on the filename extension
4243
0
        char extension[HTS_MAX_EXT_LEN];
4244
0
        if (find_file_extension(fn, extension) < 0) return -1;
4245
0
        return vcf_open_mode(mode, fn, extension);
4246
0
    }
4247
0
    else if (strcasecmp(format, "bcf") == 0) strcpy(mode, "b");
4248
0
    else if (strcasecmp(format, "vcf") == 0) strcpy(mode, "");
4249
0
    else if (strcasecmp(format, "vcf.gz") == 0 || strcasecmp(format, "vcf.bgz") == 0) strcpy(mode, "z");
4250
0
    else return -1;
4251
4252
0
    return 0;
4253
0
}
4254
4255
int vcf_read(htsFile *fp, const bcf_hdr_t *h, bcf1_t *v)
4256
61.4k
{
4257
61.4k
    int ret;
4258
61.4k
    ret = hts_getline(fp, KS_SEP_LINE, &fp->line);
4259
61.4k
    if (ret < 0) return ret;
4260
60.6k
    return vcf_parse1(&fp->line, h, v);
4261
61.4k
}
4262
4263
static inline uint8_t *bcf_unpack_fmt_core1(uint8_t *ptr, int n_sample, bcf_fmt_t *fmt)
4264
0
{
4265
0
    uint8_t *ptr_start = ptr;
4266
0
    fmt->id = bcf_dec_typed_int1(ptr, &ptr);
4267
0
    fmt->n = bcf_dec_size(ptr, &ptr, &fmt->type);
4268
0
    fmt->size = fmt->n << bcf_type_shift[fmt->type];
4269
0
    fmt->p = ptr;
4270
0
    fmt->p_off  = ptr - ptr_start;
4271
0
    fmt->p_free = 0;
4272
0
    ptr += n_sample * fmt->size;
4273
0
    fmt->p_len = ptr - fmt->p;
4274
0
    return ptr;
4275
0
}
4276
4277
static inline uint8_t *bcf_unpack_info_core1(uint8_t *ptr, bcf_info_t *info)
4278
705
{
4279
705
    uint8_t *ptr_start = ptr;
4280
705
    int64_t len = 0;
4281
705
    info->key = bcf_dec_typed_int1(ptr, &ptr);
4282
705
    len = info->len = bcf_dec_size(ptr, &ptr, &info->type);
4283
705
    info->vptr = ptr;
4284
705
    info->vptr_off  = ptr - ptr_start;
4285
705
    info->vptr_free = 0;
4286
705
    info->v1.i = 0;
4287
705
    if (info->len == 1) {
4288
3
        switch(info->type) {
4289
0
        case BCF_BT_INT8:
4290
3
        case BCF_BT_CHAR:
4291
3
            info->v1.i = *(int8_t*)ptr;
4292
3
            break;
4293
0
        case BCF_BT_INT16:
4294
0
            info->v1.i = le_to_i16(ptr);
4295
0
            len <<= 1;
4296
0
            break;
4297
0
        case BCF_BT_INT32:
4298
0
            info->v1.i = le_to_i32(ptr);
4299
0
            len <<= 2;
4300
0
            break;
4301
0
        case BCF_BT_FLOAT:
4302
0
            info->v1.f = le_to_float(ptr);
4303
0
            len <<= 2;
4304
0
            break;
4305
0
        case BCF_BT_INT64:
4306
0
            info->v1.i = le_to_i64(ptr);
4307
0
            len <<= 3;
4308
0
            break;
4309
3
        }
4310
702
    } else {
4311
702
        len <<= bcf_type_shift[info->type];
4312
702
    }
4313
705
    ptr += len;
4314
4315
705
    info->vptr_len = ptr - info->vptr;
4316
705
    return ptr;
4317
705
}
4318
4319
int bcf_unpack(bcf1_t *b, int which)
4320
57.4k
{
4321
57.4k
    if ( !b->shared.l ) return 0; // Building a new BCF record from scratch
4322
57.4k
    uint8_t *ptr = (uint8_t*)b->shared.s, *ptr_ori;
4323
57.4k
    int i;
4324
57.4k
    bcf_dec_t *d = &b->d;
4325
57.4k
    if (which & BCF_UN_FLT) which |= BCF_UN_STR;
4326
57.4k
    if (which & BCF_UN_INFO) which |= BCF_UN_SHR;
4327
57.4k
    if ((which&BCF_UN_STR) && !(b->unpacked&BCF_UN_STR))
4328
57.4k
    {
4329
57.4k
        kstring_t tmp;
4330
4331
        // ID
4332
57.4k
        tmp.l = 0; tmp.s = d->id; tmp.m = d->m_id;
4333
57.4k
        ptr_ori = ptr;
4334
57.4k
        ptr = bcf_fmt_sized_array(&tmp, ptr);
4335
57.4k
        b->unpack_size[0] = ptr - ptr_ori;
4336
57.4k
        kputc_('\0', &tmp);
4337
57.4k
        d->id = tmp.s; d->m_id = tmp.m;
4338
4339
        // REF and ALT are in a single block (d->als) and d->alleles are pointers into this block
4340
57.4k
        hts_expand(char*, b->n_allele, d->m_allele, d->allele); // NM: hts_expand() is a macro
4341
57.4k
        tmp.l = 0; tmp.s = d->als; tmp.m = d->m_als;
4342
57.4k
        ptr_ori = ptr;
4343
1.52M
        for (i = 0; i < b->n_allele; ++i) {
4344
            // Use offset within tmp.s as realloc may change pointer
4345
1.46M
            d->allele[i] = (char *)(intptr_t)tmp.l;
4346
1.46M
            ptr = bcf_fmt_sized_array(&tmp, ptr);
4347
1.46M
            kputc_('\0', &tmp);
4348
1.46M
        }
4349
57.4k
        b->unpack_size[1] = ptr - ptr_ori;
4350
57.4k
        d->als = tmp.s; d->m_als = tmp.m;
4351
4352
        // Convert our offsets within tmp.s back to pointers again
4353
1.52M
        for (i = 0; i < b->n_allele; ++i)
4354
1.46M
            d->allele[i] = d->als + (ptrdiff_t)d->allele[i];
4355
57.4k
        b->unpacked |= BCF_UN_STR;
4356
57.4k
    }
4357
57.4k
    if ((which&BCF_UN_FLT) && !(b->unpacked&BCF_UN_FLT)) { // FILTER
4358
57.4k
        ptr = (uint8_t*)b->shared.s + b->unpack_size[0] + b->unpack_size[1];
4359
57.4k
        ptr_ori = ptr;
4360
57.4k
        if (*ptr>>4) {
4361
50.6k
            int type;
4362
50.6k
            d->n_flt = bcf_dec_size(ptr, &ptr, &type);
4363
50.6k
            hts_expand(int, d->n_flt, d->m_flt, d->flt);
4364
163k
            for (i = 0; i < d->n_flt; ++i)
4365
112k
                d->flt[i] = bcf_dec_int1(ptr, type, &ptr);
4366
50.6k
        } else ++ptr, d->n_flt = 0;
4367
57.4k
        b->unpack_size[2] = ptr - ptr_ori;
4368
57.4k
        b->unpacked |= BCF_UN_FLT;
4369
57.4k
    }
4370
57.4k
    if ((which&BCF_UN_INFO) && !(b->unpacked&BCF_UN_INFO)) { // INFO
4371
0
        ptr = (uint8_t*)b->shared.s + b->unpack_size[0] + b->unpack_size[1] + b->unpack_size[2];
4372
0
        hts_expand(bcf_info_t, b->n_info, d->m_info, d->info);
4373
0
        for (i = 0; i < d->m_info; ++i) d->info[i].vptr_free = 0;
4374
0
        for (i = 0; i < b->n_info; ++i)
4375
0
            ptr = bcf_unpack_info_core1(ptr, &d->info[i]);
4376
0
        b->unpacked |= BCF_UN_INFO;
4377
0
    }
4378
57.4k
    if ((which&BCF_UN_FMT) && b->n_sample && !(b->unpacked&BCF_UN_FMT)) { // FORMAT
4379
0
        ptr = (uint8_t*)b->indiv.s;
4380
0
        hts_expand(bcf_fmt_t, b->n_fmt, d->m_fmt, d->fmt);
4381
0
        for (i = 0; i < d->m_fmt; ++i) d->fmt[i].p_free = 0;
4382
0
        for (i = 0; i < b->n_fmt; ++i)
4383
0
            ptr = bcf_unpack_fmt_core1(ptr, b->n_sample, &d->fmt[i]);
4384
0
        b->unpacked |= BCF_UN_FMT;
4385
0
    }
4386
57.4k
    return 0;
4387
57.4k
}
4388
4389
int vcf_format(const bcf_hdr_t *h, const bcf1_t *v, kstring_t *s)
4390
57.4k
{
4391
57.4k
    int i;
4392
57.4k
    int32_t max_dt_id = h->n[BCF_DT_ID];
4393
57.4k
    const char *chrom = bcf_seqname(h, v);
4394
57.4k
    if (!chrom) {
4395
0
        hts_log_error("Invalid BCF, CONTIG id=%d not present in the header",
4396
0
                      v->rid);
4397
0
        errno = EINVAL;
4398
0
        return -1;
4399
0
    }
4400
4401
57.4k
    bcf_unpack((bcf1_t*)v, BCF_UN_ALL & ~(BCF_UN_INFO|BCF_UN_FMT));
4402
4403
    // Cache of key lengths so we don't keep repeatedly using them.
4404
    // This assumes we're not modifying the header between successive calls
4405
    // to vcf_format, but that would lead to many other forms of breakage
4406
    // so it feels like a valid assumption to make.
4407
    //
4408
    // We cannot just do this in bcf_hdr_sync as some code (eg bcftools
4409
    // annotate) manipulates the headers directly without calling sync to
4410
    // refresh the data structures.  So we must do just-in-time length
4411
    // calculation during writes instead.
4412
57.4k
    bcf_hdr_aux_t *aux = get_hdr_aux(h);
4413
57.4k
    if (!aux->key_len) {
4414
5.32k
        if (!(aux->key_len = calloc(h->n[BCF_DT_ID]+1, sizeof(*aux->key_len))))
4415
0
            return -1;
4416
5.32k
    }
4417
57.4k
    size_t *key_len = aux->key_len;
4418
4419
57.4k
    kputs(chrom, s); // CHROM
4420
57.4k
    kputc_('\t', s); kputll(v->pos + 1, s); // POS
4421
57.4k
    kputc_('\t', s); kputs(v->d.id ? v->d.id : ".", s); // ID
4422
57.4k
    kputc_('\t', s); // REF
4423
57.4k
    if (v->n_allele > 0) kputs(v->d.allele[0], s);
4424
0
    else kputc_('.', s);
4425
57.4k
    kputc_('\t', s); // ALT
4426
57.4k
    if (v->n_allele > 1) {
4427
1.46M
        for (i = 1; i < v->n_allele; ++i) {
4428
1.40M
            if (i > 1) kputc_(',', s);
4429
1.40M
            kputs(v->d.allele[i], s);
4430
1.40M
        }
4431
56.5k
    } else kputc_('.', s);
4432
57.4k
    kputc_('\t', s); // QUAL
4433
57.4k
    if ( bcf_float_is_missing(v->qual) ) kputc_('.', s); // QUAL
4434
56.3k
    else kputd(v->qual, s);
4435
57.4k
    kputc_('\t', s); // FILTER
4436
57.4k
    if (v->d.n_flt) {
4437
163k
        for (i = 0; i < v->d.n_flt; ++i) {
4438
112k
            int32_t idx = v->d.flt[i];
4439
112k
            if (idx < 0 || idx >= max_dt_id
4440
112k
                || h->id[BCF_DT_ID][idx].key == NULL) {
4441
0
                hts_log_error("Invalid BCF, the FILTER tag id=%d at %s:%"PRIhts_pos" not present in the header",
4442
0
                              idx, bcf_seqname_safe(h, v), v->pos + 1);
4443
0
                errno = EINVAL;
4444
0
                return -1;
4445
0
            }
4446
112k
            if (i) kputc_(';', s);
4447
112k
            if (!key_len[idx])
4448
74.9k
                key_len[idx] = strlen(h->id[BCF_DT_ID][idx].key);
4449
112k
            kputsn(h->id[BCF_DT_ID][idx].key, key_len[idx], s);
4450
112k
        }
4451
50.6k
    } else kputc_('.', s);
4452
4453
57.4k
    kputc_('\t', s); // INFO
4454
57.4k
    if (v->n_info) {
4455
27.3k
        uint8_t *ptr = v->shared.s
4456
27.3k
            ? (uint8_t *)v->shared.s + v->unpack_size[0] +
4457
27.3k
               v->unpack_size[1] + v->unpack_size[2]
4458
27.3k
            : NULL;
4459
27.3k
        int first = 1;
4460
27.3k
        bcf_info_t *info = v->d.info;
4461
4462
        // Note if we duplicate this code into custom packed and unpacked
4463
        // implementations then we gain a bit more speed, particularly with
4464
        // clang 13 (up to 5%).  Not sure why this is, but code duplication
4465
        // isn't pleasant and it's still faster adding packed support than
4466
        // not so it's a win, just not as good as it should be.
4467
27.3k
        const int info_packed = !(v->unpacked & BCF_UN_INFO) && v->shared.l;
4468
72.7k
        for (i = 0; i < v->n_info; ++i) {
4469
45.3k
            bcf_info_t in, *z;
4470
45.3k
            if (info_packed) {
4471
                // Use a local bcf_info_t when data is packed
4472
45.3k
                z = &in;
4473
45.3k
                z->key  = bcf_dec_typed_int1(ptr, &ptr);
4474
45.3k
                z->len  = bcf_dec_size(ptr, &ptr, &z->type);
4475
45.3k
                z->vptr = ptr;
4476
45.3k
                ptr += z->len << bcf_type_shift[z->type];
4477
45.3k
            } else {
4478
                // Else previously unpacked INFO struct
4479
0
                z = &info[i];
4480
4481
                // Also potentially since deleted
4482
0
                if ( !z->vptr ) continue;
4483
0
            }
4484
4485
45.3k
            bcf_idpair_t *id = z->key >= 0 && z->key < max_dt_id
4486
45.3k
                ? &h->id[BCF_DT_ID][z->key]
4487
45.3k
                : NULL;
4488
4489
45.3k
            if (!id || !id->key) {
4490
0
                hts_log_error("Invalid BCF, the INFO tag id=%d is %s at %s:%"PRIhts_pos,
4491
0
                              z->key,
4492
0
                              z->key < 0 ? "negative"
4493
0
                              : (z->key >= max_dt_id ? "too large" : "not present in the header"),
4494
0
                              bcf_seqname_safe(h, v), v->pos+1);
4495
0
                errno = EINVAL;
4496
0
                return -1;
4497
0
            }
4498
4499
            // KEY
4500
45.3k
            if (!key_len[z->key])
4501
11.8k
                key_len[z->key] = strlen(id->key);
4502
45.3k
            size_t id_len = key_len[z->key];
4503
45.3k
            if (ks_resize(s, s->l + 3 + id_len) < 0)
4504
0
                return -1;
4505
45.3k
            char *sptr = s->s + s->l;
4506
45.3k
            if ( !first ) {
4507
17.9k
                *sptr++ = ';';
4508
17.9k
                s->l++;
4509
17.9k
            }
4510
45.3k
            first = 0;
4511
45.3k
            memcpy(sptr, id->key, id_len);
4512
45.3k
            s->l += id_len;
4513
4514
            // VALUE
4515
45.3k
            if (z->len <= 0) continue;
4516
4.37k
            sptr[id_len] = '=';
4517
4.37k
            s->l++;
4518
4519
4.37k
            if (z->len != 1 || info_packed) {
4520
4.37k
                bcf_fmt_array(s, z->len, z->type, z->vptr);
4521
4.37k
            } else {
4522
                // Single length vectors are unpacked into their
4523
                // own info.v1 union and handled separately.
4524
0
                if (z->type == BCF_BT_FLOAT) {
4525
0
                    if ( bcf_float_is_missing(z->v1.f) )
4526
0
                        kputc_('.', s);
4527
0
                    else
4528
0
                        kputd(z->v1.f, s);
4529
0
                } else if (z->type == BCF_BT_CHAR) {
4530
0
                    kputc_(z->v1.i, s);
4531
0
                } else if (z->type < BCF_BT_INT64) {
4532
0
                    int64_t missing[] = {
4533
0
                        0, // BCF_BT_NULL
4534
0
                        bcf_int8_missing,
4535
0
                        bcf_int16_missing,
4536
0
                        bcf_int32_missing,
4537
0
                    };
4538
0
                    if (z->v1.i == missing[z->type])
4539
0
                        kputc_('.', s);
4540
0
                    else
4541
0
                        kputw(z->v1.i, s);
4542
0
                } else if (z->type == BCF_BT_INT64) {
4543
0
                    if (z->v1.i == bcf_int64_missing)
4544
0
                        kputc_('.', s);
4545
0
                    else
4546
0
                        kputll(z->v1.i, s);
4547
0
                } else {
4548
0
                    hts_log_error("Unexpected type %d at %s:%"PRIhts_pos, z->type, bcf_seqname_safe(h, v), v->pos+1);
4549
0
                    errno = EINVAL;
4550
0
                    return -1;
4551
0
                }
4552
0
            }
4553
4.37k
        }
4554
27.3k
        if ( first ) kputc_('.', s);
4555
30.0k
    } else kputc_('.', s);
4556
4557
    // FORMAT and individual information
4558
57.4k
    if (v->n_sample) {
4559
15.1k
        int i,j;
4560
15.1k
        if ( v->n_fmt) {
4561
14.6k
            uint8_t *ptr = (uint8_t *)v->indiv.s;
4562
14.6k
            int gt_i = -1;
4563
14.6k
            bcf_fmt_t *fmt = v->d.fmt;
4564
14.6k
            int first = 1, ret = 0;
4565
14.6k
            int fmt_packed = !(v->unpacked & BCF_UN_FMT);
4566
4567
14.6k
            if (fmt_packed) {
4568
                // Local fmt as we have an array of num FORMAT keys,
4569
                // each of which points to N.Sample values.
4570
4571
                // No real gain to be had in handling unpacked data here,
4572
                // but it doesn't cost us much in complexity either and
4573
                // it gives us flexibility.
4574
14.6k
                fmt = hts_malloc_p(sizeof(*fmt), v->n_fmt);
4575
14.6k
                if (!fmt)
4576
0
                    return -1;
4577
14.6k
            }
4578
4579
            // KEYS
4580
57.9k
            for (i = 0; i < (int)v->n_fmt; ++i) {
4581
43.3k
                bcf_fmt_t *z;
4582
43.3k
                z = &fmt[i];
4583
43.3k
                if (fmt_packed) {
4584
43.3k
                    z->id   = bcf_dec_typed_int1(ptr, &ptr);
4585
43.3k
                    z->n    = bcf_dec_size(ptr, &ptr, &z->type);
4586
43.3k
                    z->p    = ptr;
4587
43.3k
                    z->size = z->n << bcf_type_shift[z->type];
4588
43.3k
                    ptr += v->n_sample * z->size;
4589
43.3k
                }
4590
43.3k
                if ( !z->p ) continue;
4591
43.3k
                kputc_(!first ? ':' : '\t', s); first = 0;
4592
4593
43.3k
                bcf_idpair_t *id = z->id >= 0 && z->id < max_dt_id
4594
43.3k
                    ? &h->id[BCF_DT_ID][z->id]
4595
43.3k
                    : NULL;
4596
4597
43.3k
                if (!id || !id->key) {
4598
0
                    hts_log_error("Invalid BCF, the FORMAT tag id=%d at %s:%"PRIhts_pos" not present in the header", z->id, bcf_seqname_safe(h, v), v->pos+1);
4599
0
                    errno = EINVAL;
4600
0
                    if (fmt_packed)
4601
0
                        free(fmt);
4602
0
                    return -1;
4603
0
                }
4604
4605
43.3k
                if (!key_len[z->id])
4606
14.9k
                    key_len[z->id] = strlen(id->key);
4607
43.3k
                size_t id_len = key_len[z->id];
4608
43.3k
                kputsn(id->key, id_len, s);
4609
43.3k
                if (id_len == 2 && id->key[0] == 'G' && id->key[1] == 'T')
4610
8.05k
                    gt_i = i;
4611
43.3k
            }
4612
14.6k
            if ( first ) kputsn("\t.", 2, s);
4613
4614
            // VALUES per sample
4615
66.1k
            for (j = 0; j < v->n_sample; ++j) {
4616
51.5k
                kputc_('\t', s);
4617
51.5k
                first = 1;
4618
51.5k
                bcf_fmt_t *f = fmt;
4619
134k
                for (i = 0; i < (int)v->n_fmt; i++, f++) {
4620
120k
                    if ( !f->p ) continue;
4621
120k
                    if (!first) kputc_(':', s);
4622
120k
                    first = 0;
4623
120k
                    if (gt_i == i) {
4624
37.4k
                        if ((ret = bcf_format_gt_v2(h, f,j,s)) < 0) {
4625
0
                            hts_log_error("Failed to format GT value for sample %d, returned %d", i, ret);
4626
0
                            errno = EINVAL;
4627
0
                            if (fmt_packed)
4628
0
                                free(fmt);
4629
0
                            return -1;
4630
0
                        }
4631
37.4k
                        break;
4632
37.4k
                    }
4633
83.1k
                    else if (f->n == 1)
4634
14.6k
                        bcf_fmt_array1(s, f->type, f->p + j * (size_t)f->size);
4635
68.5k
                    else
4636
68.5k
                        bcf_fmt_array(s, f->n, f->type, f->p + j * (size_t)f->size);
4637
120k
                }
4638
4639
                // Simpler loop post GT and at least 1 iteration
4640
136k
                for (i++, f++; i < (int)v->n_fmt; i++, f++) {
4641
85.3k
                    if ( !f->p ) continue;
4642
85.3k
                    kputc_(':', s);
4643
85.3k
                    if (f->n == 1)
4644
699
                        bcf_fmt_array1(s, f->type, f->p + j * (size_t)f->size);
4645
84.6k
                    else
4646
84.6k
                        bcf_fmt_array(s, f->n, f->type, f->p + j * (size_t)f->size);
4647
85.3k
                }
4648
51.5k
                if ( first ) kputc_('.', s);
4649
51.5k
            }
4650
14.6k
            if (fmt_packed)
4651
14.6k
                free(fmt);
4652
14.6k
        }
4653
562
        else
4654
4.08k
            for (j=0; j<=v->n_sample; j++)
4655
3.52k
                kputsn("\t.", 2, s);
4656
15.1k
    }
4657
57.4k
    kputc('\n', s);
4658
57.4k
    return 0;
4659
57.4k
}
4660
4661
int vcf_write_line(htsFile *fp, kstring_t *line)
4662
0
{
4663
0
    int ret;
4664
0
    if ( line->s[line->l-1]!='\n' ) kputc('\n',line);
4665
0
    if ( fp->format.compression!=no_compression )
4666
0
        ret = bgzf_write(fp->fp.bgzf, line->s, line->l);
4667
0
    else
4668
0
        ret = hwrite(fp->fp.hfile, line->s, line->l);
4669
0
    return ret==line->l ? 0 : -1;
4670
0
}
4671
4672
int vcf_write(htsFile *fp, const bcf_hdr_t *h, bcf1_t *v)
4673
57.4k
{
4674
57.4k
    ssize_t ret;
4675
57.4k
    fp->line.l = 0;
4676
57.4k
    if (vcf_format1(h, v, &fp->line) != 0)
4677
0
        return -1;
4678
57.4k
    if ( fp->format.compression!=no_compression ) {
4679
0
        if (bgzf_flush_try(fp->fp.bgzf, fp->line.l) < 0)
4680
0
            return -1;
4681
0
        if (fp->idx && !fp->fp.bgzf->mt)
4682
0
            hts_idx_amend_last(fp->idx, bgzf_tell(fp->fp.bgzf));
4683
0
        ret = bgzf_write(fp->fp.bgzf, fp->line.s, fp->line.l);
4684
57.4k
    } else {
4685
57.4k
        ret = hwrite(fp->fp.hfile, fp->line.s, fp->line.l);
4686
57.4k
    }
4687
4688
57.4k
    if (fp->idx && fp->format.compression == bgzf) {
4689
0
        int tid;
4690
0
        if ((tid = hts_idx_tbi_name(fp->idx, v->rid, bcf_seqname_safe(h, v))) < 0)
4691
0
            return -1;
4692
4693
0
        if (bgzf_idx_push(fp->fp.bgzf, fp->idx,
4694
0
                          tid, v->pos, v->pos + v->rlen,
4695
0
                          bgzf_tell(fp->fp.bgzf), 1) < 0)
4696
0
            return -1;
4697
0
    }
4698
4699
57.4k
    return ret==fp->line.l ? 0 : -1;
4700
57.4k
}
4701
4702
/************************
4703
 * Data access routines *
4704
 ************************/
4705
4706
int bcf_hdr_id2int(const bcf_hdr_t *h, int which, const char *id)
4707
278k
{
4708
278k
    khint_t k;
4709
278k
    vdict_t *d = (vdict_t*)h->dict[which];
4710
278k
    k = kh_get(vdict, d, id);
4711
278k
    return k == kh_end(d)? -1 : kh_val(d, k).id;
4712
278k
}
4713
4714
4715
/********************
4716
 *** BCF indexing ***
4717
 ********************/
4718
4719
// Calculate number of index levels given min_shift and the header contig
4720
// list.  Also returns number of contigs in *nids_out.
4721
static int idx_calc_n_lvls_ids(const bcf_hdr_t *h, int *min_shift_in_out,
4722
                               int starting_n_lvls, int *nids_out)
4723
0
{
4724
0
    int n_lvls = starting_n_lvls, i, nids = 0;
4725
0
    int64_t max_len = 0;
4726
4727
0
    for (i = 0; i < h->n[BCF_DT_CTG]; ++i)
4728
0
    {
4729
0
        if ( !h->id[BCF_DT_CTG][i].val ) continue;
4730
0
        if ( max_len < h->id[BCF_DT_CTG][i].val->info[0] )
4731
0
            max_len = h->id[BCF_DT_CTG][i].val->info[0];
4732
0
        nids++;
4733
0
    }
4734
0
    if ( !max_len ) max_len = (1LL<<31) - 1;  // In case contig line is broken.
4735
4736
0
    hts_adjust_csi_settings(max_len, min_shift_in_out, &n_lvls);
4737
4738
0
    if (nids_out) *nids_out = nids;
4739
0
    return n_lvls;
4740
0
}
4741
4742
hts_idx_t *bcf_index(htsFile *fp, int min_shift)
4743
0
{
4744
0
    int n_lvls;
4745
0
    bcf1_t *b = NULL;
4746
0
    hts_idx_t *idx = NULL;
4747
0
    bcf_hdr_t *h;
4748
0
    int r;
4749
0
    h = bcf_hdr_read(fp);
4750
0
    if ( !h ) return NULL;
4751
0
    int nids = 0;
4752
0
    n_lvls = idx_calc_n_lvls_ids(h, &min_shift, 0, &nids);
4753
0
    idx = hts_idx_init(nids, HTS_FMT_CSI, bgzf_tell(fp->fp.bgzf), min_shift, n_lvls);
4754
0
    if (!idx) goto fail;
4755
0
    b = bcf_init1();
4756
0
    if (!b) goto fail;
4757
0
    while ((r = bcf_read1(fp,h, b)) >= 0) {
4758
0
        int ret;
4759
0
        ret = hts_idx_push(idx, b->rid, b->pos, b->pos + b->rlen, bgzf_tell(fp->fp.bgzf), 1);
4760
0
        if (ret < 0) goto fail;
4761
0
    }
4762
0
    if (r < -1) goto fail;
4763
0
    hts_idx_finish(idx, bgzf_tell(fp->fp.bgzf));
4764
0
    bcf_destroy1(b);
4765
0
    bcf_hdr_destroy(h);
4766
0
    return idx;
4767
4768
0
 fail:
4769
0
    hts_idx_destroy(idx);
4770
0
    bcf_destroy1(b);
4771
0
    bcf_hdr_destroy(h);
4772
0
    return NULL;
4773
0
}
4774
4775
hts_idx_t *bcf_index_load2(const char *fn, const char *fnidx)
4776
0
{
4777
0
    return fnidx? hts_idx_load2(fn, fnidx) : bcf_index_load(fn);
4778
0
}
4779
4780
hts_idx_t *bcf_index_load3(const char *fn, const char *fnidx, int flags)
4781
0
{
4782
0
    return hts_idx_load3(fn, fnidx, HTS_FMT_CSI, flags);
4783
0
}
4784
4785
int bcf_index_build3(const char *fn, const char *fnidx, int min_shift, int n_threads)
4786
0
{
4787
0
    htsFile *fp;
4788
0
    hts_idx_t *idx;
4789
0
    tbx_t *tbx;
4790
0
    int ret;
4791
0
    if ((fp = hts_open(fn, "rb")) == 0) return -2;
4792
0
    if (n_threads)
4793
0
        hts_set_threads(fp, n_threads);
4794
0
    if ( fp->format.compression!=bgzf ) { hts_close(fp); return -3; }
4795
0
    switch (fp->format.format) {
4796
0
        case bcf:
4797
0
            if (!min_shift) {
4798
0
                hts_log_error("TBI indices for BCF files are not supported");
4799
0
                ret = -1;
4800
0
            } else {
4801
0
                idx = bcf_index(fp, min_shift);
4802
0
                if (idx) {
4803
0
                    ret = hts_idx_save_as(idx, fn, fnidx, HTS_FMT_CSI);
4804
0
                    if (ret < 0) ret = -4;
4805
0
                    hts_idx_destroy(idx);
4806
0
                }
4807
0
                else ret = -1;
4808
0
            }
4809
0
            break;
4810
4811
0
        case vcf:
4812
0
            tbx = tbx_index(hts_get_bgzfp(fp), min_shift, &tbx_conf_vcf);
4813
0
            if (tbx) {
4814
0
                ret = hts_idx_save_as(tbx->idx, fn, fnidx, min_shift > 0 ? HTS_FMT_CSI : HTS_FMT_TBI);
4815
0
                if (ret < 0) ret = -4;
4816
0
                tbx_destroy(tbx);
4817
0
            }
4818
0
            else ret = -1;
4819
0
            break;
4820
4821
0
        default:
4822
0
            ret = -3;
4823
0
            break;
4824
0
    }
4825
0
    hts_close(fp);
4826
0
    return ret;
4827
0
}
4828
4829
int bcf_index_build2(const char *fn, const char *fnidx, int min_shift)
4830
0
{
4831
0
    return bcf_index_build3(fn, fnidx, min_shift, 0);
4832
0
}
4833
4834
int bcf_index_build(const char *fn, int min_shift)
4835
0
{
4836
0
    return bcf_index_build3(fn, NULL, min_shift, 0);
4837
0
}
4838
4839
// Initialise fp->idx for the current format type.
4840
// This must be called after the header has been written but no other data.
4841
0
static int vcf_idx_init(htsFile *fp, bcf_hdr_t *h, int min_shift, const char *fnidx) {
4842
0
    int n_lvls, fmt;
4843
4844
0
    if (min_shift == 0) {
4845
0
        min_shift = 14;
4846
0
        n_lvls = 5;
4847
0
        fmt = HTS_FMT_TBI;
4848
0
    } else {
4849
        // Set initial n_lvls to match tbx_index()
4850
0
        int starting_n_lvls = (TBX_MAX_SHIFT - min_shift + 2) / 3;
4851
        // Increase if necessary
4852
0
        n_lvls = idx_calc_n_lvls_ids(h, &min_shift, starting_n_lvls, NULL);
4853
0
        fmt = HTS_FMT_CSI;
4854
0
    }
4855
4856
0
    fp->idx = hts_idx_init(0, fmt, bgzf_tell(fp->fp.bgzf), min_shift, n_lvls);
4857
0
    if (!fp->idx) return -1;
4858
4859
    // Tabix meta data, added even in CSI for VCF
4860
0
    uint8_t conf[4*7];
4861
0
    u32_to_le(TBX_VCF, conf+0);  // fmt
4862
0
    u32_to_le(1,       conf+4);  // name col
4863
0
    u32_to_le(2,       conf+8);  // beg col
4864
0
    u32_to_le(0,       conf+12); // end col
4865
0
    u32_to_le('#',     conf+16); // comment
4866
0
    u32_to_le(0,       conf+20); // n.skip
4867
0
    u32_to_le(0,       conf+24); // ref name len
4868
0
    if (hts_idx_set_meta(fp->idx, sizeof(conf)*sizeof(*conf), (uint8_t *)conf, 1) < 0) {
4869
0
        hts_idx_destroy(fp->idx);
4870
0
        fp->idx = NULL;
4871
0
        return -1;
4872
0
    }
4873
0
    fp->fnidx = fnidx;
4874
4875
0
    return 0;
4876
0
}
4877
4878
// Initialise fp->idx for the current format type.
4879
// This must be called after the header has been written but no other data.
4880
0
int bcf_idx_init(htsFile *fp, bcf_hdr_t *h, int min_shift, const char *fnidx) {
4881
0
    int n_lvls, nids = 0;
4882
4883
0
    if (fp->format.compression != bgzf) {
4884
0
        hts_log_error("Indexing is only supported on BGZF-compressed files");
4885
0
        return -3; // Matches no-compression return for bcf_index_build3()
4886
0
    }
4887
4888
0
    if (fp->format.format == vcf)
4889
0
        return vcf_idx_init(fp, h, min_shift, fnidx);
4890
4891
0
    if (!min_shift)
4892
0
        min_shift = 14;
4893
4894
0
    n_lvls = idx_calc_n_lvls_ids(h, &min_shift, 0, &nids);
4895
4896
0
    fp->idx = hts_idx_init(nids, HTS_FMT_CSI, bgzf_tell(fp->fp.bgzf), min_shift, n_lvls);
4897
0
    if (!fp->idx) return -1;
4898
0
    fp->fnidx = fnidx;
4899
4900
0
    return 0;
4901
0
}
4902
4903
// Finishes an index. Call after the last record has been written.
4904
// Returns 0 on success, <0 on failure.
4905
//
4906
// NB: same format as SAM/BAM as it uses bgzf.
4907
0
int bcf_idx_save(htsFile *fp) {
4908
0
    return sam_idx_save(fp);
4909
0
}
4910
4911
// Wrap around bcf_hdr_name2id() to get the right signature for hts_name2id_f
4912
0
static int bcf_hdr_name2id_wrapper(void *vhdr, const char *ref) {
4913
0
    return bcf_hdr_name2id((bcf_hdr_t *) vhdr, ref);
4914
0
}
4915
4916
hts_itr_t *bcf_itr_querys1(const hts_idx_t *idx, bcf_hdr_t *hdr,
4917
0
                           const char *region) {
4918
0
    return hts_itr_querys(idx, region, bcf_hdr_name2id_wrapper, hdr,
4919
0
                          hts_itr_query, bcf_readrec);
4920
0
}
4921
4922
hts_itr_t *bcf_itr_regarray(const hts_idx_t *idx, bcf_hdr_t *hdr,
4923
0
                            char **regarray, unsigned int regcount) {
4924
0
    hts_itr_t *itr = NULL;
4925
0
    hts_reglist_t *r_list = NULL;
4926
0
    int r_count = 0;
4927
4928
0
    r_list = hts_reglist_create(regarray, regcount, &r_count, hdr,
4929
0
                                bcf_hdr_name2id_wrapper);
4930
0
    if (!r_list)
4931
0
        return NULL;
4932
4933
0
    itr = hts_itr_regions(idx, r_list, r_count, bcf_hdr_name2id_wrapper, hdr,
4934
0
                          hts_itr_multi_bam, bcf_readrec,
4935
0
                          bgzf_pseek, bgzf_ptell);
4936
0
    if (!itr)
4937
0
        hts_reglist_free(r_list, r_count);
4938
4939
0
    return itr;
4940
0
}
4941
4942
hts_itr_t *bcf_itr_regions(const hts_idx_t *idx, bcf_hdr_t *hdr,
4943
0
                           hts_reglist_t *reglist, unsigned int regcount) {
4944
0
    return hts_itr_regions(idx, reglist, regcount, bcf_hdr_name2id_wrapper, hdr,
4945
0
                           hts_itr_multi_bam, bcf_readrec,
4946
0
                           bgzf_pseek, bgzf_ptell);
4947
0
}
4948
4949
/*****************
4950
 *** Utilities ***
4951
 *****************/
4952
4953
int bcf_hdr_combine(bcf_hdr_t *dst, const bcf_hdr_t *src)
4954
0
{
4955
0
    int i, ndst_ori = dst->nhrec, need_sync = 0, ret = 0, res;
4956
0
    for (i=0; i<src->nhrec; i++)
4957
0
    {
4958
0
        if ( src->hrec[i]->type==BCF_HL_GEN && src->hrec[i]->value )
4959
0
        {
4960
0
            int j;
4961
0
            for (j=0; j<ndst_ori; j++)
4962
0
            {
4963
0
                if ( dst->hrec[j]->type!=BCF_HL_GEN ) continue;
4964
4965
                // Checking only the key part of generic lines, otherwise
4966
                // the VCFs are too verbose. Should we perhaps add a flag
4967
                // to bcf_hdr_combine() and make this optional?
4968
0
                if ( !strcmp(src->hrec[i]->key,dst->hrec[j]->key) ) break;
4969
0
            }
4970
0
            if ( j>=ndst_ori ) {
4971
0
                res = bcf_hdr_add_hrec(dst, bcf_hrec_dup(src->hrec[i]));
4972
0
                if (res < 0) return -1;
4973
0
                need_sync += res;
4974
0
            }
4975
0
        }
4976
0
        else if ( src->hrec[i]->type==BCF_HL_STR )
4977
0
        {
4978
            // NB: we are ignoring fields without ID
4979
0
            int j = bcf_hrec_find_key(src->hrec[i],"ID");
4980
0
            if ( j>=0 )
4981
0
            {
4982
0
                bcf_hrec_t *rec = bcf_hdr_get_hrec(dst, src->hrec[i]->type, "ID", src->hrec[i]->vals[j], src->hrec[i]->key);
4983
0
                if ( !rec ) {
4984
0
                    res = bcf_hdr_add_hrec(dst, bcf_hrec_dup(src->hrec[i]));
4985
0
                    if (res < 0) return -1;
4986
0
                    need_sync += res;
4987
0
                }
4988
0
            }
4989
0
        }
4990
0
        else
4991
0
        {
4992
0
            int j = bcf_hrec_find_key(src->hrec[i],"ID");
4993
0
            assert( j>=0 ); // this should always be true for valid VCFs
4994
4995
0
            bcf_hrec_t *rec = bcf_hdr_get_hrec(dst, src->hrec[i]->type, "ID", src->hrec[i]->vals[j], NULL);
4996
0
            if ( !rec ) {
4997
0
                res = bcf_hdr_add_hrec(dst, bcf_hrec_dup(src->hrec[i]));
4998
0
                if (res < 0) return -1;
4999
0
                need_sync += res;
5000
0
            } else if ( src->hrec[i]->type==BCF_HL_INFO || src->hrec[i]->type==BCF_HL_FMT )
5001
0
            {
5002
                // Check that both records are of the same type. The bcf_hdr_id2length
5003
                // macro cannot be used here because dst header is not synced yet.
5004
0
                vdict_t *d_src = (vdict_t*)src->dict[BCF_DT_ID];
5005
0
                vdict_t *d_dst = (vdict_t*)dst->dict[BCF_DT_ID];
5006
0
                khint_t k_src  = kh_get(vdict, d_src, src->hrec[i]->vals[0]);
5007
0
                khint_t k_dst  = kh_get(vdict, d_dst, src->hrec[i]->vals[0]);
5008
0
                if ( (kh_val(d_src,k_src).info[rec->type]>>8 & 0xf) != (kh_val(d_dst,k_dst).info[rec->type]>>8 & 0xf) )
5009
0
                {
5010
0
                    hts_log_warning("Trying to combine \"%s\" tag definitions of different lengths",
5011
0
                        src->hrec[i]->vals[0]);
5012
0
                    ret |= 1;
5013
0
                }
5014
0
                if ( (kh_val(d_src,k_src).info[rec->type]>>4 & 0xf) != (kh_val(d_dst,k_dst).info[rec->type]>>4 & 0xf) )
5015
0
                {
5016
0
                    hts_log_warning("Trying to combine \"%s\" tag definitions of different types",
5017
0
                        src->hrec[i]->vals[0]);
5018
0
                    ret |= 1;
5019
0
                }
5020
0
            }
5021
0
        }
5022
0
    }
5023
0
    if ( need_sync ) {
5024
0
        if (bcf_hdr_sync(dst) < 0) return -1;
5025
0
    }
5026
0
    return ret;
5027
0
}
5028
5029
bcf_hdr_t *bcf_hdr_merge(bcf_hdr_t *dst, const bcf_hdr_t *src)
5030
0
{
5031
0
    if ( !dst )
5032
0
    {
5033
        // this will effectively strip existing IDX attributes from src to become dst
5034
0
        dst = bcf_hdr_init("r");
5035
0
        kstring_t htxt = {0,0,0};
5036
0
        if (bcf_hdr_format(src, 0, &htxt) < 0) {
5037
0
            free(htxt.s);
5038
0
            return NULL;
5039
0
        }
5040
0
        if ( bcf_hdr_parse(dst, htxt.s) < 0 ) {
5041
0
            bcf_hdr_destroy(dst);
5042
0
            dst = NULL;
5043
0
        }
5044
0
        free(htxt.s);
5045
0
        return dst;
5046
0
    }
5047
5048
0
    int i, ndst_ori = dst->nhrec, need_sync = 0, res;
5049
0
    for (i=0; i<src->nhrec; i++)
5050
0
    {
5051
0
        if ( src->hrec[i]->type==BCF_HL_GEN && src->hrec[i]->value )
5052
0
        {
5053
0
            int j;
5054
0
            for (j=0; j<ndst_ori; j++)
5055
0
            {
5056
0
                if ( dst->hrec[j]->type!=BCF_HL_GEN ) continue;
5057
5058
                // Checking only the key part of generic lines, otherwise
5059
                // the VCFs are too verbose. Should we perhaps add a flag
5060
                // to bcf_hdr_combine() and make this optional?
5061
0
                if ( !strcmp(src->hrec[i]->key,dst->hrec[j]->key) ) break;
5062
0
            }
5063
0
            if ( j>=ndst_ori ) {
5064
0
                res = bcf_hdr_add_hrec(dst, bcf_hrec_dup(src->hrec[i]));
5065
0
                if (res < 0) return NULL;
5066
0
                need_sync += res;
5067
0
            }
5068
0
            else if ( !strcmp(src->hrec[i]->key,"fileformat") )
5069
0
            {
5070
0
                int ver_src = bcf_get_version(src,src->hrec[i]->value);
5071
0
                int ver_dst = bcf_get_version(dst,dst->hrec[j]->value);
5072
0
                if ( ver_src > ver_dst )
5073
0
                {
5074
0
                    if (bcf_hdr_set_version(dst,src->hrec[i]->value) < 0)
5075
0
                        return NULL;
5076
0
                    need_sync = 1;
5077
0
                }
5078
0
            }
5079
0
        }
5080
0
        else if ( src->hrec[i]->type==BCF_HL_STR )
5081
0
        {
5082
            // NB: we are ignoring fields without ID
5083
0
            int j = bcf_hrec_find_key(src->hrec[i],"ID");
5084
0
            if ( j>=0 )
5085
0
            {
5086
0
                bcf_hrec_t *rec = bcf_hdr_get_hrec(dst, src->hrec[i]->type, "ID", src->hrec[i]->vals[j], src->hrec[i]->key);
5087
0
                if ( !rec ) {
5088
0
                    res = bcf_hdr_add_hrec(dst, bcf_hrec_dup(src->hrec[i]));
5089
0
                    if (res < 0) return NULL;
5090
0
                    need_sync += res;
5091
0
                }
5092
0
            }
5093
0
        }
5094
0
        else
5095
0
        {
5096
0
            int j = bcf_hrec_find_key(src->hrec[i],"ID");
5097
0
            assert( j>=0 ); // this should always be true for valid VCFs
5098
5099
0
            bcf_hrec_t *rec = bcf_hdr_get_hrec(dst, src->hrec[i]->type, "ID", src->hrec[i]->vals[j], NULL);
5100
0
            if ( !rec ) {
5101
0
                res = bcf_hdr_add_hrec(dst, bcf_hrec_dup(src->hrec[i]));
5102
0
                if (res < 0) return NULL;
5103
0
                need_sync += res;
5104
0
            } else if ( src->hrec[i]->type==BCF_HL_INFO || src->hrec[i]->type==BCF_HL_FMT )
5105
0
            {
5106
                // Check that both records are of the same type. The bcf_hdr_id2length
5107
                // macro cannot be used here because dst header is not synced yet.
5108
0
                vdict_t *d_src = (vdict_t*)src->dict[BCF_DT_ID];
5109
0
                vdict_t *d_dst = (vdict_t*)dst->dict[BCF_DT_ID];
5110
0
                khint_t k_src  = kh_get(vdict, d_src, src->hrec[i]->vals[0]);
5111
0
                khint_t k_dst  = kh_get(vdict, d_dst, src->hrec[i]->vals[0]);
5112
0
                if ( (kh_val(d_src,k_src).info[rec->type]>>8 & 0xf) != (kh_val(d_dst,k_dst).info[rec->type]>>8 & 0xf) )
5113
0
                {
5114
0
                    hts_log_warning("Trying to combine \"%s\" tag definitions of different lengths",
5115
0
                        src->hrec[i]->vals[0]);
5116
0
                }
5117
0
                if ( (kh_val(d_src,k_src).info[rec->type]>>4 & 0xf) != (kh_val(d_dst,k_dst).info[rec->type]>>4 & 0xf) )
5118
0
                {
5119
0
                    hts_log_warning("Trying to combine \"%s\" tag definitions of different types",
5120
0
                        src->hrec[i]->vals[0]);
5121
0
                }
5122
0
            }
5123
0
        }
5124
0
    }
5125
0
    if ( need_sync ) {
5126
0
        if (bcf_hdr_sync(dst) < 0) return NULL;
5127
0
    }
5128
0
    return dst;
5129
0
}
5130
5131
int bcf_translate(const bcf_hdr_t *dst_hdr, bcf_hdr_t *src_hdr, bcf1_t *line)
5132
0
{
5133
0
    int i;
5134
0
    if ( line->errcode )
5135
0
    {
5136
0
        char errordescription[1024] = "";
5137
0
        hts_log_error("Unchecked error (%d %s) at %s:%"PRIhts_pos", exiting", line->errcode, bcf_strerror(line->errcode, errordescription, sizeof(errordescription)),  bcf_seqname_safe(src_hdr,line), line->pos+1);
5138
0
        exit(1);
5139
0
    }
5140
0
    if ( src_hdr->ntransl==-1 ) return 0;    // no need to translate, all tags have the same id
5141
0
    if ( !src_hdr->ntransl )  // called for the first time, see what needs translating
5142
0
    {
5143
0
        int dict;
5144
0
        for (dict=0; dict<2; dict++)    // BCF_DT_ID and BCF_DT_CTG
5145
0
        {
5146
0
            src_hdr->transl[dict] = hts_malloc_p(sizeof(int), src_hdr->n[dict]);
5147
0
            for (i=0; i<src_hdr->n[dict]; i++)
5148
0
            {
5149
0
                if ( !src_hdr->id[dict][i].key ) // gap left after removed BCF header lines
5150
0
                {
5151
0
                    src_hdr->transl[dict][i] = -1;
5152
0
                    continue;
5153
0
                }
5154
0
                src_hdr->transl[dict][i] = bcf_hdr_id2int(dst_hdr,dict,src_hdr->id[dict][i].key);
5155
0
                if ( src_hdr->transl[dict][i]!=-1 && i!=src_hdr->transl[dict][i] ) src_hdr->ntransl++;
5156
0
            }
5157
0
        }
5158
0
        if ( !src_hdr->ntransl )
5159
0
        {
5160
0
            free(src_hdr->transl[0]); src_hdr->transl[0] = NULL;
5161
0
            free(src_hdr->transl[1]); src_hdr->transl[1] = NULL;
5162
0
            src_hdr->ntransl = -1;
5163
0
        }
5164
0
        if ( src_hdr->ntransl==-1 ) return 0;
5165
0
    }
5166
0
    bcf_unpack(line,BCF_UN_ALL);
5167
5168
    // CHROM
5169
0
    if ( src_hdr->transl[BCF_DT_CTG][line->rid] >=0 ) line->rid = src_hdr->transl[BCF_DT_CTG][line->rid];
5170
5171
    // FILTER
5172
0
    for (i=0; i<line->d.n_flt; i++)
5173
0
    {
5174
0
        int src_id = line->d.flt[i];
5175
0
        if ( src_hdr->transl[BCF_DT_ID][src_id] >=0 )
5176
0
            line->d.flt[i] = src_hdr->transl[BCF_DT_ID][src_id];
5177
0
        line->d.shared_dirty |= BCF1_DIRTY_FLT;
5178
0
    }
5179
5180
    // INFO
5181
0
    for (i=0; i<line->n_info; i++)
5182
0
    {
5183
0
        int src_id = line->d.info[i].key;
5184
0
        int dst_id = src_hdr->transl[BCF_DT_ID][src_id];
5185
0
        if ( dst_id<0 ) continue;
5186
0
        line->d.info[i].key = dst_id;
5187
0
        if ( !line->d.info[i].vptr ) continue;  // skip deleted
5188
0
        int src_size = src_id>>7 ? ( src_id>>15 ? BCF_BT_INT32 : BCF_BT_INT16) : BCF_BT_INT8;
5189
0
        int dst_size = dst_id>>7 ? ( dst_id>>15 ? BCF_BT_INT32 : BCF_BT_INT16) : BCF_BT_INT8;
5190
0
        if ( src_size==dst_size )   // can overwrite
5191
0
        {
5192
0
            uint8_t *vptr = line->d.info[i].vptr - line->d.info[i].vptr_off;
5193
0
            if ( dst_size==BCF_BT_INT8 ) { vptr[1] = (uint8_t)dst_id; }
5194
0
            else if ( dst_size==BCF_BT_INT16 ) { *(uint16_t*)vptr = (uint16_t)dst_id; }
5195
0
            else { *(uint32_t*)vptr = (uint32_t)dst_id; }
5196
0
        }
5197
0
        else    // must realloc
5198
0
        {
5199
0
            bcf_info_t *info = &line->d.info[i];
5200
0
            kstring_t str = {0,0,0};
5201
0
            bcf_enc_int1(&str, dst_id);
5202
0
            bcf_enc_size(&str, info->len,info->type);
5203
0
            uint32_t vptr_off = str.l;
5204
0
            kputsn((char*)info->vptr, info->vptr_len, &str);
5205
0
            if( info->vptr_free ) free(info->vptr - info->vptr_off);
5206
0
            info->vptr_off = vptr_off;
5207
0
            info->vptr = (uint8_t*)str.s + info->vptr_off;
5208
0
            info->vptr_free = 1;
5209
0
            line->d.shared_dirty |= BCF1_DIRTY_INF;
5210
0
        }
5211
0
    }
5212
5213
    // FORMAT
5214
0
    for (i=0; i<line->n_fmt; i++)
5215
0
    {
5216
0
        int src_id = line->d.fmt[i].id;
5217
0
        int dst_id = src_hdr->transl[BCF_DT_ID][src_id];
5218
0
        if ( dst_id<0 ) continue;
5219
0
        line->d.fmt[i].id = dst_id;
5220
0
        if( !line->d.fmt[i].p ) continue;  // skip deleted
5221
0
        int src_size = src_id>>7 ? ( src_id>>15 ? BCF_BT_INT32 : BCF_BT_INT16) : BCF_BT_INT8;
5222
0
        int dst_size = dst_id>>7 ? ( dst_id>>15 ? BCF_BT_INT32 : BCF_BT_INT16) : BCF_BT_INT8;
5223
0
        if ( src_size==dst_size )   // can overwrite
5224
0
        {
5225
0
            uint8_t *p = line->d.fmt[i].p - line->d.fmt[i].p_off;    // pointer to the vector size (4bits) and BT type (4bits)
5226
0
            if ( dst_size==BCF_BT_INT8 ) { p[1] = dst_id; }
5227
0
            else if ( dst_size==BCF_BT_INT16 ) { i16_to_le(dst_id, p + 1); }
5228
0
            else { i32_to_le(dst_id, p + 1); }
5229
0
        }
5230
0
        else    // must realloc
5231
0
        {
5232
0
            bcf_fmt_t *fmt = &line->d.fmt[i];
5233
0
            kstring_t str = {0,0,0};
5234
0
            bcf_enc_int1(&str, dst_id);
5235
0
            bcf_enc_size(&str, fmt->n, fmt->type);
5236
0
            uint32_t p_off = str.l;
5237
0
            kputsn((char*)fmt->p, fmt->p_len, &str);
5238
0
            if( fmt->p_free ) free(fmt->p - fmt->p_off);
5239
0
            fmt->p_off = p_off;
5240
0
            fmt->p = (uint8_t*)str.s + fmt->p_off;
5241
0
            fmt->p_free = 1;
5242
0
            line->d.indiv_dirty = 1;
5243
0
        }
5244
0
    }
5245
0
    return 0;
5246
0
}
5247
5248
bcf_hdr_t *bcf_hdr_dup(const bcf_hdr_t *hdr)
5249
0
{
5250
0
    bcf_hdr_t *hout = bcf_hdr_init("r");
5251
0
    if (!hout) {
5252
0
        hts_log_error("Failed to allocate bcf header");
5253
0
        return NULL;
5254
0
    }
5255
0
    kstring_t htxt = {0,0,0};
5256
0
    if (bcf_hdr_format(hdr, 1, &htxt) < 0) {
5257
0
        free(htxt.s);
5258
0
        return NULL;
5259
0
    }
5260
0
    if ( bcf_hdr_parse(hout, htxt.s) < 0 ) {
5261
0
        bcf_hdr_destroy(hout);
5262
0
        hout = NULL;
5263
0
    }
5264
0
    free(htxt.s);
5265
0
    return hout;
5266
0
}
5267
5268
bcf_hdr_t *bcf_hdr_subset(const bcf_hdr_t *h0, int n, char *const* samples, int *imap)
5269
0
{
5270
0
    void *names_hash = khash_str2int_init();
5271
0
    kstring_t htxt = {0,0,0};
5272
0
    kstring_t str = {0,0,0};
5273
0
    bcf_hdr_t *h = bcf_hdr_init("w");
5274
0
    int r = 0;
5275
0
    if (!h || !names_hash) {
5276
0
        hts_log_error("Failed to allocate bcf header");
5277
0
        goto err;
5278
0
    }
5279
0
    if (bcf_hdr_format(h0, 1, &htxt) < 0) {
5280
0
        hts_log_error("Failed to get header text");
5281
0
        goto err;
5282
0
    }
5283
0
    bcf_hdr_set_version(h,bcf_hdr_get_version(h0));
5284
0
    int j;
5285
0
    for (j=0; j<n; j++) imap[j] = -1;
5286
0
    if ( bcf_hdr_nsamples(h0) > 0) {
5287
0
        char *p = find_chrom_header_line(htxt.s);
5288
0
        int i = 0, end = n? 8 : 7;
5289
0
        while ((p = strchr(p, '\t')) != 0 && i < end) ++i, ++p;
5290
0
        if (i != end) {
5291
0
            hts_log_error("Wrong number of columns in header #CHROM line");
5292
0
            goto err;
5293
0
        }
5294
0
        r |= kputsn(htxt.s, p - htxt.s, &str) < 0;
5295
0
        for (i = 0; i < n; ++i) {
5296
0
            if ( khash_str2int_has_key(names_hash,samples[i]) )
5297
0
            {
5298
0
                hts_log_error("Duplicate sample name \"%s\"", samples[i]);
5299
0
                goto err;
5300
0
            }
5301
0
            imap[i] = bcf_hdr_id2int(h0, BCF_DT_SAMPLE, samples[i]);
5302
0
            if (imap[i] < 0) continue;
5303
0
            r |= kputc('\t', &str) < 0;
5304
0
            r |= kputs(samples[i], &str) < 0;
5305
0
            r |= khash_str2int_inc(names_hash,samples[i]) < 0;
5306
0
        }
5307
0
    } else r |= kputsn(htxt.s, htxt.l, &str) < 0;
5308
0
    while (str.l && (!str.s[str.l-1] || str.s[str.l-1]=='\n') ) str.l--; // kill trailing zeros and newlines
5309
0
    r |= kputc('\n',&str) < 0;
5310
0
    if (r) {
5311
0
        hts_log_error("%s", strerror(errno));
5312
0
        goto err;
5313
0
    }
5314
0
    if ( bcf_hdr_parse(h, str.s) < 0 ) {
5315
0
        bcf_hdr_destroy(h);
5316
0
        h = NULL;
5317
0
    }
5318
0
    free(str.s);
5319
0
    free(htxt.s);
5320
0
    khash_str2int_destroy(names_hash);
5321
0
    return h;
5322
5323
0
 err:
5324
0
    ks_free(&str);
5325
0
    ks_free(&htxt);
5326
0
    khash_str2int_destroy(names_hash);
5327
0
    bcf_hdr_destroy(h);
5328
0
    return NULL;
5329
0
}
5330
5331
int bcf_hdr_set_samples(bcf_hdr_t *hdr, const char *samples, int is_file)
5332
0
{
5333
0
    if ( samples && !strcmp("-",samples) ) return 0;            // keep all samples
5334
5335
0
    int i, narr = bit_array_size(bcf_hdr_nsamples(hdr));
5336
0
    hdr->keep_samples = (uint8_t*) calloc(narr,1);
5337
0
    if (!hdr->keep_samples) return -1;
5338
5339
0
    hdr->nsamples_ori = bcf_hdr_nsamples(hdr);
5340
0
    if ( !samples )
5341
0
    {
5342
        // exclude all samples
5343
0
        khint_t k;
5344
0
        vdict_t *d = (vdict_t*)hdr->dict[BCF_DT_SAMPLE], *new_dict;
5345
0
        new_dict = kh_init(vdict);
5346
0
        if (!new_dict) return -1;
5347
5348
0
        bcf_hdr_nsamples(hdr) = 0;
5349
5350
0
        for (k = kh_begin(d); k != kh_end(d); ++k)
5351
0
            if (kh_exist(d, k)) free((char*)kh_key(d, k));
5352
0
        kh_destroy(vdict, d);
5353
0
        hdr->dict[BCF_DT_SAMPLE] = new_dict;
5354
0
        if (bcf_hdr_sync(hdr) < 0) return -1;
5355
5356
0
        return 0;
5357
0
    }
5358
5359
0
    if ( samples[0]=='^' )
5360
0
        for (i=0; i<bcf_hdr_nsamples(hdr); i++) bit_array_set(hdr->keep_samples,i);
5361
5362
0
    int idx, n, ret = 0;
5363
0
    char **smpls = hts_readlist(samples[0]=='^'?samples+1:samples, is_file, &n);
5364
0
    if ( !smpls ) return -1;
5365
0
    for (i=0; i<n; i++)
5366
0
    {
5367
0
        idx = bcf_hdr_id2int(hdr,BCF_DT_SAMPLE,smpls[i]);
5368
0
        if ( idx<0 )
5369
0
        {
5370
0
            if ( !ret ) ret = i+1;
5371
0
            continue;
5372
0
        }
5373
0
        assert( idx<bcf_hdr_nsamples(hdr) );
5374
0
        if (  samples[0]=='^' )
5375
0
            bit_array_clear(hdr->keep_samples, idx);
5376
0
        else
5377
0
            bit_array_set(hdr->keep_samples, idx);
5378
0
    }
5379
0
    for (i=0; i<n; i++) free(smpls[i]);
5380
0
    free(smpls);
5381
5382
0
    bcf_hdr_nsamples(hdr) = 0;
5383
0
    for (i=0; i<hdr->nsamples_ori; i++)
5384
0
        if ( bit_array_test(hdr->keep_samples,i) ) bcf_hdr_nsamples(hdr)++;
5385
5386
0
    if ( !bcf_hdr_nsamples(hdr) ) { free(hdr->keep_samples); hdr->keep_samples=NULL; }
5387
0
    else
5388
0
    {
5389
        // Make new list and dictionary with desired samples
5390
0
        char **samples = hts_malloc_p(sizeof(char*), bcf_hdr_nsamples(hdr));
5391
0
        vdict_t *new_dict, *d;
5392
0
        int k, res;
5393
0
        if (!samples) return -1;
5394
5395
0
        new_dict = kh_init(vdict);
5396
0
        if (!new_dict) {
5397
0
            free(samples);
5398
0
            return -1;
5399
0
        }
5400
0
        idx = 0;
5401
0
        for (i=0; i<hdr->nsamples_ori; i++) {
5402
0
            if ( bit_array_test(hdr->keep_samples,i) ) {
5403
0
                samples[idx] = hdr->samples[i];
5404
0
                k = kh_put(vdict, new_dict, hdr->samples[i], &res);
5405
0
                if (res < 0) {
5406
0
                    free(samples);
5407
0
                    kh_destroy(vdict, new_dict);
5408
0
                    return -1;
5409
0
                }
5410
0
                kh_val(new_dict, k) = bcf_idinfo_def;
5411
0
                kh_val(new_dict, k).id = idx;
5412
0
                idx++;
5413
0
            }
5414
0
        }
5415
5416
        // Delete desired samples from old dictionary, so we don't free them
5417
0
        d = (vdict_t*)hdr->dict[BCF_DT_SAMPLE];
5418
0
        for (i=0; i < idx; i++) {
5419
0
            int k = kh_get(vdict, d, samples[i]);
5420
0
            if (k < kh_end(d)) kh_del(vdict, d, k);
5421
0
        }
5422
5423
        // Free everything else
5424
0
        for (k = kh_begin(d); k != kh_end(d); ++k)
5425
0
            if (kh_exist(d, k)) free((char*)kh_key(d, k));
5426
0
        kh_destroy(vdict, d);
5427
0
        hdr->dict[BCF_DT_SAMPLE] = new_dict;
5428
5429
0
        free(hdr->samples);
5430
0
        hdr->samples = samples;
5431
5432
0
        if (bcf_hdr_sync(hdr) < 0)
5433
0
            return -1;
5434
0
    }
5435
5436
0
    return ret;
5437
0
}
5438
5439
int bcf_subset(const bcf_hdr_t *h, bcf1_t *v, int n, int *imap)
5440
0
{
5441
0
    kstring_t ind;
5442
0
    ind.s = 0; ind.l = ind.m = 0;
5443
0
    if (n) {
5444
0
        bcf_fmt_t fmt[MAX_N_FMT];
5445
0
        int i, j;
5446
0
        uint8_t *ptr = (uint8_t*)v->indiv.s;
5447
0
        for (i = 0; i < v->n_fmt; ++i)
5448
0
            ptr = bcf_unpack_fmt_core1(ptr, v->n_sample, &fmt[i]);
5449
0
        for (i = 0; i < (int)v->n_fmt; ++i) {
5450
0
            bcf_fmt_t *f = &fmt[i];
5451
0
            bcf_enc_int1(&ind, f->id);
5452
0
            bcf_enc_size(&ind, f->n, f->type);
5453
0
            for (j = 0; j < n; ++j)
5454
0
                if (imap[j] >= 0) kputsn((char*)(f->p + imap[j] * f->size), f->size, &ind);
5455
0
        }
5456
0
        for (i = j = 0; j < n; ++j) if (imap[j] >= 0) ++i;
5457
0
        v->n_sample = i;
5458
0
    } else v->n_sample = 0;
5459
0
    if ( !v->n_sample ) v->n_fmt = 0;
5460
0
    free(v->indiv.s);
5461
0
    v->indiv = ind;
5462
0
    v->unpacked &= ~BCF_UN_FMT;    // only BCF is ready for output, VCF will need to unpack again
5463
0
    return 0;
5464
0
}
5465
5466
int bcf_is_snp(bcf1_t *v)
5467
0
{
5468
0
    int i;
5469
0
    bcf_unpack(v, BCF_UN_STR);
5470
0
    for (i = 0; i < v->n_allele; ++i)
5471
0
    {
5472
0
        if ( v->d.allele[i][1]==0 && v->d.allele[i][0]!='*' ) continue;
5473
5474
        // mpileup's <X> allele, see also below. This is not completely satisfactory,
5475
        // a general library is here narrowly tailored to fit samtools.
5476
0
        if ( v->d.allele[i][0]=='<' && v->d.allele[i][1]=='X' && v->d.allele[i][2]=='>' ) continue;
5477
0
        if ( v->d.allele[i][0]=='<' && v->d.allele[i][1]=='*' && v->d.allele[i][2]=='>' ) continue;
5478
5479
0
        break;
5480
0
    }
5481
0
    return i == v->n_allele;
5482
0
}
5483
5484
static void bcf_set_variant_type(const char *ref, const char *alt, bcf_variant_t *var)
5485
0
{
5486
0
    if ( *alt == '*' && !alt[1] ) { var->n = 0; var->type = VCF_OVERLAP; return; }  // overlapping variant
5487
5488
    // The most frequent case
5489
0
    if ( !ref[1] && !alt[1] )
5490
0
    {
5491
0
        if ( *alt == '.' || *ref==*alt ) { var->n = 0; var->type = VCF_REF; return; }
5492
0
        if ( *alt == 'X' ) { var->n = 0; var->type = VCF_REF; return; }  // mpileup's X allele shouldn't be treated as variant
5493
0
        var->n = 1; var->type = VCF_SNP; return;
5494
0
    }
5495
0
    if ( alt[0]=='<' )
5496
0
    {
5497
0
        if ( alt[1]=='X' && alt[2]=='>' ) { var->n = 0; var->type = VCF_REF; return; }  // mpileup's X allele shouldn't be treated as variant
5498
0
        if ( alt[1]=='*' && alt[2]=='>' ) { var->n = 0; var->type = VCF_REF; return; }
5499
0
        if ( !strcmp("NON_REF>",alt+1) ) { var->n = 0; var->type = VCF_REF; return; }
5500
0
        var->type = VCF_OTHER;
5501
0
        return;
5502
0
    }
5503
5504
    // Catch "joined before" breakend case
5505
0
    if ( alt[0]==']' || alt[0] == '[' )
5506
0
    {
5507
0
        var->type = VCF_BND; return;
5508
0
    }
5509
5510
    // Iterate through alt characters that match the reference
5511
0
    const char *r = ref, *a = alt;
5512
0
    while (*r && *a && toupper_c(*r)==toupper_c(*a) ) { r++; a++; }     // unfortunately, matching REF,ALT case is not guaranteed
5513
5514
0
    if ( *a && !*r )
5515
0
    {
5516
0
        while ( *a ) a++;
5517
0
        if ( *(a-1)==']' || *(a-1)=='[' ) { var->type = VCF_BND; return; } // "joined after" breakend
5518
0
        var->n = (a-alt)-(r-ref); var->type = VCF_INDEL | VCF_INS; return;
5519
0
    }
5520
0
    else if ( *r && !*a )
5521
0
    {
5522
0
        while ( *r ) r++;
5523
0
        var->n = (a-alt)-(r-ref); var->type = VCF_INDEL | VCF_DEL; return;
5524
0
    }
5525
0
    else if ( !*r && !*a )
5526
0
    {
5527
0
        var->n = 0; var->type = VCF_REF; return;
5528
0
    }
5529
5530
0
    const char *re = r, *ae = a;
5531
0
    while ( re[1] ) re++;
5532
0
    while ( ae[1] ) ae++;
5533
0
    if ( ae[0]==']' || ae[0]=='[' ) { var->type = VCF_BND; return; }    // "joined after" breakend
5534
0
    while ( re>r && ae>a && toupper_c(*re)==toupper_c(*ae) ) { re--; ae--; }
5535
0
    if ( ae==a )
5536
0
    {
5537
0
        if ( re==r ) { var->n = 1; var->type = VCF_SNP; return; }
5538
0
        var->n = -(re-r);
5539
0
        if ( toupper_c(*re)==toupper_c(*ae) ) { var->type = VCF_INDEL | VCF_DEL; return; }
5540
0
        var->type = VCF_OTHER; return;
5541
0
    }
5542
0
    else if ( re==r )
5543
0
    {
5544
0
        var->n = ae-a;
5545
0
        if ( toupper_c(*re)==toupper_c(*ae) ) { var->type = VCF_INDEL | VCF_INS; return; }
5546
0
        var->type = VCF_OTHER; return;
5547
0
    }
5548
5549
0
    var->type = ( re-r == ae-a ) ? VCF_MNP : VCF_OTHER;
5550
0
    var->n = ( re-r > ae-a ) ? -(re-r+1) : ae-a+1;
5551
5552
    // should do also complex events, SVs, etc...
5553
0
}
5554
5555
static int bcf_set_variant_types(bcf1_t *b)
5556
0
{
5557
0
    if ( !(b->unpacked & BCF_UN_STR) ) bcf_unpack(b, BCF_UN_STR);
5558
0
    bcf_dec_t *d = &b->d;
5559
0
    if ( d->n_var < b->n_allele )
5560
0
    {
5561
0
        bcf_variant_t *new_var = hts_realloc_p(d->var, sizeof(bcf_variant_t),
5562
0
                                              b->n_allele);
5563
0
        if (!new_var)
5564
0
            return -1;
5565
0
        d->var = new_var;
5566
0
        d->n_var = b->n_allele;
5567
0
    }
5568
0
    int i;
5569
0
    b->d.var_type = 0;
5570
0
    d->var[0].type = VCF_REF;
5571
0
    d->var[0].n    = 0;
5572
0
    for (i=1; i<b->n_allele; i++)
5573
0
    {
5574
0
        bcf_set_variant_type(d->allele[0],d->allele[i], &d->var[i]);
5575
0
        b->d.var_type |= d->var[i].type;
5576
        //fprintf(stderr,"[set_variant_type] %d   %s %s -> %d %d .. %d\n", b->pos+1,d->allele[0],d->allele[i],d->var[i].type,d->var[i].n, b->d.var_type);
5577
0
    }
5578
0
    return 0;
5579
0
}
5580
5581
// bcf_get_variant_type/bcf_get_variant_types should only return the following,
5582
// to be compatible with callers that are not expecting newer values
5583
// like VCF_INS, VCF_DEL.  The full set is available from the newer
5584
// vcf_has_variant_type* interfaces.
5585
0
#define ORIG_VAR_TYPES (VCF_SNP|VCF_MNP|VCF_INDEL|VCF_OTHER|VCF_BND|VCF_OVERLAP)
5586
int bcf_get_variant_types(bcf1_t *rec)
5587
0
{
5588
0
    if ( rec->d.var_type==-1 ) {
5589
0
        if (bcf_set_variant_types(rec) != 0) {
5590
0
            hts_log_error("Couldn't get variant types: %s", strerror(errno));
5591
0
            exit(1); // Due to legacy API having no way to report failures
5592
0
        }
5593
0
    }
5594
0
    return rec->d.var_type & ORIG_VAR_TYPES;
5595
0
}
5596
5597
int bcf_get_variant_type(bcf1_t *rec, int ith_allele)
5598
0
{
5599
0
    if ( rec->d.var_type==-1 ) {
5600
0
        if (bcf_set_variant_types(rec) != 0) {
5601
0
            hts_log_error("Couldn't get variant types: %s", strerror(errno));
5602
0
            exit(1); // Due to legacy API having no way to report failures
5603
0
        }
5604
0
    }
5605
0
    if (ith_allele < 0 || ith_allele >= rec->n_allele) {
5606
0
        hts_log_error("Requested allele outside valid range");
5607
0
        exit(1);
5608
0
    }
5609
0
    return rec->d.var[ith_allele].type & ORIG_VAR_TYPES;
5610
0
}
5611
#undef ORIG_VAR_TYPES
5612
5613
int bcf_has_variant_type(bcf1_t *rec, int ith_allele, uint32_t bitmask)
5614
0
{
5615
0
    if ( rec->d.var_type==-1 ) {
5616
0
        if (bcf_set_variant_types(rec) != 0) return -1;
5617
0
    }
5618
0
    if (ith_allele < 0 || ith_allele >= rec->n_allele) return -1;
5619
0
    if (bitmask == VCF_REF) {  // VCF_REF is 0, so handled as a special case
5620
0
        return rec->d.var[ith_allele].type == VCF_REF;
5621
0
    }
5622
0
    return bitmask & rec->d.var[ith_allele].type;
5623
0
}
5624
5625
int bcf_variant_length(bcf1_t *rec, int ith_allele)
5626
0
{
5627
0
    if ( rec->d.var_type==-1 ) {
5628
0
        if (bcf_set_variant_types(rec) != 0) return bcf_int32_missing;
5629
0
    }
5630
0
    if (ith_allele < 0 || ith_allele >= rec->n_allele) return bcf_int32_missing;
5631
0
    return rec->d.var[ith_allele].n;
5632
0
}
5633
5634
int bcf_has_variant_types(bcf1_t *rec, uint32_t bitmask,
5635
                          enum bcf_variant_match mode)
5636
0
{
5637
0
    if ( rec->d.var_type==-1 ) {
5638
0
        if (bcf_set_variant_types(rec) != 0) return -1;
5639
0
    }
5640
0
    uint32_t type = rec->d.var_type;
5641
0
    if ( mode==bcf_match_overlap ) return bitmask & type;
5642
5643
    // VCF_INDEL is always set with VCF_INS and VCF_DEL by bcf_set_variant_type[s], but the bitmask may
5644
    // ask for say `VCF_INS` or `VCF_INDEL` only
5645
0
    if ( bitmask&(VCF_INS|VCF_DEL) && !(bitmask&VCF_INDEL) ) type &= ~VCF_INDEL;
5646
0
    else if ( bitmask&VCF_INDEL && !(bitmask&(VCF_INS|VCF_DEL)) ) type &= ~(VCF_INS|VCF_DEL);
5647
5648
0
    if ( mode==bcf_match_subset )
5649
0
    {
5650
0
        if ( ~bitmask & type ) return 0;
5651
0
        else return bitmask & type;
5652
0
    }
5653
    // mode == bcf_match_exact
5654
0
    if ( bitmask==VCF_REF ) return type==bitmask ? 1 : 0;
5655
0
    return type==bitmask ? type : 0;
5656
0
}
5657
5658
int bcf_update_info(const bcf_hdr_t *hdr, bcf1_t *line, const char *key, const void *values, int n, int type)
5659
0
{
5660
0
    static int negative_rlen_warned = 0;
5661
0
    int is_end_tag, is_svlen_tag = 0;
5662
5663
    // Is the field already present?
5664
0
    int i, inf_id = bcf_hdr_id2int(hdr,BCF_DT_ID,key);
5665
0
    if ( !bcf_hdr_idinfo_exists(hdr,BCF_HL_INFO,inf_id) ) return -1;    // No such INFO field in the header
5666
0
    if ( !(line->unpacked & BCF_UN_INFO) ) bcf_unpack(line, BCF_UN_INFO);
5667
5668
0
    is_end_tag = strcmp(key, "END") == 0;
5669
0
    is_svlen_tag = strcmp(key, "SVLEN") == 0;
5670
5671
0
    for (i=0; i<line->n_info; i++)
5672
0
        if ( inf_id==line->d.info[i].key ) break;
5673
0
    bcf_info_t *inf = i==line->n_info ? NULL : &line->d.info[i];
5674
5675
0
    if ( !n || (type==BCF_HT_STR && !values) )
5676
0
    {
5677
0
        if ( inf )
5678
0
        {
5679
            // Mark the tag for removal, free existing memory if necessary
5680
0
            if ( inf->vptr_free )
5681
0
            {
5682
0
                free(inf->vptr - inf->vptr_off);
5683
0
                inf->vptr_free = 0;
5684
0
            }
5685
0
            line->d.shared_dirty |= BCF1_DIRTY_INF;
5686
0
            inf->vptr = NULL;
5687
0
            inf->vptr_off = inf->vptr_len = 0;
5688
0
        }
5689
0
        if ( n==0 && (is_end_tag || is_svlen_tag) ) {
5690
0
            line->rlen = get_rlen(hdr, line);
5691
0
        }
5692
0
        return 0;
5693
0
    }
5694
5695
0
    if (is_end_tag)
5696
0
    {
5697
0
        if (n != 1)
5698
0
        {
5699
0
            hts_log_error("END info tag should only have one value at %s:%"PRIhts_pos, bcf_seqname_safe(hdr,line), line->pos+1);
5700
0
            line->errcode |= BCF_ERR_TAG_INVALID;
5701
0
            return -1;
5702
0
        }
5703
0
        if (type != BCF_HT_INT && type != BCF_HT_LONG)
5704
0
        {
5705
0
            hts_log_error("Wrong type (%d) for END info tag at %s:%"PRIhts_pos, type, bcf_seqname_safe(hdr,line), line->pos+1);
5706
0
            line->errcode |= BCF_ERR_TAG_INVALID;
5707
0
            return -1;
5708
0
        }
5709
0
    }
5710
5711
    // Encode the values and determine the size required to accommodate the values
5712
0
    kstring_t str = {0,0,0};
5713
0
    bcf_enc_int1(&str, inf_id);
5714
0
    if ( type==BCF_HT_INT )
5715
0
        bcf_enc_vint(&str, n, (int32_t*)values, -1);
5716
0
    else if ( type==BCF_HT_REAL )
5717
0
        bcf_enc_vfloat(&str, n, (float*)values);
5718
0
    else if ( type==BCF_HT_FLAG || type==BCF_HT_STR )
5719
0
    {
5720
0
        if ( values==NULL )
5721
0
            bcf_enc_size(&str, 0, BCF_BT_NULL);
5722
0
        else
5723
0
            bcf_enc_vchar(&str, strlen((char*)values), (char*)values);
5724
0
    }
5725
#ifdef VCF_ALLOW_INT64
5726
    else if ( type==BCF_HT_LONG )
5727
    {
5728
        if (n != 1) {
5729
            hts_log_error("Only storing a single BCF_HT_LONG value is supported at %s:%"PRIhts_pos, bcf_seqname_safe(hdr,line), line->pos+1);
5730
            abort();
5731
        }
5732
        bcf_enc_long1(&str, *(int64_t *) values);
5733
    }
5734
#endif
5735
0
    else
5736
0
    {
5737
0
        hts_log_error("The type %d not implemented yet at %s:%"PRIhts_pos, type, bcf_seqname_safe(hdr,line), line->pos+1);
5738
0
        abort();
5739
0
    }
5740
5741
    // Is the INFO tag already present
5742
0
    if ( inf )
5743
0
    {
5744
        // Is it big enough to accommodate new block?
5745
0
        if ( inf->vptr && str.l <= inf->vptr_len + inf->vptr_off )
5746
0
        {
5747
0
            if ( str.l != inf->vptr_len + inf->vptr_off ) line->d.shared_dirty |= BCF1_DIRTY_INF;
5748
0
            uint8_t *ptr = inf->vptr - inf->vptr_off;
5749
0
            memcpy(ptr, str.s, str.l);
5750
0
            free(str.s);
5751
0
            int vptr_free = inf->vptr_free;
5752
0
            bcf_unpack_info_core1(ptr, inf);
5753
0
            inf->vptr_free = vptr_free;
5754
0
        }
5755
0
        else
5756
0
        {
5757
0
            if ( inf->vptr_free )
5758
0
                free(inf->vptr - inf->vptr_off);
5759
0
            bcf_unpack_info_core1((uint8_t*)str.s, inf);
5760
0
            inf->vptr_free = 1;
5761
0
            line->d.shared_dirty |= BCF1_DIRTY_INF;
5762
0
        }
5763
0
    }
5764
0
    else
5765
0
    {
5766
        // The tag is not present, create new one
5767
0
        line->n_info++;
5768
0
        hts_expand0(bcf_info_t, line->n_info, line->d.m_info , line->d.info);
5769
0
        inf = &line->d.info[line->n_info-1];
5770
0
        bcf_unpack_info_core1((uint8_t*)str.s, inf);
5771
0
        inf->vptr_free = 1;
5772
0
        line->d.shared_dirty |= BCF1_DIRTY_INF;
5773
0
    }
5774
0
    line->unpacked |= BCF_UN_INFO;
5775
5776
0
   if ( n==1 && is_end_tag) {
5777
0
        hts_pos_t end = type == BCF_HT_INT ? *(int32_t *) values : *(int64_t *) values;
5778
0
        if ( (type == BCF_HT_INT && end!=bcf_int32_missing) || (type == BCF_HT_LONG && end!=bcf_int64_missing) )
5779
0
        {
5780
0
            if ( end <= line->pos )
5781
0
            {
5782
0
                if ( !negative_rlen_warned )
5783
0
                {
5784
0
                    hts_log_warning("INFO/END=%"PRIhts_pos" is smaller than POS at %s:%"PRIhts_pos,end,bcf_seqname_safe(hdr,line),line->pos+1);
5785
0
                    negative_rlen_warned = 1;
5786
0
                }
5787
0
            }
5788
0
        }
5789
0
    }
5790
0
    if (is_svlen_tag || is_end_tag) {
5791
0
        line->rlen = get_rlen(hdr, line);
5792
0
    }
5793
0
    return 0;
5794
0
}
5795
5796
int bcf_update_format_string(const bcf_hdr_t *hdr, bcf1_t *line, const char *key, const char **values, int n)
5797
0
{
5798
0
    if ( !n )
5799
0
        return bcf_update_format(hdr,line,key,NULL,0,BCF_HT_STR);
5800
5801
0
    int i, max_len = 0;
5802
0
    for (i=0; i<n; i++)
5803
0
    {
5804
0
        int len = strlen(values[i]);
5805
0
        if ( len > max_len ) max_len = len;
5806
0
    }
5807
0
    char *out = hts_malloc_p(max_len, n);
5808
0
    if ( !out ) return -2;
5809
0
    for (i=0; i<n; i++)
5810
0
    {
5811
0
        char *dst = out+i*max_len;
5812
0
        const char *src = values[i];
5813
0
        int j = 0;
5814
0
        while ( src[j] ) { dst[j] = src[j]; j++; }
5815
0
        for (; j<max_len; j++) dst[j] = 0;
5816
0
    }
5817
0
    int ret = bcf_update_format(hdr,line,key,out,max_len*n,BCF_HT_STR);
5818
0
    free(out);
5819
0
    return ret;
5820
0
}
5821
5822
int bcf_update_format(const bcf_hdr_t *hdr, bcf1_t *line, const char *key, const void *values, int n, int type)
5823
0
{
5824
    // Is the field already present?
5825
0
    int i, fmt_id = bcf_hdr_id2int(hdr,BCF_DT_ID,key);
5826
0
    int is_len = 0;
5827
0
    if ( !bcf_hdr_idinfo_exists(hdr,BCF_HL_FMT,fmt_id) )
5828
0
    {
5829
0
        if ( !n ) return 0;
5830
0
        return -1;  // the key not present in the header
5831
0
    }
5832
5833
0
    if ( !(line->unpacked & BCF_UN_FMT) ) bcf_unpack(line, BCF_UN_FMT);
5834
5835
0
    for (i=0; i<line->n_fmt; i++)
5836
0
        if ( line->d.fmt[i].id==fmt_id ) break;
5837
0
    bcf_fmt_t *fmt = i==line->n_fmt ? NULL : &line->d.fmt[i];
5838
5839
0
    is_len = strcmp(key, "LEN") == 0;
5840
0
    if ( !n )
5841
0
    {
5842
0
        if ( fmt )
5843
0
        {
5844
            // Mark the tag for removal, free existing memory if necessary
5845
0
            if ( fmt->p_free )
5846
0
            {
5847
0
                free(fmt->p - fmt->p_off);
5848
0
                fmt->p_free = 0;
5849
0
            }
5850
0
            line->d.indiv_dirty = 1;
5851
0
            fmt->p = NULL;
5852
0
        }
5853
0
        if (is_len) {
5854
0
            line->rlen = get_rlen(hdr, line);
5855
0
        }
5856
0
        return 0;
5857
0
    }
5858
5859
0
    line->n_sample = bcf_hdr_nsamples(hdr);
5860
0
    int nps = n / line->n_sample;  // number of values per sample
5861
0
    assert( nps && nps*line->n_sample==n );     // must be divisible by n_sample
5862
5863
    // Encode the values and determine the size required to accommodate the values
5864
0
    kstring_t str = {0,0,0};
5865
0
    bcf_enc_int1(&str, fmt_id);
5866
0
    assert(values != NULL);
5867
0
    if ( type==BCF_HT_INT )
5868
0
        bcf_enc_vint(&str, n, (int32_t*)values, nps);
5869
0
    else if ( type==BCF_HT_REAL )
5870
0
    {
5871
0
        bcf_enc_size(&str, nps, BCF_BT_FLOAT);
5872
0
        serialize_float_array(&str, nps*line->n_sample, (float *) values);
5873
0
    }
5874
0
    else if ( type==BCF_HT_STR )
5875
0
    {
5876
0
        bcf_enc_size(&str, nps, BCF_BT_CHAR);
5877
0
        kputsn((char*)values, nps*line->n_sample, &str);
5878
0
    }
5879
0
    else
5880
0
    {
5881
0
        hts_log_error("The type %d not implemented yet at %s:%"PRIhts_pos, type, bcf_seqname_safe(hdr,line), line->pos+1);
5882
0
        abort();
5883
0
    }
5884
5885
0
    if ( !fmt )
5886
0
    {
5887
        // Not present, new format field
5888
0
        line->n_fmt++;
5889
0
        hts_expand0(bcf_fmt_t, line->n_fmt, line->d.m_fmt, line->d.fmt);
5890
5891
        // Special case: VCF specification requires that GT is always first
5892
0
        if ( line->n_fmt > 1 && key[0]=='G' && key[1]=='T' && !key[2] )
5893
0
        {
5894
0
            for (i=line->n_fmt-1; i>0; i--)
5895
0
                line->d.fmt[i] = line->d.fmt[i-1];
5896
0
            fmt = &line->d.fmt[0];
5897
0
        }
5898
0
        else
5899
0
            fmt = &line->d.fmt[line->n_fmt-1];
5900
0
        bcf_unpack_fmt_core1((uint8_t*)str.s, line->n_sample, fmt);
5901
0
        line->d.indiv_dirty = 1;
5902
0
        fmt->p_free = 1;
5903
0
    }
5904
0
    else
5905
0
    {
5906
        // The tag is already present, check if it is big enough to accommodate the new block
5907
0
        if ( fmt->p && str.l <= fmt->p_len + fmt->p_off )
5908
0
        {
5909
            // good, the block is big enough
5910
0
            if ( str.l != fmt->p_len + fmt->p_off ) line->d.indiv_dirty = 1;
5911
0
            uint8_t *ptr = fmt->p - fmt->p_off;
5912
0
            memcpy(ptr, str.s, str.l);
5913
0
            free(str.s);
5914
0
            int p_free = fmt->p_free;
5915
0
            bcf_unpack_fmt_core1(ptr, line->n_sample, fmt);
5916
0
            fmt->p_free = p_free;
5917
0
        }
5918
0
        else
5919
0
        {
5920
0
            if ( fmt->p_free )
5921
0
                free(fmt->p - fmt->p_off);
5922
0
            bcf_unpack_fmt_core1((uint8_t*)str.s, line->n_sample, fmt);
5923
0
            fmt->p_free = 1;
5924
0
            line->d.indiv_dirty = 1;
5925
0
        }
5926
0
    }
5927
0
    line->unpacked |= BCF_UN_FMT;
5928
5929
0
    if (is_len) {
5930
0
        line->rlen = get_rlen(hdr, line);
5931
0
    }
5932
0
    return 0;
5933
0
}
5934
5935
5936
int bcf_update_filter(const bcf_hdr_t *hdr, bcf1_t *line, int *flt_ids, int n)
5937
0
{
5938
0
    if ( !(line->unpacked & BCF_UN_FLT) ) bcf_unpack(line, BCF_UN_FLT);
5939
0
    line->d.shared_dirty |= BCF1_DIRTY_FLT;
5940
0
    line->d.n_flt = n;
5941
0
    if ( !n ) return 0;
5942
0
    hts_expand(int, line->d.n_flt, line->d.m_flt, line->d.flt);
5943
0
    int i;
5944
0
    for (i=0; i<n; i++)
5945
0
        line->d.flt[i] = flt_ids[i];
5946
0
    return 0;
5947
0
}
5948
5949
int bcf_add_filter(const bcf_hdr_t *hdr, bcf1_t *line, int flt_id)
5950
0
{
5951
0
    if ( !(line->unpacked & BCF_UN_FLT) ) bcf_unpack(line, BCF_UN_FLT);
5952
0
    int i;
5953
0
    for (i=0; i<line->d.n_flt; i++)
5954
0
        if ( flt_id==line->d.flt[i] ) break;
5955
0
    if ( i<line->d.n_flt ) return 0;    // this filter is already set
5956
0
    line->d.shared_dirty |= BCF1_DIRTY_FLT;
5957
0
    if ( flt_id==0 )    // set to PASS
5958
0
        line->d.n_flt = 1;
5959
0
    else if ( line->d.n_flt==1 && line->d.flt[0]==0 )
5960
0
        line->d.n_flt = 1;
5961
0
    else
5962
0
        line->d.n_flt++;
5963
0
    hts_expand(int, line->d.n_flt, line->d.m_flt, line->d.flt);
5964
0
    line->d.flt[line->d.n_flt-1] = flt_id;
5965
0
    return 1;
5966
0
}
5967
int bcf_remove_filter(const bcf_hdr_t *hdr, bcf1_t *line, int flt_id, int pass)
5968
0
{
5969
0
    if ( !(line->unpacked & BCF_UN_FLT) ) bcf_unpack(line, BCF_UN_FLT);
5970
0
    int i;
5971
0
    for (i=0; i<line->d.n_flt; i++)
5972
0
        if ( flt_id==line->d.flt[i] ) break;
5973
0
    if ( i==line->d.n_flt ) return 0;   // the filter is not present
5974
0
    line->d.shared_dirty |= BCF1_DIRTY_FLT;
5975
0
    if ( i!=line->d.n_flt-1 ) memmove(line->d.flt+i,line->d.flt+i+1,(line->d.n_flt-i-1)*sizeof(*line->d.flt));
5976
0
    line->d.n_flt--;
5977
0
    if ( !line->d.n_flt && pass ) bcf_add_filter(hdr,line,0);
5978
0
    return 0;
5979
0
}
5980
5981
int bcf_has_filter(const bcf_hdr_t *hdr, bcf1_t *line, char *filter)
5982
0
{
5983
0
    if ( filter[0]=='.' && !filter[1] ) filter = "PASS";
5984
0
    int id = bcf_hdr_id2int(hdr, BCF_DT_ID, filter);
5985
0
    if ( !bcf_hdr_idinfo_exists(hdr,BCF_HL_FLT,id) ) return -1;  // not defined in the header
5986
5987
0
    if ( !(line->unpacked & BCF_UN_FLT) ) bcf_unpack(line, BCF_UN_FLT);
5988
0
    if ( id==0 && !line->d.n_flt) return 1; // PASS
5989
5990
0
    int i;
5991
0
    for (i=0; i<line->d.n_flt; i++)
5992
0
        if ( line->d.flt[i]==id ) return 1;
5993
0
    return 0;
5994
0
}
5995
5996
static inline int _bcf1_sync_alleles(const bcf_hdr_t *hdr, bcf1_t *line, int nals)
5997
0
{
5998
0
    line->d.shared_dirty |= BCF1_DIRTY_ALS;
5999
0
    line->d.var_type = -1;
6000
6001
0
    line->n_allele = nals;
6002
0
    hts_expand(char*, line->n_allele, line->d.m_allele, line->d.allele);
6003
6004
0
    char *als = line->d.als;
6005
0
    int n = 0;
6006
0
    while (n<nals)
6007
0
    {
6008
0
        line->d.allele[n] = als;
6009
0
        while ( *als ) als++;
6010
0
        als++;
6011
0
        n++;
6012
0
    }
6013
    // Update REF length. Note that END is 1-based while line->pos 0-based
6014
0
    line->rlen = get_rlen(hdr, line);
6015
6016
0
    return 0;
6017
0
}
6018
int bcf_update_alleles(const bcf_hdr_t *hdr, bcf1_t *line, const char **alleles, int nals)
6019
0
{
6020
0
    if ( !(line->unpacked & BCF_UN_STR) ) bcf_unpack(line, BCF_UN_STR);
6021
0
    char *free_old = NULL;
6022
0
    char buffer[256];
6023
0
    size_t used = 0;
6024
6025
    // The pointers in alleles may point into the existing line->d.als memory,
6026
    // so care needs to be taken not to clobber them while updating.  Usually
6027
    // they will be short so we can copy through an intermediate buffer.
6028
    // If they're longer, or won't fit in the existing allocation we
6029
    // can allocate a new buffer to write into.  Note that in either case
6030
    // pointers to line->d.als memory in alleles may not be valid when we've
6031
    // finished.
6032
0
    int i;
6033
0
    size_t avail = line->d.m_als < sizeof(buffer) ? line->d.m_als : sizeof(buffer);
6034
0
    for (i=0; i<nals; i++) {
6035
0
        size_t sz = strlen(alleles[i]) + 1;
6036
0
        if (avail - used < sz)
6037
0
            break;
6038
0
        memcpy(buffer + used, alleles[i], sz);
6039
0
        used += sz;
6040
0
    }
6041
6042
    // Did we miss anything?
6043
0
    if (i < nals) {
6044
0
        int j;
6045
0
        size_t needed = used;
6046
0
        char *new_als;
6047
0
        for (j = i; j < nals; j++)
6048
0
            needed += strlen(alleles[j]) + 1;
6049
0
        if (needed < line->d.m_als) // Don't shrink the buffer
6050
0
            needed = line->d.m_als;
6051
0
        if (needed > INT_MAX) {
6052
0
            hts_log_error("REF + alleles too long to fit in a BCF record");
6053
0
            return -1;
6054
0
        }
6055
0
        new_als = malloc(needed);
6056
0
        if (!new_als)
6057
0
            return -1;
6058
0
        free_old = line->d.als;
6059
0
        line->d.als = new_als;
6060
0
        line->d.m_als = needed;
6061
0
    }
6062
6063
    // Copy from the temp buffer to the destination
6064
0
    if (used) {
6065
0
        assert(used <= line->d.m_als);
6066
0
        memcpy(line->d.als, buffer, used);
6067
0
    }
6068
6069
    // Add in any remaining entries - if this happens we will always be
6070
    // writing to a newly-allocated buffer.
6071
0
    for (; i < nals; i++) {
6072
0
        size_t sz = strlen(alleles[i]) + 1;
6073
0
        memcpy(line->d.als + used, alleles[i], sz);
6074
0
        used += sz;
6075
0
    }
6076
6077
0
    if (free_old)
6078
0
        free(free_old);
6079
0
    return _bcf1_sync_alleles(hdr,line,nals);
6080
0
}
6081
6082
int bcf_update_alleles_str(const bcf_hdr_t *hdr, bcf1_t *line, const char *alleles_string)
6083
0
{
6084
0
    if ( !(line->unpacked & BCF_UN_STR) ) bcf_unpack(line, BCF_UN_STR);
6085
0
    kstring_t tmp;
6086
0
    tmp.l = 0; tmp.s = line->d.als; tmp.m = line->d.m_als;
6087
0
    kputs(alleles_string, &tmp);
6088
0
    line->d.als = tmp.s; line->d.m_als = tmp.m;
6089
6090
0
    int nals = 1;
6091
0
    char *t = line->d.als;
6092
0
    while (*t)
6093
0
    {
6094
0
        if ( *t==',' ) { *t = 0; nals++; }
6095
0
        t++;
6096
0
    }
6097
0
    return _bcf1_sync_alleles(hdr, line, nals);
6098
0
}
6099
6100
int bcf_update_id(const bcf_hdr_t *hdr, bcf1_t *line, const char *id)
6101
0
{
6102
0
    if ( !(line->unpacked & BCF_UN_STR) ) bcf_unpack(line, BCF_UN_STR);
6103
0
    kstring_t tmp;
6104
0
    tmp.l = 0; tmp.s = line->d.id; tmp.m = line->d.m_id;
6105
0
    if ( id )
6106
0
        kputs(id, &tmp);
6107
0
    else
6108
0
        kputs(".", &tmp);
6109
0
    line->d.id = tmp.s; line->d.m_id = tmp.m;
6110
0
    line->d.shared_dirty |= BCF1_DIRTY_ID;
6111
0
    return 0;
6112
0
}
6113
6114
int bcf_add_id(const bcf_hdr_t *hdr, bcf1_t *line, const char *id)
6115
0
{
6116
0
    if ( !id ) return 0;
6117
0
    if ( !(line->unpacked & BCF_UN_STR) ) bcf_unpack(line, BCF_UN_STR);
6118
6119
0
    kstring_t tmp;
6120
0
    tmp.l = 0; tmp.s = line->d.id; tmp.m = line->d.m_id;
6121
6122
0
    int len = strlen(id);
6123
0
    char *dst = line->d.id;
6124
0
    while ( *dst && (dst=strstr(dst,id)) )
6125
0
    {
6126
0
        if ( dst[len]!=0 && dst[len]!=';' ) dst++;              // a prefix, not a match
6127
0
        else if ( dst==line->d.id || dst[-1]==';' ) return 0;   // already present
6128
0
        dst++;  // a suffix, not a match
6129
0
    }
6130
0
    if ( line->d.id && (line->d.id[0]!='.' || line->d.id[1]) )
6131
0
    {
6132
0
        tmp.l = strlen(line->d.id);
6133
0
        kputc(';',&tmp);
6134
0
    }
6135
0
    kputs(id,&tmp);
6136
6137
0
    line->d.id = tmp.s; line->d.m_id = tmp.m;
6138
0
    line->d.shared_dirty |= BCF1_DIRTY_ID;
6139
0
    return 0;
6140
6141
0
}
6142
6143
bcf_fmt_t *bcf_get_fmt(const bcf_hdr_t *hdr, bcf1_t *line, const char *key)
6144
0
{
6145
0
    int id = bcf_hdr_id2int(hdr, BCF_DT_ID, key);
6146
0
    if ( !bcf_hdr_idinfo_exists(hdr,BCF_HL_FMT,id) ) return NULL;   // no such FMT field in the header
6147
0
    return bcf_get_fmt_id(line, id);
6148
0
}
6149
6150
bcf_info_t *bcf_get_info(const bcf_hdr_t *hdr, bcf1_t *line, const char *key)
6151
0
{
6152
0
    int id = bcf_hdr_id2int(hdr, BCF_DT_ID, key);
6153
0
    if ( !bcf_hdr_idinfo_exists(hdr,BCF_HL_INFO,id) ) return NULL;   // no such INFO field in the header
6154
0
    return bcf_get_info_id(line, id);
6155
0
}
6156
6157
bcf_fmt_t *bcf_get_fmt_id(bcf1_t *line, const int id)
6158
0
{
6159
0
    int i;
6160
0
    if ( !(line->unpacked & BCF_UN_FMT) ) bcf_unpack(line, BCF_UN_FMT);
6161
0
    for (i=0; i<line->n_fmt; i++)
6162
0
    {
6163
0
        if ( line->d.fmt[i].id==id ) return &line->d.fmt[i];
6164
0
    }
6165
0
    return NULL;
6166
0
}
6167
6168
bcf_info_t *bcf_get_info_id(bcf1_t *line, const int id)
6169
0
{
6170
0
    int i;
6171
0
    if ( !(line->unpacked & BCF_UN_INFO) ) bcf_unpack(line, BCF_UN_INFO);
6172
0
    for (i=0; i<line->n_info; i++)
6173
0
    {
6174
0
        if ( line->d.info[i].key==id ) return &line->d.info[i];
6175
0
    }
6176
0
    return NULL;
6177
0
}
6178
6179
6180
int bcf_get_info_values(const bcf_hdr_t *hdr, bcf1_t *line, const char *tag, void **dst, int *ndst, int type)
6181
0
{
6182
0
    int i, ret = -4, tag_id = bcf_hdr_id2int(hdr, BCF_DT_ID, tag);
6183
0
    if ( !bcf_hdr_idinfo_exists(hdr,BCF_HL_INFO,tag_id) ) return -1;    // no such INFO field in the header
6184
0
    if ( bcf_hdr_id2type(hdr,BCF_HL_INFO,tag_id)!=(type & 0xff) ) return -2;     // expected different type
6185
6186
0
    if ( !(line->unpacked & BCF_UN_INFO) ) bcf_unpack(line, BCF_UN_INFO);
6187
6188
0
    for (i=0; i<line->n_info; i++)
6189
0
        if ( line->d.info[i].key==tag_id ) break;
6190
0
    if ( i==line->n_info ) return ( type==BCF_HT_FLAG ) ? 0 : -3;       // the tag is not present in this record
6191
0
    if ( type==BCF_HT_FLAG ) return 1;
6192
6193
0
    bcf_info_t *info = &line->d.info[i];
6194
0
    if ( !info->vptr ) return -3;           // the tag was marked for removal
6195
0
    if ( type==BCF_HT_STR )
6196
0
    {
6197
0
        if ( *ndst < info->len+1 )
6198
0
        {
6199
0
            *ndst = info->len + 1;
6200
0
            *dst  = realloc(*dst, *ndst);
6201
0
        }
6202
0
        memcpy(*dst,info->vptr,info->len);
6203
0
        ((uint8_t*)*dst)[info->len] = 0;
6204
0
        return info->len;
6205
0
    }
6206
6207
    // Make sure the buffer is big enough
6208
0
    int size1;
6209
0
    switch (type) {
6210
0
        case BCF_HT_INT:  size1 = sizeof(int32_t); break;
6211
0
        case BCF_HT_LONG: size1 = sizeof(int64_t); break;
6212
0
        case BCF_HT_REAL: size1 = sizeof(float); break;
6213
0
        default:
6214
0
            hts_log_error("Unexpected output type %d at %s:%"PRIhts_pos, type, bcf_seqname_safe(hdr,line), line->pos+1);
6215
0
            return -2;
6216
0
    }
6217
0
    if ( *ndst < info->len )
6218
0
    {
6219
0
        *ndst = info->len;
6220
0
        *dst  = hts_realloc_p(*dst, *ndst, size1);
6221
0
    }
6222
6223
0
    #define BRANCH(type_t, convert, is_missing, is_vector_end, set_missing, set_regular, out_type_t) do { \
6224
0
        out_type_t *tmp = (out_type_t *) *dst; \
6225
0
        int j; \
6226
0
        for (j=0; j<info->len; j++) \
6227
0
        { \
6228
0
            type_t p = convert(info->vptr + j * sizeof(type_t)); \
6229
0
            if ( is_vector_end ) break; \
6230
0
            if ( is_missing ) set_missing; \
6231
0
            else set_regular; \
6232
0
            tmp++; \
6233
0
        } \
6234
0
        ret = j; \
6235
0
    } while (0)
6236
0
    switch (info->type) {
6237
0
        case BCF_BT_INT8:
6238
0
            if (type == BCF_HT_LONG) {
6239
0
                BRANCH(int8_t,  le_to_i8,  p==bcf_int8_missing,  p==bcf_int8_vector_end,  *tmp=bcf_int64_missing, *tmp=p, int64_t);
6240
0
            } else {
6241
0
                BRANCH(int8_t,  le_to_i8,  p==bcf_int8_missing,  p==bcf_int8_vector_end,  *tmp=bcf_int32_missing, *tmp=p, int32_t);
6242
0
            }
6243
0
            break;
6244
0
        case BCF_BT_INT16:
6245
0
            if (type == BCF_HT_LONG) {
6246
0
                BRANCH(int16_t, le_to_i16, p==bcf_int16_missing, p==bcf_int16_vector_end, *tmp=bcf_int64_missing, *tmp=p, int64_t);
6247
0
            } else {
6248
0
                BRANCH(int16_t, le_to_i16, p==bcf_int16_missing, p==bcf_int16_vector_end, *tmp=bcf_int32_missing, *tmp=p, int32_t);
6249
0
            }
6250
0
            break;
6251
0
        case BCF_BT_INT32:
6252
0
            if (type == BCF_HT_LONG) {
6253
0
                BRANCH(int32_t, le_to_i32, p==bcf_int32_missing, p==bcf_int32_vector_end, *tmp=bcf_int64_missing, *tmp=p, int64_t); break;
6254
0
            } else {
6255
0
                BRANCH(int32_t, le_to_i32, p==bcf_int32_missing, p==bcf_int32_vector_end, *tmp=bcf_int32_missing, *tmp=p, int32_t); break;
6256
0
            }
6257
0
        case BCF_BT_FLOAT: BRANCH(uint32_t, le_to_u32, p==bcf_float_missing, p==bcf_float_vector_end, bcf_float_set_missing(*tmp), bcf_float_set(tmp, p), float); break;
6258
0
        default: hts_log_error("Unexpected type %d at %s:%"PRIhts_pos, info->type, bcf_seqname_safe(hdr,line), line->pos+1); return -2;
6259
0
    }
6260
0
    #undef BRANCH
6261
0
    return ret;  // set by BRANCH
6262
0
}
6263
6264
int bcf_get_format_string(const bcf_hdr_t *hdr, bcf1_t *line, const char *tag, char ***dst, int *ndst)
6265
0
{
6266
0
    int i,tag_id = bcf_hdr_id2int(hdr, BCF_DT_ID, tag);
6267
0
    if ( !bcf_hdr_idinfo_exists(hdr,BCF_HL_FMT,tag_id) ) return -1;    // no such FORMAT field in the header
6268
0
    if ( bcf_hdr_id2type(hdr,BCF_HL_FMT,tag_id)!=BCF_HT_STR ) return -2;     // expected different type
6269
6270
0
    if ( !(line->unpacked & BCF_UN_FMT) ) bcf_unpack(line, BCF_UN_FMT);
6271
6272
0
    for (i=0; i<line->n_fmt; i++)
6273
0
        if ( line->d.fmt[i].id==tag_id ) break;
6274
0
    if ( i==line->n_fmt ) return -3;                               // the tag is not present in this record
6275
0
    bcf_fmt_t *fmt = &line->d.fmt[i];
6276
0
    if ( !fmt->p ) return -3;                                      // the tag was marked for removal
6277
6278
0
    int nsmpl = bcf_hdr_nsamples(hdr);
6279
0
    if ( !*dst )
6280
0
    {
6281
0
        *dst = hts_malloc_p(sizeof(char*), nsmpl);
6282
0
        if ( !*dst ) return -4;     // could not alloc
6283
0
        (*dst)[0] = NULL;
6284
0
    }
6285
0
    int n = (fmt->n+1)*nsmpl;
6286
0
    if ( *ndst < n )
6287
0
    {
6288
0
        (*dst)[0] = realloc((*dst)[0], n);
6289
0
        if ( !(*dst)[0] ) return -4;    // could not alloc
6290
0
        *ndst = n;
6291
0
    }
6292
0
    for (i=0; i<nsmpl; i++)
6293
0
    {
6294
0
        uint8_t *src = fmt->p + i*fmt->n;
6295
0
        uint8_t *tmp = (uint8_t*)(*dst)[0] + i*(fmt->n+1);
6296
0
        memcpy(tmp,src,fmt->n);
6297
0
        tmp[fmt->n] = 0;
6298
0
        (*dst)[i] = (char*) tmp;
6299
0
    }
6300
0
    return n;
6301
0
}
6302
6303
int bcf_get_format_values(const bcf_hdr_t *hdr, bcf1_t *line, const char *tag, void **dst, int *ndst, int type)
6304
0
{
6305
0
    int i,j, tag_id = bcf_hdr_id2int(hdr, BCF_DT_ID, tag);
6306
0
    if ( !bcf_hdr_idinfo_exists(hdr,BCF_HL_FMT,tag_id) ) return -1;    // no such FORMAT field in the header
6307
0
    if ( tag[0]=='G' && tag[1]=='T' && tag[2]==0 )
6308
0
    {
6309
        // Ugly: GT field is considered to be a string by the VCF header but BCF represents it as INT.
6310
0
        if ( bcf_hdr_id2type(hdr,BCF_HL_FMT,tag_id)!=BCF_HT_STR ) return -2;
6311
0
    }
6312
0
    else if ( bcf_hdr_id2type(hdr,BCF_HL_FMT,tag_id)!=type ) return -2;     // expected different type
6313
6314
0
    if ( !(line->unpacked & BCF_UN_FMT) ) bcf_unpack(line, BCF_UN_FMT);
6315
6316
0
    for (i=0; i<line->n_fmt; i++)
6317
0
        if ( line->d.fmt[i].id==tag_id ) break;
6318
0
    if ( i==line->n_fmt ) return -3;                               // the tag is not present in this record
6319
0
    bcf_fmt_t *fmt = &line->d.fmt[i];
6320
0
    if ( !fmt->p ) return -3;                                      // the tag was marked for removal
6321
6322
0
    if ( type==BCF_HT_STR )
6323
0
    {
6324
0
        int n = fmt->n*bcf_hdr_nsamples(hdr);
6325
0
        if ( *ndst < n )
6326
0
        {
6327
0
            *dst  = realloc(*dst, n);
6328
0
            if ( !*dst ) return -4;     // could not alloc
6329
0
            *ndst = n;
6330
0
        }
6331
0
        memcpy(*dst,fmt->p,n);
6332
0
        return n;
6333
0
    }
6334
6335
    // Make sure the buffer is big enough
6336
0
    int nsmpl = bcf_hdr_nsamples(hdr);
6337
0
    int size1 = type==BCF_HT_INT ? sizeof(int32_t) : sizeof(float);
6338
0
    if ( *ndst < fmt->n*nsmpl )
6339
0
    {
6340
0
        *ndst = fmt->n*nsmpl;
6341
0
        *dst  = hts_realloc_p(*dst, *ndst, size1);
6342
0
        if ( !*dst ) return -4;     // could not alloc
6343
0
    }
6344
6345
0
    #define BRANCH(type_t, convert, is_missing, is_vector_end, set_missing, set_vector_end, set_regular, out_type_t) { \
6346
0
        out_type_t *tmp = (out_type_t *) *dst; \
6347
0
        uint8_t *fmt_p = fmt->p; \
6348
0
        for (i=0; i<nsmpl; i++) \
6349
0
        { \
6350
0
            for (j=0; j<fmt->n; j++) \
6351
0
            { \
6352
0
                type_t p = convert(fmt_p + j * sizeof(type_t)); \
6353
0
                if ( is_missing ) set_missing; \
6354
0
                else if ( is_vector_end ) { set_vector_end; break; } \
6355
0
                else set_regular; \
6356
0
                tmp++; \
6357
0
            } \
6358
0
            for (; j<fmt->n; j++) { set_vector_end; tmp++; } \
6359
0
            fmt_p += fmt->size; \
6360
0
        } \
6361
0
    }
6362
0
    switch (fmt->type) {
6363
0
        case BCF_BT_INT8:  BRANCH(int8_t,  le_to_i8, p==bcf_int8_missing,  p==bcf_int8_vector_end,  *tmp=bcf_int32_missing, *tmp=bcf_int32_vector_end, *tmp=p, int32_t); break;
6364
0
        case BCF_BT_INT16: BRANCH(int16_t, le_to_i16, p==bcf_int16_missing, p==bcf_int16_vector_end, *tmp=bcf_int32_missing, *tmp=bcf_int32_vector_end, *tmp=p, int32_t); break;
6365
0
        case BCF_BT_INT32: BRANCH(int32_t, le_to_i32, p==bcf_int32_missing, p==bcf_int32_vector_end, *tmp=bcf_int32_missing, *tmp=bcf_int32_vector_end, *tmp=p, int32_t); break;
6366
0
        case BCF_BT_FLOAT: BRANCH(uint32_t, le_to_u32, p==bcf_float_missing, p==bcf_float_vector_end, bcf_float_set_missing(*tmp), bcf_float_set_vector_end(*tmp), bcf_float_set(tmp, p), float); break;
6367
0
        default: hts_log_error("Unexpected type %d at %s:%"PRIhts_pos, fmt->type, bcf_seqname_safe(hdr,line), line->pos+1); exit(1);
6368
0
    }
6369
0
    #undef BRANCH
6370
6371
0
    return nsmpl*fmt->n;
6372
0
}
6373
6374
//error description structure definition
6375
typedef struct err_desc {
6376
    int  errorcode;
6377
    const char *description;
6378
}err_desc;
6379
6380
// error descriptions
6381
static const err_desc errdesc_bcf[] = {
6382
    { BCF_ERR_CTG_UNDEF, "Contig not defined in header"},
6383
    { BCF_ERR_TAG_UNDEF, "Tag not defined in header" },
6384
    { BCF_ERR_NCOLS, "Incorrect number of columns" },
6385
    { BCF_ERR_LIMITS, "Limits reached" },
6386
    { BCF_ERR_CHAR, "Invalid character" },
6387
    { BCF_ERR_CTG_INVALID, "Invalid contig" },
6388
    { BCF_ERR_TAG_INVALID, "Invalid tag" },
6389
};
6390
6391
/// append given description to buffer based on available size and add ... when not enough space
6392
    /** @param buffer       buffer to which description to be appended
6393
        @param offset       offset at which to be appended
6394
        @param maxbuffer    maximum size of the buffer
6395
        @param description  the description to be appended
6396
on failure returns -1 - when buffer is not big enough; returns -1 on invalid params and on too small buffer which are improbable due to validation at caller site
6397
on success returns 0
6398
    */
6399
3.41k
static int add_desc_to_buffer(char *buffer, size_t *offset, size_t maxbuffer, const char *description) {
6400
6401
3.41k
    if (!description || !buffer || !offset || (maxbuffer < 4))
6402
0
        return -1;
6403
6404
3.41k
    size_t rembuffer = maxbuffer - *offset;
6405
3.41k
    if (rembuffer > (strlen(description) + (rembuffer == maxbuffer ? 0 : 1))) {    //add description with optionally required ','
6406
3.41k
        *offset += snprintf(buffer + *offset, rembuffer, "%s%s", (rembuffer == maxbuffer)? "": ",", description);
6407
3.41k
    } else {    //not enough space for description, put ...
6408
0
        size_t tmppos = (rembuffer <= 4) ? maxbuffer - 4 : *offset;
6409
0
        snprintf(buffer + tmppos, 4, "...");    //ignore offset update
6410
0
        return -1;
6411
0
    }
6412
3.41k
    return 0;
6413
3.41k
}
6414
6415
//get description for given error code. return NULL on error
6416
1.62k
const char *bcf_strerror(int errorcode, char *buffer, size_t maxbuffer) {
6417
1.62k
    size_t usedup = 0;
6418
1.62k
    int ret = 0;
6419
1.62k
    int idx;
6420
6421
1.62k
    if (!buffer || maxbuffer < 4)
6422
0
        return NULL;           //invalid / insufficient buffer
6423
6424
1.62k
    if (!errorcode) {
6425
0
        buffer[0] = '\0';      //no error, set null
6426
0
        return buffer;
6427
0
    }
6428
6429
12.9k
    for (idx = 0; idx < sizeof(errdesc_bcf) / sizeof(err_desc); ++idx) {
6430
11.3k
        if (errorcode & errdesc_bcf[idx].errorcode) {    //error is set, add description
6431
3.41k
            ret = add_desc_to_buffer(buffer, &usedup, maxbuffer, errdesc_bcf[idx].description);
6432
3.41k
            if (ret < 0)
6433
0
                break;         //not enough space, ... added, no need to continue
6434
6435
3.41k
            errorcode &= ~errdesc_bcf[idx].errorcode;    //reset the error
6436
3.41k
        }
6437
11.3k
    }
6438
6439
1.62k
    if (errorcode && (ret >= 0))  {     //undescribed error is present in error code and had enough buffer, try to add unknown error as well
6440
0
        add_desc_to_buffer(buffer, &usedup, maxbuffer, "Unknown error");
6441
0
    }
6442
1.62k
    return buffer;
6443
1.62k
}
6444
6445
/**
6446
 *  bcf_format_gt_v2 - formats GT information on a string
6447
 *  @param hdr - bcf header, to get version
6448
 *  @param fmt - pointer to bcf format data
6449
 *  @param isample - position of interested sample in data
6450
 *  @param str - pointer to output string
6451
 *  Returns 0 on success and -1 on failure
6452
 *  This method is preferred over bcf_format_gt as this supports vcf4.4 and
6453
 *  prefixed phasing. Explicit / prefixed phasing for 1st allele is used only
6454
 *  when it is a must to correctly express phasing.
6455
 * correctly express phasing.
6456
 */
6457
int bcf_format_gt_v2(const bcf_hdr_t *hdr, bcf_fmt_t *fmt, int isample, kstring_t *str)
6458
37.4k
{
6459
37.4k
    uint32_t e = 0;
6460
37.4k
    int ploidy = 1, anyunphased = 0;
6461
37.4k
    int32_t val0 = 0;
6462
37.4k
    size_t pos = str ? str->l : 0;
6463
6464
37.4k
    #define BRANCH(type_t, convert, missing, vector_end) { \
6465
29.2k
        uint8_t *ptr = fmt->p + isample*fmt->size; \
6466
29.2k
        int i; \
6467
75.0k
        for (i=0; i<fmt->n; i++, ptr += sizeof(type_t)) \
6468
67.2k
        { \
6469
67.2k
            type_t val = convert(ptr); \
6470
67.2k
            if ( val == vector_end ) break; \
6471
67.2k
            if (!i) { val0 = val; } \
6472
45.8k
            if (i) { \
6473
16.5k
                e |= kputc("/|"[val & 1], str) < 0; \
6474
16.5k
                anyunphased |= !(val & 1); \
6475
16.5k
            } \
6476
45.8k
            if (!(val >> 1)) e |= kputc('.', str) < 0; \
6477
45.8k
            else e |= kputw((val >> 1) - 1, str) < 0; \
6478
45.8k
        } \
6479
29.2k
        if (i == 0) e |= kputc('.', str) < 0; \
6480
29.2k
        ploidy = i; \
6481
29.2k
    }
6482
37.4k
    switch (fmt->type) {
6483
15.7k
        case BCF_BT_INT8:  BRANCH(int8_t,  le_to_i8,  bcf_int8_missing,
6484
15.7k
            bcf_int8_vector_end); break;
6485
8.47k
        case BCF_BT_INT16: BRANCH(int16_t, le_to_i16, bcf_int16_missing,
6486
8.47k
            bcf_int16_vector_end); break;
6487
5.10k
        case BCF_BT_INT32: BRANCH(int32_t, le_to_i32, bcf_int32_missing,
6488
5.10k
            bcf_int32_vector_end); break;
6489
8.17k
        case BCF_BT_NULL:  e |= kputc('.', str) < 0; break;
6490
0
        default: hts_log_error("Unexpected type %d", fmt->type); return -2;
6491
37.4k
    }
6492
37.4k
    #undef BRANCH
6493
6494
37.4k
    if (hdr && get_hdr_aux(hdr)->version >= VCF44) {
6495
        //output which supports prefixed phasing
6496
6497
        /* update 1st allele's phasing if required and append rest to it.
6498
        use prefixed phasing only when it is a must. i.e. without which the
6499
        inferred value will be incorrect */
6500
191
        if (val0 & 1) {
6501
            /* 1st one is phased, if ploidy is > 1 and an unphased allele exists
6502
             need to specify explicitly */
6503
174
            e |= (ploidy > 1 && anyunphased) ?
6504
166
                    (kinsert_char('|', pos, str) < 0) :
6505
174
                        (ploidy <= 1 && !((val0 >> 1)) ? //|. needs explicit o/p
6506
0
                            (kinsert_char('|', pos, str) < 0) :
6507
8
                            0);
6508
174
        } else {
6509
            /* 1st allele is unphased, if ploidy is = 1 or allele is '.' or
6510
             ploidy > 1 and no other unphased allele exist, need to specify
6511
             explicitly */
6512
17
            e |= ((ploidy <= 1 && val0 != 0) || (ploidy > 1 && !anyunphased)) ?
6513
16
                    (kinsert_char('/', pos, str) < 0) :
6514
17
                    0;
6515
17
        }
6516
191
    }
6517
37.4k
    return e == 0 ? 0 : -1;
6518
37.4k
}
6519
6520
/**
6521
 *  get_rlen - calculates and returns rlen value
6522
 *  @param h - bcf header
6523
 *  @param v - bcf data
6524
 *  Returns rlen calculated on success and -1 on failure.
6525
 *  rlen calculation is dependent on vcf version and a few other field data.
6526
 *  When bcf decoded data is available, refers it. When not available, retrieves
6527
 *  required field data by seeking on the data stream.
6528
 *  Ideally pos & version be set appropriately before any info/format field
6529
 *  update to have proper rlen calculation.
6530
 *  As version is not kept properly updated in practice, it is ignored in calcs.
6531
 */
6532
static int64_t get_rlen(const bcf_hdr_t *h, bcf1_t *v)
6533
59.1k
{
6534
59.1k
    uint8_t *f = (uint8_t*)v->shared.s, *t = NULL,
6535
59.1k
        *e = (uint8_t*)v->shared.s + v->shared.l;
6536
59.1k
    int size, type, id, lenid, endid, svlenid, i, bad, gvcf = 0, use_svlen = 0;
6537
59.1k
    bcf_info_t *endinfo = NULL, *svleninfo = NULL, end_lcl, svlen_lcl;
6538
59.1k
    bcf_fmt_t *lenfmt = NULL, len_lcl;
6539
6540
    //holds SVLEN allele status for the max no of alleles
6541
59.1k
    uint8_t svlenals[8192];
6542
    //pos from info END, fmt LEN, info SVLEN
6543
59.1k
    hts_pos_t end = 0, end_fmtlen = 0, end_svlen = 0, hpos;
6544
59.1k
    int64_t len_ref = 0, len = 0, tmp;
6545
59.1k
    endid = bcf_hdr_id2int(h, BCF_DT_ID, "END");
6546
6547
    //initialise bytes which are to be used
6548
59.1k
    memset(svlenals, 0, 1 + v->n_allele / 8);
6549
6550
    //use decoded data where ever available and where not, get from stream
6551
59.1k
    if (v->unpacked & BCF_UN_STR || v->d.shared_dirty & BCF1_DIRTY_ALS) {
6552
0
        for (i = 1; i < v->n_allele; ++i) {
6553
            // check only symbolic alt alleles
6554
0
            if (v->d.allele[i][0] != '<')
6555
0
                continue;
6556
0
            if (svlen_on_ref_for_vcf_alt(v->d.allele[i], -1)) {
6557
                // del, dup or cnv allele, note to check corresponding svlen val
6558
0
                svlenals[i >> 3] |= 1 << (i & 7);
6559
0
                use_svlen = 1;
6560
0
            } else if (!strcmp(v->d.allele[i], "<*>") ||
6561
0
                         !strcmp(v->d.allele[i], "<NON_REF>")) {
6562
0
                gvcf = 1;   //gvcf present, have to check for LEN field
6563
0
            }
6564
0
        }
6565
0
        f += v->unpack_size[0] + v->unpack_size[1];
6566
0
        len_ref = v->n_allele ? strlen(v->d.allele[0]) : 0;
6567
59.1k
    } else if (f < e) {
6568
        //skip ID
6569
59.1k
        size = bcf_dec_size(f, &f, &type);
6570
59.1k
        f += size << bcf_type_shift[type];
6571
        // REF, ALT
6572
2.60M
        for (i = 0; i < v->n_allele; ++i) {
6573
            //check all alleles, w/o NUL
6574
2.54M
            size = bcf_dec_size(f, &f, &type);
6575
2.54M
            if (!i) {   //REF length
6576
59.1k
                len_ref = size;
6577
2.48M
            } else if (size > 0 && *f == '<') {
6578
34.3k
                if (svlen_on_ref_for_vcf_alt((char *) f, size)) {
6579
                    // del, dup or cnv allele, note to check corresponding svlen val
6580
396
                    svlenals[i >> 3] |= 1 << (i & 7);
6581
396
                    use_svlen = 1;
6582
33.9k
                } else if ((size == 3 && !strncmp((char*)f, "<*>", size)) ||
6583
22.9k
                    (size == 9 && !strncmp((char*)f, "<NON_REF>", size))) {
6584
11.8k
                    gvcf = 1;   //gvcf present, have to check for LEN field
6585
11.8k
                }
6586
34.3k
            }
6587
2.54M
            f += size << bcf_type_shift[type];
6588
2.54M
        }
6589
59.1k
    }
6590
    // FILTER
6591
59.1k
    if (v->unpacked & BCF_UN_FLT) {
6592
0
        f += v->unpack_size[2];
6593
59.1k
    } else if (f < e) {
6594
59.1k
        size = bcf_dec_size(f, &f, &type);
6595
59.1k
        f += size << bcf_type_shift[type];
6596
59.1k
    }
6597
6598
    // Only do SVLEN lookup if there are suitable symbolic alleles
6599
59.1k
    svlenid = use_svlen ? bcf_hdr_id2int(h, BCF_DT_ID, "SVLEN") : -1;
6600
6601
    // INFO
6602
59.1k
    if (svlenid >= 0 || endid >= 0 ) {  //only if end/svlen present
6603
34.2k
        if (v->unpacked & BCF_UN_INFO || v->d.shared_dirty & BCF1_DIRTY_INF) {
6604
0
            endinfo = bcf_get_info(h, v, "END");
6605
0
            svleninfo = bcf_get_info(h, v, "SVLEN");
6606
34.2k
        } else if (f < e) {
6607
29.0k
            for (i = 0; i < v->n_info; ++i) {
6608
15.6k
                id = bcf_dec_typed_int1(f, &t);
6609
15.6k
                if (id == endid) {  //END
6610
705
                    t = bcf_unpack_info_core1(f, &end_lcl);
6611
705
                    endinfo = &end_lcl;
6612
705
                    if (svleninfo || svlenid < 0) {
6613
705
                        break;  //already got svlen or no need to search further
6614
705
                    }
6615
14.9k
                } else if (id == svlenid) { //SVLEN
6616
0
                    t = bcf_unpack_info_core1(f, &svlen_lcl);
6617
0
                    svleninfo = &svlen_lcl;
6618
0
                    if (endinfo || endid < 0 ) {
6619
0
                        break;  //already got end or no need to search further
6620
0
                    }
6621
14.9k
                } else {
6622
14.9k
                    f = t;
6623
14.9k
                    size = bcf_dec_size(f, &t, &type);
6624
14.9k
                    t += size << bcf_type_shift[type];
6625
14.9k
                }
6626
14.9k
                f = t;
6627
14.9k
            }
6628
14.0k
        }
6629
34.2k
    }
6630
6631
    // Only do LEN lookup if a <*> allele was found
6632
59.1k
    lenid = gvcf ? bcf_hdr_id2int(h, BCF_DT_ID, "LEN") : -1;
6633
6634
    // FORMAT
6635
59.1k
    if (lenid >= 0) {
6636
        //with LEN and has gvcf allele
6637
0
        f = (uint8_t*)v->indiv.s; t = NULL; e = (uint8_t*)v->indiv.s + v->indiv.l;
6638
0
        if (v->unpacked & BCF_UN_FMT || v->d.indiv_dirty) {
6639
0
            lenfmt = bcf_get_fmt(h, v, "LEN");
6640
0
        } else if (f < e) {
6641
0
            for (i = 0; i < v->n_fmt; ++i) {
6642
0
                id = bcf_dec_typed_int1(f, &t);
6643
0
                if (id == lenid) {
6644
0
                        t = bcf_unpack_fmt_core1(f, v->n_sample, &len_lcl);
6645
0
                    lenfmt = &len_lcl;
6646
0
                    break;  //that's all needed
6647
0
                } else {
6648
0
                    f = t;
6649
0
                    size = bcf_dec_size(f, &t, &type);
6650
0
                    t += size * v->n_sample << bcf_type_shift[type];
6651
0
                }
6652
0
                f = t;
6653
0
            }
6654
0
        }
6655
0
    }
6656
    //got required data, find end and rlen
6657
59.1k
    if (endinfo && endinfo->vptr) { //end position given by info END
6658
        //end info exists, not being deleted
6659
705
        end = endinfo->v1.i;
6660
705
        switch(endinfo->type) {
6661
0
            case BCF_BT_INT8:  end = end == bcf_int8_missing ? 0 : end;  break;
6662
0
            case BCF_BT_INT16: end = end == bcf_int16_missing ? 0 : end; break;
6663
0
            case BCF_BT_INT32: end = end == bcf_int32_missing ? 0 : end; break;
6664
0
            case BCF_BT_INT64: end = end == bcf_int64_missing ? 0 : end; break;
6665
705
            default: end = 0; break; //invalid
6666
705
        }
6667
705
    }
6668
6669
59.1k
    if (svleninfo && svleninfo->vptr) {
6670
        //svlen info exists, not being deleted
6671
0
        bad = 0;
6672
        //get largest svlen corresponding to a <DEL> symbolic allele
6673
0
        for (i = 0; i < svleninfo->len && i + 1 < v->n_allele; ++i) {
6674
0
            if (!(svlenals[i >> 3] & (1 << ((i + 1) & 7))))
6675
0
                continue;
6676
6677
0
            switch(svleninfo->type) {
6678
0
                case BCF_BT_INT8:
6679
0
                    tmp = le_to_i8(&svleninfo->vptr[i]);
6680
0
                    tmp = tmp == bcf_int8_missing ? 0 : tmp;
6681
0
                break;
6682
0
                case BCF_BT_INT16:
6683
0
                    tmp = le_to_i16(&svleninfo->vptr[i * 2]);
6684
0
                    tmp = tmp == bcf_int16_missing ? 0 : tmp;
6685
0
                break;
6686
0
                case BCF_BT_INT32:
6687
0
                    tmp = le_to_i32(&svleninfo->vptr[i * 4]);
6688
0
                    tmp = tmp == bcf_int32_missing ? 0 : tmp;
6689
0
                break;
6690
0
                case BCF_BT_INT64:
6691
0
                    tmp = le_to_i64(&svleninfo->vptr[i * 8]);
6692
0
                    tmp = tmp == bcf_int64_missing ? 0 : tmp;
6693
0
                break;
6694
0
                default: //invalid
6695
0
                    tmp = 0;
6696
0
                    bad = 1;
6697
0
                break;
6698
0
            }
6699
0
            if (bad) {  //stop svlen check
6700
0
                len = 0;
6701
0
                break;
6702
0
            }
6703
6704
0
            tmp = tmp < 0 ? llabs(tmp) : tmp;
6705
0
            if (len < tmp) len = tmp;
6706
0
        }
6707
0
    }
6708
59.1k
    if ((!svleninfo || !len) && end) { //no svlen, infer from end
6709
0
        len = end > v->pos ? end - v->pos - 1 : 0;
6710
0
    }
6711
59.1k
    end_svlen = v->pos + len + 1;   //end position found from SVLEN
6712
6713
59.1k
    len = 0;
6714
59.1k
    if (lenfmt && lenfmt->p) {
6715
        //fmt len exists, not being deleted, has gvcf and version >= 4.5
6716
0
        int j = 0;
6717
0
        int64_t offset = 0;
6718
0
        bad = 0;
6719
0
        for (i = 0; i < v->n_sample; ++i) {
6720
0
            for (j = 0; j < lenfmt->n; ++j) {
6721
0
                switch(lenfmt->type) {
6722
0
                case BCF_BT_INT8:
6723
0
                    tmp = le_to_i8(lenfmt->p + offset + j);
6724
0
                    tmp = tmp == bcf_int8_missing ? 0 : tmp;
6725
0
                break;
6726
0
                case BCF_BT_INT16:
6727
0
                    tmp = le_to_i16(lenfmt->p + offset + j * 2);
6728
0
                    tmp = tmp == bcf_int16_missing ? 0 : tmp;
6729
0
                break;
6730
0
                case BCF_BT_INT32:
6731
0
                    tmp = le_to_i32(lenfmt->p + offset + j * 4);
6732
0
                    tmp = tmp == bcf_int32_missing ? 0 : tmp;
6733
0
                break;
6734
0
                case BCF_BT_INT64:
6735
0
                    tmp = le_to_i64(lenfmt->p + offset + j * 8);
6736
0
                    tmp = tmp == bcf_int64_missing ? 0 : tmp;
6737
0
                break;
6738
0
                default: //invalid
6739
0
                    bad = 1;
6740
0
                break;
6741
0
                }
6742
0
                if (bad) {  //stop LEN check
6743
0
                    len = 0;
6744
0
                    break;
6745
0
                }
6746
                //assumes only gvcf have valid LEN
6747
0
                if (len < tmp) len = tmp;
6748
0
            }
6749
0
            offset += j << bcf_type_shift[lenfmt->type];
6750
0
        }
6751
0
    }
6752
59.1k
    if ((!lenfmt || !len) && end) { //no fmt len, infer from end
6753
0
        len = end > v->pos ? end - v->pos : 0;
6754
0
    }
6755
59.1k
    end_fmtlen = v->pos + len;  //end position found from LEN
6756
6757
    //get largest pos, based on END, SVLEN, fmt LEN and length using it
6758
59.1k
    hpos = end < end_svlen ?
6759
22.1k
            end_svlen < end_fmtlen ? end_fmtlen : end_svlen :
6760
59.1k
            end < end_fmtlen ? end_fmtlen : end;
6761
59.1k
    len = hpos - v->pos;
6762
6763
    //NOTE: 'end' calculation be in sync with tbx.c:tbx_parse1
6764
6765
    /* rlen to be calculated based on version, END, SVLEN, fmt LEN, ref len.
6766
    Relevance of these fields vary across different vcf versions.
6767
    Many times, these info/fmt fields are used without version updates;
6768
    hence these fields are used for calculation disregarding vcf version */
6769
59.1k
    return len < len_ref ? len_ref : len;
6770
59.1k
}