// File: /workspace/github_c_makefile_star2_O1/aokad[P]sequeeze/seqtk.c
// Function: stk_mergefa
int stk_mergefa(int argc, char *argv[])
{
	gzFile fp[2];
	kseq_t *seq[2];
	int i, l, c, is_intersect = 0, is_haploid = 0, qual = 0, is_mask = 0, is_randhet = 0;
	uint64_t cnt[5];
	while ((c = getopt(argc, argv, "himrq:")) >= 0) {
		switch (c) {
			case 'i': is_intersect = 1; break;
			case 'h': is_haploid = 1; break;
			case 'm': is_mask = 1; break;
			case 'r': is_randhet = 1; break;
			case 'q': qual = atoi(optarg); break;
		}
	}
	if (is_mask && is_intersect) {
		fprintf(stderr, "[%s] `-i' and `-h' cannot be applied at the same time.\n", __func__);
		return 1;
	}
	if (optind + 2 > argc) {
		fprintf(stderr, "\nUsage: seqtk mergefa [options] <in1.fa> <in2.fa>\n\n");
		fprintf(stderr, "Options: -q INT   quality threshold [0]\n");
		fprintf(stderr, "         -i       take intersection\n");
		fprintf(stderr, "         -m       convert to lowercase when one of the input base is N\n");
		fprintf(stderr, "         -r       pick a random allele from het\n");
		fprintf(stderr, "         -h       suppress hets in the input\n\n");
		return 1;
	}
	for (i = 0; i < 2; ++i) {
		fp[i] = strcmp(argv[optind+i], "-")? gzopen(argv[optind+i], "r") : gzdopen(fileno(stdin), "r");
		seq[i] = kseq_init(fp[i]);
	}
	if (fp[0] == 0 || fp[1] == 0) {
		fprintf(stderr, "[E::%s] failed to open the input file/stream.\n", __func__);
		return 1;
	}
	cnt[0] = cnt[1] = cnt[2] = cnt[3] = cnt[4] = 0;
	srand48(11);
	while (kseq_read(seq[0]) >= 0) {
		int min_l, c[2], b[2], is_upper;
		kseq_read(seq[1]);
		if (strcmp(seq[0]->name.s, seq[1]->name.s))
			fprintf(stderr, "[%s] Different sequence names: %s != %s\n", __func__, seq[0]->name.s, seq[1]->name.s);
		if (seq[0]->seq.l != seq[1]->seq.l)
			fprintf(stderr, "[%s] Unequal sequence length: %ld != %ld\n", __func__, seq[0]->seq.l, seq[1]->seq.l);
		min_l = seq[0]->seq.l < seq[1]->seq.l? seq[0]->seq.l : seq[1]->seq.l;
		printf(">%s", seq[0]->name.s);
		for (l = 0; l < min_l; ++l) {
			c[0] = seq[0]->seq.s[l]; c[1] = seq[1]->seq.s[l];
			if (seq[0]->qual.l && seq[0]->qual.s[l] - 33 < qual) c[0] = tolower(c[0]);
			if (seq[1]->qual.l && seq[1]->qual.s[l] - 33 < qual) c[1] = tolower(c[1]);
			if (is_intersect) is_upper = (isupper(c[0]) || isupper(c[1]))? 1 : 0;
			else if (is_mask) is_upper = (isupper(c[0]) || isupper(c[1]))? 1 : 0;
			else is_upper = (isupper(c[0]) && isupper(c[1]))? 1 : 0;
			c[0] = seq_nt16_table[c[0]]; c[1] = seq_nt16_table[c[1]];
			if (c[0] == 0) c[0] = 15;
			if (c[1] == 0) c[1] = 15;
			b[0] = bitcnt_table[c[0]];
			b[1] = bitcnt_table[c[1]];
			if (is_upper) {
				if (b[0] == 1 && b[1] == 1) {
					if (c[0] == c[1]) ++cnt[0];
					else ++cnt[1];
				} else if (b[0] == 1 && b[1] == 2) ++cnt[2];
				else if (b[0] == 2 && b[1] == 1) ++cnt[3];
				else if (b[0] == 2 && b[1] == 2) ++cnt[4];
			}
			if (is_haploid && (b[0] > 1 || b[1] > 1)) is_upper = 0;
			if (is_intersect) {
				c[0] = c[0] & c[1];
				if (c[0] == 0) is_upper = 0; // FIXME: is this a bug - c[0] cannot be 0!
			} else if (is_mask) {
				if (c[0] == 15 || c[1] == 15) is_upper = 0;
				c[0] &= c[1];
				if (c[0] == 0) is_upper = 0;
			} else if (is_randhet) {
				if (b[0] == 1 && b[1] == 1) { // two homs
					c[0] |= c[1];
				} else if (((b[0] == 1 && b[1] == 2) || (b[0] == 2 && b[1] == 1)) && (c[0]&c[1])) { // one hom, one het
					c[0] = (lrand48()&1)? (c[0] & c[1]) : (c[0] | c[1]);
				} else if (b[0] == 2 && b[1] == 2 && c[0] == c[1]) { // double hets
					if (lrand48()&1) {
						if (lrand48()&1) {
							for (i = 8; i >= 1; i >>= 1) // pick the "larger" allele
								if (c[0]&i) c[0] &= i;
						} else {
							for (i = 1; i <= 8; i <<= 1) // pick the "smaller" allele
								if (c[0]&i) c[0] &= i;
						}
					} // else set as het
				} else is_upper = 0;
			} else c[0] |= c[1];
			c[0] = seq_nt16_rev_table[c[0]];
			if (!is_upper) c[0] = tolower(c[0]);
			if (l%60 == 0) putchar('\n');
			putchar(c[0]);
		}
		putchar('\n');
	}
	fprintf(stderr, "[%s] (same,diff,hom-het,het-hom,het-het)=(%ld,%ld,%ld,%ld,%ld)\n", __func__, (long)cnt[0], (long)cnt[1], (long)cnt[2], (long)cnt[3], (long)cnt[4]);
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rsi, %r14
movl %edi, %ebp
leaq 0x65d4(%rip), %rdx      # 0xb6ef
callq 0x2240
testl %eax, %eax
js 0x51cc
movl $0x0, 0x10(%rsp)
leaq 0x65b8(%rip), %r15      # 0xb6ef
leaq 0x5f82(%rip), %r12      # 0xb0c0
movl $0x0, 0x18(%rsp)
movl $0x0, 0x14(%rsp)
xorl %r13d, %r13d
xorl %ebx, %ebx
addl $-0x68, %eax
cmpl $0xa, %eax
ja 0x519a
movslq (%r12,%rax,4), %rax
addq %r12, %rax
jmpq *%rax
movl $0x1, 0x18(%rsp)
jmp 0x519a
movl $0x1, %r13d
jmp 0x519a
movl $0x1, 0x10(%rsp)
jmp 0x519a
movq 0xae51(%rip), %rax      # 0xffd8
movq (%rax), %rdi
callq 0x2250
movl %eax, 0x14(%rsp)
jmp 0x519a
movl $0x1, %ebx
movl %ebp, %edi
movq %r14, %rsi
movq %r15, %rdx
callq 0x2240
testl %eax, %eax
jns 0x5153
testl %r13d, %r13d
setne %cl
cmpl $0x0, 0x10(%rsp)
setne %dl
cmpl $0x0, 0x18(%rsp)
sete 0xf(%rsp)
testl %ebx, %ebx
sete 0xe(%rsp)
jmp 0x51e2
xorl %ecx, %ecx
movb $0x1, 0xe(%rsp)
movl $0x0, 0x14(%rsp)
movb $0x1, 0xf(%rsp)
xorl %edx, %edx
movl %ecx, %eax
andb %dl, %al
cmpb $0x1, %al
jne 0x51f4
callq 0x2659
jmp 0x5677
movq 0xadd5(%rip), %rbx      # 0xffd0
movl (%rbx), %eax
addl $0x2, %eax
cmpl %ebp, %eax
jle 0x520e
callq 0x25c6
jmp 0x5677
movl %edx, 0x10(%rsp)
movl %ecx, 0x24(%rsp)
xorl %ebp, %ebp
leaq 0x718f(%rip), %r15      # 0xc3ae
leaq 0x5f72(%rip), %r12      # 0xb198
movslq (%rbx), %rax
addq %rbp, %rax
movq (%r14,%rax,8), %r13
movq %r13, %rdi
movq %r15, %rsi
callq 0x2170
testl %eax, %eax
je 0x524c
movq %r13, %rdi
movq %r12, %rsi
callq 0x2220
jmp 0x5265
movq 0xad75(%rip), %rax      # 0xffc8
movq (%rax), %rdi
callq 0x21b0
movl %eax, %edi
movq %r12, %rsi
callq 0x20b0
movq %rax, 0x70(%rsp,%rbp,8)
movq %rax, %rdi
callq 0x3e57
movq %rax, 0x60(%rsp,%rbp,8)
incq %rbp
cmpq $0x1, %rbp
je 0x5226
cmpq $0x0, 0x70(%rsp)
je 0x5672
cmpq $0x0, 0x78(%rsp)
je 0x5672
movl $0xb, %edi
callq 0x2210
movq 0x60(%rsp), %r15
movq %r15, %rdi
callq 0x3ea1
testl %eax, %eax
js 0x568e
movq 0x68(%rsp), %r14
movq $0x0, 0x28(%rsp)
movq $0x0, 0x38(%rsp)
movq $0x0, 0x40(%rsp)
movq $0x0, 0x48(%rsp)
movq $0x0, 0x30(%rsp)
movq %r14, %rdi
callq 0x3ea1
movq 0x10(%r15), %rbp
movq 0x10(%r14), %r13
movq %rbp, %rdi
movq %r13, %rsi
callq 0x2170
testl %eax, %eax
jne 0x5624
movq 0x30(%r15), %rcx
movq 0x30(%r14), %r8
cmpq %r8, %rcx
jne 0x564e
movq 0x10(%r15), %rsi
movq 0x30(%r15), %rax
movq 0x30(%r14), %rbx
cmpq %rbx, %rax
cmovbq %rax, %rbx
leaq 0x615d(%rip), %rdi      # 0xb494
xorl %eax, %eax
callq 0x20f0
testl %ebx, %ebx
jle 0x5605
andl $0x7fffffff, %ebx       # imm = 0x7FFFFFFF
movq %rbx, 0x18(%rsp)
callq 0x2290
movq %rax, 0x58(%rsp)
xorl %r12d, %r12d
movq 0x40(%r15), %rax
movsbl (%rax,%r12), %ebp
movq 0x40(%r14), %rax
movsbl (%rax,%r12), %r13d
cmpq $0x0, 0x48(%r15)
je 0x5392
movq 0x58(%r15), %rax
movsbl (%rax,%r12), %eax
addl $-0x21, %eax
cmpl 0x14(%rsp), %eax
jge 0x5392
movl %ebp, %edi
callq 0x21c0
movl %eax, %ebp
movl 0x10(%rsp), %r9d
cmpq $0x0, 0x48(%r14)
je 0x53c0
movq 0x58(%r14), %rax
movsbl (%rax,%r12), %eax
addl $-0x21, %eax
cmpl 0x14(%rsp), %eax
jge 0x53c0
movl %r13d, %edi
callq 0x21c0
movl 0x10(%rsp), %r9d
movl %eax, %r13d
movq 0x58(%rsp), %rax
movq (%rax), %rsi
movslq %ebp, %rax
movzwl (%rsi,%rax,2), %edi
movslq %r13d, %rcx
testb %r9b, %r9b
jne 0x53de
cmpb $0x0, 0x24(%rsp)
je 0x53ea
movw $0x1, %dx
btl $0x8, %edi
jb 0x53fc
jmp 0x53f4
btl $0x8, %edi
jb 0x53f4
xorl %edx, %edx
jmp 0x53fc
movzbl 0x1(%rsi,%rcx,2), %edx
andl $0x1, %edx
leaq 0xad6d(%rip), %rsi      # 0x10170
movzbl (%rax,%rsi), %r13d
movzbl (%rcx,%rsi), %ebp
testb %r13b, %r13b
movl $0xf, %eax
cmovel %eax, %r13d
movl $0xff, %ecx
andl %ecx, %r13d
testb %bpl, %bpl
cmovel %eax, %ebp
andl %ecx, %ebp
leaq 0xaf71(%rip), %rax      # 0x103a0
movl (%rax,%r13,4), %ecx
movl (%rax,%rbp,4), %eax
testw %dx, %dx
je 0x5456
cmpl $0x1, %ecx
movl $0x0, %esi
jne 0x545a
cmpl $0x1, %eax
jne 0x545a
cmpb %bpl, %r13b
jne 0x547c
incq 0x38(%rsp)
jmp 0x54a0
xorl %esi, %esi
jmp 0x54a0
cmpl $0x1, %ecx
jne 0x546b
cmpl $0x2, %eax
jne 0x546b
incq 0x48(%rsp)
jmp 0x54a0
cmpl $0x2, %ecx
jne 0x5483
cmpl $0x1, %eax
jne 0x5483
incq 0x30(%rsp)
jmp 0x54a0
incq 0x40(%rsp)
jmp 0x54a0
movl %ecx, %esi
xorl $0x2, %esi
movl %eax, %edi
xorl $0x2, %edi
xorl %r8d, %r8d
orl %esi, %edi
movl $0x0, %esi
sete %r8b
addq %r8, 0x28(%rsp)
movzwl %dx, %edx
cmpl $0x2, %eax
movl %edx, %ebx
cmovgel %esi, %ebx
cmpl $0x2, %ecx
cmovgel %esi, %ebx
cmpb $0x0, 0xf(%rsp)
cmovnel %edx, %ebx
testb %r9b, %r9b
je 0x54c6
andl %r13d, %ebp
cmovel %esi, %ebx
jmp 0x54fb
cmpb $0x0, 0x24(%rsp)
je 0x54e7
movl %ebp, %eax
andl %r13d, %eax
cmovel %esi, %ebx
cmpl $0xf, %ebp
cmovel %esi, %ebx
cmpl $0xf, %r13d
cmovel %esi, %ebx
movl %eax, %r13d
jmp 0x54fe
cmpb $0x0, 0xe(%rsp)
jne 0x54f8
cmpl $0x1, %ecx
jne 0x5551
cmpl $0x1, %eax
jne 0x5551
orl %r13d, %ebp
movl %ebp, %r13d
movq 0xae6b(%rip), %rax      # 0x10370
movl %r13d, %ecx
movsbl (%rax,%rcx), %ebp
testl %ebx, %ebx
jne 0x5519
movl %ebp, %edi
callq 0x21c0
movl %eax, %ebp
movq 0x18(%rsp), %rbx
imull $0xeeeeeeef, %r12d, %eax # imm = 0xEEEEEEEF
rorl $0x2, %eax
cmpl $0x4444444, %eax        # imm = 0x4444444
ja 0x5539
movl $0xa, %edi
callq 0x2060
movl %ebp, %edi
callq 0x2060
incq %r12
cmpq %rbx, %r12
jne 0x535e
jmp 0x5605
movl %eax, %edx
xorl $0x1, %edx
movl %ecx, %esi
xorl $0x1, %esi
movl %eax, %edi
xorl $0x2, %edi
movl %ecx, %r8d
xorl $0x2, %r8d
orl %edx, %r8d
sete %dl
orl %esi, %edi
je 0x5575
testb %dl, %dl
je 0x5596
movl %ebp, %edx
andl %r13d, %edx
je 0x5596
movl %edx, 0x54(%rsp)
callq 0x21f0
orl %r13d, %ebp
testb $0x1, %al
movl 0x54(%rsp), %eax
cmovel %ebp, %eax
jmp 0x54e2
cmpb %bpl, %r13b
jne 0x55d9
cmpl $0x2, %ecx
jne 0x55d9
cmpl $0x2, %eax
jne 0x55d9
callq 0x21f0
testb $0x1, %al
je 0x54fe
callq 0x21f0
testb $0x1, %al
jne 0x55e0
movl $0x1, %eax
movl %r13d, %ecx
movl %eax, %r13d
andl %ecx, %r13d
cmovel %ecx, %r13d
addl %eax, %eax
cmpl $0x9, %eax
jl 0x55c0
jmp 0x54fe
xorl %ebx, %ebx
jmp 0x54fe
movl $0x8, %eax
movl $0x8, %ecx
movl %r13d, %edx
movl %eax, %r13d
andl %edx, %r13d
cmovel %edx, %r13d
shrl %ecx
cmpl $0x2, %eax
movl %ecx, %eax
jae 0x55ea
jmp 0x54fe
movl $0xa, %edi
callq 0x2060
movq %r15, %rdi
callq 0x3ea1
testl %eax, %eax
jns 0x52e9
jmp 0x56bb
movq 0xa9cd(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x622f(%rip), %rsi      # 0xb864
leaq 0x60f2(%rip), %rdx      # 0xb72e
movq %rbp, %rcx
movq %r13, %r8
xorl %eax, %eax
callq 0x2190
jmp 0x530c
movq 0xa9a3(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x622e(%rip), %rsi      # 0xb88d
leaq 0x60c8(%rip), %rdx      # 0xb72e
xorl %eax, %eax
callq 0x2190
jmp 0x531d
callq 0x25a7
movl $0x1, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq $0x0, 0x30(%rsp)
movq $0x0, 0x48(%rsp)
movq $0x0, 0x40(%rsp)
movq $0x0, 0x38(%rsp)
movq $0x0, 0x28(%rsp)
movq 0xa936(%rip), %rax      # 0xfff8
movq (%rax), %rdi
leaq 0x61eb(%rip), %rsi      # 0xb8b7
leaq 0x605b(%rip), %rdx      # 0xb72e
movq 0x38(%rsp), %rcx
movq 0x40(%rsp), %r8
movq 0x48(%rsp), %r9
xorl %eax, %eax
pushq 0x28(%rsp)
pushq 0x38(%rsp)
callq 0x2190
addq $0x10, %rsp
xorl %eax, %eax
jmp 0x567c