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