// File: /workspace/github_cpp_makefile_star2_O1/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 0x14e9
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 0x1522
xorl %esi, %esi
xorl %ecx, %ecx
jmp 0x1558
movl 0x8(%rsp), %eax
xorl %edx, %edx
xorl %ecx, %ecx
xorl %edi, %edi
movzbl (%r15,%rdx), %esi
movq (%r14), %r8
movq (%r8), %r8
movb %sil, (%r8,%rdx)
movzbl %cl, %ecx
cmpb %sil, %cl
cmovgel %esi, %ecx
movzbl %dil, %edi
cmpb %sil, %dil
cmovgl %edi, %esi
incq %rdx
movl %esi, %edi
cmpq %rdx, %rax
jne 0x152c
movzbl %sil, %eax
movsbl %cl, %ecx
movq (%r14), %r15
movb %cl, 0xc(%r15)
movb %al, 0xd(%r15)
movl %eax, %edx
subl %ecx, %edx
movq %rdx, 0x8(%rsp)
leal 0x1(%rdx), %ebp
leaq (,%rbx,8), %rdi
callq 0x1030
movq %rax, 0x10(%r15)
movl %ebp, %r12d
testl %r13d, %r13d
je 0x15b4
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 0x1599
movq (%r14), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rax), %r15
testl %r13d, %r13d
je 0x15ea
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 0x15d4
leaq (,%r12,4), %rdi
callq 0x1030
movq %rax, %r14
movq 0x8(%rsp), %rax
leaq 0x4(,%rax,4), %rdx
movq %r14, %rdi
xorl %esi, %esi
callq 0x1080
testl %r13d, %r13d
je 0x164b
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 0x1637
cmpq %rbx, %rcx
jne 0x1620
movq %r14, %rdi
callq 0x10b0
movb $0x1, %al
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq