// File: /workspace/github_c_makefile_star2_O1/jondurbin[P]dre2/src/dre2_match.c
// Function: dre2_matcher
struct dre2_single_match dre2_matcher( struct dre2 *graph, unsigned char *begin_ptr, unsigned char *input, int start, int direction, int length, int *r_temp, int *reachable, int *state )
{
  int i, j, k;
  int *swapper, *next_nodes, *previous_nodes;
  int iter, l_iter;
  int matched, single_match;
  int r;
  int count, previous_count;
  int found, complete, assertion, assertion_match;
  struct dre2_node *node;
  struct dre2_single_match ret;

  ret.match = NULL;
  ret.skip_to = DRE2_INFINITE;
  ret.assertion_match = false;

  i = 0;
  next_nodes = direction == DRE2_LEFT ? graph->v[start].p : graph->v[start].n;
  count = direction == DRE2_LEFT ? graph->v[start].p_count : graph->v[start].n_count;

  if ( start == 0 || start == graph->count - 1 )
  {
    for ( i = 0; i < count; i++ )
      reachable[i] = next_nodes[i];
    l_iter = i;
  } else
  {
    reachable[0] = start;
    l_iter = 1;
  }

  assertion_match = false;
  while ( true )
  {
    // Check for valid states.
    i = 0;
    iter = 0;
    matched = false;
    complete = false;
    for ( i = 0; i < l_iter; i++ )
    {
      r = reachable[i];
      node = &graph->v[r];

      // Check if the character matches the node.
      single_match = false;
      switch ( node->c )
      {
        case DRE2_BOL:
        case DRE2_EOF:
        case DRE2_EOL:
          assertion = true;
          break;
        default:
          assertion = false;
          break;
      }

      if ( node->c == DRE2_BOL )
      {
        if ( ( direction == DRE2_LEFT && input - begin_ptr == -1 ) || ( direction == DRE2_RIGHT && input - begin_ptr == 0 ) )
          single_match = true;
      } else if ( node->c == DRE2_EOL && ( *input == '\n' || *input == '\0' ) )
      {
        single_match = true;
      } else if ( node->c == DRE2_EOF && *input == '\0' )
      {
        single_match = true;
      } else if ( node->c == DRE2_EOF && *input == '\n' && input - begin_ptr + 1 == length )
      {
        single_match = true;
      } else if ( node->c == DRE2_EOF && *input == ' ' && input - begin_ptr + 1 == length - 1 )
      {
        single_match = true;
      } else if ( dre2_char_matches( graph, node, *input ) )
      {
        single_match = true;
      }

      if ( assertion && single_match )
        assertion_match = true;

      // Set the next possible nodes.
      if ( single_match == true )
      {
        matched = true;

        // Set the next state to include this node's neighbors/parents.
        next_nodes = direction == DRE2_LEFT ? node->p : node->n;
        count = direction == DRE2_LEFT ? node->p_count : node->n_count;
        for ( j = 0; j < count; j++ )
        {
          if ( !state[next_nodes[j]] )
          {
            state[next_nodes[j]] = true;
            r_temp[iter++] = next_nodes[j];
            if ( ( direction == DRE2_RIGHT && next_nodes[j] == graph->count - 1 ) || ( direction == DRE2_LEFT && next_nodes[j] == 0 ) )
              complete = true;
          }
        }
      } else if ( graph->impossible[*input] )
      {
        ret.skip_to = input - begin_ptr;
      }
    }

    if ( !matched && graph->impossible[*input] )
    {
      for ( i = 0; i < graph->v[0].n_count; i++ )
      {
        if ( direction == DRE2_LEFT && graph->v[graph->v[0].n[i]].c == DRE2_BOL )
        {
          ret.skip_to = length;
          break;
        }
      }
    }

    if ( complete )
    {
      ret.match = input;
      ret.assertion_match = assertion_match;
      if ( !( graph->options & DRE2_GREEDY ) )
      {
        for ( i = 0; i < iter; i++ )
          state[r_temp[i]] = false;
        return ret;
      }
    }

    // Reset the state lookup table.
    for ( i = 0; i < iter; i++ )
      state[r_temp[i]] = false;

    l_iter = iter;

    swapper = reachable;
    reachable = r_temp;
    r_temp = swapper;

    // Increment/Decrement input.
    if ( !assertion_match )
    {
      if ( direction == DRE2_LEFT )
        *input--;
      else
        *input++;
    }

    // If none of the active states matched, the regex failed to match.
    if ( matched == false )
      return ret;
  }
  return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rcx, %r13
movq %rdx, 0x40(%rsp)
movq %rsi, %r11
movq 0xd0(%rsp), %rdx
movq $0x0, 0x10(%rdi)
movl $0xffffffff, 0x8(%rdi)  # imm = 0xFFFFFFFF
movq %rdi, 0x10(%rsp)
movl $0x0, (%rdi)
movslq %r8d, %rsi
movq %rsi, %rcx
shlq $0x6, %rcx
testl %r9d, %r9d
movq (%r11), %rdi
leaq 0x18(%rdi,%rcx), %rax
leaq 0x8(%rdi,%rcx), %r10
cmoveq %rax, %r10
movq (%r10), %rax
leaq 0x20(%rdi,%rcx), %r10
leaq 0x10(%rdi,%rcx), %rcx
cmoveq %r10, %rcx
movl (%rcx), %ecx
testl %esi, %esi
je 0x60eb
movl 0x8(%r11), %esi
decl %esi
cmpl %r8d, %esi
jne 0x6101
xorl %ebx, %ebx
testl %ecx, %ecx
jle 0x6109
movl (%rax,%rbx,4), %esi
movl %esi, (%rdx,%rbx,4)
incq %rbx
cmpq %rbx, %rcx
jne 0x60f1
jmp 0x6109
movl %r8d, (%rdx)
movl $0x1, %ebx
movq 0xd8(%rsp), %r14
movq 0xc8(%rsp), %rax
movq %rax, 0x18(%rsp)
xorl %ecx, %ecx
testl %r9d, %r9d
sete %cl
movslq 0xc0(%rsp), %rax
movq %rax, 0x48(%rsp)
decl %eax
cltq
movq %rax, 0x38(%rsp)
shll $0x4, %ecx
leaq 0x8(%rcx), %rax
movq %rax, 0x50(%rsp)
addq $0x10, %rcx
movq %rcx, 0x70(%rsp)
xorl %eax, %eax
movl %r9d, 0x24(%rsp)
movq %r11, 0x58(%rsp)
movq 0x18(%rsp), %r15
movq %rdx, 0x18(%rsp)
movb $0x1, %cl
testl %ebx, %ebx
jg 0x6176
xorl %ebx, %ebx
movb $0x1, %dl
jmp 0x6381
movq %r15, 0x30(%rsp)
cmpl $0x1, %r9d
sete %cl
testl %r9d, %r9d
sete %dl
movq (%r11), %rsi
movq %rsi, 0x80(%rsp)
movq %r13, %rdi
subq 0x40(%rsp), %rdi
sete %r8b
cmpq $-0x1, %rdi
sete %sil
andb %dl, %sil
andb %cl, %r8b
orb %sil, %r8b
movb %r8b, 0x7(%rsp)
movq %rdi, 0x60(%rsp)
leaq 0x1(%rdi), %rcx
movq %rcx, 0x28(%rsp)
movl %ebx, %ecx
movq %rcx, 0x78(%rsp)
xorl %r12d, %r12d
movl $0x0, 0xc(%rsp)
movl $0x0, 0x8(%rsp)
xorl %ebx, %ebx
movq %r13, 0x68(%rsp)
movq 0x18(%rsp), %rcx
movslq (%rcx,%r12,4), %rsi
shlq $0x6, %rsi
movq 0x80(%rsp), %rdi
movl (%rdi,%rsi), %edx
leal 0x12(%rdx), %ecx
cmpl $0xf, %ecx
setb %r14b
movl $0x4003, %r15d          # imm = 0x4003
shrl %cl, %r15d
movl %eax, %ebp
addq %rdi, %rsi
movb 0x7(%rsp), %cl
cmpl $-0x12, %edx
je 0x6297
cmpl $-0x11, %edx
jne 0x6232
movzbl (%r13), %eax
movb $0x1, %cl
testl %eax, %eax
je 0x6297
cmpl $0xa, %eax
je 0x6297
cmpl $-0x4, %edx
jne 0x6270
movb $0x1, %cl
cmpb $0x0, (%r13)
je 0x6297
cmpl $-0x4, %edx
jne 0x6270
cmpb $0xa, (%r13)
jne 0x6258
movq 0x28(%rsp), %rax
cmpq 0x48(%rsp), %rax
je 0x6297
cmpl $-0x4, %edx
jne 0x6270
cmpb $0x20, (%r13)
jne 0x6270
movq 0x28(%rsp), %rax
cmpq 0x38(%rsp), %rax
je 0x6297
movzbl (%r13), %edx
movq %r11, %rdi
movq %rsi, %r13
callq 0x2100
movq %r13, %rsi
movq 0x68(%rsp), %r13
movq 0x58(%rsp), %r11
movl 0x24(%rsp), %r9d
testl %eax, %eax
setne %cl
andb %r15b, %r14b
testb %cl, %cl
movl %ebp, %eax
movl $0x1, %edx
cmovnel %edx, %eax
testb %r14b, %r14b
cmovel %ebp, %eax
testb %cl, %cl
je 0x6339
movq 0x70(%rsp), %rcx
movslq (%rsi,%rcx), %rcx
movl $0x1, 0x8(%rsp)
testq %rcx, %rcx
movq 0xd8(%rsp), %r14
movq 0x30(%rsp), %r15
jle 0x635e
movq 0x50(%rsp), %rdx
movq (%rsi,%rdx), %rdx
xorl %esi, %esi
movslq (%rdx,%rsi,4), %r8
cmpl $0x0, (%r14,%r8,4)
jne 0x632f
leal 0x1(%rbx), %edi
movl $0x1, (%r14,%r8,4)
movl (%rdx,%rsi,4), %r8d
movslq %ebx, %r10
movl %r8d, (%r15,%r10,4)
cmpl $0x1, %r9d
jne 0x631a
movl 0x8(%r11), %r8d
decl %r8d
cmpl %r8d, (%rdx,%rsi,4)
je 0x6325
testl %r9d, %r9d
jne 0x632d
cmpl $0x0, (%rdx,%rsi,4)
jne 0x632d
movl $0x1, 0xc(%rsp)
movl %edi, %ebx
incq %rsi
cmpq %rsi, %rcx
jne 0x62e6
jmp 0x635e
movzbl (%r13), %ecx
cmpl $0x0, 0x464(%r11,%rcx,4)
movq 0xd8(%rsp), %r14
je 0x635e
movq 0x10(%rsp), %rcx
movq 0x60(%rsp), %rdx
movl %edx, 0x8(%rcx)
incq %r12
cmpq 0x78(%rsp), %r12
jne 0x61e4
cmpl $0x0, 0x8(%rsp)
sete %cl
cmpl $0x0, 0xc(%rsp)
sete %dl
movq 0x30(%rsp), %r15
testb %cl, %cl
je 0x63d5
movzbl (%r13), %esi
cmpl $0x0, 0x464(%r11,%rsi,4)
je 0x63d5
movq (%r11), %rsi
movslq 0x10(%rsi), %rdi
testq %rdi, %rdi
jle 0x63d5
xorl %r8d, %r8d
testl %r9d, %r9d
jne 0x63bc
movq 0x8(%rsi), %r10
movslq (%r10,%r8,4), %r10
shlq $0x6, %r10
cmpl $-0x12, (%rsi,%r10)
je 0x63c6
incq %r8
cmpq %r8, %rdi
jne 0x63a4
jmp 0x63d5
movq 0x10(%rsp), %rsi
movl 0xc0(%rsp), %edi
movl %edi, 0x8(%rsi)
testb %dl, %dl
jne 0x63ee
movq 0x10(%rsp), %rdx
movq %r13, 0x10(%rdx)
movl %eax, (%rdx)
testb $0x1, 0x43c(%r11)
je 0x6428
testl %ebx, %ebx
jle 0x640a
movl %ebx, %edx
xorl %esi, %esi
movslq (%r15,%rsi,4), %rdi
movl $0x0, (%r14,%rdi,4)
incq %rsi
cmpq %rsi, %rdx
jne 0x63f6
testl %eax, %eax
jne 0x641b
testl %r9d, %r9d
je 0x6418
incq %r13
jmp 0x641b
decq %r13
movq %r15, %rdx
testb %cl, %cl
je 0x615d
jmp 0x6444
testl %ebx, %ebx
jle 0x6444
movl %ebx, %eax
xorl %ecx, %ecx
movslq (%r15,%rcx,4), %rdx
movl $0x0, (%r14,%rdx,4)
incq %rcx
cmpq %rcx, %rax
jne 0x6430
movq 0x10(%rsp), %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq