// File: aquirel[P]reminder/reminder.cpp
// Function: main
int main(int argc, char *argv[])
{
    const char *rc_file_name = ".reminderrc";
    string rc_file_path;

    if (2 <= argc)
    {
        if (0 == strcmp("--help", argv[1]) ||
            0 == strcmp("-h", argv[1]))
        {
            printf("Usage: %s [.reminderrc]\n", argv[0]);
            return 0;
        }
        else
        {
            rc_file_path = argv[1];
        }
    }

    if (0 == rc_file_path.length())
    {
        rc_file_path = getenv("HOME") ?: ".";

        if ('/' != rc_file_path.back())
        {
            rc_file_path.append("/");
        }

        rc_file_path.append(rc_file_name);
    }

    vector<Person> persons;
    unsigned remind_before = 3; // In days.

    ifstream rc_file(rc_file_path);

    string remind_before_prefix = "remind_before",
           buf;

    while (rc_file.good())
    {
        getline(rc_file, buf, '\n');

        if (0 == buf.length() ||
            '#' == buf[0] ||
            ';' == buf[0])
        {
            continue;
        }

        if (equal(remind_before_prefix.begin(), remind_before_prefix.end(), buf.begin()))
        {
            buf = buf.substr(remind_before_prefix.length());
            while (0 < buf.length() && isspace(buf[0]))
            {
                buf.erase(0, 1);
            }

            if (0 < buf.length() && '=' == buf[0])
            {
                buf.erase(0, 1);

                if (0 < buf.length())
                {
                    remind_before = stoul(buf);
                }
            }
        }
        else
        {
            unsigned year, month, day;
            if (3 != sscanf(buf.c_str(), "%4u-%02u-%02u", &year, &month, &day))
            {
                continue;
            }

            tm birthday;
            memset(&birthday, 0, sizeof(birthday));

            birthday.tm_year = year - 1900;
            birthday.tm_mon = month - 1;
            birthday.tm_mday = day;

            if (-1 == mktime(&birthday))
            {
                continue;
            }

            auto delimiter = find_if(buf.begin(), buf.end(), [] (const char c) { return isspace(c); });
            if (buf.end() == delimiter)
            {
                continue;
            }

            buf = buf.substr(delimiter - buf.begin());

            while (0 < buf.length() && isspace(buf[0]))
            {
                buf.erase(0, 1);
            }

            while (0 < buf.length() && isspace(buf.back()))
            {
                buf.erase(buf.length() - 1, 1);
            }

            Person new_person {
                .birthday = birthday,
                .name = buf
            };

            persons.push_back(new_person);
        }
    }

    rc_file.close();

    time_t time_since_epoch = time(nullptr);
    tm now = *localtime(&time_since_epoch);

    for (unsigned shift = 0; shift <= remind_before; ++shift)
    {
        tm birthday = now;
        birthday.tm_mday += shift;
        mktime(&birthday);

        for (auto person = persons.begin(); person != persons.end(); ++person)
        {
            if (birthday.tm_mon == person->birthday.tm_mon &&
                birthday.tm_mday == person->birthday.tm_mday)
            {
                char buf[16];
                strftime(buf, sizeof(buf), "%F", &birthday);

                printf("%s has birthday on %s ", person->name.c_str(), buf);

                if (0 == shift)
                {
                    printf("(TODAY!). ");
                }
                else
                {
                    printf("(in %u days). ", shift);
                }

                printf("He/she becomes %u.\n", birthday.tm_year - person->birthday.tm_year);
            }
        }
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x530, %rsp            # imm = 0x530
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq 0x2b14(%rip), %rax      # 0x5014
movq %rax, -0x18(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x22f0
movl $0x2, %eax
cmpl -0x8(%rbp), %eax
jg 0x25a5
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0x2af6(%rip), %rdi      # 0x5020
callq 0x2300
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
je 0x2553
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0x2ae1(%rip), %rdi      # 0x5027
callq 0x2300
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x258e
movq -0x10(%rbp), %rax
movq (%rax), %rsi
leaq 0x2ac9(%rip), %rdi      # 0x502a
xorl %eax, %eax
callq 0x2040
jmp 0x256a
movl $0x0, -0x4(%rbp)
movl $0x1, -0x48(%rbp)
jmp 0x2f05
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2f1a
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x38(%rbp), %rdi
callq 0x22e0
jmp 0x25a1
jmp 0x25a3
jmp 0x25a5
leaq -0x38(%rbp), %rdi
callq 0x2330
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
jne 0x2641
leaq 0x2a80(%rip), %rdi      # 0x5043
callq 0x22b0
movq %rax, -0x488(%rbp)
cmpq $0x0, %rax
je 0x25e5
movq -0x488(%rbp), %rax
movq %rax, -0x490(%rbp)
jmp 0x25f5
leaq 0x2a5c(%rip), %rax      # 0x5048
movq %rax, -0x490(%rbp)
jmp 0x25f5
movq -0x490(%rbp), %rsi
leaq -0x38(%rbp), %rdi
callq 0x22e0
jmp 0x2607
leaq -0x38(%rbp), %rdi
callq 0x21a0
movsbl (%rax), %ecx
movl $0x2f, %eax
cmpl %ecx, %eax
je 0x2630
leaq 0x2a27(%rip), %rsi      # 0x504a
leaq -0x38(%rbp), %rdi
callq 0x23b0
jmp 0x262e
jmp 0x2630
movq -0x18(%rbp), %rsi
leaq -0x38(%rbp), %rdi
callq 0x23b0
jmp 0x263f
jmp 0x2641
leaq -0x60(%rbp), %rdi
callq 0x3240
movl $0x3, -0x64(%rbp)
leaq -0x270(%rbp), %rdi
leaq -0x38(%rbp), %rsi
movl $0x8, %edx
callq 0x2340
jmp 0x2668
leaq -0x291(%rbp), %rdi
movq %rdi, -0x498(%rbp)
callq 0x2380
movq -0x498(%rbp), %rdx
leaq 0x29c3(%rip), %rsi      # 0x504c
leaq -0x290(%rbp), %rdi
callq 0x3260
jmp 0x2697
leaq -0x291(%rbp), %rdi
callq 0x2280
leaq -0x2b8(%rbp), %rdi
callq 0x22f0
movq -0x270(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x270(%rbp,%rax), %rdi
callq 0x2360
movb %al, -0x499(%rbp)
jmp 0x26cf
movb -0x499(%rbp), %al
testb $0x1, %al
jne 0x26de
jmp 0x2c92
leaq -0x270(%rbp), %rdi
leaq -0x2b8(%rbp), %rsi
movl $0xa, %edx
callq 0x23a0
jmp 0x26f8
leaq -0x2b8(%rbp), %rdi
callq 0x2330
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
je 0x2766
xorl %eax, %eax
movl %eax, %esi
leaq -0x2b8(%rbp), %rdi
callq 0x23d0
movq %rax, -0x4a8(%rbp)
jmp 0x2727
movq -0x4a8(%rbp), %rax
movsbl (%rax), %ecx
movl $0x23, %eax
cmpl %ecx, %eax
je 0x2766
xorl %eax, %eax
movl %eax, %esi
leaq -0x2b8(%rbp), %rdi
callq 0x23d0
movq %rax, -0x4b0(%rbp)
jmp 0x2753
movq -0x4b0(%rbp), %rax
movsbl (%rax), %ecx
movl $0x3b, %eax
cmpl %ecx, %eax
jne 0x27aa
jmp 0x26af
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2efa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x291(%rbp), %rdi
callq 0x2280
jmp 0x2eee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2ed6
leaq -0x290(%rbp), %rdi
movq %rdi, -0x4c0(%rbp)
callq 0x2210
movq -0x4c0(%rbp), %rdi
movq %rax, -0x2c0(%rbp)
callq 0x2130
movq %rax, -0x2c8(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0x2210
movq %rax, -0x2d0(%rbp)
movq -0x2c0(%rbp), %rdi
movq -0x2c8(%rbp), %rsi
movq -0x2d0(%rbp), %rdx
callq 0x3310
movb %al, -0x4b1(%rbp)
jmp 0x280c
movb -0x4b1(%rbp), %al
testb $0x1, %al
jne 0x281b
jmp 0x297e
leaq -0x290(%rbp), %rdi
callq 0x2330
movq %rax, %rdx
leaq -0x2f0(%rbp), %rdi
leaq -0x2b8(%rbp), %rsi
movq $-0x1, %rcx
callq 0x2260
jmp 0x2846
leaq -0x2b8(%rbp), %rdi
leaq -0x2f0(%rbp), %rsi
callq 0x22c0
leaq -0x2f0(%rbp), %rdi
callq 0x2160
leaq -0x2b8(%rbp), %rdi
callq 0x2330
movq %rax, %rdx
xorl %eax, %eax
xorl %ecx, %ecx
cmpq %rdx, %rcx
movb %al, -0x4c1(%rbp)
jae 0x28b7
xorl %eax, %eax
movl %eax, %esi
leaq -0x2b8(%rbp), %rdi
callq 0x23d0
movq %rax, -0x4d0(%rbp)
jmp 0x289c
movq -0x4d0(%rbp), %rax
movsbl (%rax), %edi
callq 0x2050
cmpl $0x0, %eax
setne %al
movb %al, -0x4c1(%rbp)
movb -0x4c1(%rbp), %al
testb $0x1, %al
jne 0x28c3
jmp 0x28dc
xorl %eax, %eax
movl %eax, %esi
leaq -0x2b8(%rbp), %rdi
movl $0x1, %edx
callq 0x2080
jmp 0x28da
jmp 0x2865
leaq -0x2b8(%rbp), %rdi
callq 0x2330
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
jae 0x2979
xorl %eax, %eax
movl %eax, %esi
leaq -0x2b8(%rbp), %rdi
callq 0x23d0
movq %rax, -0x4d8(%rbp)
jmp 0x290f
movq -0x4d8(%rbp), %rax
movsbl (%rax), %ecx
movl $0x3d, %eax
cmpl %ecx, %eax
jne 0x2979
xorl %eax, %eax
movl %eax, %esi
leaq -0x2b8(%rbp), %rdi
movl $0x1, %edx
callq 0x2080
jmp 0x2939
leaq -0x2b8(%rbp), %rdi
callq 0x2330
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
jae 0x2977
xorl %eax, %eax
movl %eax, %esi
leaq -0x2b8(%rbp), %rdi
movl $0xa, %edx
callq 0x3360
movq %rax, -0x4e0(%rbp)
jmp 0x296d
movq -0x4e0(%rbp), %rax
movl %eax, -0x64(%rbp)
jmp 0x2979
jmp 0x2c8d
leaq -0x2b8(%rbp), %rdi
callq 0x20d0
movq %rax, %rdi
leaq 0x26c6(%rip), %rsi      # 0x505a
leaq -0x2f4(%rbp), %rdx
leaq -0x2f8(%rbp), %rcx
leaq -0x2fc(%rbp), %r8
movb $0x0, %al
callq 0x2230
movl %eax, %ecx
movl $0x3, %eax
cmpl %ecx, %eax
je 0x29c0
jmp 0x26af
leaq -0x338(%rbp), %rdi
xorl %esi, %esi
movl $0x38, %edx
callq 0x2120
movl -0x2f4(%rbp), %eax
subl $0x76c, %eax            # imm = 0x76C
movl %eax, -0x324(%rbp)
movl -0x2f8(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x328(%rbp)
movl -0x2fc(%rbp), %eax
movl %eax, -0x32c(%rbp)
leaq -0x338(%rbp), %rdi
callq 0x2170
movq %rax, %rcx
movq $-0x1, %rax
cmpq %rcx, %rax
jne 0x2a1f
jmp 0x26af
leaq -0x2b8(%rbp), %rdi
movq %rdi, -0x4f0(%rbp)
callq 0x2210
movq -0x4f0(%rbp), %rdi
movq %rax, -0x348(%rbp)
callq 0x2130
movq %rax, -0x350(%rbp)
movq -0x348(%rbp), %rdi
movq -0x350(%rbp), %rsi
callq 0x2f30
movq %rax, -0x4e8(%rbp)
jmp 0x2a68
movq -0x4e8(%rbp), %rax
movq %rax, -0x340(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0x2130
movq %rax, -0x360(%rbp)
leaq -0x360(%rbp), %rdi
leaq -0x340(%rbp), %rsi
callq 0x33a0
testb $0x1, %al
jne 0x2aa2
jmp 0x2aa7
jmp 0x26af
leaq -0x2b8(%rbp), %rdi
movq %rdi, -0x4f8(%rbp)
callq 0x2210
movq %rax, -0x388(%rbp)
leaq -0x340(%rbp), %rdi
leaq -0x388(%rbp), %rsi
callq 0x33e0
movq -0x4f8(%rbp), %rsi
movq %rax, %rdx
leaq -0x380(%rbp), %rdi
movq $-0x1, %rcx
callq 0x2260
jmp 0x2af3
leaq -0x2b8(%rbp), %rdi
leaq -0x380(%rbp), %rsi
callq 0x22c0
leaq -0x380(%rbp), %rdi
callq 0x2160
leaq -0x2b8(%rbp), %rdi
callq 0x2330
movq %rax, %rdx
xorl %eax, %eax
xorl %ecx, %ecx
cmpq %rdx, %rcx
movb %al, -0x4f9(%rbp)
jae 0x2b64
xorl %eax, %eax
movl %eax, %esi
leaq -0x2b8(%rbp), %rdi
callq 0x23d0
movq %rax, -0x508(%rbp)
jmp 0x2b49
movq -0x508(%rbp), %rax
movsbl (%rax), %edi
callq 0x2050
cmpl $0x0, %eax
setne %al
movb %al, -0x4f9(%rbp)
movb -0x4f9(%rbp), %al
testb $0x1, %al
jne 0x2b70
jmp 0x2b89
xorl %eax, %eax
movl %eax, %esi
leaq -0x2b8(%rbp), %rdi
movl $0x1, %edx
callq 0x2080
jmp 0x2b87
jmp 0x2b12
jmp 0x2b8b
leaq -0x2b8(%rbp), %rdi
callq 0x2330
movq %rax, %rdx
xorl %eax, %eax
xorl %ecx, %ecx
cmpq %rdx, %rcx
movb %al, -0x509(%rbp)
jae 0x2bc9
leaq -0x2b8(%rbp), %rdi
callq 0x21a0
movsbl (%rax), %edi
callq 0x2050
cmpl $0x0, %eax
setne %al
movb %al, -0x509(%rbp)
movb -0x509(%rbp), %al
testb $0x1, %al
jne 0x2bd5
jmp 0x2c03
leaq -0x2b8(%rbp), %rdi
movq %rdi, -0x518(%rbp)
callq 0x2330
movq -0x518(%rbp), %rdi
movq %rax, %rsi
decq %rsi
movl $0x1, %edx
callq 0x2080
jmp 0x2c01
jmp 0x2b8b
movq -0x308(%rbp), %rax
movq %rax, -0x3b0(%rbp)
movups -0x338(%rbp), %xmm0
movups -0x328(%rbp), %xmm1
movups -0x318(%rbp), %xmm2
movaps %xmm2, -0x3c0(%rbp)
movaps %xmm1, -0x3d0(%rbp)
movaps %xmm0, -0x3e0(%rbp)
leaq -0x3a8(%rbp), %rdi
leaq -0x2b8(%rbp), %rsi
callq 0x20e0
jmp 0x2c50
leaq -0x60(%rbp), %rdi
leaq -0x3e0(%rbp), %rsi
callq 0x3420
jmp 0x2c62
leaq -0x3e0(%rbp), %rdi
callq 0x3490
jmp 0x2c8d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x3e0(%rbp), %rdi
callq 0x3490
jmp 0x2ed6
jmp 0x26af
leaq -0x270(%rbp), %rdi
callq 0x2070
jmp 0x2ca0
xorl %eax, %eax
movl %eax, %edi
callq 0x2220
movq %rax, -0x3e8(%rbp)
leaq -0x3e8(%rbp), %rdi
callq 0x21b0
movq %rax, %rsi
leaq -0x420(%rbp), %rdi
movl $0x38, %edx
callq 0x21f0
movl $0x0, -0x424(%rbp)
movl -0x424(%rbp), %eax
cmpl -0x64(%rbp), %eax
ja 0x2e99
leaq -0x460(%rbp), %rdi
leaq -0x420(%rbp), %rsi
movl $0x38, %edx
callq 0x21f0
movl -0x424(%rbp), %eax
addl -0x454(%rbp), %eax
movl %eax, -0x454(%rbp)
leaq -0x460(%rbp), %rdi
callq 0x2170
leaq -0x60(%rbp), %rdi
callq 0x34b0
movq %rax, -0x468(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x3520
movq %rax, -0x470(%rbp)
leaq -0x468(%rbp), %rdi
leaq -0x470(%rbp), %rsi
callq 0x34e0
testb $0x1, %al
jne 0x2d5b
jmp 0x2e83
movl -0x450(%rbp), %eax
movl %eax, -0x51c(%rbp)
leaq -0x468(%rbp), %rdi
callq 0x3550
movq %rax, %rcx
movl -0x51c(%rbp), %eax
cmpl 0x10(%rcx), %eax
jne 0x2e70
movl -0x454(%rbp), %eax
movl %eax, -0x520(%rbp)
leaq -0x468(%rbp), %rdi
callq 0x3550
movq %rax, %rcx
movl -0x520(%rbp), %eax
cmpl 0xc(%rcx), %eax
jne 0x2e70
leaq 0x22b2(%rip), %rdx      # 0x5068
leaq -0x480(%rbp), %rdi
movq %rdi, -0x528(%rbp)
movl $0x10, %esi
leaq -0x460(%rbp), %rcx
callq 0x21e0
leaq -0x468(%rbp), %rdi
callq 0x3550
movq %rax, %rdi
addq $0x38, %rdi
callq 0x20d0
movq -0x528(%rbp), %rdx
movq %rax, %rsi
leaq 0x226d(%rip), %rdi      # 0x506b
xorl %eax, %eax
callq 0x2040
jmp 0x2e07
xorl %eax, %eax
cmpl -0x424(%rbp), %eax
jne 0x2e23
leaq 0x226a(%rip), %rdi      # 0x5082
xorl %eax, %eax
callq 0x2040
jmp 0x2e21
jmp 0x2e3b
movl -0x424(%rbp), %esi
leaq 0x225d(%rip), %rdi      # 0x508d
xorl %eax, %eax
callq 0x2040
jmp 0x2e39
jmp 0x2e3b
movl -0x44c(%rbp), %eax
movl %eax, -0x52c(%rbp)
leaq -0x468(%rbp), %rdi
callq 0x3550
movl -0x52c(%rbp), %esi
movl 0x14(%rax), %eax
subl %eax, %esi
leaq 0x2237(%rip), %rdi      # 0x509c
xorl %eax, %eax
callq 0x2040
jmp 0x2e6e
jmp 0x2e70
jmp 0x2e72
leaq -0x468(%rbp), %rdi
callq 0x3570
jmp 0x2d2f
jmp 0x2e85
movl -0x424(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x424(%rbp)
jmp 0x2cda
movl $0x0, -0x4(%rbp)
movl $0x1, -0x48(%rbp)
leaq -0x2b8(%rbp), %rdi
callq 0x2160
leaq -0x290(%rbp), %rdi
callq 0x2160
leaq -0x270(%rbp), %rdi
callq 0x2090
leaq -0x60(%rbp), %rdi
callq 0x3590
jmp 0x2f05
leaq -0x2b8(%rbp), %rdi
callq 0x2160
leaq -0x290(%rbp), %rdi
callq 0x2160
leaq -0x270(%rbp), %rdi
callq 0x2090
leaq -0x60(%rbp), %rdi
callq 0x3590
jmp 0x2f1a
leaq -0x38(%rbp), %rdi
callq 0x2160
movl -0x4(%rbp), %eax
addq $0x530, %rsp            # imm = 0x530
popq %rbp
retq
leaq -0x38(%rbp), %rdi
callq 0x2160
movq -0x40(%rbp), %rdi
callq 0x2370
nopl (%rax)