// File: /workspace/github_c_makefile_star2_O3/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 0x32333b(%rip), %rdi    # 0x4824e0
callq 0x15f159
movq %rax, 0x18(%rsp)
testq %rbx, %rbx
je 0x15f1c4
movq %rbx, %rdi
callq 0x310f0
testb %al, %al
jne 0x15f5d1
cmpq $0x0, 0x18(%rsp)
je 0x15f5c7
callq 0x30600
movq %rax, 0x28(%rsp)
callq 0x30600
movq %rax, %r15
movq %r14, %rax
orq %rbp, %rax
orq %r12, %rax
je 0x15f5cc
movq %r14, 0x30(%rsp)
movq %rbx, 0x8(%rsp)
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rdi
testq %rdi, %rdi
je 0x15f20e
callq 0x2db30
movl $0x1, %eax
movq %rax, 0x20(%rsp)
xorl %r13d, %r13d
xorl %ebx, %ebx
xorl %eax, %eax
movl %eax, %r14d
testl %r14d, %r14d
jne 0x15f576
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rdi
movl $0x1, %edx
leaq 0x7(%rsp), %rsi
callq 0x2e260
testl %eax, %eax
je 0x15f4a9
cmpl $0x2, %ebx
jne 0x15f2e7
movzbl 0x7(%rsp), %eax
cmpl $0x3e, %eax
jne 0x15f347
testq %r13, %r13
movq 0x8(%rsp), %rbx
je 0x15f416
testq %rbp, %rbp
je 0x15f2ad
movq %r15, %rdi
callq 0x2fe50
testq %rax, %rax
je 0x15f5c2
movq %r15, %rdi
callq 0x31b20
movq %rax, %r14
movq %r15, %rdi
callq 0x2fe50
movq %r14, %rdi
movq %rax, %rsi
movq 0x10(%rsp), %rdx
movq %rbx, %rcx
callq *%rbp
testl %eax, %eax
jne 0x15f2dd
movq %r15, %rdi
callq 0x316e0
xorl %r14d, %r14d
movl $0x0, %eax
testq %r12, %r12
je 0x15f2d0
movq %r13, %rdi
movq 0x10(%rsp), %rsi
movq %rbx, %rdx
callq *%r12
movl $0x1, %ebx
testl %eax, %eax
je 0x15f222
movl $0x2, %ebx
jmp 0x15f21f
cmpl $0x1, %ebx
jne 0x15f3cc
movb 0x7(%rsp), %cl
cmpb $0xa, %cl
jne 0x15f44b
cmpq $0x0, 0x30(%rsp)
je 0x15f497
movq 0x28(%rsp), %rbx
movq %rbx, %rdi
callq 0x31b20
movq %rax, %r14
movq %rbx, %rdi
callq 0x2fe50
movq %r14, %rdi
movq %rax, %rsi
movq 0x10(%rsp), %rdx
movq 0x8(%rsp), %rcx
callq *0x30(%rsp)
movl $0x1, %ebx
testl %eax, %eax
jne 0x15f21f
jmp 0x15f48d
cmpl $0xa, %eax
je 0x15f476
incq %r13
movl $0x2, %ebx
movl $0x0, %eax
testq %rbp, %rbp
je 0x15f21f
movq %r15, %rdi
callq 0x2fe50
cmpq $0x2000, %rax           # imm = 0x2000
jne 0x15f3ab
movq %r15, %rdi
callq 0x31b20
movq %rax, %r14
movq %r15, %rdi
callq 0x2fe50
movq %r14, %rdi
movq %rax, %rsi
movq 0x10(%rsp), %rdx
movq 0x8(%rsp), %rcx
callq *%rbp
testl %eax, %eax
jne 0x15f21f
movq %r15, %rdi
callq 0x316e0
movzbl 0x7(%rsp), %ecx
movl $0x0, %eax
cmpl $0xd, %ecx
je 0x15f21f
cmpl $0x20, %ecx
je 0x15f21f
jmp 0x15f47d
movl $0x1, %ebx
cmpb $0x3e, 0x7(%rsp)
movl $0x0, %eax
je 0x15f21f
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x31b20
xorl %ebx, %ebx
movq 0x8(%rsp), %rdi
leaq 0x1eaba6(%rip), %rsi    # 0x349fa3
movq %rax, %rdx
movl $0x3e, %ecx
xorl %eax, %eax
callq 0x2f9e0
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x15f21f
movq 0x20(%rsp), %rax
testq %rax, %rax
je 0x15f5d6
leaq -0x1(%rax), %rdx
movq %rbx, %rdi
leaq 0x1eabb4(%rip), %rsi    # 0x349fe6
xorl %eax, %eax
callq 0x2f9e0
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl $0x2, %ebx
xorl %r13d, %r13d
jmp 0x15f21f
cmpq $0x0, 0x30(%rsp)
sete %al
cmpb $0xd, %cl
sete %dl
movl $0x1, %ebx
orb %al, %dl
movl $0x0, %eax
jne 0x15f21f
movsbl %cl, %esi
movq 0x28(%rsp), %rdi
jmp 0x15f483
incq 0x20(%rsp)
jmp 0x15f49f
movsbl %cl, %esi
movq %r15, %rdi
callq 0x31390
jmp 0x15f21d
movq 0x28(%rsp), %rdi
callq 0x316e0
incq 0x20(%rsp)
xorl %r13d, %r13d
movl $0x2, %ebx
jmp 0x15f21d
cmpl $0x2, %ebx
je 0x15f4e1
cmpl $0x1, %ebx
jne 0x15f52a
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x31b20
leaq 0x1eab6d(%rip), %rsi    # 0x34a035
movq 0x8(%rsp), %rdi
movq 0x20(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x2f9e0
jmp 0x15f570
testq %r13, %r13
je 0x15f54c
testq %rbp, %rbp
je 0x15f59a
movq %r15, %rdi
callq 0x2fe50
testq %rax, %rax
je 0x15f5db
movq %r15, %rdi
callq 0x31b20
movq %rax, %rbx
movq %r15, %rdi
callq 0x2fe50
movq %rbx, %rdi
movq %rax, %rsi
movq 0x10(%rsp), %rdx
movq 0x8(%rsp), %rcx
callq *%rbp
movl %eax, %r14d
jmp 0x15f59d
movq 0x8(%rsp), %rbx
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x31b20
leaq 0x1eaad5(%rip), %rsi    # 0x34a019
movq %rbx, %rdi
movq %rax, %rdx
jmp 0x15f569
movq 0x20(%rsp), %rdx
testq %rdx, %rdx
movq 0x8(%rsp), %rdi
je 0x15f5e0
decq %rdx
leaq 0x1eaa7d(%rip), %rsi    # 0x349fe6
xorl %eax, %eax
callq 0x2f9e0
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
movq %r15, %rdi
callq 0x31fe0
movq 0x28(%rsp), %rdi
callq 0x31fe0
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 0x15f576
movq %r13, %rdi
movq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdx
callq *%r12
movl %eax, %r14d
jmp 0x15f576
callq 0x424e0
callq 0x425c0
callq 0x424a9
callq 0x42472
callq 0x42517
callq 0x4254e
callq 0x42587