I always find it so hard to help out proof-reading code for causes like this. Often, the code is more complicated than I find reasonable, while omitting things that make a lot of sense in "real" code, and it's very hard to know as an outside reader what the exact motivation for each decision was, by the author. A few such things that caused me to WTF: The initial few examples use a pointlessly static and global line…
/* Fake readline function */
char* readline(const char* prompt) {
fputs(prompt, stdout);
fgets(buffer, sizeof buffer, stdin);
size_t bufsiz = strlen(buffer);
char* cpy = malloc(bufsiz + 1);
strcpy(cpy, buffer);
cpy[bufsiz - 1] = '\0';
return cpy;
}