// File: ndsol[P]git-mine/./hashapi.h
// Function: CommitReader::read_from(_IO_FILE*, CommitMessage*)
int read_from(FILE* fin, CommitMessage* out) {
    size_t max = 1024;
    char* message = reinterpret_cast<char*>(malloc(max));
    if (!message) {
      fprintf(stderr, "%s: out of memory at %zuK\n", whoami, max / 1024);
      return 1;
    }

    char extra_room_sizer[16];
    size_t remain = max;
    // EXTRA_ROOM_PAD: padding to make this a commit.
    // strlen("commit ") + strlen("\0") + '\0' at the very end
    #define EXTRA_ROOM_PAD (7+1+1)
    int extra_room = EXTRA_ROOM_PAD + 4 /*strlen(sprintf("%s", max))*/;
    char* p = message;
    while (!feof(fin)) {
      size_t r = fread(p, 1, remain - extra_room, fin);
      if (r < remain && !feof(fin) && errno) {
        // This utility must be passed on stdin the
        // contents of the commit (completely unedited), like so:
        // git cat-file commit HEAD | $whoami
        fprintf(stderr, "Usage: %s $GIT_TOPLEVEL\n"
          "Failed to read stdin after %zu bytes: %d %s\n",
          whoami, max - remain, errno, strerror(errno));
        return 1;
      }
      p += r;
      remain -= r;
      if (remain <= (size_t) extra_room) {
        remain += max;
        message = reinterpret_cast<char*>(realloc(message, max *= 2));
        if (!message) {
          fprintf(stderr, "%s: out of memory at %zuK\n", whoami,
                  max / (2*1024));
          return 1;
        }
        p = message + (max - remain);
        extra_room = snprintf(extra_room_sizer, sizeof(extra_room_sizer), "%zu",
                              max);
        if (extra_room < 4) {
          fprintf(stderr, "%s: failed to size extra_room\n", whoami);
          return 1;
        }
        extra_room += EXTRA_ROOM_PAD;
      }
    }

    // Success. Clean up message.
    if (remain <= (size_t) extra_room) {
      fprintf(stderr, "%s: BUG: remain too small (want %d)\n", whoami,
              extra_room);
      return 1;
    }
    size_t len = max - remain;
    extra_room = snprintf(extra_room_sizer, sizeof(extra_room_sizer), "%zu",
                          len);
    if (extra_room < 1) {
      fprintf(stderr, "%s: failed to get final extra_room\n", whoami);
      return 1;
    }
    // Make room at the beginning for "commit %zu\0"
    max = max - remain + extra_room + EXTRA_ROOM_PAD;
    memmove(message + extra_room + 7 + 1, message, len);
    // Write "commit %zu\0"
    strncpy(message, "commit ", 7);
    strncpy(message + 7, extra_room_sizer, extra_room);
    message[extra_room + 7] = 0;
    message[max - 1] = 0;  // Add '\0' null terminator at very end of message.

    return out->set(message, max - 1);
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x70(%rbp)
movq $0x400, -0x28(%rbp)     # imm = 0x400
movq -0x28(%rbp), %rdi
callq 0x4440
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x4d1e
movq -0x70(%rbp), %rax
movq 0x1b2e2(%rip), %rcx     # 0x1ffd8
movq (%rcx), %rdi
movq (%rax), %rdx
movq -0x28(%rbp), %rcx
shrq $0xa, %rcx
leaq 0x13391(%rip), %rsi     # 0x1809c
movb $0x0, %al
callq 0x44c0
movl $0x1, -0x4(%rbp)
jmp 0x5034
movq -0x28(%rbp), %rax
movq %rax, -0x48(%rbp)
movl $0xd, -0x4c(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rdi
callq 0x4520
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x4d4f
jmp 0x4f04
movq -0x58(%rbp), %rdi
movq -0x48(%rbp), %rdx
movslq -0x4c(%rbp), %rax
subq %rax, %rdx
movq -0x18(%rbp), %rcx
movl $0x1, %esi
callq 0x4500
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
cmpq -0x48(%rbp), %rax
jae 0x4e0a
movq -0x18(%rbp), %rdi
callq 0x4520
cmpl $0x0, %eax
jne 0x4e0a
callq 0x4030
cmpl $0x0, (%rax)
je 0x4e0a
movq -0x70(%rbp), %rax
movq 0x1b237(%rip), %rcx     # 0x1ffd8
movq (%rcx), %rcx
movq %rcx, -0x90(%rbp)
movq (%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x28(%rbp), %rax
subq -0x48(%rbp), %rax
movq %rax, -0x80(%rbp)
callq 0x4030
movl (%rax), %eax
movl %eax, -0x74(%rbp)
callq 0x4030
movl (%rax), %edi
callq 0x40c0
movq -0x90(%rbp), %rdi
movq -0x88(%rbp), %rdx
movq -0x80(%rbp), %rcx
movl -0x74(%rbp), %r8d
movq %rax, %r9
leaq 0x132c0(%rip), %rsi     # 0x180b7
movb $0x0, %al
callq 0x44c0
movl $0x1, -0x4(%rbp)
jmp 0x5034
movq -0x60(%rbp), %rax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x60(%rbp), %rcx
movq -0x48(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movslq -0x4c(%rbp), %rcx
cmpq %rcx, %rax
ja 0x4eff
movq -0x28(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x30(%rbp), %rdi
movq -0x28(%rbp), %rsi
shlq %rsi
movq %rsi, -0x28(%rbp)
callq 0x4590
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x4e94
movq -0x70(%rbp), %rax
movq 0x1b16c(%rip), %rcx     # 0x1ffd8
movq (%rcx), %rdi
movq (%rax), %rdx
movq -0x28(%rbp), %rcx
shrq $0xb, %rcx
leaq 0x1321b(%rip), %rsi     # 0x1809c
movb $0x0, %al
callq 0x44c0
movl $0x1, -0x4(%rbp)
jmp 0x5034
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
subq -0x48(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x58(%rbp)
leaq -0x40(%rbp), %rdi
movq -0x28(%rbp), %rcx
movl $0x10, %esi
leaq 0x13241(%rip), %rdx     # 0x180fc
movb $0x0, %al
callq 0x4550
movl %eax, -0x4c(%rbp)
cmpl $0x4, -0x4c(%rbp)
jge 0x4ef6
movq -0x70(%rbp), %rax
movq 0x1b102(%rip), %rcx     # 0x1ffd8
movq (%rcx), %rdi
movq (%rax), %rdx
leaq 0x1321d(%rip), %rsi     # 0x18100
movb $0x0, %al
callq 0x44c0
movl $0x1, -0x4(%rbp)
jmp 0x5034
movl -0x4c(%rbp), %eax
addl $0x9, %eax
movl %eax, -0x4c(%rbp)
jmp 0x4d35
movq -0x48(%rbp), %rax
movslq -0x4c(%rbp), %rcx
cmpq %rcx, %rax
ja 0x4f3f
movq -0x70(%rbp), %rax
movq 0x1b0bc(%rip), %rcx     # 0x1ffd8
movq (%rcx), %rdi
movq (%rax), %rdx
movl -0x4c(%rbp), %ecx
leaq 0x131f3(%rip), %rsi     # 0x1811f
movb $0x0, %al
callq 0x44c0
movl $0x1, -0x4(%rbp)
jmp 0x5034
movq -0x28(%rbp), %rax
subq -0x48(%rbp), %rax
movq %rax, -0x68(%rbp)
leaq -0x40(%rbp), %rdi
movq -0x68(%rbp), %rcx
movl $0x10, %esi
leaq 0x1319d(%rip), %rdx     # 0x180fc
movb $0x0, %al
callq 0x4550
movl %eax, -0x4c(%rbp)
cmpl $0x1, -0x4c(%rbp)
jge 0x4f9a
movq -0x70(%rbp), %rax
movq 0x1b05e(%rip), %rcx     # 0x1ffd8
movq (%rcx), %rdi
movq (%rax), %rdx
leaq 0x131bd(%rip), %rsi     # 0x18144
movb $0x0, %al
callq 0x44c0
movl $0x1, -0x4(%rbp)
jmp 0x5034
movq -0x28(%rbp), %rax
subq -0x48(%rbp), %rax
movslq -0x4c(%rbp), %rcx
addq %rcx, %rax
addq $0x9, %rax
movq %rax, -0x28(%rbp)
movq -0x30(%rbp), %rdi
movslq -0x4c(%rbp), %rax
addq %rax, %rdi
addq $0x7, %rdi
addq $0x1, %rdi
movq -0x30(%rbp), %rsi
movq -0x68(%rbp), %rdx
callq 0x4560
movq -0x30(%rbp), %rdi
leaq 0x1318c(%rip), %rsi     # 0x18168
movl $0x7, %edx
callq 0x4190
movq -0x30(%rbp), %rdi
addq $0x7, %rdi
leaq -0x40(%rbp), %rsi
movslq -0x4c(%rbp), %rdx
callq 0x4190
movq -0x30(%rbp), %rax
movl -0x4c(%rbp), %ecx
addl $0x7, %ecx
movslq %ecx, %rcx
movb $0x0, (%rax,%rcx)
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
subq $0x1, %rcx
movb $0x0, (%rax,%rcx)
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x28(%rbp), %rdx
subq $0x1, %rdx
callq 0x6340
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq