// File: /workspace/github_cpp_makefile_star2_O3/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
subq $0x18, %rsp
movq %rsi, %r14
movq %rdi, %r15
movl $0x18, %edi
callq 0x10c0
movq %rax, %r12
xorps %xmm0, %xmm0
movaps %xmm0, (%rax)
movq $0x0, 0x10(%rax)
movq %rax, (%r14)
xorl %r13d, %r13d
movl %r13d, %ebp
incl %r13d
cmpb $0x0, (%r15,%rbp)
jne 0x150d
leal -0x1(%r13), %eax
movl %eax, 0x8(%rsp)
movl %eax, 0x8(%r12)
movl %r13d, %ebx
movq %rbx, %rdi
callq 0x1030
movq %rax, (%r12)
movb $0x0, (%rax,%rbp)
cmpl $0x1, %r13d
jne 0x1546
xorl %esi, %esi
xorl %eax, %eax
jmp 0x157f
movl 0x8(%rsp), %ecx
xorl %edx, %edx
xorl %eax, %eax
xorl %esi, %esi
movzbl %sil, %esi
movzbl (%r15,%rdx), %edi
movq (%r14), %r8
movq (%r8), %r8
movzbl %al, %eax
cmpb %dil, %al
cmovgel %edi, %eax
movb %dil, (%r8,%rdx)
cmpb %dil, %sil
cmovgl %esi, %edi
movl %edi, %esi
incq %rdx
cmpq %rdx, %rcx
jne 0x1550
movq (%r14), %r12
movzbl %sil, %ecx
movsbl %al, %eax
movb %al, 0xc(%r12)
movb %cl, 0xd(%r12)
movl %ecx, %r15d
subl %eax, %r15d
leal 0x1(%r15), %ebp
leaq (,%rbx,8), %rdi
callq 0x1030
movq %rax, 0x10(%r12)
movl %ebp, %r12d
movl %r15d, %ebp
testl %r13d, %r13d
je 0x161e
movq %rbp, 0x8(%rsp)
leaq (,%r12,4), %r15
xorl %ebp, %ebp
movq %r15, %rdi
callq 0x1030
movq (%r14), %rcx
movq 0x10(%rcx), %rcx
movq %rax, (%rcx,%rbp,8)
incq %rbp
cmpq %rbp, %rbx
jne 0x15c6
movq (%r14), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rax), %r15
testl %r13d, %r13d
je 0x1617
movq 0x8(%rsp), %rax
leaq 0x4(,%rax,4), %r14
xorl %ebp, %ebp
movq (%r15,%rbp,8), %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x1080
incq %rbp
cmpq %rbp, %rbx
jne 0x1601
movq 0x8(%rsp), %rbp
jmp 0x162a
movq (%r14), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rax), %r15
leaq (,%r12,4), %rdi
callq 0x1030
movq %rax, %r14
leaq 0x4(,%rbp,4), %rdx
movq %rax, %rdi
xorl %esi, %esi
callq 0x1080
testl %r13d, %r13d
je 0x1686
movq 0x10(%rsp), %rax
movq (%rax), %rax
xorl %ecx, %ecx
movq %rcx, %rdx
movsbq (%rax,%rcx), %rsi
incq %rcx
movl %esi, %esi
movl %ecx, (%r14,%rsi,4)
movq (%r15,%rdx,8), %rdx
xorl %esi, %esi
movl (%r14,%rsi,4), %edi
movl %edi, (%rdx,%rsi,4)
incq %rsi
cmpq %rsi, %r12
jne 0x1672
cmpq %rbx, %rcx
jne 0x165b
movq %r14, %rdi
callq 0x10b0
movb $0x1, %al
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq