// File: maxgodfrey2004[P]gss/src/kmp.cc
// Function: gss::kmp::FindMatches(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
std::vector<int> FindMatches(std::string search, std::string pattern) {
  if (search == "") {
    std::cerr << "ERROR: text to search must not be blank" << std::endl;
  }

  std::vector<int> prefix_vals = ComputePrefix(search);
  std::vector<int> occurrences;

  int max_length_prefix = 0;
  for (int i = 0; i < static_cast<int>(search.length()); ++i) {
    // Jump by prefix values to try smaller prefixes. Keep jumping until we
    // either find a match, or reach zero.
    while (max_length_prefix > 0 && search[i] != pattern[max_length_prefix]) {
      max_length_prefix = prefix_vals[max_length_prefix - 1];
    }
    if (search[i] == pattern[max_length_prefix]) {
      ++max_length_prefix;
    }
    if (max_length_prefix == static_cast<int>(pattern.length())) {
      // We have found an occurrence of pattern in our search string!
      occurrences.push_back(i - pattern.length() + 1);
      max_length_prefix = prefix_vals[max_length_prefix - 1];
    }
  }

  return occurrences;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdx, -0x90(%rbp)
movq %rsi, -0x88(%rbp)
movq %rdi, %rax
movq -0x88(%rbp), %rdi
movq %rax, -0x80(%rbp)
movq %rax, %rcx
movq %rcx, -0x78(%rbp)
movq %rax, -0x8(%rbp)
movq %rdi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
leaq 0x210b(%rip), %rsi      # 0x60ac
callq 0x35d0
testb $0x1, %al
jne 0x3fac
jmp 0x3fce
movq 0x503d(%rip), %rdi      # 0x8ff0
leaq 0x217e(%rip), %rsi      # 0x6138
callq 0x2180
movq %rax, %rdi
movq 0x4fef(%rip), %rsi      # 0x8fb8
callq 0x21b0
movq -0x88(%rbp), %rsi
leaq -0x50(%rbp), %rdi
movq %rdi, -0x98(%rbp)
callq 0x20c0
movq -0x98(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x3d70
jmp 0x3ff7
leaq -0x50(%rbp), %rdi
callq 0x2308
movq -0x80(%rbp), %rdi
movb $0x0, -0x5d(%rbp)
callq 0x35b0
movl $0x0, -0x64(%rbp)
movl $0x0, -0x68(%rbp)
movq -0x88(%rbp), %rdi
movl -0x68(%rbp), %eax
movl %eax, -0x9c(%rbp)
callq 0x2260
movq %rax, %rcx
movl -0x9c(%rbp), %eax
cmpl %ecx, %eax
jge 0x41ef
jmp 0x4043
xorl %eax, %eax
cmpl $0x0, -0x64(%rbp)
movb %al, -0x9d(%rbp)
jle 0x40ae
movq -0x88(%rbp), %rdi
movslq -0x68(%rbp), %rsi
callq 0x22f0
movq %rax, -0xa8(%rbp)
jmp 0x406a
movq -0x90(%rbp), %rdi
movq -0xa8(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0xb4(%rbp)
movslq -0x64(%rbp), %rsi
callq 0x22f0
movq %rax, -0xb0(%rbp)
jmp 0x4093
movl -0xb4(%rbp), %eax
movq -0xb0(%rbp), %rcx
movsbl (%rcx), %ecx
cmpl %ecx, %eax
setne %al
movb %al, -0x9d(%rbp)
movb -0x9d(%rbp), %al
testb $0x1, %al
jne 0x40ba
jmp 0x4113
movl -0x64(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x42a0
movl (%rax), %eax
movl %eax, -0x64(%rbp)
jmp 0x4043
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x2308
jmp 0x4218
movq -0x80(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
callq 0x3630
leaq -0x30(%rbp), %rdi
callq 0x3630
jmp 0x4218
movq -0x88(%rbp), %rdi
movslq -0x68(%rbp), %rsi
callq 0x22f0
movq %rax, -0xc0(%rbp)
jmp 0x412c
movq -0x90(%rbp), %rdi
movq -0xc0(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0xcc(%rbp)
movslq -0x64(%rbp), %rsi
callq 0x22f0
movq %rax, -0xc8(%rbp)
jmp 0x4155
movl -0xcc(%rbp), %eax
movq -0xc8(%rbp), %rcx
movsbl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x4172
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
movq -0x90(%rbp), %rdi
movl -0x64(%rbp), %eax
movl %eax, -0xd0(%rbp)
callq 0x2260
movq %rax, %rcx
movl -0xd0(%rbp), %eax
cmpl %ecx, %eax
jne 0x41df
movq -0x90(%rbp), %rdi
movl -0x68(%rbp), %eax
movl %eax, -0xd4(%rbp)
callq 0x2260
movq -0x80(%rbp), %rdi
movq %rax, %rcx
movl -0xd4(%rbp), %eax
subl %ecx, %eax
incl %eax
movl %eax, -0x6c(%rbp)
leaq -0x6c(%rbp), %rsi
callq 0x42c0
jmp 0x41c8
movl -0x64(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x42a0
movl (%rax), %eax
movl %eax, -0x64(%rbp)
jmp 0x41e1
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x401b
movb $0x1, -0x5d(%rbp)
testb $0x1, -0x5d(%rbp)
jne 0x4202
movq -0x80(%rbp), %rdi
callq 0x3630
leaq -0x30(%rbp), %rdi
callq 0x3630
movq -0x78(%rbp), %rax
addq $0xe0, %rsp
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x22b0
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)