#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/time.h", "source/kit/atomic.h", "source/kit/threads.h", "source/kit/array_ref.h", "source/kit/dynamic_array.h", "source/kit/string_ref.h", "source/kit/string_builder.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", "source/kit/shared_memory.h", "source/kit/xml.h" }; char *IMPL[] = { "source/kit/allocator.c", "source/kit/atomic.win32.c", "source/kit/threads.posix.c", "source/kit/threads.win32.c", "source/kit/array_ref.c", "source/kit/dynamic_array.c", "source/kit/string_builder.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", "source/kit/shared_memory.posix.c", "source/kit/shared_memory.win32.c", "source/kit/xml.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, "// " "=====================================================" "===========\n"); fprintf(out, "//\n"); fprintf(out, "// File: %s\n", source); fprintf(out, "//\n"); fprintf(out, "// " "=====================================================" "===========\n"); 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, "// " "=====================================================" "===========\n"); fprintf(out, "//\n"); fprintf(out, "// kit.inl.h\n"); fprintf(out, "// https://guattari.tech/kit.git\n"); fprintf(out, "//\n"); fprintf(out, "// Single header-only cross-platform utility " "library for C.\n"); fprintf(out, "//\n"); fprintf(out, "// " "=====================================================" "===========\n"); fprintf(out, "//\n"); fprintf(out, "// The MIT License\n"); fprintf(out, "//\n"); fprintf(out, "// Copyright (c) 2022-2023 Mitya Selivanov\n"); fprintf(out, "//\n"); fprintf(out, "// Permission is hereby granted, free of charge, to " "any person\n"); fprintf(out, "// obtaining a copy of this software and associated " "documentation\n"); fprintf(out, "// files (the \"Software\"), to deal in the " "Software without\n"); fprintf(out, "// restriction, including without limitation the " "rights to use, copy,\n"); fprintf(out, "// modify, merge, publish, distribute, sublicense, " "and/or sell copies\n"); fprintf(out, "// of the Software, and to permit persons to whom " "the Software is\n"); fprintf(out, "// furnished to do so, subject to the following " "conditions:\n"); fprintf(out, "//\n"); fprintf(out, "// The above copyright notice and this permission " "notice shall be\n"); fprintf(out, "// included in all copies or substantial portions " "of the Software.\n"); fprintf(out, "//\n"); fprintf(out, "// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT " "WARRANTY OF ANY KIND,\n"); fprintf(out, "// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO " "THE WARRANTIES OF\n"); fprintf( out, "// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n"); fprintf(out, "// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS " "OR COPYRIGHT\n"); fprintf(out, "// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR " "OTHER LIABILITY,\n"); fprintf(out, "// WHETHER IN AN ACTION OF CONTRACT, TORT OR " "OTHERWISE, ARISING FROM,\n"); fprintf(out, "// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE " "USE OR OTHER\n"); fprintf(out, "// DEALINGS IN THE SOFTWARE.\n"); fprintf(out, "//\n"); fprintf(out, "// " "=====================================================" "===========\n"); 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, "#endif\n"); fprintf(out, "// " "=====================================================" "===========\n"); fprintf(out, "//\n"); fprintf(out, "// IMPLEMENTATION\n"); fprintf(out, "//\n"); fprintf(out, "// " "=====================================================" "===========\n"); fprintf(out, "#if defined(KIT_IMPLEMENTATION) && " "!defined(KIT_INL_H_IMPL)\n"); fprintf(out, "#define KIT_INL_H_IMPL\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"); fclose(out); return 0; }