// File: /workspace/github_cpp_makefile_star2_O2/ivanzamanov[P]kmeans/src/common/matcher.cpp
// Function: build_matcher(char const*, matcher*&)
bool build_matcher(const char* string, matcher* &result) {
	// The result
	result = new matcher();
	unsigned int n = 0;
	// strlen
	while(*(string + n) != 0) {
		n++;
	}
	// Save the string and it's lenght
	// Not sure why...
	result->n = n;
	result->string = new char[n + 1];
	result->string[n] = 0;

	// While copying the string, find and save
	// the min and max chars to reduce
	// memory footprint
	char min_char = 0;
	char max_char = 0;
	for(unsigned int k = 0; k < n; k++) {
		char c = string[k];
		result->string[k] = c;
		if(min_char > c) {
			min_char = c;
		}
		if(max_char < c) {
			max_char = c;
		}
	}
	unsigned int range = max_char - min_char + 1;
	result->min_char = min_char;
	result->max_char = max_char;
	// Transitions table
	result->table = new unsigned int*[n + 1];
	for (unsigned int i = 0; i < n + 1; i++) {
		result->table[i] = new unsigned int[range];
	}

	unsigned int** table = result->table;
	for (unsigned int i = 0; i < n+1; i++) {
		for (unsigned int j = 0; j < range; j++) {
			table[i][j] = 0;
		}
	}
	
	// Will hold the sink state for each character
	// So we won't need to go back every time and search
	unsigned int* sinks = new unsigned int[range];
	for(unsigned int i = 0; i < range; i++) {
		sinks[i] = 0;
	}

	// Populate transitions
	for (unsigned int i = 0; i < n+1; i++) {
		unsigned int c = (unsigned int) result->string[i];
		// Sink back to the first state which has
		// a transition with this char for all previous
		// characters
		// Always a transition to the next state
		// with the current char
		// This is the new sink state for this char
		sinks[c] = i+1;
		for (unsigned int j = 0; j < range; j++) {
			table[i][j] = sinks[j];
		}
	}
	delete sinks;
	return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r14
movq %rdi, %r15
pushq $0x18
popq %rdi
callq 0x10a0
movq %rax, %r12
andq $0x0, 0x10(%rax)
xorps %xmm0, %xmm0
movaps %xmm0, (%rax)
movq %rax, (%r14)
xorl %eax, %eax
movl %eax, %ebp
incl %eax
cmpb $0x0, (%r15,%rbp)
jne 0x14a4
leal -0x1(%rax), %r13d
movl %r13d, 0x8(%r12)
movl %eax, %ebx
movq %rbx, %rdi
callq 0x1030
movq %rax, (%r12)
movb $0x0, (%rax,%rbp)
xorl %ecx, %ecx
xorl %edx, %edx
xorl %eax, %eax
movzbl %dl, %esi
cmpq %rcx, %r13
je 0x14f9
movzbl (%r15,%rcx), %edx
movq (%r14), %rdi
movq (%rdi), %rdi
movb %dl, (%rdi,%rcx)
movzbl %al, %eax
cmpb %dl, %al
cmovgel %edx, %eax
cmpb %dl, %sil
cmovgl %esi, %edx
incq %rcx
jmp 0x14d0
movsbl %al, %ecx
movl %esi, %r12d
subl %ecx, %r12d
incl %r12d
movq (%r14), %r15
movb %al, 0xc(%r15)
movb %sil, 0xd(%r15)
leaq (,%rbx,8), %rdi
callq 0x1030
movq %rax, 0x10(%r15)
leaq (,%r12,4), %r15
xorl %r13d, %r13d
cmpq %r13, %rbx
je 0x1549
movq %r15, %rdi
callq 0x1030
movq (%r14), %rcx
movq 0x10(%rcx), %rcx
movq %rax, (%rcx,%r13,8)
incq %r13
jmp 0x152c
movq (%r14), %r14
movq 0x10(%r14), %r13
xorl %eax, %eax
cmpq %rbx, %rax
je 0x1571
xorl %ecx, %ecx
cmpq %rcx, %r12
je 0x156c
movq (%r13,%rax,8), %rdx
andl $0x0, (%rdx,%rcx,4)
incq %rcx
jmp 0x1559
incq %rax
jmp 0x1552
movq %r15, %rdi
callq 0x1030
xorl %ecx, %ecx
cmpq %rcx, %r12
je 0x1589
andl $0x0, (%rax,%rcx,4)
incq %rcx
jmp 0x157b
xorl %ecx, %ecx
cmpq %rbx, %rcx
je 0x15be
movq (%r14), %rdx
movsbq (%rdx,%rcx), %rsi
leaq 0x1(%rcx), %rdx
movl %esi, %esi
movl %edx, (%rax,%rsi,4)
xorl %esi, %esi
cmpq %rsi, %r12
je 0x15b9
movl (%rax,%rsi,4), %edi
movq (%r13,%rcx,8), %r8
movl %edi, (%r8,%rsi,4)
incq %rsi
jmp 0x15a3
movq %rdx, %rcx
jmp 0x158b
movq %rax, %rdi
callq 0x1090
movb $0x1, %al
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq