1///////////////////////////////////////////////////////////////////////////////
2//
3/// \file       create_compress_files.c
4/// \brief      Creates bunch of test files to be compressed
5///
6/// Using a test file generator program saves space in the source code
7/// package considerably.
8//
9//  Author:     Lasse Collin
10//
11//  This file has been put into the public domain.
12//  You can do whatever you want with this file.
13//
14///////////////////////////////////////////////////////////////////////////////
15
16#include "sysdefs.h"
17#include <stdio.h>
18
19
20// Avoid re-creating the test files every time the tests are run.
21#define create_test(name) \
22do { \
23	if (!file_exists("compress_generated_" #name)) { \
24		FILE *file = file_create("compress_generated_" #name); \
25		write_ ## name(file); \
26		file_finish(file, "compress_generated_" #name); \
27	} \
28} while (0)
29
30
31static bool
32file_exists(const char *filename)
33{
34	// Trying to be somewhat portable by avoiding stat().
35	FILE *file = fopen(filename, "rb");
36	bool ret;
37
38	if (file != NULL) {
39		fclose(file);
40		ret = true;
41	} else {
42		ret = false;
43	}
44
45	return ret;
46}
47
48
49static FILE *
50file_create(const char *filename)
51{
52	FILE *file = fopen(filename, "wb");
53
54	if (file == NULL) {
55		perror(filename);
56		exit(1);
57	}
58
59	return file;
60}
61
62
63static void
64file_finish(FILE *file, const char *filename)
65{
66	const bool ferror_fail = ferror(file);
67	const bool fclose_fail = fclose(file);
68
69	if (ferror_fail || fclose_fail) {
70		perror(filename);
71		exit(1);
72	}
73}
74
75
76// File that repeats "abc\n" a few thousand times. This is targeted
77// especially at Subblock filter's run-length encoder.
78static void
79write_abc(FILE *file)
80{
81	for (size_t i = 0; i < 12345; ++i)
82		fwrite("abc\n", 4, 1, file);
83}
84
85
86// File that doesn't compress. We always use the same random seed to
87// generate identical files on all systems.
88static void
89write_random(FILE *file)
90{
91	uint32_t n = 5;
92
93	for (size_t i = 0; i < 123456; ++i) {
94		n = 101771 * n + 71777;
95
96		putc(n & 0xFF, file);
97		putc((n >> 8) & 0xFF, file);
98		putc((n >> 16) & 0xFF, file);
99		putc(n >> 24, file);
100	}
101}
102
103
104// Text file
105static void
106write_text(FILE *file)
107{
108	static const char *lorem[] = {
109		"Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur",
110		"adipisicing", "elit,", "sed", "do", "eiusmod", "tempor",
111		"incididunt", "ut", "labore", "et", "dolore", "magna",
112		"aliqua.", "Ut", "enim", "ad", "minim", "veniam,", "quis",
113		"nostrud", "exercitation", "ullamco", "laboris", "nisi",
114		"ut", "aliquip", "ex", "ea", "commodo", "consequat.",
115		"Duis", "aute", "irure", "dolor", "in", "reprehenderit",
116		"in", "voluptate", "velit", "esse", "cillum", "dolore",
117		"eu", "fugiat", "nulla", "pariatur.", "Excepteur", "sint",
118		"occaecat", "cupidatat", "non", "proident,", "sunt", "in",
119		"culpa", "qui", "officia", "deserunt", "mollit", "anim",
120		"id", "est", "laborum."
121	};
122
123	// Let the first paragraph be the original text.
124	for (size_t w = 0; w < ARRAY_SIZE(lorem); ++w) {
125		fprintf(file, "%s ", lorem[w]);
126
127		if (w % 7 == 6)
128			fprintf(file, "\n");
129	}
130
131	// The rest shall be (hopefully) meaningless combinations of
132	// the same words.
133	uint32_t n = 29;
134
135	for (size_t p = 0; p < 500; ++p) {
136		fprintf(file, "\n\n");
137
138		for (size_t w = 0; w < ARRAY_SIZE(lorem); ++w) {
139			n = 101771 * n + 71777;
140
141			fprintf(file, "%s ", lorem[n % ARRAY_SIZE(lorem)]);
142
143			if (w % 7 == 6)
144				fprintf(file, "\n");
145		}
146	}
147}
148
149
150int
151main(void)
152{
153	create_test(abc);
154	create_test(random);
155	create_test(text);
156	return 0;
157}
158