// File: /workspace/github_c_makefile_star2_O3/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 %r15d, %r15d
leaq 0x18(%rsp), %rbx
xorl %r13d, %r13d
testl %r13d, %r13d
jne 0x14b6
movq %r14, %rdi
callq 0x1090
movq %rax, %r15
movq %r14, %rdi
movl $0x2a, %esi
movq %rbx, %rdx
callq 0x12bf
testl %eax, %eax
je 0x1563
movq 0x18(%rsp), %r12
testq %r12, %r12
jle 0x14a6
movq %r15, 0x8(%rsp)
xorl %r15d, %r15d
movl %r13d, %ebx
movq %r14, %rdi
leaq 0x10(%rsp), %rsi
callq 0x13ff
testl %eax, %eax
je 0x1568
movq 0x10(%rsp), %rbp
testq %r15, %r15
je 0x1513
movl %ebx, %r13d
movq %rbp, %rdi
callq 0x1030
incq %r15
cmpq %r15, %r12
jne 0x14e0
jmp 0x1554
movq %rbp, %rdi
leaq 0xb5b(%rip), %rsi       # 0x2078
callq 0x1040
testl %eax, %eax
je 0x1545
movq %rbp, %rdi
leaq 0xb5f(%rip), %rsi       # 0x208f
callq 0x1040
testl %eax, %eax
jne 0x14fe
xorl %r13d, %r13d
decl %ebx
je 0x1501
jmp 0x1628
movl $0x1, %r13d
testl %ebx, %ebx
je 0x1501
jmp 0x1611
movq 0x8(%rsp), %r15
leaq 0x18(%rsp), %rbx
jmp 0x14a6
movl %r13d, %ebx
jmp 0x157f
movq 0x10(%rsp), %rbp
testq %rbp, %rbp
je 0x157a
movq %rbp, %rdi
callq 0x1030
movq 0x8(%rsp), %r15
movq %r14, %rdi
callq 0x10c0
testl %eax, %eax
setne %al
testl %ebx, %ebx
setne %cl
andb %al, %cl
movb 0x2b37(%rip), %al       # 0x40d0
testb %al, %al
sete %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0x15ec
movups 0xb12(%rip), %xmm0      # 0x20be
leaq 0x20(%rsp), %rcx
movups %xmm0, 0x1a(%rcx)
movups 0xaf8(%rip), %xmm0      # 0x20b4
movaps %xmm0, 0x10(%rcx)
movups 0xadd(%rip), %xmm0      # 0x20a4
movaps %xmm0, (%rcx)
movq 0x2eff(%rip), %rdx      # 0x44d0
leaq 0x2af8(%rip), %rdi      # 0x40d0
leaq 0xa42(%rip), %rsi       # 0x2021
xorl %eax, %eax
callq 0x1130
movb 0x2ae4(%rip), %al       # 0x40d0
testb %al, %al
je 0x15fc
leaq 0x2ad9(%rip), %rdi      # 0x40d0
callq 0x1050
movq %r15, %rax
addq $0x428, %rsp            # imm = 0x428
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
incl %ebx
movups 0xa64(%rip), %xmm0      # 0x207e
leaq 0x20(%rsp), %rcx
movaps %xmm0, (%rcx)
movb $0x0, 0x10(%rcx)
jmp 0x1637
movups 0xa65(%rip), %xmm0      # 0x2094
leaq 0x20(%rsp), %rcx
movaps %xmm0, (%rcx)
movq 0x2e92(%rip), %rdx      # 0x44d0
leaq 0x2a8b(%rip), %rdi      # 0x40d0
leaq 0x9d5(%rip), %rsi       # 0x2021
xorl %eax, %eax
callq 0x1130
jmp 0x156d