// File: /workspace/github_c_makefile_star2_O2/genometools[P]genometools/src/core/fasta_reader_fsm.c
// Function: gt_fasta_reader_fsm_run
static int gt_fasta_reader_fsm_run(GtFastaReader *fasta_reader,
                                   GtFastaReaderProcDescription
                                   proc_description,
                                   GtFastaReaderProcSequencePart
                                   proc_sequence_part,
                                   GtFastaReaderProcSequenceLength
                                   proc_sequence_length,
                                   void *data, GtError *err)
{
  GtFastaReaderFSM *fr = gt_fasta_reader_fsm_cast(fasta_reader);
  unsigned char cc;
  GtFastaReaderState state = EXPECTING_SEPARATOR;
  GtUword sequence_length = 0, line_counter = 1;
  GtStr *description, *sequence;
  int had_err = 0;

  gt_error_check(err);
  gt_assert(fr);

  /* init */
  description = gt_str_new();
  sequence    = gt_str_new();

  /* at least one function has to be defined */
  gt_assert(proc_description || proc_sequence_part || proc_sequence_length);

  /* rewind sequence file (to allow multiple calls) */
  if (fr->sequence_file)
    gt_file_xrewind(fr->sequence_file);

  /* reading */
  while (!had_err && gt_file_xread(fr->sequence_file, &cc, 1) != 0) {
    switch (state) {
      case EXPECTING_SEPARATOR:
        if (cc != GT_FASTA_SEPARATOR) {
          gt_error_set(err,
                    "the first character of fasta file \"%s\" has to be '%c'",
                    gt_str_get(fr->sequence_filename), GT_FASTA_SEPARATOR);
          had_err = -1;
        }
        else
          state = READING_DESCRIPTION;
        break;
      case READING_DESCRIPTION:
        if (cc == '\n') {
          if (proc_description) {
            had_err = proc_description(gt_str_get(description),
                                       gt_str_length(description), data, err);
            if (!had_err)
              gt_str_reset(description);
          }
          if (!had_err) {
            sequence_length = 0;
            line_counter++;
            state = READING_SEQUENCE_AFTER_NEWLINE;
          }
        }
        else if (proc_description && cc != '\r')
          gt_str_append_char(description, cc);
        break;
      case READING_SEQUENCE_AFTER_NEWLINE:
        if (cc == GT_FASTA_SEPARATOR) {
          if (!sequence_length) {
            gt_assert(line_counter);
            gt_error_set(err, "empty sequence after description given in line "
                              ""GT_WU"", line_counter - 1);
            had_err = -1;
            break;
          }
          else {
            if (proc_sequence_part) {
              gt_assert(gt_str_length(sequence));
              had_err = proc_sequence_part(gt_str_get(sequence),
                                           gt_str_length(sequence), data, err);
            }
            if (had_err)
              break;
            gt_str_reset(sequence);
            if (proc_sequence_length)
              had_err = proc_sequence_length(sequence_length, data, err);
            if (had_err)
              break;
            state = READING_DESCRIPTION;
            continue;
          }
        }
        /*@fallthrough@*/
      case READING_SEQUENCE:
        if (cc == '\n') {
          line_counter++;
          state = READING_SEQUENCE_AFTER_NEWLINE;
        }
        else {
          sequence_length++;
          if (proc_sequence_part) {
            if (gt_str_length(sequence) == BUFSIZ) {
              had_err = proc_sequence_part(gt_str_get(sequence),
                                           gt_str_length(sequence), data, err);
              if (had_err)
                break;
              gt_str_reset(sequence);
            }
            if (cc != ' ' && cc != '\r')
              gt_str_append_char(sequence, cc);
          }
        }
        break;
    }
  }

  if (!had_err) {
    /* checks after reading */
    switch (state) {
      case EXPECTING_SEPARATOR:
        gt_error_set(err, "sequence file \"%s\" is empty",
                  gt_str_get(fr->sequence_filename));
        had_err = -1;
        break;
      case READING_DESCRIPTION:
        gt_error_set(err, "unfinished fasta entry in line " GT_WU
                     " of sequence file \"%s\"",
                     line_counter, gt_str_get(fr->sequence_filename));
        had_err = -1;
        break;
      case READING_SEQUENCE_AFTER_NEWLINE:
      case READING_SEQUENCE:
        if (!sequence_length) {
          gt_assert(line_counter);
          gt_error_set(err, "empty sequence after description given in line "
                            ""GT_WU"", line_counter - 1);
          had_err = -1;
        }
        else {
          if (proc_sequence_part) {
            gt_assert(gt_str_length(sequence));
            had_err = proc_sequence_part(gt_str_get(sequence),
                                         gt_str_length(sequence), data, err);
          }
          if (!had_err && proc_sequence_length)
            had_err = proc_sequence_length(sequence_length, data, err);
        }
    }
  }

  /* free */
  gt_str_delete(sequence);
  gt_str_delete(description);

  return had_err;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %r9, %rbx
movq %r8, 0x10(%rsp)
movq %rcx, %r12
movq %rdx, %rbp
movq %rsi, %r14
movq %rdi, %rsi
leaq 0x3277c7(%rip), %rdi    # 0x4074b0
callq 0xdfc6b
movq %rax, 0x18(%rsp)
testq %rbx, %rbx
je 0xdfd08
movq %rbx, %rdi
callq 0x32150
testb %al, %al
jne 0xe0182
cmpq $0x0, 0x18(%rsp)
je 0xe012e
callq 0x31660
movq %rax, 0x28(%rsp)
callq 0x31660
movq %rax, %r15
movq %r14, %rax
orq %rbp, %rax
orq %r12, %rax
je 0xe0158
movq %r14, 0x30(%rsp)
movq %rbx, 0x8(%rsp)
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rdi
testq %rdi, %rdi
je 0xdfd52
callq 0x2eb40
pushq $0x1
popq %rax
movq %rax, 0x20(%rsp)
xorl %r13d, %r13d
xorl %ebx, %ebx
xorl %eax, %eax
movl %eax, %r14d
testl %r14d, %r14d
jne 0xe00ac
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rdi
leaq 0x7(%rsp), %rsi
pushq $0x1
popq %rdx
callq 0x2f270
testl %eax, %eax
je 0xdffe1
cmpl $0x2, %ebx
jne 0xdfe23
movzbl 0x7(%rsp), %eax
cmpl $0x3e, %eax
jne 0xdfe81
testq %r13, %r13
movq 0x8(%rsp), %rbx
je 0xdff4e
testq %rbp, %rbp
je 0xdfded
movq %r15, %rdi
callq 0x30ea0
testq %rax, %rax
je 0xe00f8
movq %r15, %rdi
callq 0x32b70
movq %rax, %r14
movq %r15, %rdi
callq 0x30ea0
movq %r14, %rdi
movq %rax, %rsi
movq 0x10(%rsp), %rdx
movq %rbx, %rcx
callq *%rbp
testl %eax, %eax
jne 0xdfe1b
movq %r15, %rdi
callq 0x32720
xorl %r14d, %r14d
movl $0x0, %eax
testq %r12, %r12
je 0xdfe10
movq %r13, %rdi
movq 0x10(%rsp), %rsi
movq %rbx, %rdx
callq *%r12
pushq $0x1
popq %rbx
testl %eax, %eax
je 0xdfd64
pushq $0x2
popq %rbx
jmp 0xdfd61
cmpl $0x1, %ebx
jne 0xdff0a
movb 0x7(%rsp), %cl
cmpb $0xa, %cl
jne 0xdff7f
cmpq $0x0, 0x30(%rsp)
je 0xdffd1
movq 0x28(%rsp), %rbx
movq %rbx, %rdi
callq 0x32b70
movq %rax, %r14
movq %rbx, %rdi
callq 0x30ea0
movq %r14, %rdi
movq %rax, %rsi
movq 0x10(%rsp), %rdx
movq 0x8(%rsp), %rcx
callq *0x30(%rsp)
pushq $0x1
popq %rbx
testl %eax, %eax
jne 0xdfd61
jmp 0xdffc7
cmpl $0xa, %eax
je 0xdffb3
incq %r13
pushq $0x2
popq %rbx
movl $0x0, %eax
testq %rbp, %rbp
je 0xdfd61
movq %r15, %rdi
callq 0x30ea0
cmpq $0x2000, %rax           # imm = 0x2000
jne 0xdfee6
movq %r15, %rdi
callq 0x32b70
movq %rax, %r14
movq %r15, %rdi
callq 0x30ea0
movq %r14, %rdi
movq %rax, %rsi
movq 0x10(%rsp), %rdx
movq 0x8(%rsp), %rcx
callq *%rbp
pushq $0x2
popq %rbx
testl %eax, %eax
jne 0xdfd61
movq %r15, %rdi
callq 0x32720
movzbl 0x7(%rsp), %ecx
pushq $0x2
popq %rbx
movl $0x0, %eax
cmpl $0xd, %ecx
je 0xdfd61
cmpl $0x20, %ecx
je 0xdfd61
jmp 0xdffba
cmpb $0x3e, 0x7(%rsp)
pushq $0x1
popq %rbx
movl $0x0, %eax
je 0xdfd61
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x32b70
xorl %ebx, %ebx
movq 0x8(%rsp), %rdi
leaq 0x20cf6a(%rip), %rsi    # 0x2ecea3
movq %rax, %rdx
pushq $0x3e
popq %rcx
xorl %eax, %eax
callq 0x30a30
pushq $-0x1
popq %rax
jmp 0xdfd61
movq 0x20(%rsp), %rax
testq %rax, %rax
je 0xe01af
leaq -0x1(%rax), %rdx
movq %rbx, %rdi
leaq 0x20cf7c(%rip), %rsi    # 0x2ecee6
xorl %eax, %eax
callq 0x30a30
xorl %r13d, %r13d
pushq $0x2
popq %rbx
pushq $-0x1
popq %rax
jmp 0xdfd61
cmpq $0x0, 0x30(%rsp)
sete %al
cmpb $0xd, %cl
sete %dl
orb %al, %dl
pushq $0x1
popq %rbx
movl $0x0, %eax
jne 0xdfd61
movsbl %cl, %esi
movq 0x28(%rsp), %rdi
callq 0x323d0
pushq $0x1
popq %rbx
jmp 0xdfd5f
incq 0x20(%rsp)
jmp 0xdffd9
movsbl %cl, %esi
movq %r15, %rdi
callq 0x323d0
jmp 0xdffd9
movq 0x28(%rsp), %rdi
callq 0x32720
incq 0x20(%rsp)
xorl %r13d, %r13d
pushq $0x2
popq %rbx
jmp 0xdfd5f
cmpl $0x2, %ebx
je 0xe0019
cmpl $0x1, %ebx
jne 0xe0062
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x32b70
leaq 0x20cf35(%rip), %rsi    # 0x2ecf35
movq 0x8(%rsp), %rdi
movq 0x20(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x30a30
jmp 0xe00a8
testq %r13, %r13
je 0xe0084
testq %rbp, %rbp
je 0xe00d0
movq %r15, %rdi
callq 0x30ea0
testq %rax, %rax
je 0xe01dc
movq %r15, %rdi
callq 0x32b70
movq %rax, %rbx
movq %r15, %rdi
callq 0x30ea0
movq %rbx, %rdi
movq %rax, %rsi
movq 0x10(%rsp), %rdx
movq 0x8(%rsp), %rcx
callq *%rbp
movl %eax, %r14d
jmp 0xe00d3
movq 0x8(%rsp), %rbx
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x32b70
leaq 0x20ce9d(%rip), %rsi    # 0x2ecf19
movq %rbx, %rdi
movq %rax, %rdx
jmp 0xe00a1
movq 0x20(%rsp), %rdx
testq %rdx, %rdx
movq 0x8(%rsp), %rdi
je 0xe020d
decq %rdx
leaq 0x20ce45(%rip), %rsi    # 0x2ecee6
xorl %eax, %eax
callq 0x30a30
pushq $-0x1
popq %r14
movq %r15, %rdi
callq 0x33020
movq 0x28(%rsp), %rdi
callq 0x33020
movl %r14d, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r14d, %r14d
testq %r12, %r12
sete %al
testl %r14d, %r14d
setne %cl
orb %al, %cl
jne 0xe00ac
movq %r13, %rdi
movq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdx
callq *%r12
movl %eax, %r14d
jmp 0xe00ac
movq 0x32aeb1(%rip), %rax    # 0x40afb0
movq (%rax), %rdi
leaq 0x1fe6e7(%rip), %rsi    # 0x2de7f0
leaq 0x20cee1(%rip), %rdx    # 0x2ecff1
leaq 0x20cd16(%rip), %rcx    # 0x2ece2d
leaq 0x20cd27(%rip), %r8     # 0x2ece45
pushq $0x6d
popq %r9
xorl %eax, %eax
callq 0x32960
callq 0x2e820
movq 0x32ae7b(%rip), %rax    # 0x40afb0
movq (%rax), %rdi
leaq 0x1fe6b1(%rip), %rsi    # 0x2de7f0
leaq 0x20cd1b(%rip), %rdx    # 0x2ece61
leaq 0x20cce0(%rip), %rcx    # 0x2ece2d
leaq 0x20ccf1(%rip), %r8     # 0x2ece45
pushq $0x37
jmp 0xe0120
movq 0x32ae51(%rip), %rax    # 0x40afb0
movq (%rax), %rdi
leaq 0x1fe687(%rip), %rsi    # 0x2de7f0
leaq 0x20ccf4(%rip), %rdx    # 0x2ece64
leaq 0x20ccb6(%rip), %rcx    # 0x2ece2d
leaq 0x20ccc7(%rip), %r8     # 0x2ece45
pushq $0x3e
jmp 0xe0120
movq 0x32ae27(%rip), %rax    # 0x40afb0
movq (%rax), %rdi
leaq 0x1fe65d(%rip), %rsi    # 0x2de7f0
leaq 0x1fe829(%rip), %rdx    # 0x2de9c3
leaq 0x20cc8c(%rip), %rcx    # 0x2ece2d
leaq 0x20cc9d(%rip), %r8     # 0x2ece45
pushq $0x36
jmp 0xe0120
movq 0x32adfa(%rip), %rax    # 0x40afb0
movq (%rax), %rdi
leaq 0x1fe630(%rip), %rsi    # 0x2de7f0
leaq 0x20cd12(%rip), %rdx    # 0x2eced9
leaq 0x20cc5f(%rip), %rcx    # 0x2ece2d
leaq 0x20cc70(%rip), %r8     # 0x2ece45
pushq $0x65
jmp 0xe0120
movq 0x32adcd(%rip), %rax    # 0x40afb0
movq (%rax), %rdi
leaq 0x1fe603(%rip), %rsi    # 0x2de7f0
leaq 0x20cdfd(%rip), %rdx    # 0x2ecff1
leaq 0x20cc32(%rip), %rcx    # 0x2ece2d
leaq 0x20cc43(%rip), %r8     # 0x2ece45
movl $0xac, %r9d
jmp 0xe0122
movq 0x32ad9c(%rip), %rax    # 0x40afb0
movq (%rax), %rdi
leaq 0x1fe5d2(%rip), %rsi    # 0x2de7f0
leaq 0x20ccb4(%rip), %rdx    # 0x2eced9
leaq 0x20cc01(%rip), %rcx    # 0x2ece2d
leaq 0x20cc12(%rip), %r8     # 0x2ece45
movl $0xa5, %r9d
jmp 0xe0122