⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 random-test.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * random-test.c:  Test delta generation and application using random data.
 *
 * ====================================================================
 * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */


#include <assert.h>

#define APR_WANT_STDIO
#define APR_WANT_STRFUNC
#include <apr_want.h>
#include <apr_general.h>
#include <apr_getopt.h>
#include <apr_file_io.h>

#include "svn_delta.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_test.h"

#include "../../libsvn_delta/delta.h"
#include "delta-window-test.h"


#define DEFAULT_ITERATIONS 30
#define DEFAULT_MAXLEN (100 * 1024)
#define DEFAULT_DUMP_FILES 0
#define DEFAULT_PRINT_WINDOWS 0
#define SEEDS 50
#define MAXSEQ 100


/* Initialize parameters for the random tests. */
extern int test_argc;
extern const char **test_argv;

static void init_params (apr_uint32_t *seed,
                         apr_uint32_t *maxlen, int *iterations,
                         int *dump_files, int *print_windows,
                         const char **random_bytes,
                         apr_uint32_t *bytes_range,
                         apr_pool_t *pool)
{
  apr_getopt_t *opt;
  char optch;
  const char *opt_arg;
  apr_status_t status;

  *seed = (apr_uint32_t) apr_time_now();
  *maxlen = DEFAULT_MAXLEN;
  *iterations = DEFAULT_ITERATIONS;
  *dump_files = DEFAULT_DUMP_FILES;
  *print_windows = DEFAULT_PRINT_WINDOWS;
  *random_bytes = NULL;
  *bytes_range = 256;

  apr_getopt_init (&opt, pool, test_argc, test_argv);
  while (APR_SUCCESS
         == (status = apr_getopt (opt, "s:l:n:r:FW", &optch, &opt_arg)))
    {
      switch (optch)
        {
        case 's':
          *seed = atol (opt_arg);
          break;
        case 'l':
          *maxlen = atoi (opt_arg);
          break;
        case 'n':
          *iterations = atoi (opt_arg);
          break;
        case 'r':
          *random_bytes = opt_arg + 1;
          *bytes_range = strlen (*random_bytes);
          break;
        case 'F':
          *dump_files = !*dump_files;
          break;
        case 'W':
          *print_windows = !*print_windows;
          break;
        }
    }
}


/* Open a temporary file. */
static apr_file_t *
open_tempfile (const char *name_template, apr_pool_t *pool)
{
  apr_status_t apr_err;
  apr_file_t *fp = NULL;
  char *templ;

  if (!name_template)
    templ = apr_pstrdup (pool, "tempfile_XXXXXX");
  else
    templ = apr_pstrdup (pool, name_template);

  apr_err = apr_file_mktemp (&fp, templ, 0, pool);
  assert (apr_err == 0);
  assert (fp != NULL);
  return fp;
}

/* Rewind the file pointer */
static void rewind_file (apr_file_t *fp)
{
  apr_off_t offset = 0;
#ifndef NDEBUG
  apr_status_t apr_err =
#endif
    apr_file_seek (fp, APR_SET, &offset);
  assert (apr_err == 0);
  assert (offset == 0);
}


static void
dump_file_contents (apr_file_t *fp)
{
  static char file_buffer[10240];
  apr_size_t length = sizeof file_buffer;
  fputs ("--------\n", stdout);
  do
    {
      apr_file_read_full (fp, file_buffer, sizeof file_buffer, &length);
      fwrite (file_buffer, 1, length, stdout);
    }
  while (length == sizeof file_buffer);
  putc ('\n', stdout);
  rewind_file (fp);
}

/* Generate a temporary file containing sort-of random data.  Diffs
   between files of random data tend to be pretty boring, so we try to
   make sure there are a bunch of common substrings between two runs
   of this function with the same seedbase.  */
static apr_file_t *
generate_random_file (apr_uint32_t maxlen,
                      apr_uint32_t subseed_base,
                      apr_uint32_t *seed,
                      const char *random_bytes,
                      apr_uint32_t bytes_range,
                      int dump_files,
                      apr_pool_t *pool)
{
  static char file_buffer[10240];
  char *buf = file_buffer;
  char *const end = buf + sizeof file_buffer;

  apr_uint32_t len, seqlen;
  apr_file_t *fp;
  unsigned long r;

  fp = open_tempfile ("random_XXXXXX", pool);
  len = svn_test_rand (seed) % maxlen; /* We might go over this by a bit.  */
  while (len > 0)
    {
      /* Generate a pseudo-random sequence of up to MAXSEQ bytes,
         where the seed is in the range [seedbase..seedbase+MAXSEQ-1].
         (Use our own pseudo-random number generator here to avoid
         clobbering the seed of the libc random number generator.)  */

      seqlen = svn_test_rand (seed) % MAXSEQ;
      if (seqlen > len) seqlen = len;
      len -= seqlen;
      r = subseed_base + svn_test_rand (seed) % SEEDS;
      while (seqlen-- > 0)
        {
          const int ch = (random_bytes
                          ? (unsigned)random_bytes[r % bytes_range]
                          : r % bytes_range);
          if (buf == end)
            {
              apr_size_t ignore_length;
              apr_file_write_full (fp, file_buffer, sizeof file_buffer,
                                   &ignore_length);
              buf = file_buffer;
            }

          *buf++ = ch;
          r = r * 1103515245 + 12345;
        }
    }

  if (buf > file_buffer)
    {
      apr_size_t ignore_length;
      apr_file_write_full (fp, file_buffer, buf - file_buffer, &ignore_length);
      buf = file_buffer;
    }
  rewind_file (fp);

  if (dump_files)
    dump_file_contents (fp);

  return fp;
}

/* Compare two open files. The file positions may change. */
static svn_error_t *
compare_files (apr_file_t *f1, apr_file_t *f2, int dump_files)
{
  static char file_buffer_1[10240];
  static char file_buffer_2[10240];

  char *c1, *c2;
  apr_off_t pos = 0;
  apr_size_t len1, len2;

  rewind_file (f1);
  rewind_file (f2);

  if (dump_files)
    dump_file_contents (f2);

  do
    {
      apr_file_read_full(f1, file_buffer_1, sizeof file_buffer_1, &len1);
      apr_file_read_full(f2, file_buffer_2, sizeof file_buffer_2, &len2);

      for (c1 = file_buffer_1, c2 = file_buffer_2;
           c1 < file_buffer_1 + len1 && c2 < file_buffer_2 + len2;
           ++c1, ++c2, ++pos)
        {
          if (*c1 != *c2)
            return svn_error_createf (SVN_ERR_TEST_FAILED, NULL,
                                      "mismatch at position %"APR_OFF_T_FMT,
                                      pos);
        }

      if (len1 != len2)
        return svn_error_createf (SVN_ERR_TEST_FAILED, NULL,
                                  "unequal file sizes at position"
                                  " %"APR_OFF_T_FMT, pos);
    }
  while (len1 == sizeof file_buffer_1);
  return SVN_NO_ERROR;
}


static apr_file_t *
copy_tempfile (apr_file_t *fp, apr_pool_t *pool)
{
  static char file_buffer[10240];
  apr_file_t *newfp;
  apr_size_t length1, length2;

  newfp = open_tempfile ("copy_XXXXXX", pool);

  rewind_file (fp);
  do
    {
      apr_file_read_full (fp, file_buffer, sizeof file_buffer, &length1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -