// File: /workspace/github_cpp_makefile_star2_O2/sundale[P]gcode/inifile.cc
// Function: IniFile::Find(char const*, char const*, int)
const char *
IniFile::Find(const char *_tag, const char *_section, int _num)
{
    // WTF, return a pointer to the middle of a local buffer?
    // FIX: this is totally non-reentrant.
    static char                 line[LINELEN + 2] = "";        /* 1 for newline, 1 for NULL */
    char                        bracketSection[LINELEN + 2] = "";
    char                        *nonWhite;
    int                         newLinePos;                /* position of newline to strip */
    int                         len;
    char                        tagEnd;
    char                        *valueString;
    char                        *endValueString;

    // For exceptions.
    lineNo = 0;
    tag = _tag;
    section = _section;
    num = _num;

    /* check valid file */
    if(!CheckIfOpen())
        return(NULL);

    /* start from beginning */
    rewind(fp);

    /* check for section first-- if it's non-NULL, then position file at
       line after [section] */
    if(section != NULL){
        sprintf(bracketSection, "[%s]", section);

        /* find [section], and position fp just after it */
        while (!feof(fp)) {

            if (NULL == fgets(line, LINELEN + 1, fp)) {
                /* got to end of file without finding it */
                ThrowException(ERR_SECTION_NOT_FOUND);
                return(NULL);
            }

            if(check_line_endings(line)) {
                ThrowException(ERR_CONVERSION);
                return(NULL);
            }

            /* got a line */
            lineNo++;

            /* strip off newline */
            newLinePos = strlen(line) - 1;        /* newline is on back from 0 */
            if (newLinePos < 0) {
                newLinePos = 0;
            }
            if (line[newLinePos] == '\n') {
                line[newLinePos] = 0;        /* make the newline 0 */
            }

            if (NULL == (nonWhite = SkipWhite(line))) {
                /* blank line-- skip */
                continue;
            }

            /* not a blank line, and nonwhite is first char */
            if (strncmp(bracketSection, nonWhite, strlen(bracketSection)) != 0){
                /* not on this line */
                continue;
            }

            /* it matches-- fp is now set up for search on tag */
            break;
        }
    }

    while (!feof(fp)) {
        /* check for end of file */
        if (NULL == fgets(line, LINELEN + 1, (FILE *) fp)) {
            /* got to end of file without finding it */
            ThrowException(ERR_TAG_NOT_FOUND);
            return(NULL);
        }

        if(check_line_endings(line)) {
            ThrowException(ERR_CONVERSION);
            return(NULL);
        }

        /* got a line */
        lineNo++;

        /* strip off newline */
        newLinePos = strlen(line) - 1;        /* newline is on back from 0 */
        if (newLinePos < 0) {
            newLinePos = 0;
        }
        if (line[newLinePos] == '\n') {
            line[newLinePos] = 0;        /* make the newline 0 */
        }

        /* skip leading whitespace */
        if (NULL == (nonWhite = SkipWhite(line))) {
            /* blank line-- skip */
            continue;
        }

        /* check for '[' char-- if so, it's a section tag, and we're out
           of our section */
        if (NULL != section && nonWhite[0] == '[') {
            ThrowException(ERR_TAG_NOT_FOUND);
            return(NULL);
        }

        len = strlen(tag);
        if (strncmp(tag, nonWhite, len) != 0) {
            /* not on this line */
            continue;
        }

        /* it matches the first part of the string-- if whitespace or = is
           next char then call it a match */
        tagEnd = nonWhite[len];
        if (tagEnd == ' ' || tagEnd == '\r' || tagEnd == '\t'
            || tagEnd == '\n' || tagEnd == '=') {
            /* it matches-- return string after =, or NULL */
            if (--_num > 0) {
                /* Not looking for this one, so skip it... */
                continue;
            }
            nonWhite += len;
            valueString = AfterEqual(nonWhite);
            /* Eliminate white space at the end of a line also. */
            if (NULL == valueString) {
                ThrowException(ERR_TAG_NOT_FOUND);
                return(NULL);
            }
            endValueString = valueString + strlen(valueString) - 1;
            while (*endValueString == ' ' || *endValueString == '\t'
                   || *endValueString == '\r') {
                *endValueString = 0;
                endValueString--;
            }
            return(valueString);
        }
        /* else continue */
    }

    ThrowException(ERR_TAG_NOT_FOUND);
    return(NULL);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movl %ecx, %r14d
movq %rdx, %r15
movq %rsi, %r13
movq %rdi, %rbx
leaq -0x140(%rbp), %rdi
xorl %r12d, %r12d
movl $0x101, %edx            # imm = 0x101
xorl %esi, %esi
callq 0x40e0
andl $0x0, 0x54(%rbx)
movq %r13, 0x58(%rbx)
movq %r15, 0x60(%rbx)
movq %r14, -0x30(%rbp)
movl %r14d, 0x68(%rbx)
movq %rbx, %rdi
callq 0x50c6
testb %al, %al
je 0x4e5c
movq (%rbx), %rdi
callq 0x4040
movq 0x60(%rbx), %rdx
testq %rdx, %rdx
je 0x4d22
leaq 0x4431(%rip), %rsi      # 0x90bd
xorl %r14d, %r14d
leaq -0x140(%rbp), %r12
movq %r12, %rdi
xorl %eax, %eax
callq 0x4060
leaq 0x9539(%rip), %r13      # 0xe1e0
movq (%rbx), %rdi
callq 0x4250
testl %eax, %eax
jne 0x4d22
movq (%rbx), %rdx
movq %r13, %rdi
movl $0x100, %esi            # imm = 0x100
callq 0x4280
testq %rax, %rax
je 0x4e4e
callq 0x50e9
testb %al, %al
jne 0x4e4a
incl 0x54(%rbx)
movq %r13, %rdi
callq 0x40a0
decl %eax
testl %eax, %eax
cmovlel %r14d, %eax
cmpb $0xa, (%rax,%r13)
jne 0x4cf8
movb $0x0, (%rax,%r13)
movq %r13, %rsi
callq 0x518a
testq %rax, %rax
je 0x4ca7
movq %rax, %r15
movq %r12, %rdi
callq 0x40a0
movq %r12, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x40b0
testl %eax, %eax
jne 0x4ca7
leaq 0x94b7(%rip), %r12      # 0xe1e0
movq (%rbx), %rdi
callq 0x4250
testl %eax, %eax
jne 0x4e46
movq (%rbx), %rdx
movq %r12, %rdi
movl $0x100, %esi            # imm = 0x100
callq 0x4280
testq %rax, %rax
je 0x4e46
callq 0x50e9
testb %al, %al
jne 0x4e4a
incl 0x54(%rbx)
movq %r12, %rdi
callq 0x40a0
decl %eax
testl %eax, %eax
movl $0x0, %ecx
cmovlel %ecx, %eax
cmpb $0xa, (%rax,%r12)
jne 0x4d82
movb $0x0, (%rax,%r12)
movq %r12, %rsi
callq 0x518a
testq %rax, %rax
je 0x4d29
movq %rax, %r13
cmpq $0x0, 0x60(%rbx)
je 0x4da4
cmpb $0x5b, (%r13)
je 0x4e46
movq 0x58(%rbx), %r14
movq %r14, %rdi
callq 0x40a0
movslq %eax, %r15
movq %r14, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0x40b0
testl %eax, %eax
jne 0x4d29
movzbl (%r13,%r15), %eax
cmpq $0x3d, %rax
ja 0x4d29
movabsq $0x2000000100002600, %rcx # imm = 0x2000000100002600
btq %rax, %rcx
jae 0x4d29
movq -0x30(%rbp), %rcx
leal -0x1(%rcx), %eax
cmpl $0x1, %ecx
movq %rax, -0x30(%rbp)
jg 0x4d29
addq %r15, %r13
movq %r13, %rsi
callq 0x51c4
testq %rax, %rax
pushq $0x4
popq %rsi
je 0x4e51
movq %rax, %r12
movq %rax, %rdi
callq 0x40a0
addq %r12, %rax
decq %rax
movabsq $0x100002200, %rcx      # imm = 0x100002200
movzbl (%rax), %edx
cmpq $0x20, %rdx
ja 0x4e5c
btq %rdx, %rcx
jae 0x4e5c
movb $0x0, (%rax)
decq %rax
jmp 0x4e2f
pushq $0x4
jmp 0x4e50
pushq $0x8
jmp 0x4e50
pushq $0x2
popq %rsi
movq %rbx, %rdi
callq 0x4e72
xorl %r12d, %r12d
movq %r12, %rax
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop