#if 0 gcc -fsanitize=address,undefined,leak gen_inl.c -o gen_inl && ./gen_inl exit #endif #include #include #include #include char *HEADERS[] = { "source/kit/types.h", "source/kit/status.h", "source/kit/allocator.h", "source/kit/thread_defs.h", "source/kit/thread.h", "source/kit/atomic.h", "source/kit/mutex.h", "source/kit/condition_variable.h", "source/kit/array_ref.h", "source/kit/string_ref.h", "source/kit/dynamic_array.h", "source/kit/lower_bound.h", "source/kit/move_back.h", "source/kit/bigint.h", "source/kit/input_stream.h", "source/kit/input_buffer.h", "source/kit/async_function.h", "source/kit/file.h", "source/kit/mersenne_twister_64.h", "source/kit/secure_random.h", "source/kit/sha256.h", "source/kit/sockets.h" }; char *IMPL[] = { "source/kit/allocator.c", "source/kit/thread.posix.c", "source/kit/thread.win32.c", "source/kit/atomic.win32.c", "source/kit/mutex.c", "source/kit/condition_variable.c", "source/kit/dynamic_array.c", "source/kit/input_stream.c", "source/kit/input_buffer.c", "source/kit/file.c", "source/kit/mersenne_twister_64.c", "source/kit/secure_random.c", "source/kit/sha256.c" }; char *repeat(int n, char c) { static char buf[200]; for (int i = 0; i < n && i < 199; i++) buf[i] = c; buf[n] = '\0'; return buf; } int skip_whitespaces(char *line, int i) { while (line[i] == ' ') i++; return i; } int skip(char *line, int i, char *s) { int j = 0; while (s[j] != '\0') { if (line[i] != s[j]) return -1; i++; j++; } return i; } int is_local_include(char *line) { if (line[0] != '#') return 0; int i = skip_whitespaces(line, 1); i = skip(line, i, "include"); if (i == -1) return 0; i = skip_whitespaces(line, i); if (line[i] != '"') return 0; return 1; } int is_empty_line(char *line) { int i = skip_whitespaces(line, 0); return line[i] == '\0' || line[i] == '\n'; } int write_file(FILE *out, char *source) { assert(out != NULL); assert(source != NULL); FILE *in = fopen(source, "rt"); if (in == NULL) { fprintf(stderr, "File not found: %s\n", source); return 1; } fprintf(out, "/*%s*\n", repeat(67, '*')); fprintf(out, " *%s*\n", repeat(67, ' ')); fprintf(out, " * File: %s%s*\n", source, repeat(55 - strlen(source), ' ')); fprintf(out, " *%s*\n", repeat(67, ' ')); fprintf(out, " *%s*/\n", repeat(67, '*')); char line[200]; char buf[400]; while (fgets(line, 199, in) != NULL) { if (is_empty_line(line) || is_local_include(line)) continue; int j = 0; for (int i = 0; line[i] != '\0'; i++) { if (line[i] == '\t') { buf[j++] = ' '; buf[j++] = ' '; } else if (line[i] != '\n' && line[i] != '\r') buf[j++] = line[i]; } buf[j] = '\0'; fprintf(out, "%s\n", buf); } fclose(in); return 0; } int main(int argc, char **argv) { char *out_file = "./include/kit.inl.h"; FILE *out = fopen(out_file, "wt"); if (out == NULL) { fprintf(stderr, "Can't write: %s\n", out_file); return 1; } fprintf(out, "#ifndef KIT_INL_H\n"); fprintf(out, "#define KIT_INL_H\n"); for (int i = 0; i < sizeof HEADERS / sizeof *HEADERS; i++) if (write_file(out, HEADERS[i]) != 0) { fclose(out); return 1; } fprintf(out, "#ifdef KIT_IMPLEMENTATION\n"); for (int i = 0; i < sizeof IMPL / sizeof *IMPL; i++) if (write_file(out, IMPL[i]) != 0) { fclose(out); return 1; } fprintf(out, "#endif\n"); fprintf(out, "#endif\n"); fclose(out); return 0; }