// File: /workspace/github_c_makefile_star2_O1/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 $0x48, %rsp
movq %r9, %rbx
movq %r8, 0x18(%rsp)
movq %rcx, %r12
movq %rdx, %rbp
movq %rsi, %r14
movq %rdi, %rsi
leaq 0x328903(%rip), %rdi    # 0x48c4e0
callq 0x163b91
movq %rax, 0x20(%rsp)
testq %rbx, %rbx
je 0x163bfc
movq %rbx, %rdi
callq 0x310f0
testb %al, %al
jne 0x16401a
cmpq $0x0, 0x20(%rsp)
je 0x164010
callq 0x30600
movq %rax, 0x30(%rsp)
callq 0x30600
movq %rax, %r15
movq %r14, %rax
orq %rbp, %rax
orq %r12, %rax
je 0x164015
movq %r14, 0x38(%rsp)
movq %rbx, 0x10(%rsp)
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rdi
testq %rdi, %rdi
je 0x163c46
callq 0x2db30
movl $0x1, %eax
movq %rax, 0x28(%rsp)
xorl %r13d, %r13d
xorl %ebx, %ebx
xorl %eax, %eax
movl %eax, %r14d
testl %r14d, %r14d
jne 0x163fbf
movq 0x20(%rsp), %rax
movq 0x10(%rax), %rdi
movl $0x1, %edx
leaq 0xf(%rsp), %rsi
callq 0x2e260
testl %eax, %eax
je 0x163eeb
cmpl $0x2, %ebx
jne 0x163d23
movzbl 0xf(%rsp), %eax
cmpl $0x3e, %eax
jne 0x163d96
testq %r13, %r13
je 0x163e60
testq %rbp, %rbp
movq 0x10(%rsp), %rbx
je 0x163ce3
movq %r15, %rdi
callq 0x2fe50
testq %rax, %rax
je 0x16400b
movq %r15, %rdi
callq 0x31b20
movq %rax, %r14
movq %r15, %rdi
callq 0x2fe50
movq %r14, %rdi
movq %rax, %rsi
movq 0x18(%rsp), %rdx
movq %rbx, %rcx
callq *%rbp
jmp 0x163ce5
xorl %eax, %eax
testl %eax, %eax
jne 0x163d19
movq %r15, %rdi
callq 0x316e0
xorl %r14d, %r14d
movl $0x0, %eax
testq %r12, %r12
je 0x163d0c
movq %r13, %rdi
movq 0x18(%rsp), %rsi
movq %rbx, %rdx
callq *%r12
movl $0x1, %ebx
testl %eax, %eax
je 0x163c5a
movl $0x2, %ebx
jmp 0x163c57
cmpl $0x1, %ebx
jne 0x163e16
movb 0xf(%rsp), %cl
cmpb $0xa, %cl
jne 0x163e97
xorl %eax, %eax
movq 0x38(%rsp), %r14
testq %r14, %r14
je 0x163d84
movq 0x30(%rsp), %rbx
movq %rbx, %rdi
callq 0x31b20
movq %rax, 0x40(%rsp)
movq %rbx, %rdi
callq 0x2fe50
movq 0x40(%rsp), %rdi
movq %rax, %rsi
movq 0x18(%rsp), %rdx
movq 0x10(%rsp), %rcx
callq *%r14
testl %eax, %eax
jne 0x163d84
movq 0x30(%rsp), %rdi
callq 0x316e0
xorl %eax, %eax
movl $0x1, %ebx
testl %eax, %eax
jne 0x163c57
jmp 0x163ed1
cmpl $0xa, %eax
je 0x163ec2
incq %r13
movl $0x0, %eax
testq %rbp, %rbp
je 0x163c57
movq %r15, %rdi
callq 0x2fe50
cmpq $0x2000, %rax           # imm = 0x2000
jne 0x163df5
movq %r15, %rdi
callq 0x31b20
movq %rax, %r14
movq %r15, %rdi
callq 0x2fe50
movq %r14, %rdi
movq %rax, %rsi
movq 0x18(%rsp), %rdx
movq 0x10(%rsp), %rcx
callq *%rbp
testl %eax, %eax
jne 0x163c57
movq %r15, %rdi
callq 0x316e0
movzbl 0xf(%rsp), %ecx
movl $0x0, %eax
cmpl $0xd, %ecx
je 0x163c57
cmpl $0x20, %ecx
je 0x163c57
jmp 0x163edb
movl $0x1, %ebx
cmpb $0x3e, 0xf(%rsp)
movl $0x0, %eax
je 0x163c57
movq 0x20(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x31b20
xorl %ebx, %ebx
movq 0x10(%rsp), %rdi
leaq 0x1ef25c(%rip), %rsi    # 0x3530a3
movq %rax, %rdx
movl $0x3e, %ecx
xorl %eax, %eax
callq 0x2f9e0
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x163c57
movq 0x28(%rsp), %rax
testq %rax, %rax
movq 0x10(%rsp), %rdi
je 0x16401f
leaq -0x1(%rax), %rdx
leaq 0x1ef268(%rip), %rsi    # 0x3530e6
xorl %eax, %eax
callq 0x2f9e0
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl $0x2, %ebx
xorl %r13d, %r13d
jmp 0x163c57
cmpq $0x0, 0x38(%rsp)
sete %al
cmpb $0xd, %cl
sete %dl
movl $0x1, %ebx
orb %al, %dl
movl $0x0, %eax
jne 0x163c57
movsbl %cl, %esi
movq 0x30(%rsp), %rdi
jmp 0x163ee1
incq 0x28(%rsp)
movl $0x2, %ebx
jmp 0x163c55
incq 0x28(%rsp)
xorl %r13d, %r13d
jmp 0x163ec7
movsbl %cl, %esi
movq %r15, %rdi
callq 0x31390
jmp 0x163c55
leal -0x2(%rbx), %eax
cmpl $0x2, %eax
jae 0x163f43
testq %r13, %r13
je 0x163f95
testq %rbp, %rbp
je 0x163fe3
movq %r15, %rdi
callq 0x2fe50
testq %rax, %rax
je 0x164024
movq %r15, %rdi
callq 0x31b20
movq %rax, %rbx
movq %r15, %rdi
callq 0x2fe50
movq %rbx, %rdi
movq %rax, %rsi
movq 0x18(%rsp), %rdx
movq 0x10(%rsp), %rcx
callq *%rbp
movl %eax, %r14d
jmp 0x163fe6
cmpl $0x1, %ebx
jne 0x163f73
movq 0x20(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x31b20
leaq 0x1ef1d8(%rip), %rsi    # 0x353135
movq 0x10(%rsp), %rdi
movq 0x28(%rsp), %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x2f9e0
jmp 0x163fb9
movq 0x10(%rsp), %rbx
movq 0x20(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x31b20
leaq 0x1ef18c(%rip), %rsi    # 0x353119
movq %rbx, %rdi
movq %rax, %rdx
jmp 0x163fb2
movq 0x28(%rsp), %rdx
testq %rdx, %rdx
movq 0x10(%rsp), %rdi
je 0x164029
decq %rdx
leaq 0x1ef134(%rip), %rsi    # 0x3530e6
xorl %eax, %eax
callq 0x2f9e0
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
movq %r15, %rdi
callq 0x31fe0
movq 0x30(%rsp), %rdi
callq 0x31fe0
movl %r14d, %eax
addq $0x48, %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 0x163fbf
movq %r13, %rdi
movq 0x18(%rsp), %rsi
movq 0x10(%rsp), %rdx
callq *%r12
movl %eax, %r14d
jmp 0x163fbf
callq 0x42978
callq 0x42a58
callq 0x42941
callq 0x4290a
callq 0x429af
callq 0x429e6
callq 0x42a1f