blob: 42b30e23eb152c2f8b001af0fc2aa829035b0702 [file] [log] [blame]
/*
* translate-test.c -- test the eol and keyword translation subroutine
*
* ====================================================================
* Copyright (c) 2000-2002 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/.
* ====================================================================
*/
/* Advice to those adding new tests to this file:
* ==============================================
*
* Read the doc string for substitute_and_verify(), then read the
* test functions themselves -- they're small, and they'll be very
* easy to understand once you know substitute_and_verify().
*/
#include <stdio.h>
#include <string.h>
#include <apr_general.h>
#include <apr_file_io.h>
#include <apr_time.h>
#include <svn_wc.h>
#include "svn_test.h"
/*** Helpers ***/
/* (Almost) all the tests share the same test data. */
const char *lines[] =
{
"Line 1: fairly boring subst test data... blah blah",
"Line 2: fairly boring subst test data... blah blah.",
"Line 3: Valid $LastChangedRevision$, started unexpanded.",
"Line 4: fairly boring subst test data... blah blah.",
"Line 5: Valid $Rev$, started unexpanded.",
"Line 6: fairly boring subst test data... blah blah.",
"Line 7: fairly boring subst test data... blah blah.",
"Line 8: Valid $LastChangedBy$, started unexpanded.",
"Line 9: Valid $Author$, started unexpanded.",
"Line 10: fairly boring subst test data... blah blah.",
"Line 11: fairly boring subst test data... blah blah.",
"Line 12: Valid $LastChangedDate$, started unexpanded.",
"Line 13: Valid $Date$, started unexpanded.",
"Line 14: fairly boring subst test data... blah blah.",
"Line 15: fairly boring subst test data... blah blah.",
"Line 16: Valid $HeadURL$, started unexpanded.",
"Line 17: Valid $URL$, started unexpanded.",
"Line 18: fairly boring subst test data... blah blah.",
"Line 19: Invalid expanded keyword spanning two lines: $Author: ",
/* The idea here is that, were it not broken across two lines,
"$Author: Line 20: jrandom$" would be a valid if odd, keyword. */
"Line 20: jrandom$ remainder of invalid keyword spanning two lines.",
"Line 21: fairly boring subst test data... blah blah.",
"Line 22: an unknown keyword $LastChangedSocks$.",
"Line 23: fairly boring subst test data... blah blah.",
/* In line 24, the third dollar sign terminates the first, and the
fourth should therefore remain a literal dollar sign. */
"Line 24: keyword in a keyword: $Author: $Date$ $",
"Line 25: fairly boring subst test data... blah blah.",
"Line 26: Emptily expanded keyword $Rev: $.",
"Line 27: fairly boring subst test data... blah blah.",
"Line 28: fairly boring subst test data... blah blah.",
"Line 29: Valid $LastChangedRevision: 1729 $, started expanded.",
"Line 30: Valid $Rev: 1729 $, started expanded.",
"Line 31: fairly boring subst test data... blah blah.",
"Line 32: fairly boring subst test data... blah blah.",
"Line 33: Valid $LastChangedDate: 2002-01-01 $, started expanded.",
"Line 34: Valid $Date: 2002-01-01 $, started expanded.",
"Line 35: fairly boring subst test data... blah blah.",
"Line 36: fairly boring subst test data... blah blah.",
"Line 37: Valid $LastChangedBy: jrandom $, started expanded.",
"Line 38: Valid $Author: jrandom $, started expanded.",
"Line 39: fairly boring subst test data... blah blah.",
"Line 40: fairly boring subst test data... blah blah.",
"Line 41: Valid $HeadURL: http://tomato/mauve $, started expanded.",
"Line 42: Valid $URL: http://tomato/mauve $, started expanded.",
"Line 43: fairly boring subst test data... blah blah.",
"Line 44: fairly boring subst test data... blah blah.",
"Line 45: Invalid $LastChangedRevisionWithSuffix$, started unexpanded.",
"Line 46: Invalid $Rev:$ is missing a space.",
"Line 47: fairly boring subst test data... blah blah.",
"Line 48: Two keywords back to back: $Author$$Rev$.",
"Line 49: One keyword, one not, back to back: $Author$Rev$.",
"Line 50: a series of dollar signs $$$$$$$$$$$$$$$$$$$$$$$$$$$$.",
"Line 51: same, but with embedded keyword $$$$$$$$Date$$$$$$$$$$.",
"Line 52: same, with expanded, empty keyword $$$$$$Date: $$$$$$.",
"", /* Lines 53-69 are blank to test consecutive newlines */
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"Line 70: end of subst test data."
};
/* Return a randomly selected eol sequence. */
static const char *
random_eol_marker (void)
{
/* Select a random eol marker from this set. */
static int seeded = 0;
/* ### todo: allowing '\r' to be in this list of possible random
eol_markers causes problems for the current testing framework
which expects a 1:1 ratio of input-line-count to output-line-count.
Problems occur when there are two consecutive line ending markers
where the first is '\r' and the second is '\n' -- our
translation routine reads that as a single '\r\n' which throws
off the linecount on the output side, and fouls up substitute_and_verify.
*/
const char *eol_markers[] = { "\n", "\r\n" };
if (! seeded)
{
srand (1729); /* we want errors to be reproducible */
seeded = 1;
}
return eol_markers[rand()
% ((sizeof (eol_markers)) / (sizeof (*eol_markers)))];
}
/* Create FNAME with global `lines' as initial data. Use EOL_STR as
* the end-of-line marker between lines, or if EOL_STR is NULL, choose
* a random marker at each opportunity. Use POOL for any temporary
* allocation.
*/
static svn_error_t *
create_file (const char *fname, const char *eol_str, apr_pool_t *pool)
{
apr_status_t apr_err;
apr_file_t *f;
int i, j;
apr_err = apr_file_open (&f, fname,
(APR_WRITE | APR_CREATE | APR_EXCL | APR_BINARY),
APR_OS_DEFAULT, pool);
if (! APR_STATUS_IS_SUCCESS (apr_err))
return svn_error_create (apr_err, 0, NULL, pool, fname);
for (i = 0; i < (sizeof (lines) / sizeof (*lines)); i++)
{
const char *this_eol_str = eol_str ? eol_str : random_eol_marker ();
apr_err = apr_file_printf (f, lines[i]);
/* Is it overly paranoid to use putc(), because of worry about
fprintf() doing a newline conversion? */
for (j = 0; this_eol_str[j]; j++)
{
apr_err = apr_file_putc (this_eol_str[j], f);
if (! APR_STATUS_IS_SUCCESS (apr_err))
return svn_error_create (apr_err, 0, NULL, pool, fname);
}
}
apr_err = apr_file_close (f);
if (! APR_STATUS_IS_SUCCESS (apr_err))
return svn_error_create (apr_err, 0, NULL, pool, fname);
return SVN_NO_ERROR;
}
/* If FNAME is a regular file, remove it; if it doesn't exist at all,
return success. Otherwise, return error. */
static svn_error_t *
remove_file (const char *fname, apr_pool_t *pool)
{
apr_status_t apr_err;
apr_finfo_t finfo;
if (APR_STATUS_IS_SUCCESS (apr_stat (&finfo, fname, APR_FINFO_TYPE, pool)))
{
if (finfo.filetype == APR_REG)
{
apr_err = apr_file_remove (fname, pool);
if (! APR_STATUS_IS_SUCCESS (apr_err))
return svn_error_create (apr_err, 0, NULL, pool, fname);
}
else
return svn_error_createf (SVN_ERR_TEST_FAILED, 0, NULL, pool,
"non-file `%s' is in the way", fname);
}
return SVN_NO_ERROR;
}
/* Set up, run, and verify the results of a substitution.
*
* Create a file TEST_NAME.src using global `lines' as the initial
* data, with SRC_EOL as the line separator, then convert it to file
* TEST_NAME.dst (using DST_EOL, REPAIR, EXPAND, REV, AUTHOR, DATE,
* and URL as svn_wc_copy_and_translate() does), and verify that the
* conversion worked. Null SRC_EOL means create a mixed eol src
* file.
*
* If the verification succeeds, remove both files and return
* SVN_NO_ERROR.
*
* If the verification fails, leave the files for post-mortem. If the
* failure is due to non-eol data being wrong, return
* SVN_ERR_MALFORMED_FILE. If the problem is an incorrect eol marker,
* return SVN_ERR_CORRUPT_EOL. If the problem is that a mixed eol
* style was repaired even though no repair flag was passed, return
* SVN_ERR_TEST_FAILED.
*
* Use POOL for temporary allocation.
*
* Note: as with svn_wc_copy_and_translate(), if any of DST_EOL, REV,
* AUTHOR, DATE, and/or URL is null, then that substitution is not
* performed.
*/
static svn_error_t *
substitute_and_verify (const char *test_name,
const char *src_eol,
const char *dst_eol,
svn_boolean_t repair,
const char *rev,
const char *date,
const char *author,
const char *url,
svn_boolean_t expand,
apr_pool_t *pool)
{
svn_error_t *err;
svn_stringbuf_t *contents;
svn_wc_keywords_t keywords;
int idx = 0;
int i;
const char *expect[(sizeof (lines) / sizeof (*lines))];
const char *src_fname = apr_pstrcat (pool, test_name, ".src", NULL);
const char *dst_fname = apr_pstrcat (pool, test_name, ".dst", NULL);
/** Clean up from previous tests, set up src data, and convert. **/
SVN_ERR (remove_file (src_fname, pool));
SVN_ERR (remove_file (dst_fname, pool));
SVN_ERR (create_file (src_fname, src_eol, pool));
keywords.revision = rev ? svn_string_create (rev, pool) : NULL;
keywords.date = date ? svn_string_create (date, pool) : NULL;
keywords.author = author ? svn_string_create (author, pool) : NULL;
keywords.url = url ? svn_string_create (url, pool) : NULL;
err = svn_wc_copy_and_translate (src_fname, dst_fname, dst_eol, repair,
&keywords, expand, pool);
/* Conversion should have failed, if src has mixed eol, and the
repair flag was not set, and we requested eol translation. */
if ((! src_eol) && dst_eol && (! repair))
{
if (! err)
{
return svn_error_createf
(SVN_ERR_TEST_FAILED, 0, NULL, pool,
"translation of %s should have failed, but didn't", src_fname);
}
else if (err->apr_err != SVN_ERR_IO_INCONSISTENT_EOL)
{
char buf[1024];
svn_strerror (err->apr_err, buf, sizeof (buf));
return svn_error_createf
(SVN_ERR_TEST_FAILED, 0, NULL, pool,
"translation of %s should fail, but not with error \"%s\"",
src_fname, buf);
}
else
return SVN_NO_ERROR;
}
else if (err)
return err;
/** Verify that the conversion worked. **/
for (i = 0; i < (sizeof (expect) / sizeof (*expect)); i++)
expect[i] = lines[i];
/* Certain lines contain keywords; expect their expansions. */
if (rev)
{
if (expand)
{
expect[3 - 1] =
apr_pstrcat (pool, "Line 3: ",
"Valid $LastChangedRevision: ",
rev,
" $, started unexpanded.",
NULL);
expect[5 - 1] =
apr_pstrcat (pool, "Line 5: ",
"Valid $Rev: ", rev, " $, started unexpanded.",
NULL);
expect[26 - 1] =
apr_pstrcat (pool, "Line 26: ",
"Emptily expanded keyword $Rev: ", rev," $.",
NULL);
expect[29 - 1] =
apr_pstrcat (pool, "Line 29: ",
"Valid $LastChangedRevision: ",
rev,
" $, started expanded.",
NULL);
expect[30 - 1] =
apr_pstrcat (pool, "Line 30: ",
"Valid $Rev: ",
rev,
" $, started expanded.",
NULL);
}
else /* unexpand */
{
/* Lines 3 and 5 remain unchanged. */
expect[26 - 1] = "Line 26: Emptily expanded keyword $Rev$.";
expect[29 - 1] =
"Line 29: Valid $LastChangedRevision$, started expanded.";
expect[30 - 1] =
"Line 30: Valid $Rev$, started expanded.";
}
}
if (date)
{
if (expand)
{
expect[12 - 1] =
apr_pstrcat (pool, "Line 12: ",
"Valid $LastChangedDate: ",
date,
" $, started unexpanded.",
NULL);
expect[13 - 1] =
apr_pstrcat (pool, "Line 13: ",
"Valid $Date: ", date, " $, started unexpanded.",
NULL);
expect[33 - 1] =
apr_pstrcat (pool, "Line 33: ",
"Valid $LastChangedDate: ",
date,
" $, started expanded.",
NULL);
expect[34 - 1] =
apr_pstrcat (pool, "Line 34: ",
"Valid $Date: ", date, " $, started expanded.",
NULL);
expect[51 - 1] =
apr_pstrcat (pool, "Line 51: ",
"same, but with embedded keyword ",
"$$$$$$$$Date: ", date, " $$$$$$$$$$.",
NULL);
expect[52 - 1] =
apr_pstrcat (pool, "Line 52: ",
"same, with expanded, empty keyword ",
"$$$$$$Date: ", date, " $$$$$$.",
NULL);
}
else /* unexpand */
{
/* Lines 12 and 13 remain unchanged. */
expect[33 - 1] =
"Line 33: Valid $LastChangedDate$, started expanded.";
expect[34 - 1] =
"Line 34: Valid $Date$, started expanded.";
expect[51 - 1] =
"Line 51: same, but with embedded keyword $$$$$$$$Date$$$$$$$$$$.";
expect[52 - 1] =
"Line 52: same, with expanded, empty keyword $$$$$$Date$$$$$$.";
}
}
if (author)
{
if (expand)
{
expect[8 - 1] =
apr_pstrcat (pool, "Line 8: ",
"Valid $LastChangedBy: ",
author,
" $, started unexpanded.",
NULL);
expect[9 - 1] =
apr_pstrcat (pool, "Line 9: ",
"Valid $Author: ", author, " $, started unexpanded.",
NULL);
expect[37 - 1] =
apr_pstrcat (pool, "Line 37: ",
"Valid $LastChangedBy: ", author,
" $, started expanded.", NULL);
expect[38 - 1] =
apr_pstrcat (pool, "Line 38: ",
"Valid $Author: ", author, " $, started expanded.",
NULL);
}
else /* unexpand */
{
/* Lines 8 and 9 remain unchanged. */
expect[37 - 1] =
"Line 37: Valid $LastChangedBy$, started expanded.";
expect[38 - 1] =
"Line 38: Valid $Author$, started expanded.";
}
}
if (url)
{
if (expand)
{
expect[16 - 1] =
apr_pstrcat (pool, "Line 16: ",
"Valid $HeadURL: ", url, " $, started unexpanded.",
NULL);
expect[17 - 1] =
apr_pstrcat (pool, "Line 17: ",
"Valid $URL: ", url, " $, started unexpanded.",
NULL);
expect[41 - 1] =
apr_pstrcat (pool, "Line 41: ",
"Valid $HeadURL: ", url, " $, started expanded.",
NULL);
expect[42 - 1] =
apr_pstrcat (pool, "Line 42: ",
"Valid $URL: ", url, " $, started expanded.",
NULL);
}
else /* unexpand */
{
/* Lines 16 and 17 and remain unchanged. */
expect[41 - 1] =
"Line 41: Valid $HeadURL$, started expanded.";
expect[42 - 1] =
"Line 42: Valid $URL$, started expanded.";
}
}
/* Handle line 48 specially, as it contains two valid keywords. */
if (rev && author)
{
if (expand)
{
expect[48 - 1] =
apr_pstrcat (pool, "Line 48: ",
"Two keywords back to back: "
"$Author: ", author, " $"
"$Rev: ", rev, " $.",
NULL);
expect[49 - 1] =
apr_pstrcat (pool, "Line 49: ",
"One keyword, one not, back to back: "
"$Author: ", author, " $Rev$.",
NULL);
}
/* Else Lines 48 and 49 remain unchanged. */
}
else if (rev && (! author))
{
if (expand)
{
expect[48 - 1] =
apr_pstrcat (pool, "Line 48: ",
"Two keywords back to back: "
"$Author$$Rev: ", rev, " $.",
NULL);
expect[49 - 1] =
apr_pstrcat (pool, "Line 49: ",
"One keyword, one not, back to back: "
"$Author$Rev: ", rev, " $.",
NULL);
}
/* Else Lines 48 and 49 remain unchanged. */
}
else if ((! rev) && author)
{
if (expand)
{
expect[48 - 1] =
apr_pstrcat (pool, "Line 48: ",
"Two keywords back to back: "
"$Author: ", author, " $$Rev$.",
NULL);
expect[49 - 1] =
apr_pstrcat (pool, "Line 49: ",
"One keyword, one not, back to back: "
"$Author: ", author, " $Rev$.",
NULL);
}
/* Else Lines 48 and 49 remain unchanged. */
}
/* Else neither rev nor author, so Lines 48 and 49 remain unchanged. */
/* Handle line 24 specially, as it contains two valid keywords. */
if (date && author)
{
if (expand)
{
expect[24 - 1] =
apr_pstrcat (pool, "Line 24: ",
"keyword in a keyword: $Author: ",
author,
" $Date$ $",
NULL);
}
else /* unexpand */
{
expect[24 - 1] =
apr_pstrcat (pool, "Line 24: ",
"keyword in a keyword: $Author$Date$ $",
NULL);
}
}
else if (date && (! author))
{
if (expand)
{
expect[24 - 1] =
apr_pstrcat (pool, "Line 24: ",
"keyword in a keyword: $Author: $Date: ",
date,
" $ $",
NULL);
}
/* Else Line 24 remains unchanged. */
}
else if ((! date) && author)
{
if (expand)
{
expect[24 - 1] =
apr_pstrcat (pool, "Line 24: ",
"keyword in a keyword: $Author: ",
author,
" $Date$ $",
NULL);
}
else /* unexpand */
{
expect[24 - 1] =
apr_pstrcat (pool, "Line 24: ",
"keyword in a keyword: $Author$Date$ $",
NULL);
}
}
/* Else neither author nor date, so Line 24 remains unchanged. */
/** Ready to verify. **/
SVN_ERR (svn_string_from_file (&contents, dst_fname, pool));
for (i = 0; i < (sizeof (expect) / sizeof (*expect)); i++)
{
if (contents->len < idx)
return svn_error_createf
(SVN_ERR_MALFORMED_FILE, 0, NULL, pool,
"%s has short contents at line %d", dst_fname, i + 1);
if (strncmp (contents->data + idx, expect[i], strlen (expect[i])) != 0)
return svn_error_createf
(SVN_ERR_MALFORMED_FILE, 0, NULL, pool,
"%s has wrong contents at line %d", dst_fname, i + 1);
/* Else, the data is correct, at least up to the next eol. */
idx += strlen (expect[i]);
if (dst_eol) /* verify the promised consistent eol style */
{
if (strncmp (contents->data + idx, dst_eol, strlen (dst_eol)) != 0)
return svn_error_createf
(SVN_ERR_IO_CORRUPT_EOL, 0, NULL, pool,
"%s has wrong eol style at line %d", dst_fname, i + 1);
else
idx += strlen (dst_eol);
}
else /* allow any eol style, even inconsistent ones, loosely */
{
while ((*(contents->data + idx) == '\r')
|| (*(contents->data + idx) == '\n'))
idx++;
}
}
/* Clean up this test, since successful. */
SVN_ERR (remove_file (src_fname, pool));
SVN_ERR (remove_file (dst_fname, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
noop (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "no conversions";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("noop", NULL, NULL, 0, NULL, NULL, NULL, NULL, 1, pool));
SVN_ERR (substitute_and_verify
("noop", "\r", NULL, 0, NULL, NULL, NULL, NULL, 1, pool));
SVN_ERR (substitute_and_verify
("noop", "\n", NULL, 0, NULL, NULL, NULL, NULL, 1, pool));
SVN_ERR (substitute_and_verify
("noop", "\r\n", NULL, 0, NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
/** EOL conversion alone. **/
static svn_error_t *
crlf_to_crlf (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert CRLF to CRLF";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("crlf_to_crlf", "\r\n", "\r\n", 0,
NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
lf_to_crlf (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert LF to CRLF";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("lf_to_crlf", "\n", "\r\n", 0, NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
cr_to_crlf (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert CR to CRLF";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("cr_to_crlf", "\r", "\r\n", 0, NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
mixed_to_crlf (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert mixed line endings to CRLF";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("mixed_to_crlf", NULL, "\r\n", 1,
NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
lf_to_lf (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert LF to LF";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("lf_to_lf", "\n", "\n", 0, NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
crlf_to_lf (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert CRLF to LF";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("crlf_to_lf", "\r\n", "\n", 0, NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
cr_to_lf (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert CR to LF";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("cr_to_lf", "\r", "\n", 0, NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
mixed_to_lf (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert mixed line endings to LF";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("cr_to_lf", NULL, "\n", 1, NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
crlf_to_cr (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert CRLF to CR";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("crlf_to_cr", "\r\n", "\r", 0, NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
lf_to_cr (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert LF to CR";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("lf_to_cr", "\n", "\r", 0, NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
cr_to_cr (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert CR to CR";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("cr_to_cr", "\r", "\r", 0, NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
mixed_to_cr (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "convert mixed line endings to CR";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("mixed_to_cr", NULL, "\r", 1, NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
mixed_no_repair (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "don't convert mixed line endings in absence of repair flag";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("mixed_no_repair", NULL, "\n", 0,
NULL, NULL, NULL, NULL, 1, pool));
SVN_ERR (substitute_and_verify
("mixed_no_repair", NULL, "\r\n", 0,
NULL, NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
/** Keyword expansion alone. **/
static svn_error_t *
expand_author (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "expand author keyword";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("author", "\n", NULL, 0, NULL, NULL, "jrandom", NULL, 1, pool));
SVN_ERR (substitute_and_verify
("author", "\r\n", NULL, 0, NULL, NULL, "jrandom", NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
expand_date (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "expand date keyword";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("date", "\n", NULL, 0,
NULL, "Wed Jan 9 07:49:05 2002", NULL, NULL, 1, pool));
SVN_ERR (substitute_and_verify
("date", "\r\n", NULL, 0,
NULL, "Wed Jan 9 07:49:05 2002", NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
expand_author_date (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "expand author and date keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("author_date", "\n", NULL, 0,
NULL, "Wed Jan 9 07:49:05 2002", "jrandom", NULL, 1, pool));
SVN_ERR (substitute_and_verify
("author_date", "\r\n", NULL, 0,
NULL, "Wed Jan 9 07:49:05 2002", "jrandom", NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
expand_author_rev (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "expand author and rev keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("author_rev", "\n", NULL, 0,
"1729", NULL, "jrandom", NULL, 1, pool));
SVN_ERR (substitute_and_verify
("author_rev", "\r\n", NULL, 0,
"1729", NULL, "jrandom", NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
expand_rev (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "expand rev keyword";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("rev", "\n", NULL, 0,
"1729", NULL, NULL, NULL, 1, pool));
SVN_ERR (substitute_and_verify
("rev", "\r\n", NULL, 0,
"1729", NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
expand_rev_url (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "expand rev and url keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("rev_url", "\n", NULL, 0,
"1729", NULL, NULL, "http://subversion.tigris.org", 1, pool));
SVN_ERR (substitute_and_verify
("rev_url", "\r\n", NULL, 0,
"1729", NULL, NULL, "http://subversion.tigris.org", 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
expand_author_date_rev_url (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "expand author, date, rev, and url keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("author_date_rev_url", "\n", NULL, 0,
"1729",
"Wed Jan 9 07:49:05 2002",
"jrandom",
"http://subversion.tigris.org",
1, pool));
SVN_ERR (substitute_and_verify
("author_date_rev_url", "\r\n", NULL, 0,
"1729",
"Wed Jan 9 07:49:05 2002",
"jrandom",
"http://subversion.tigris.org",
1, pool));
return SVN_NO_ERROR;
}
/** Keyword expansion and EOL conversion together. **/
static svn_error_t *
lf_to_crlf_expand_author (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "lf_to_crlf, plus expand author keyword";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("lf_to_crlf_author", "\n", "\r\n", 0,
NULL, NULL, "jrandom", NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
mixed_to_lf_expand_author_date (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "mixed_to_lf, plus expand author and date keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("mixed_to_lf_author_date", NULL, "\n", 1,
NULL, "Wed Jan 9 07:49:05 2002", "jrandom", NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
crlf_to_cr_expand_author_rev (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "crlf_to_cr, plus expand author and rev keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("crlf_to_cr_author_rev", "\r\n", "\r", 0,
"1729", NULL, "jrandom", NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
cr_to_crlf_expand_rev (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "cr_to_crlf, plus expand rev keyword";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("cr_to_crlf_rev", "\r", "\r\n", 0,
"1729", NULL, NULL, NULL, 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
cr_to_crlf_expand_rev_url (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "cr_to_crlf, plus expand rev and url keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("cr_to_crlf_rev_url", "\r", "\r\n", 0,
"1729", NULL, NULL, "http://subversion.tigris.org", 1, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
mixed_to_crlf_expand_author_date_rev_url (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "mixed_to_crlf, plus expand author, date, rev, and url keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("mixed_to_crlf_author_date_rev_url", NULL, "\r\n", 1,
"1729",
"Wed Jan 9 07:49:05 2002",
"jrandom",
"http://subversion.tigris.org",
1,
pool));
return SVN_NO_ERROR;
}
/** Keyword unexpansion alone. **/
static svn_error_t *
unexpand_author (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "unexpand author keyword";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("author", "\n", NULL, 0, NULL, NULL, "jrandom", NULL, 0, pool));
SVN_ERR (substitute_and_verify
("author", "\r\n", NULL, 0, NULL, NULL, "jrandom", NULL, 0, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
unexpand_date (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "unexpand date keyword";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("date", "\n", NULL, 0,
NULL, "Wed Jan 9 07:49:05 2002", NULL, NULL, 0, pool));
SVN_ERR (substitute_and_verify
("date", "\r\n", NULL, 0,
NULL, "Wed Jan 9 07:49:05 2002", NULL, NULL, 0, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
unexpand_author_date (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "unexpand author and date keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("author_date", "\n", NULL, 0,
NULL, "Wed Jan 9 07:49:05 2002", "jrandom", NULL, 0, pool));
SVN_ERR (substitute_and_verify
("author_date", "\r\n", NULL, 0,
NULL, "Wed Jan 9 07:49:05 2002", "jrandom", NULL, 0, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
unexpand_author_rev (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "unexpand author and rev keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("author_rev", "\n", NULL, 0,
"1729", NULL, "jrandom", NULL, 0, pool));
SVN_ERR (substitute_and_verify
("author_rev", "\r\n", NULL, 0,
"1729", NULL, "jrandom", NULL, 0, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
unexpand_rev (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "unexpand rev keyword";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("rev", "\n", NULL, 0,
"1729", NULL, NULL, NULL, 0, pool));
SVN_ERR (substitute_and_verify
("rev", "\r\n", NULL, 0,
"1729", NULL, NULL, NULL, 0, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
unexpand_rev_url (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "unexpand rev and url keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("rev_url", "\n", NULL, 0,
"1729", NULL, NULL, "http://subversion.tigris.org", 0, pool));
SVN_ERR (substitute_and_verify
("rev_url", "\r\n", NULL, 0,
"1729", NULL, NULL, "http://subversion.tigris.org", 0, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
unexpand_author_date_rev_url (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "unexpand author, date, rev, and url keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("author_date_rev_url", "\n", NULL, 0,
"1729",
"Wed Jan 9 07:49:05 2002",
"jrandom",
"http://subversion.tigris.org",
1, pool));
SVN_ERR (substitute_and_verify
("author_date_rev_url", "\r\n", NULL, 0,
"1729",
"Wed Jan 9 07:49:05 2002",
"jrandom",
"http://subversion.tigris.org",
1, pool));
return SVN_NO_ERROR;
}
/** Keyword unexpansion and EOL conversion together. **/
static svn_error_t *
lf_to_crlf_unexpand_author (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "lf_to_crlf, plus unexpand author keyword";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("lf_to_crlf_author", "\n", "\r\n", 0,
NULL, NULL, "jrandom", NULL, 0, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
mixed_to_lf_unexpand_author_date (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "mixed_to_lf, plus unexpand author and date keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("mixed_to_lf_author_date", NULL, "\n", 1,
NULL, "Wed Jan 9 07:49:05 2002", "jrandom", NULL, 0, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
crlf_to_cr_unexpand_author_rev (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "crlf_to_cr, plus unexpand author and rev keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("crlf_to_cr_author_rev", "\r\n", "\r", 0,
"1729", NULL, "jrandom", NULL, 0, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
cr_to_crlf_unexpand_rev (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "cr_to_crlf, plus unexpand rev keyword";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("cr_to_crlf_rev", "\r", "\r\n", 0,
"1729", NULL, NULL, NULL, 0, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
cr_to_crlf_unexpand_rev_url (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "cr_to_crlf, plus unexpand rev and url keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("cr_to_crlf_rev_url", "\r", "\r\n", 0,
"1729", NULL, NULL, "http://subversion.tigris.org", 0, pool));
return SVN_NO_ERROR;
}
static svn_error_t *
mixed_to_crlf_unexpand_author_date_rev_url (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool)
{
*msg = "mixed_to_crlf, plus unexpand author, date, rev, and url keywords";
if (msg_only)
return SVN_NO_ERROR;
SVN_ERR (substitute_and_verify
("mixed_to_crlf_author_date_rev_url", NULL, "\r\n", 1,
"1729",
"Wed Jan 9 07:49:05 2002",
"jrandom",
"http://subversion.tigris.org",
0,
pool));
return SVN_NO_ERROR;
}
/* The test table. */
svn_error_t * (*test_funcs[]) (const char **msg,
svn_boolean_t msg_only,
apr_pool_t *pool) = {
0,
/* The no-op conversion. */
noop,
/* Conversions resulting in crlf, no keywords involved. */
crlf_to_crlf,
lf_to_crlf,
cr_to_crlf,
mixed_to_crlf,
/* Conversions resulting in lf, no keywords involved. */
lf_to_lf,
crlf_to_lf,
cr_to_lf,
mixed_to_lf,
/* Conversions resulting in cr, no keywords involved. */
crlf_to_cr,
lf_to_cr,
cr_to_cr,
mixed_to_cr,
/* Random eol stuff. */
mixed_no_repair,
/* Keyword expansion alone, no eol conversion involved. */
expand_author,
expand_date,
expand_author_date,
expand_author_rev,
expand_rev,
expand_rev_url,
expand_author_date_rev_url,
/* Keyword expansion and eol conversion together. */
lf_to_crlf_expand_author,
mixed_to_lf_expand_author_date,
crlf_to_cr_expand_author_rev,
cr_to_crlf_expand_rev,
cr_to_crlf_expand_rev_url,
mixed_to_crlf_expand_author_date_rev_url,
/* Keyword unexpansion alone, no eol conversion involved. */
unexpand_author,
unexpand_date,
unexpand_author_date,
unexpand_author_rev,
unexpand_rev,
unexpand_rev_url,
unexpand_author_date_rev_url,
/* Keyword unexpansion and eol conversion together. */
lf_to_crlf_unexpand_author,
mixed_to_lf_unexpand_author_date,
crlf_to_cr_unexpand_author_rev,
cr_to_crlf_unexpand_rev,
cr_to_crlf_unexpand_rev_url,
mixed_to_crlf_unexpand_author_date_rev_url,
0
};
/*
* local variables:
* eval: (load-file "../../../tools/dev/svn-dev.el")
* end:
*/