// File: /workspace/github_c_makefile_star2_O0/ttoobne[P]bohttpd/src/core/config.c
// Function: parse_configuration
config_t* parse_configuration(char* filename) {
    config_t* config;
    char buf[CONFBUF_SIZE] = { '\0' };
    FILE* fp;
    char* p;
    char* name_st;
    char* name_ed;
    char* value_st;
    char* value_ed;
    char ch;
    int have_name;
    int have_value;
    int line;

    /* 维护状态机来解析配置文件 */
    /* 按行读取，每行格式 [<name> = <value>] [#[...]] */
    enum {
        start,
        name,
        spaces_before_equal_sign,
        equal_sign,
        spaces_before_value,
        value,
        end,
    } state;

    do {
        if ((config = (config_t*)malloc(sizeof(config_t))) == NULL) {
            log_error("config_t malloc failed.");
            return NULL;
        }

        /* 设置配置默认值 */
        config->threadpool = THREADPOOL_DEF;
        config->taskqueue = TASKQUEUE_DEF;
        memset(config->root, 0, sizeof(config->root));
        memset(config->defile, 0, sizeof(config->defile));
        strncpy(config->root, ROOT_DEF, 2);
        strncpy(config->defile, DEFILE_DEF, 10);
        config->timeout = TIMEOUT_DEF;
        config->port = PORT_DEF;

        /* 只读打开配置文件 */
        if ((fp = fopen(filename, "r")) == NULL) {
            log_error("config file open failed.");
            break;
        }

        state = start;
        line = 0;
        
        while (fgets(buf, sizeof(buf), fp) != NULL) {
            line ++ ;

            for (p = buf; *p != '\0'; ++ p) {
                ch = *p;

                switch (state) {
                case start:
                    have_name = 0;
                    have_value = 0;

                    if (ch == ' ' || ch == '\t') {
                        break;
                    }

                    if (ch == '#' || ch == '\n') {
                        state = end;
                        p -- ;
                        break;
                    }

                    if (!isalpha(ch) && !isdigit(ch)) {
                        if (!iscntrl(ch)) {
                            log_warn("line %d in configuration file: unrecognized syntax or character '%c'.", line, ch);
                        } else {
                            log_warn("line %d in configuration file: unrecognized syntax or character '0x%x'.", line, ch);
                        }
                        state = end;
                        p -- ;
                        break;
                    }

                    name_st = p;
                    state = name;

                    break;
                
                case name:
                    if (ch == ' ' || ch == '\t') {
                        name_ed = p - 1;
                        have_name = 1;
                        state = spaces_before_equal_sign;
                        break;
                    }

                    if (ch == '=') {
                        name_ed = p - 1;
                        have_name = 1;
                        state = spaces_before_value;
                        break;
                    }

                    if (!isalpha(ch) && !isdigit(ch)) {
                        if (!iscntrl(ch)) {
                            log_warn("line %d in configuration file: unrecognized syntax or character '%c'.", line, ch);
                        } else {
                            log_warn("line %d in configuration file: unrecognized syntax or character '0x%x'.", line, ch);
                        }
                        state = end;
                        p -- ;
                        break;
                    }

                    break;

                case spaces_before_equal_sign:
                    if (ch == ' ' || ch == '\t') {
                        break;
                    }

                    if (ch == '=') {
                        state = spaces_before_value;
                        break;
                    }
                    
                    if (!iscntrl(ch)) {
                        log_warn("line %d in configuration file: unrecognized syntax or character '%c'.", line, ch);
                    } else {
                        log_warn("line %d in configuration file: unrecognized syntax or character '0x%x'.", line, ch);
                    }
                    state = end;
                    p -- ;
                    break;

                case spaces_before_value:
                    if (ch == ' ' || ch == '\t') {
                        break;
                    }

                    value_st = p;
                    state = value;

                    break;

                case value:
                    if (ch == ' ' || ch == '\t' || ch == '#' || ch == '\n') {
                        value_ed = p - 1;
                        have_value = 1;
                        state = end;
                        p -- ;
                        break;
                    }

                    break;

                case end:
                    *(p + 1) = '\0';
                    state = start;

                    if (have_name != have_value) {
                        log_warn("line %d in configuration file: unrecognized syntax .", line);
                        break;
                    }

                    if (have_name) {
                        if (check_name_value(config, name_st, name_ed, value_st, value_ed) != 0) {
                            log_warn("line %d in configuration file: unrecognized identifier or value.", line);
                            break;
                        }
                    }

                    break;

                default:
                    break;
                }
            }
        }

        fclose(fp);
        fp = NULL;

        return config;

    } while(0);
    
    if (fp != NULL) {
        fclose(fp);
        fp = NULL;
    }

    config_destroy(config);

    return NULL;
    
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x480, %rsp            # imm = 0x480
movq %rdi, -0x10(%rbp)
leaq -0x420(%rbp), %rdi
xorl %esi, %esi
movl $0x400, %edx            # imm = 0x400
callq 0x21d0
movl $0x218, %edi            # imm = 0x218
callq 0x22f0
movq %rax, -0x18(%rbp)
cmpq $0x0, %rax
jne 0x2bd9
movl $0x4, %edi
leaq 0x6746(%rip), %rsi      # 0x92f8
leaq 0x6751(%rip), %rdx      # 0x930a
movl $0x31, %ecx
leaq 0x6759(%rip), %r8       # 0x931e
movb $0x0, %al
callq 0x6450
movq $0x0, -0x8(%rbp)
jmp 0x3307
movq -0x18(%rbp), %rax
movl $0x40, (%rax)
movq -0x18(%rbp), %rax
movl $0x20, 0x4(%rax)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
xorl %esi, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x21d0
movq -0x18(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
xorl %esi, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x21d0
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
leaq 0x670e(%rip), %rsi      # 0x9336
movl $0x2, %edx
callq 0x2060
movq -0x18(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
leaq 0x66fa(%rip), %rsi      # 0x933e
movl $0xa, %edx
callq 0x2060
movq -0x18(%rbp), %rax
movq $0x3e8, 0x208(%rax) # imm = 0x3E8
movq -0x18(%rbp), %rax
movw $0x50, 0x210(%rax)
movq -0x10(%rbp), %rdi
leaq 0x7076(%rip), %rsi      # 0x9ceb
callq 0x23c0
movq %rax, -0x428(%rbp)
cmpq $0x0, %rax
jne 0x2cb2
movl $0x4, %edi
leaq 0x6665(%rip), %rsi      # 0x92f8
leaq 0x6670(%rip), %rdx      # 0x930a
movl $0x41, %ecx
leaq 0x66a3(%rip), %r8       # 0x9349
movb $0x0, %al
callq 0x6450
jmp 0x32d5
movl $0x0, -0x464(%rbp)
movl $0x0, -0x460(%rbp)
leaq -0x420(%rbp), %rdi
movq -0x428(%rbp), %rdx
movl $0x400, %esi            # imm = 0x400
callq 0x2230
cmpq $0x0, %rax
je 0x32b4
movl -0x460(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x460(%rbp)
leaq -0x420(%rbp), %rax
movq %rax, -0x430(%rbp)
movq -0x430(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
je 0x32af
movq -0x430(%rbp), %rax
movb (%rax), %al
movb %al, -0x451(%rbp)
movl -0x464(%rbp), %eax
movq %rax, -0x470(%rbp)
subq $0x6, %rax
ja 0x3294
movq -0x470(%rbp), %rax
leaq 0x6574(%rip), %rcx      # 0x92c0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x0, -0x458(%rbp)
movl $0x0, -0x45c(%rbp)
movsbl -0x451(%rbp), %eax
cmpl $0x20, %eax
je 0x2d81
movsbl -0x451(%rbp), %eax
cmpl $0x9, %eax
jne 0x2d86
jmp 0x3296
movsbl -0x451(%rbp), %eax
cmpl $0x23, %eax
je 0x2d9e
movsbl -0x451(%rbp), %eax
cmpl $0xa, %eax
jne 0x2dbf
movl $0x6, -0x464(%rbp)
movq -0x430(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x430(%rbp)
jmp 0x3296
callq 0x24b0
movq (%rax), %rax
movsbl -0x451(%rbp), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x400, %eax            # imm = 0x400
cmpl $0x0, %eax
jne 0x2eb6
callq 0x24b0
movq (%rax), %rax
movsbl -0x451(%rbp), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
jne 0x2eb6
callq 0x24b0
movq (%rax), %rax
movsbl -0x451(%rbp), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x2e5e
movl -0x460(%rbp), %r9d
movsbl -0x451(%rbp), %eax
movl $0x3, %edi
leaq 0x64b9(%rip), %rsi      # 0x92f8
leaq 0x64c4(%rip), %rdx      # 0x930a
movl $0x5f, %ecx
leaq 0x6510(%rip), %r8       # 0x9362
movl %eax, (%rsp)
movb $0x0, %al
callq 0x6450
jmp 0x2e95
movl -0x460(%rbp), %r9d
movsbl -0x451(%rbp), %eax
movl $0x3, %edi
leaq 0x6480(%rip), %rsi      # 0x92f8
leaq 0x648b(%rip), %rdx      # 0x930a
movl $0x61, %ecx
leaq 0x651d(%rip), %r8       # 0x93a8
movl %eax, (%rsp)
movb $0x0, %al
callq 0x6450
movl $0x6, -0x464(%rbp)
movq -0x430(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x430(%rbp)
jmp 0x3296
movq -0x430(%rbp), %rax
movq %rax, -0x438(%rbp)
movl $0x1, -0x464(%rbp)
jmp 0x3296
movsbl -0x451(%rbp), %eax
cmpl $0x20, %eax
je 0x2eeb
movsbl -0x451(%rbp), %eax
cmpl $0x9, %eax
jne 0x2f16
movq -0x430(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x440(%rbp)
movl $0x1, -0x458(%rbp)
movl $0x2, -0x464(%rbp)
jmp 0x3296
movsbl -0x451(%rbp), %eax
cmpl $0x3d, %eax
jne 0x2f4d
movq -0x430(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x440(%rbp)
movl $0x1, -0x458(%rbp)
movl $0x4, -0x464(%rbp)
jmp 0x3296
callq 0x24b0
movq (%rax), %rax
movsbl -0x451(%rbp), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x400, %eax            # imm = 0x400
cmpl $0x0, %eax
jne 0x3044
callq 0x24b0
movq (%rax), %rax
movsbl -0x451(%rbp), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
jne 0x3044
callq 0x24b0
movq (%rax), %rax
movsbl -0x451(%rbp), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x2fec
movl -0x460(%rbp), %r9d
movsbl -0x451(%rbp), %eax
movl $0x3, %edi
leaq 0x632b(%rip), %rsi      # 0x92f8
leaq 0x6336(%rip), %rdx      # 0x930a
movl $0x7e, %ecx
leaq 0x6382(%rip), %r8       # 0x9362
movl %eax, (%rsp)
movb $0x0, %al
callq 0x6450
jmp 0x3023
movl -0x460(%rbp), %r9d
movsbl -0x451(%rbp), %eax
movl $0x3, %edi
leaq 0x62f2(%rip), %rsi      # 0x92f8
leaq 0x62fd(%rip), %rdx      # 0x930a
movl $0x80, %ecx
leaq 0x638f(%rip), %r8       # 0x93a8
movl %eax, (%rsp)
movb $0x0, %al
callq 0x6450
movl $0x6, -0x464(%rbp)
movq -0x430(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x430(%rbp)
jmp 0x3296
jmp 0x3296
movsbl -0x451(%rbp), %eax
cmpl $0x20, %eax
je 0x3061
movsbl -0x451(%rbp), %eax
cmpl $0x9, %eax
jne 0x3066
jmp 0x3296
movsbl -0x451(%rbp), %eax
cmpl $0x3d, %eax
jne 0x3081
movl $0x4, -0x464(%rbp)
jmp 0x3296
callq 0x24b0
movq (%rax), %rax
movsbl -0x451(%rbp), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x30d8
movl -0x460(%rbp), %r9d
movsbl -0x451(%rbp), %eax
movl $0x3, %edi
leaq 0x623f(%rip), %rsi      # 0x92f8
leaq 0x624a(%rip), %rdx      # 0x930a
movl $0x94, %ecx
leaq 0x6296(%rip), %r8       # 0x9362
movl %eax, (%rsp)
movb $0x0, %al
callq 0x6450
jmp 0x310f
movl -0x460(%rbp), %r9d
movsbl -0x451(%rbp), %eax
movl $0x3, %edi
leaq 0x6206(%rip), %rsi      # 0x92f8
leaq 0x6211(%rip), %rdx      # 0x930a
movl $0x96, %ecx
leaq 0x62a3(%rip), %r8       # 0x93a8
movl %eax, (%rsp)
movb $0x0, %al
callq 0x6450
movl $0x6, -0x464(%rbp)
movq -0x430(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x430(%rbp)
jmp 0x3296
movsbl -0x451(%rbp), %eax
cmpl $0x20, %eax
je 0x3148
movsbl -0x451(%rbp), %eax
cmpl $0x9, %eax
jne 0x314d
jmp 0x3296
movq -0x430(%rbp), %rax
movq %rax, -0x448(%rbp)
movl $0x5, -0x464(%rbp)
jmp 0x3296
movsbl -0x451(%rbp), %eax
cmpl $0x20, %eax
je 0x319a
movsbl -0x451(%rbp), %eax
cmpl $0x9, %eax
je 0x319a
movsbl -0x451(%rbp), %eax
cmpl $0x23, %eax
je 0x319a
movsbl -0x451(%rbp), %eax
cmpl $0xa, %eax
jne 0x31d7
movq -0x430(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x450(%rbp)
movl $0x1, -0x45c(%rbp)
movl $0x6, -0x464(%rbp)
movq -0x430(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x430(%rbp)
jmp 0x3296
jmp 0x3296
movq -0x430(%rbp), %rax
movb $0x0, 0x1(%rax)
movl $0x0, -0x464(%rbp)
movl -0x458(%rbp), %eax
cmpl -0x45c(%rbp), %eax
je 0x322e
movl -0x460(%rbp), %r9d
movl $0x3, %edi
leaq 0x60e6(%rip), %rsi      # 0x92f8
leaq 0x60f1(%rip), %rdx      # 0x930a
movl $0xb6, %ecx
leaq 0x61cb(%rip), %r8       # 0x93f0
movb $0x0, %al
callq 0x6450
jmp 0x3296
cmpl $0x0, -0x458(%rbp)
je 0x3292
movq -0x18(%rbp), %rdi
movq -0x438(%rbp), %rsi
movq -0x440(%rbp), %rdx
movq -0x448(%rbp), %rcx
movq -0x450(%rbp), %r8
callq 0x3320
cmpl $0x0, %eax
je 0x3290
movl -0x460(%rbp), %r9d
movl $0x3, %edi
leaq 0x6084(%rip), %rsi      # 0x92f8
leaq 0x608f(%rip), %rdx      # 0x930a
movl $0xbc, %ecx
leaq 0x619e(%rip), %r8       # 0x9425
movb $0x0, %al
callq 0x6450
jmp 0x3296
jmp 0x3292
jmp 0x3296
jmp 0x3296
jmp 0x3298
movq -0x430(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x430(%rbp)
jmp 0x2d05
jmp 0x2cc6
movq -0x428(%rbp), %rdi
callq 0x2120
movq $0x0, -0x428(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x3307
cmpq $0x0, -0x428(%rbp)
je 0x32f6
movq -0x428(%rbp), %rdi
callq 0x2120
movq $0x0, -0x428(%rbp)
movq -0x18(%rbp), %rdi
callq 0x3620
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x480, %rsp            # imm = 0x480
popq %rbp
retq
nopw %cs:(%rax,%rax)