// File: attractivechaos[P]udb2/stb/./stb.h
// Function: stb_stringfile
char ** stb_stringfile(char *filename, int *plen)
{
   FILE *f = stb__fopen(filename, "rb");
   char *buffer, **list=NULL, *s;
   size_t len, count, i;

   if (!f) return NULL;
   len = stb_filelen(f);
   buffer = (char *) malloc(len+1);
   len = fread(buffer, 1, len, f);
   buffer[len] = 0;
   fclose(f);

   // two passes through: first time count lines, second time set them
   for (i=0; i < 2; ++i) {
      s = buffer;
      if (i == 1)
         list[0] = s;
      count = 1;
      while (*s) {
         if (*s == '\n' || *s == '\r') {
            // detect if both cr & lf are together
            int crlf = (s[0] + s[1]) == ('\n' + '\r');
            if (i == 1) *s = 0;
            if (crlf) ++s;
            if (s[1]) {  // it's not over yet
               if (i == 1) list[count] = s+1;
               ++count;
            }
         }
         ++s;
      }
      if (i == 0) {
         list = (char **) malloc(sizeof(*list) * (count+1) + len+1);
         if (!list) return NULL;
         list[count] = 0;
         // recopy the file so there's just a single allocation to free
         memcpy(&list[count+1], buffer, len+1);
         free(buffer);
         buffer = (char *) &list[count+1];
         if (plen) *plen = count;
      }
   }
   return list;
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x48(%rsp)
movq %rsi, 0x40(%rsp)
movq 0x48(%rsp), %rdi
leaq 0x11e1a(%rip), %rsi     # 0x1f6d4
callq 0x22f0
movq %rax, 0x38(%rsp)
movq $0x0, 0x28(%rsp)
cmpq $0x0, 0x38(%rsp)
jne 0xd8e3
movq $0x0, 0x50(%rsp)
jmp 0xdb0f
movq 0x38(%rsp), %rdi
callq 0xd100
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rdi
addq $0x1, %rdi
callq 0x2260
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rdi
movq 0x18(%rsp), %rdx
movq 0x38(%rsp), %rcx
movl $0x1, %esi
callq 0x20b0
movq %rax, 0x18(%rsp)
movq 0x30(%rsp), %rax
movq 0x18(%rsp), %rcx
movb $0x0, (%rax,%rcx)
movq 0x38(%rsp), %rdi
callq 0x20d0
movq $0x0, 0x8(%rsp)
cmpq $0x2, 0x8(%rsp)
jae 0xdb05
movq 0x30(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x1, 0x8(%rsp)
jne 0xd96f
movq 0x20(%rsp), %rcx
movq 0x28(%rsp), %rax
movq %rcx, (%rax)
movq $0x1, 0x10(%rsp)
movq 0x20(%rsp), %rax
cmpb $0x0, (%rax)
je 0xda38
movq 0x20(%rsp), %rax
movsbl (%rax), %eax
cmpl $0xa, %eax
je 0xd9a4
movq 0x20(%rsp), %rax
movsbl (%rax), %eax
cmpl $0xd, %eax
jne 0xda25
movq 0x20(%rsp), %rax
movsbl (%rax), %eax
movq 0x20(%rsp), %rcx
movsbl 0x1(%rcx), %ecx
addl %ecx, %eax
cmpl $0x17, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x4(%rsp)
cmpq $0x1, 0x8(%rsp)
jne 0xd9d6
movq 0x20(%rsp), %rax
movb $0x0, (%rax)
cmpl $0x0, 0x4(%rsp)
je 0xd9eb
movq 0x20(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rax
cmpb $0x0, 0x1(%rax)
je 0xda23
cmpq $0x1, 0x8(%rsp)
jne 0xda15
movq 0x20(%rsp), %rdx
addq $0x1, %rdx
movq 0x28(%rsp), %rax
movq 0x10(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movq 0x10(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x10(%rsp)
jmp 0xda25
movq 0x20(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x20(%rsp)
jmp 0xd978
cmpq $0x0, 0x8(%rsp)
jne 0xdaf0
movq 0x10(%rsp), %rdi
addq $0x1, %rdi
shlq $0x3, %rdi
addq 0x18(%rsp), %rdi
addq $0x1, %rdi
callq 0x2260
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
jne 0xda7a
movq $0x0, 0x50(%rsp)
jmp 0xdb0f
movq 0x28(%rsp), %rax
movq 0x10(%rsp), %rcx
movq $0x0, (%rax,%rcx,8)
movq 0x28(%rsp), %rdi
movq 0x10(%rsp), %rax
addq $0x1, %rax
shlq $0x3, %rax
addq %rax, %rdi
movq 0x30(%rsp), %rsi
movq 0x18(%rsp), %rdx
addq $0x1, %rdx
callq 0x2230
movq 0x30(%rsp), %rdi
callq 0x23c0
movq 0x28(%rsp), %rax
movq 0x10(%rsp), %rcx
addq $0x1, %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x40(%rsp)
je 0xdaee
movq 0x10(%rsp), %rax
movl %eax, %ecx
movq 0x40(%rsp), %rax
movl %ecx, (%rax)
jmp 0xdaf0
jmp 0xdaf2
movq 0x8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x8(%rsp)
jmp 0xd944
movq 0x28(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
addq $0x58, %rsp
retq
nopl (%rax)