// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/redis-check-aof.c
// Function: process
off_t process(FILE *fp) {
    long argc;
    off_t pos = 0;
    int i, multi = 0;
    char *str;

    while(1) {

        // 定位到最后一个 MULTI 出现的偏移量
        if (!multi) pos = ftello(fp);

        // 读取参数的个数
        if (!readArgc(fp, &argc)) break;

        // 遍历各个参数
        // 参数包括命令以及命令参数
        // 比如 SET key value 
        // SET 就是第一个参数，而 key 和 value 就是第二和第三个参数
        for (i = 0; i < argc; i++) {

            // 读取参数
            if (!readString(fp,&str)) break;

            // 检查命令是否 MULTI 或者 EXEC
            if (i == 0) {
                if (strcasecmp(str, "multi") == 0) {
                    // 记录一个 MULTI 
                    // 如果前面已经有一个 MULTI ，那么报错（MULTI 不应该嵌套）
                    if (multi++) {
                        ERROR("Unexpected MULTI");
                        break;
                    }
                } else if (strcasecmp(str, "exec") == 0) {
                    // 清除一个 MULTI 记录
                    // 如果前面没有 MULTI ，那么报错（MULTI 和 EXEC 应该一对对出现）
                    if (--multi) {
                        ERROR("Unexpected EXEC");
                        break;
                    }
                }
            }

            // 释放
            free(str);
        }

        /* Stop if the loop did not finish 
         *
         * 如果 for 循环没有正常结束，那么跳出 while
         */
        if (i < argc) {
            if (str) free(str);
            break;
        }
    }

    // 文件读取完了，但是没有找到和 MULTI 对应的 EXEC
    if (feof(fp) && multi && strlen(error) == 0) {
        ERROR("Reached EOF before reading EXEC for MULTI");
    }

    // 如果有错误出现，那么打印错误
    if (strlen(error) > 0) {
        printf("%s\n", error);
    }

    // 返回偏移量
    return pos;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x428, %rsp            # imm = 0x428
movq %rdi, %r14
xorl %ebx, %ebx
leaq 0x18(%rsp), %r15
movq $0x0, 0x8(%rsp)
xorl %r12d, %r12d
testl %r12d, %r12d
jne 0x14b3
movq %r14, %rdi
callq 0x1090
movq %rax, 0x8(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x146f
testl %eax, %eax
je 0x1560
movq 0x18(%rsp), %rbp
testq %rbp, %rbp
cmovleq %rbx, %rbp
xorl %r13d, %r13d
cmpq %r13, %rbp
je 0x1547
movq %r14, %rdi
leaq 0x10(%rsp), %rsi
callq 0x13fb
testl %eax, %eax
je 0x1553
movq 0x10(%rsp), %r15
testq %r13, %r13
je 0x1508
movl %r12d, %ebx
movq %r15, %rdi
callq 0x1030
incq %r13
movl %ebx, %r12d
jmp 0x14d5
movq %r15, %rdi
leaq 0xb66(%rip), %rsi       # 0x2078
callq 0x1040
testl %eax, %eax
je 0x153a
movq %r15, %rdi
leaq 0xb6a(%rip), %rsi       # 0x208f
callq 0x1040
testl %eax, %eax
jne 0x14f5
xorl %ebx, %ebx
decl %r12d
je 0x14f8
jmp 0x160d
pushq $0x1
popq %rbx
testl %r12d, %r12d
je 0x14f8
jmp 0x15f5
xorl %ebx, %ebx
leaq 0x18(%rsp), %r15
jmp 0x14a1
movq 0x10(%rsp), %r15
movq %r15, %rdi
callq 0x1030
movq %r14, %rdi
callq 0x10c0
testl %eax, %eax
setne %al
testl %r12d, %r12d
setne %cl
andb %al, %cl
movb 0x2b55(%rip), %al       # 0x40d0
testb %al, %al
sete %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0x15ce
movups 0xb30(%rip), %xmm0      # 0x20be
leaq 0x20(%rsp), %rcx
movups %xmm0, 0x1a(%rcx)
movups 0xb16(%rip), %xmm0      # 0x20b4
movaps %xmm0, 0x10(%rcx)
movups 0xafb(%rip), %xmm0      # 0x20a4
movaps %xmm0, (%rcx)
movq 0x2f1d(%rip), %rdx      # 0x44d0
leaq 0x2b16(%rip), %rdi      # 0x40d0
leaq 0xa60(%rip), %rsi       # 0x2021
xorl %eax, %eax
callq 0x1130
movb 0x2b02(%rip), %al       # 0x40d0
testb %al, %al
je 0x15de
leaq 0x2af7(%rip), %rdi      # 0x40d0
callq 0x1050
movq 0x8(%rsp), %rax
addq $0x428, %rsp            # imm = 0x428
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
incl %r12d
movups 0xa7f(%rip), %xmm0      # 0x207e
leaq 0x20(%rsp), %rcx
movaps %xmm0, (%rcx)
movb $0x0, 0x10(%rcx)
jmp 0x161c
movups 0xa80(%rip), %xmm0      # 0x2094
leaq 0x20(%rsp), %rcx
movaps %xmm0, (%rcx)
movq 0x2ead(%rip), %rdx      # 0x44d0
leaq 0x2aa6(%rip), %rdi      # 0x40d0
leaq 0x9f0(%rip), %rsi       # 0x2021
xorl %eax, %eax
callq 0x1130
jmp 0x1558