forked from samtools/bcftools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvcmp.c
90 lines (78 loc) · 2.15 KB
/
vcmp.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <htslib/hts.h>
#include "vcmp.h"
struct _vcmp_t
{
char *dref;
int ndref, mdref; // ndref: positive when ref1 longer, negative when ref2 is longer
int nmatch;
};
vcmp_t *vcmp_init()
{
return (vcmp_t*)calloc(1,sizeof(vcmp_t));
}
void vcmp_destroy(vcmp_t *vcmp)
{
free(vcmp->dref);
free(vcmp);
}
int vcmp_set_ref(vcmp_t *vcmp, char *ref1, char *ref2)
{
vcmp->ndref = 0;
char *a = ref1, *b = ref2;
while ( *a && *b && *a==*b ) { a++; b++; }
if ( !*a && !*b ) return 0;
if ( *a && *b ) return -1; // refs not compatible
if ( *a ) // ref1 is longer
{
vcmp->nmatch = b-ref2;
while ( *a ) a++;
vcmp->ndref = (a-ref1) - vcmp->nmatch;
hts_expand(char,vcmp->ndref+1,vcmp->mdref,vcmp->dref);
memcpy(vcmp->dref,ref1+vcmp->nmatch,vcmp->ndref);
vcmp->dref[vcmp->ndref] = 0;
return 0;
}
// ref2 is longer
vcmp->nmatch = a-ref1;
while ( *b ) b++;
vcmp->ndref = (b-ref2) - vcmp->nmatch;
hts_expand(char,vcmp->ndref+1,vcmp->mdref,vcmp->dref);
memcpy(vcmp->dref,ref2+vcmp->nmatch,vcmp->ndref);
vcmp->dref[vcmp->ndref] = 0;
vcmp->ndref *= -1;
return 0;
}
int vcmp_find_allele(vcmp_t *vcmp, char **als1, int nals1, char *al2)
{
int i, j;
for (i=0; i<nals1; i++)
{
char *a = als1[i], *b = al2;
while ( *a && *b && *a==*b ) { a++; b++; }
if ( *a && *b ) continue; // mismatch
if ( !vcmp->ndref )
{
if ( !*a && !*b ) break; // found
continue;
}
// the prefixes match
if ( *a )
{
if ( vcmp->ndref<0 ) continue;
for (j=0; j<vcmp->ndref; j++)
if ( !a[j] || a[j]!=vcmp->dref[j] ) break;
if ( j!=vcmp->ndref || a[j] ) continue;
break; // found
}
if ( vcmp->ndref>0 ) continue;
for (j=0; j<-vcmp->ndref; j++)
if ( !b[j] || b[j]!=vcmp->dref[j] ) break;
if ( j!=-vcmp->ndref || b[j] ) continue;
break; // found
}
if (i==nals1) return -1;
return i;
}