/* tag: Tom Lord Tue Dec 4 14:41:22 2001 (test-time-re.c)
*/
/* time-re.c - timing test for rx-xml
*
****************************************************************
* Copyright (C) 2001 Tom Lord
*
* See the file "COPYING" for further information about
* the copyright and warranty status of this work.
*/
#include "hackerlab/cmd/main.h"
#include "hackerlab/rx-xml/re.h"
static t_uchar * program_name = "time-re";
static t_uchar * usage = "[options]";
static t_uchar * version_string = "1.0";
#define OPTS(OP, OP2) \
OP (opt_help_msg, "h", "help", 0, \
"Display a help message and exit.") \
OP (opt_version, "V", "version", 0, \
"Display a release identifier string") \
OP2 (opt_version, 0, 0, 0, "and exit.") \
OP (opt_verbose, "v", "verbose", 0, \
"Print cache usage information.") \
OP (opt_monoscript, "m", "monoscript", 0, \
"Don't use lots of different scripts in the tests.") \
OP (opt_utf16, 0, "utf16", 0, \
"Test matching utf16 strings.") \
OP (opt_iterations, "i", "iterations=N", 1, \
"Set the number of test iterations.") \
OP (opt_dfa_cache_threshold, "D", "dfa-cache-threshold=N", 1, \
"Set the DFA cache GC threshold.") \
OP (opt_nfa_cache_threshold, "N", "nfa-cache-threshold=N", 1, \
"Set the NFA cache GC threshold.")
enum options
{
OPTS (OPT_ENUM, OPT_IGN)
};
struct opt_desc opts[] =
{
OPTS (OPT_DESC, OPT_DESC)
{-1, 0, 0, 0, 0}
};
static t_uchar * test_exp = "\\p{Ll}{4}-\\p{Nd}{5}";
#define N_TESTS 6
static t_uchar * test_strings[N_TESTS] =
{
"lmnop-09876",
"\\u03ac\\u03ad\\u03ae\\u03af-12345",
"abcd-13579",
"\\u0255\\u0256\\u0257\\u0258-67890",
"\\u0561\\u0562\\u0563\\u0564-24680",
"\\u00e0\\u00e1\\u00e2\\u00e3-\\u0966\\u0967\\u0968\\u0969\\u096a",
};
#define BUF_SIZE 1024
static t_uchar utf16_tests[N_TESTS][BUF_SIZE];
static size_t utf16_test_sizes[N_TESTS];
static t_uchar utf8_tests[N_TESTS][BUF_SIZE];
static size_t utf8_test_sizes[N_TESTS];
static size_t
translate_str (enum uni_encoding_scheme encoding, t_uchar * output, t_uchar * input)
{
size_t input_pos;
size_t input_len;
size_t output_pos;
size_t output_len;
input_pos = 0;
input_len = str_length (input);
output_pos = 0;
output_len = BUF_SIZE;
while (input_pos < input_len)
{
t_unicode c;
c = input[input_pos++];
if ( (c == '\\')
&& (input_pos < input_len)
&& (input[input_pos] == 'u'))
{
int errn;
unsigned long x;
if ( ((input_pos + 5) > input_len)
|| (cvt_hex_to_ulong (&errn, &x, input + input_pos + 1, 4)))
panic ("bogus escape in test string");
c = x;
input_pos += 5;
}
switch (encoding)
{
case uni_utf8:
uni_utf8_iput (output, &output_pos, output_len, c);
break;
case uni_utf16:
uni_utf16_iput (output, &output_pos, output_len, c);
break;
default:
panic ("coding error in unit-re.c");
}
}
return output_pos;
}
static void
init_tests (void)
{
int x;
for (x = 0; x < N_TESTS; ++x)
{
utf16_test_sizes[x] = translate_str (uni_utf16, utf16_tests[x], test_strings[x]);
utf8_test_sizes[x] = translate_str (uni_utf8, utf8_tests[x], test_strings[x]);
}
}
int
main (int argc, char * argv[])
{
int errn;
int o;
struct opt_parsed * option;
enum uni_encoding_scheme encoding;
unsigned long cache_size;
unsigned long iterations;
int verbose;
int monoscript;
option = 0;
encoding = uni_utf8;
iterations = 150000;
verbose = 0;
monoscript = 0;
while (1)
{
o = opt_standard (lim_use_must_malloc, &option, opts, &argc, argv, program_name, usage, version_string, opt_help_msg, opt_version);
if (o == opt_none)
break;
switch (o)
{
default:
safe_printfmt (2, "unhandled option `%s'\n", option->opt_string);
panic ("internal error parsing arguments");
usage_error:
opt_usage (2, argv[0], program_name, usage, 1);
panic_exit ();
bogus_arg:
safe_printfmt (2, "ill-formed argument for `%s' (`%s')\n", option->opt_string, option->arg_string);
goto usage_error;
case opt_dfa_cache_threshold:
if (cvt_decimal_to_ulong (&errn, &cache_size, option->arg_string, str_length (option->arg_string)))
goto bogus_arg;
rx_set_dfa_cache_threshold ((size_t)cache_size);
break;
case opt_nfa_cache_threshold:
if (cvt_decimal_to_ulong (&errn, &cache_size, option->arg_string, str_length (option->arg_string)))
goto bogus_arg;
rx_set_nfa_cache_threshold ((size_t)cache_size);
break;
case opt_iterations:
if (cvt_decimal_to_ulong (&errn, &iterations, option->arg_string, str_length (option->arg_string)))
goto bogus_arg;
break;
case opt_utf16:
encoding = uni_utf16;
break;
case opt_verbose:
verbose = 1;
break;
case opt_monoscript:
monoscript = 1;
break;
}
}
init_tests ();
{
int outer;
rx_xml_rebuf re;
if (rx_xml_recomp (&re, uni_iso8859_1, (uni_string)test_exp, str_length (test_exp)))
panic ("unable to compile regexp");
for (outer = 0; outer < iterations; ++outer)
{
int inner;
for (inner = 0; inner < N_TESTS; ++inner)
{
int matches;
enum rx_xml_rematch_errno errn;
int test;
if (inner && monoscript)
test = 1;
else
test = inner;
matches = rx_xml_is_match (&errn, &re, encoding,
(uni_string)(encoding == uni_utf8 ? utf8_tests[test] : utf16_tests[test]),
(encoding == uni_utf8 ? utf8_test_sizes[test] : utf16_test_sizes[test] / 2));
if (matches && (inner == 0))
panic ("bogus string matched");
else if (matches < 0)
panic ("error during match");
}
}
}
if (verbose)
{
{
size_t threshold;
size_t failure_pt;
size_t in_use;
size_t high_water_mark;
int dfa_hits;
int dfa_misses;
int dfa_total_hits;
int dfa_total_misses;
rx_dfa_cache_statistics (&threshold, &failure_pt, &in_use, &high_water_mark, &dfa_hits, &dfa_misses, &dfa_total_hits, &dfa_total_misses);
safe_printfmt (1, "dfa cache stats:\n threshold %lu; failure_pt %lu\n in_use %lu; high_water_mark %lu\n hits %d; misses %d; total_hits %d; total_misses %d\n",
(unsigned long)threshold,
(unsigned long)failure_pt,
(unsigned long)in_use,
(unsigned long)high_water_mark,
dfa_hits, dfa_misses, dfa_total_hits, dfa_total_misses);
}
{
size_t threshold;
size_t failure_pt;
size_t in_use;
size_t high_water_mark;
int nfa_hits;
int nfa_misses;
int nfa_saves;
rx_nfa_cache_statistics (&threshold, &failure_pt, &in_use, &high_water_mark, &nfa_hits, &nfa_misses, &nfa_saves);
safe_printfmt (1, "nfa cache stats:\n threshold %lu; failure_pt %lu\n in_use %lu; high_water_mark %lu\n hits %d; misses %d; saves %d\n",
(unsigned long)threshold,
(unsigned long)failure_pt,
(unsigned long)in_use,
(unsigned long)high_water_mark,
nfa_hits, nfa_misses, nfa_saves);
}
}
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1