// SPDX-License-Identifier: 0BSD /////////////////////////////////////////////////////////////////////////////// // /// \file create_compress_files.c /// \brief Creates bunch of test files to be compressed /// /// Using a test file generator program saves space in the source code /// package considerably. // // Author: Lasse Collin // /////////////////////////////////////////////////////////////////////////////// #include "sysdefs.h" #include // If a command-line argument was given, only create the file if its // name was specified on the command line. If no args were given then // all files are created. // // Avoid re-creating the test files every time the tests are run. #define maybe_create_test(argc, argv, name) \ do { \ if ((argc < 2 || strcmp(argv[1], "compress_generated_" #name) == 0) \ && !file_exists("compress_generated_" #name)) { \ FILE *file = file_create("compress_generated_" #name); \ write_ ## name(file); \ file_finish(file, "compress_generated_" #name); \ } \ } while (0) static bool file_exists(const char *filename) { // Trying to be somewhat portable by avoiding stat(). FILE *file = fopen(filename, "rb"); bool ret; if (file != NULL) { fclose(file); ret = true; } else { ret = false; } return ret; } static FILE * file_create(const char *filename) { FILE *file = fopen(filename, "wb"); if (file == NULL) { perror(filename); exit(EXIT_FAILURE); } return file; } static void file_finish(FILE *file, const char *filename) { const bool ferror_fail = ferror(file); const bool fclose_fail = fclose(file); if (ferror_fail || fclose_fail) { perror(filename); exit(EXIT_FAILURE); } } // File that repeats "abc\n" a few thousand times. This is targeted // especially at Subblock filter's run-length encoder. static void write_abc(FILE *file) { for (size_t i = 0; i < 12345; ++i) if (fwrite("abc\n", 4, 1, file) != 1) exit(EXIT_FAILURE); } // File that doesn't compress. We always use the same random seed to // generate identical files on all systems. static void write_random(FILE *file) { uint32_t n = 5; for (size_t i = 0; i < 123456; ++i) { n = 101771 * n + 71777; putc((uint8_t)(n), file); putc((uint8_t)(n >> 8), file); putc((uint8_t)(n >> 16), file); putc((uint8_t)(n >> 24), file); } } // Text file static void write_text(FILE *file) { static const char *lorem[] = { "Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipisicing", "elit,", "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", "magna", "aliqua.", "Ut", "enim", "ad", "minim", "veniam,", "quis", "nostrud", "exercitation", "ullamco", "laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo", "consequat.", "Duis", "aute", "irure", "dolor", "in", "reprehenderit", "in", "voluptate", "velit", "esse", "cillum", "dolore", "eu", "fugiat", "nulla", "pariatur.", "Excepteur", "sint", "occaecat", "cupidatat", "non", "proident,", "sunt", "in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum." }; // Let the first paragraph be the original text. for (size_t w = 0; w < ARRAY_SIZE(lorem); ++w) { fprintf(file, "%s ", lorem[w]); if (w % 7 == 6) fprintf(file, "\n"); } // The rest shall be (hopefully) meaningless combinations of // the same words. uint32_t n = 29; for (size_t p = 0; p < 500; ++p) { fprintf(file, "\n\n"); for (size_t w = 0; w < ARRAY_SIZE(lorem); ++w) { n = 101771 * n + 71777; fprintf(file, "%s ", lorem[n % ARRAY_SIZE(lorem)]); if (w % 7 == 6) fprintf(file, "\n"); } } } int main(int argc, char **argv) { maybe_create_test(argc, argv, abc); maybe_create_test(argc, argv, random); maybe_create_test(argc, argv, text); return EXIT_SUCCESS; }