Exemple #1
0
inline void test_langen()
{
	test_match();
	test_floatplus();
	test_floatlist();
	//test_conflict();
}
Exemple #2
0
int main(void) {
        sd_rtnl *rtnl;
        sd_rtnl_message *m;
        sd_rtnl_message *r;
        char *string_data;
        int if_loopback;
        uint16_t type;

        test_match();

        test_multiple();

        test_route();

        test_container();

        assert_se(sd_rtnl_open(&rtnl, 0) >= 0);
        assert_se(rtnl);

        if_loopback = (int) if_nametoindex("lo");
        assert_se(if_loopback > 0);

        test_async(if_loopback);

        test_pipe(if_loopback);

        test_event_loop(if_loopback);

        test_link_configure(rtnl, if_loopback);

        test_get_addresses(rtnl);

        assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, if_loopback) >= 0);
        assert_se(m);

        assert_se(sd_rtnl_message_get_type(m, &type) >= 0);
        assert_se(type == RTM_GETLINK);

        assert_se(sd_rtnl_message_read_string(m, IFLA_IFNAME, &string_data) == -EPERM);

        assert_se(sd_rtnl_call(rtnl, m, 0, &r) == 1);
        assert_se(sd_rtnl_message_get_type(r, &type) >= 0);
        assert_se(type == RTM_NEWLINK);

        assert_se((r = sd_rtnl_message_unref(r)) == NULL);

        assert_se(sd_rtnl_call(rtnl, m, -1, &r) == -EPERM);
        assert_se((m = sd_rtnl_message_unref(m)) == NULL);
        assert_se((r = sd_rtnl_message_unref(r)) == NULL);

        test_link_get(rtnl, if_loopback);
        test_address_get(rtnl, if_loopback);

        assert_se(sd_rtnl_flush(rtnl) >= 0);
        assert_se((m = sd_rtnl_message_unref(m)) == NULL);
        assert_se((r = sd_rtnl_message_unref(r)) == NULL);
        assert_se((rtnl = sd_rtnl_unref(rtnl)) == NULL);

        return EXIT_SUCCESS;
}
Exemple #3
0
int main(const int argc, char *argv[])
{
  test_match(argc, argv);
  upserr_output();

  return 1;
}
int main()
{
  test_match("a", "ab*");
  test_match("aa", "a");
  test_match("aa", "aa");
  test_match("aaa", "aa");
  test_match("aa", "a*");
  test_match("aa", ".*");
  test_match("ab", ".*");
  test_match("aab", "c*a*b");
}
static void *run_test_in_thread(void *arg)
{
	struct thr_arg_s *thr_arg=(struct thr_arg_s *)arg;
	int thread_num = thr_arg->thr_num;
	int i=0;

	for(;i<NTEST;i++) test_match(thread_num,i);

	printf("Thread %d: done\n",thread_num);

	return NULL;
}
Exemple #6
0
 int main(){
 	printf("----------------------");
 	printf("|  Executanto Testes Unitarios  |");
 	printf("----------------------");
 	printf("\n");
 	
 	test_match();	
 	test_get_token();
 	test_get_output_token();
 	test_get_output_append_token();
 	
 	return 0;
 }
Exemple #7
0
int main()
{
    test_cpy();
    test_int();
    test_long();
    test_real();
    test_idx();
    test_trim();
    test_split();
    test_match();

    return 0;
}
Exemple #8
0
bool _hs_filter_match_device(const _hs_filter *filter, const hs_device *dev)
{
    // Do the fast checks first
    if (!_hs_filter_has_type(filter, hs_device_get_type(dev)))
        return false;
    if (!filter->count)
        return true;

    for (unsigned int i = 0; i < filter->count; i++) {
        if (test_match(&filter->matches[i], dev))
            return true;
    }

    return false;
}
Exemple #9
0
void test_lpm(struct sr_instance *sr){
    sr_print_routing_table(sr);

    test_match(sr, 107, 23, 53, 142, true, "eth1");
    test_match(sr, 107, 23, 77, 72, true, "eth2");
    test_match(sr, 192, 32, 11, 12, true, "eth3");
    test_match(sr, 122, 12, 15, 16, true, "eth3");
    test_match(sr, 112, 8, 0, 0, true, "eth3");
    test_match(sr, 107, 23, 77, 71, true, "eth3");
    test_match(sr, 0, 0, 0, 0, true, "eth3");

    printf("-------------------All LPM tests passed----------------------\n");

}
Exemple #10
0
int main(int argc, char** argv)
{
	printf("GLOB      TESTS\n");
	printf("====================\n\n");

	init (argc, argv);

	test_match();
	test_zeroMatchFlags();
	test_setGlobalMatch();
	test_setDirectionMatch();
	test_getGlobalMatch();
	test_getDirectionMatch();

	printf("\ntestmod_glob RESULTS: %d test(s) done. %d error(s).\n", nbTest, nbError);

	return nbError;
}
Exemple #11
0
int
main (int argc, char *argv[])
{
  test_split ();
  test_concat ();
  test_join ();
  test_validate_guid ();
  test_drive_name ();
  test_drive_index ();
  test_getumask ();
  test_command ();
  test_qemu_escape_param ();
  test_timeval_diff ();
  test_match ();
  test_stringsbuf ();

  exit (EXIT_SUCCESS);
}
int main()
{
	bool test = false;
	try
	{
		if (!test_match( "[Aa]", "Abcdes")) return -1;
		if (!test_match( "[Aa]+", "aAbcdes")) return -1;
		if (!test_match( "[Aa]+", "xAbcdes")) return -1;
		if (!test_match( "[Aa]+", "xAaabcdes")) return -1;
		if (!test_match( "b([Aa]+)", "xbAaabcdes")) return -1;
		if (!test_match( "b([Aa]+)b", "xbAaabcdes")) return -1;
		if (!test_match( "([Aa]+)b", "xbAaabcdes")) return -1;
		return 0;
	}
	catch (const std::regex_error& err)
	{
		const char* errstr = 0;
		if (err.code() == std::regex_constants::error_collate) errstr = "The expression contained an invalid collating element name";
		else if (err.code() == std::regex_constants::error_ctype) errstr = "The expression contained an invalid character class name";
		else if (err.code() == std::regex_constants::error_escape) errstr = "The expression contained an invalid escaped character, or a trailing escape";
		else if (err.code() == std::regex_constants::error_backref) errstr = "The expression contained an invalid back reference";
		else if (err.code() == std::regex_constants::error_brack) errstr = "The expression contained mismatched brackets ([ and ])";
		else if (err.code() == std::regex_constants::error_paren) errstr = "The expression contained mismatched parentheses (( and ))";
		else if (err.code() == std::regex_constants::error_brace) errstr = "The expression contained mismatched braces ({ and })";
		else if (err.code() == std::regex_constants::error_badbrace) errstr = "The expression contained an invalid range between braces ({ and })";
		else if (err.code() == std::regex_constants::error_range) errstr = "The expression contained an invalid character range";
		else if (err.code() == std::regex_constants::error_space) errstr = "There was insufficient memory to convert the expression into a finite state machine";
		else if (err.code() == std::regex_constants::error_badrepeat) errstr = "The expression contained a repeat specifier (one of *?+{) that was not preceded by a valid regular expression";
		else if (err.code() == std::regex_constants::error_complexity) errstr = "The complexity of an attempted match against a regular expression exceeded a pre-set level";
		else if (err.code() == std::regex_constants::error_stack) errstr = "There was insufficient memory to determine whether the regular expression could match the specified character sequence";
		std::cerr << "ERROR " << (errstr ? errstr : "unknown") << std::endl;
		return 1;
	}
	catch (...)
	{
		return -1;
	}
}
Exemple #13
0
int
main ( int argc, char *argv[] )
{
	int failed = 0;
	int ntest = 2;
	int i;
	newstr s;
	newstr_init( &s );

	/* ...core functions */
	for ( i=0; i<ntest; ++i )
		failed += test_empty( &s );

	/* ...adding functions */
	for ( i=0; i<ntest; ++i)
		failed += test_addchar( &s );
	for ( i=0; i<ntest; ++i)
		failed += test_strcat( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_newstrcat( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_segcat( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_indxcat( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_cattodelim( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_prepend( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_pad( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_mergestrs( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_makepath( &s );

	/* ...copying functions */
	for ( i=0; i<ntest; ++i)
		failed += test_strcpy( &s );
	for ( i=0; i<ntest; ++i)
		failed += test_newstrcpy( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_cpytodelim( &s );
	for ( i=0; i<ntest; ++i)
		failed += test_segcpy( &s );
	for ( i=0; i<ntest; ++i)
		failed += test_indxcpy( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_copyposlen( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_strdup();

	/* ...utility functions */
	for ( i=0; i<ntest; ++i)
		failed += test_findreplace( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_reverse( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_toupper( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_tolower( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_trimws( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_trim( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_case( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_newstrcmp( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_char( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_swapstrings( &s );
	for ( i=0; i<ntest; ++i )
		failed += test_match( &s );

	newstr_free( &s );

	if ( !failed ) {
		printf( "%s: PASSED\n", progname );
		return EXIT_SUCCESS;
	} else {
		printf( "%s: FAILED\n", progname );
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}
Exemple #14
0
inline void test_match(const std::string& re, const std::string& text, bool icase = false)
{ test_match(re, text, text, icase); }
Exemple #15
0
int cpp_main(int argc, char * argv[])
{
   // start by processing the command line args:
   if(argc < 2)
      return show_usage();
   int result = 0;
   for(int c = 1; c < argc; ++c)
   {
      result += handle_argument(argv[c]);
   }
   if(result)
      return result;

   if(test_matches)
   {
      // start with a simple test, this is basically a measure of the minimal overhead
      // involved in calling a regex matcher:
      test_match("abc", "abc");
      // these are from the regex docs:
      test_match("^([0-9]+)(\\-| |$)(.*)$", "100- this is a line of ftp response which contains a message string");
      test_match("([[:digit:]]{4}[- ]){3}[[:digit:]]{3,4}", "1234-5678-1234-456");
      // these are from http://www.regxlib.com/
      test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "*****@*****.**");
      test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "*****@*****.**");
      test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "*****@*****.**");
      test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "EH10 2QQ");
      test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "G1 1AA");
      test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "SW1 1ZZ");
      test_match("^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$", "4/1/2001");
      test_match("^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$", "12/12/2001");
      test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "123");
      test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "+3.14159");
      test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "-3.14159");
   }
   output_html_results(true, "%short_matches%");

   std::string file_contents;

   if(test_code)
   {
      load_file(file_contents, "../../../boost/crc.hpp");

      const char* highlight_expression = // preprocessor directives: index 1
                              "(^[ \t]*#(?:[^\\\\\\n]|\\\\[^\\n_[:punct:][:alnum:]]*[\\n[:punct:][:word:]])*)|"
                              // comment: index 2
                              "(//[^\\n]*|/\\*.*?\\*/)|"
                              // literals: index 3
                              "\\<([+-]?(?:(?:0x[[:xdigit:]]+)|(?:(?:[[:digit:]]*\\.)?[[:digit:]]+(?:[eE][+-]?[[:digit:]]+)?))u?(?:(?:int(?:8|16|32|64))|L)?)\\>|"
                              // string literals: index 4
                              "('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|"
                              // keywords: index 5
                              "\\<(__asm|__cdecl|__declspec|__export|__far16|__fastcall|__fortran|__import"
                              "|__pascal|__rtti|__stdcall|_asm|_cdecl|__except|_export|_far16|_fastcall"
                              "|__finally|_fortran|_import|_pascal|_stdcall|__thread|__try|asm|auto|bool"
                              "|break|case|catch|cdecl|char|class|const|const_cast|continue|default|delete"
                              "|do|double|dynamic_cast|else|enum|explicit|extern|false|float|for|friend|goto"
                              "|if|inline|int|long|mutable|namespace|new|operator|pascal|private|protected"
                              "|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_cast"
                              "|struct|switch|template|this|throw|true|try|typedef|typeid|typename|union|unsigned"
                              "|using|virtual|void|volatile|wchar_t|while)\\>"
                              ;

      const char* class_expression = "^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" 
                   "(class|struct)[[:space:]]*(\\<\\w+\\>([ \t]*\\([^)]*\\))?" 
                   "[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>[[:space:]]*)?" 
                   "(\\{|:[^;\\{()]*\\{)";

      const char* include_expression = "^[ \t]*#[ \t]*include[ \t]+(\"[^\"]+\"|<[^>]+>)";
      const char* boost_include_expression = "^[ \t]*#[ \t]*include[ \t]+(\"boost/[^\"]+\"|<boost/[^>]+>)";


      test_find_all(class_expression, file_contents);
      test_find_all(highlight_expression, file_contents);
      test_find_all(include_expression, file_contents);
      test_find_all(boost_include_expression, file_contents);
   }
   output_html_results(false, "%code_search%");

   if(test_html)
   {
      load_file(file_contents, "../../../libs/libraries.htm");
      test_find_all("beman|john|dave", file_contents, true);
      test_find_all("<p>.*?</p>", file_contents, true);
      test_find_all("<a[^>]+href=(\"[^\"]*\"|[^[:space:]]+)[^>]*>", file_contents, true);
      test_find_all("<h[12345678][^>]*>.*?</h[12345678]>", file_contents, true);
      test_find_all("<img[^>]+src=(\"[^\"]*\"|[^[:space:]]+)[^>]*>", file_contents, true);
      test_find_all("<font[^>]+face=(\"[^\"]*\"|[^[:space:]]+)[^>]*>.*?</font>", file_contents, true);
   }
   output_html_results(false, "%html_search%");

   if(test_short_twain)
   {
      load_file(file_contents, "short_twain.txt");

      test_find_all("Twain", file_contents);
      test_find_all("Huck[[:alpha:]]+", file_contents);
      test_find_all("[[:alpha:]]+ing", file_contents);
      test_find_all("^[^\n]*?Twain", file_contents);
      test_find_all("Tom|Sawyer|Huckleberry|Finn", file_contents);
      test_find_all("(Tom|Sawyer|Huckleberry|Finn).{0,30}river|river.{0,30}(Tom|Sawyer|Huckleberry|Finn)", file_contents);
   }
   output_html_results(false, "%short_twain_search%");

   if(test_long_twain)
   {
      load_file(file_contents, "mtent13.txt");

      test_find_all("Twain", file_contents);
      test_find_all("Huck[[:alpha:]]+", file_contents);
      test_find_all("[[:alpha:]]+ing", file_contents);
      test_find_all("^[^\n]*?Twain", file_contents);
      test_find_all("Tom|Sawyer|Huckleberry|Finn", file_contents);
      time_posix = false;
      test_find_all("(Tom|Sawyer|Huckleberry|Finn).{0,30}river|river.{0,30}(Tom|Sawyer|Huckleberry|Finn)", file_contents);
      time_posix = true;
   }   
   output_html_results(false, "%long_twain_search%");

   output_final_html();
   return 0;
}
Exemple #16
0
void
test_posix_extended ()
{
    /* Intervals can only match up to RE_DUP_MAX occurences of anything.  */
    char dup_max_plus_one[6];
    sprintf (dup_max_plus_one, "%d", RE_DUP_MAX + 1);


    printf ("\nStarting POSIX extended tests.\n");
    t = posix_extended_test;

    re_set_syntax (RE_SYNTAX_POSIX_MINIMAL_EXTENDED);

    test_posix_generic ();

    printf ("\nContinuing POSIX extended tests.\n");

    /* Grouping tests that differ from basic's.  */

    test_should_match = true;
    MATCH_SELF ("a)");

    /* Valid use of special characters.  */
    test_match ("\\(a", "(a");
    test_match ("a\\+", "a+");
    test_match ("a\\?", "a?");
    test_match ("\\{a", "{a");
    test_match ("\\|a", "|a");
    test_match ("a\\|b", "a|b");
    test_match ("a\\|?", "a");
    test_match ("a\\|?", "a|");
    test_match ("a\\|*", "a");
    test_match ("a\\|*", "a||");
    test_match ("\\(*\\)", ")");
    test_match ("\\(*\\)", "(()");
    test_match ("a\\|+", "a|");
    test_match ("a\\|+", "a||");
    test_match ("\\(+\\)", "()");
    test_match ("\\(+\\)", "(()");
    test_match ("a\\||b", "a|");
    test_match ("\\(?\\)", ")");
    test_match ("\\(?\\)", "()");

    test_match ("a+", "a");
    test_match ("a+", "aa");
    test_match ("a?", "");
    test_match ("a?", "a");

    /* Bracket expressions.  */
    test_match ("[(]", "(");
    test_match ("[+]", "+");
    test_match ("[?]", "?");
    test_match ("[{]", "{");
    test_match ("[|]", "|");
    /* Subexpressions.  */
    test_match ("(a+)*", "");
    test_match ("(a+)*", "aa");
    test_match ("(a?)*", "");
    test_match ("(a?)*", "aa");
    /* (No) back references.  */
    test_match ("(a)\\1", "a1");
    /* Invalid as intervals,
       but are valid patterns.  */
    MATCH_SELF ("{");
    test_match ("^{", "{");
    test_match ("a|{", "{");
    test_match ("({)", "{");
    MATCH_SELF ("a{");
    MATCH_SELF ("a{}");
    MATCH_SELF ("a{-1");
    MATCH_SELF ("a{-1}");
    MATCH_SELF ("a{0");
    MATCH_SELF ("a{0,");
    MATCH_SELF (concat ("a{", dup_max_plus_one));
    MATCH_SELF (concat (concat ("a{", dup_max_plus_one), ","));
    MATCH_SELF ("a{1,0");
    MATCH_SELF ("a{1,0}");
    MATCH_SELF ("a{0,1");
    test_match ("[a{0,1}]", "}");
    test_match ("a{1,3}{-1}", "aaa{-1}");
    test_match (concat ("a{1,3}{", dup_max_plus_one),
                concat ("aaa{", dup_max_plus_one));
    test_match ("a{1,3}{2,1}", "aaa{2,1}");
    test_match ("a{1,3}{1,2", "aaa{1,2");
    /* Valid consecutive repetitions.  */
    test_match ("a*+", "a");
    test_match ("a*?", "a");
    test_match ("a++", "a");
    test_match ("a+*", "a");
    test_match ("a+?", "a");
    test_match ("a??", "a");
    test_match ("a?*", "a");
    test_match ("a?+", "a");

    test_match ("a{2}?", "");
    test_match ("a{2}?", "aa");
    test_match ("a{2}+", "aa");
    test_match ("a{2}{2}", "aaaa");

    test_match ("a{1}?*", "");
    test_match ("a{1}?*", "aa");

    test_match ("(a?){0,3}b", "aaab");
    test_fastmap ("(a?){0,3}b", "ab", 0, 0);
    test_match ("(a+){0,3}b", "b");
    test_fastmap ("(a+){0,3}b", "ab", 0, 0);
    test_match ("(a+){0,3}b", "ab");
    test_fastmap ("(a+){0,3}b", "ab", 0, 0);
    test_match ("(a+){1,3}b", "aaab");
    test_match ("(a?){1,3}b", "aaab");

    test_match ("\\\\{1}", "\\");				/* Extended only.  */

    test_match ("(a?)?", "a");
    test_match ("(a?b)?c", "abc");
    test_match ("(a+)*b", "b");
    /* Alternatives.  */
    test_match ("a|b", "a");
    test_match ("a|b", "b");
    test_fastmap ("a|b", "ab", 0, 0);

    TEST_SEARCH ("a|b", "cb", 0, 2);
    TEST_SEARCH ("a|b", "cb", 0, 2);

    test_match ("(a|b|c)", "a");
    test_match ("(a|b|c)", "b");
    test_match ("(a|b|c)", "c");

    test_match ("(a|b|c)*", "abccba");

    test_match ("(a(b*))|c", "a");	/* xx do registers.  */
    test_match ("(a(b*))|c", "ab");
    test_match ("(a(b*))|c", "c");

    test_fastmap ("(a+?*|b)", "ab", 0, 0);
    test_match ("(a+?*|b)", "b");
    TEST_REGISTERS ("(a+?*|b)", "b", 0, 1, 0, 1, -1, -1);

    test_fastmap ("(a+?*|b)*", "ab", 0, 0);
    test_match ("(a+?*|b)*", "bb");
    TEST_REGISTERS ("(a+?*|b)*", "bb", 0, 2, 1, 2, -1, -1);

    test_fastmap ("(a*|b)*", "ab", 0, 0);
    test_match ("(a*|b)*", "bb");
    TEST_REGISTERS ("(a*|b)*", "bb", 0, 2, 1, 2, -1, -1);

    test_fastmap ("((a*)|b)*", "ab", 0, 0);
    test_match ("((a*)|b)*", "bb");
    TEST_REGISTERS ("((a*)|b)*", "bb", 0, 2, 1, 2, 1, 1);

    test_fastmap ("(a{0,}|b)*", "ab", 0, 0);
    test_match ("(a{0,}|b)*", "bb");
    TEST_REGISTERS ("(a{0,}|b)*", "bb", 0, 2, 1, 2, -1, -1);

    test_fastmap ("((a{0,})|b)*", "ab", 0, 0);
    test_match ("((a{0,})|b)*", "bb");
    TEST_REGISTERS ("((a{0,})|b)*", "bb", 0, 2, 1, 2, 1, 1);

    /* With c's  */
    test_fastmap ("(a+?*|b)c", "abc", 0, 0);
    test_match ("(a+?*|b)c", "bc");
    TEST_REGISTERS ("(a+?*|b)c", "bc", 0, 2, 0, 1, -1, -1);

    test_fastmap ("(a+?*|b)*c", "abc", 0, 0);
    test_match ("(a+?*|b)*c", "bbc");
    TEST_REGISTERS ("(a+?*|b)*c", "bbc", 0, 3, 1, 2, -1, -1);

    test_fastmap ("(a*|b)*c", "abc", 0, 0);
    test_match ("(a*|b)*c", "bbc");
    TEST_REGISTERS ("(a*|b)*c", "bbc", 0, 3, 1, 2, -1, -1);

    test_fastmap ("((a*)|b)*c", "abc", 0, 0);
    test_match ("((a*)|b)*c", "bbc");
    TEST_REGISTERS ("((a*)|b)*c", "bbc", 0, 3, 1, 2, 1, 1);

    test_fastmap ("(a{0,}|b)*c", "abc", 0, 0);
    test_match ("(a{0,}|b)*c", "bbc");
    TEST_REGISTERS ("(a{0,}|b)*c", "bbc", 0, 3, 1, 2, -1, -1);

    test_fastmap ("((a{0,})|b)*c", "abc", 0, 0);
    test_match ("((a{0,})|b)*c", "bbc");
    TEST_REGISTERS ("((a{0,})|b)*c", "bbc", 0, 3, 1, 2, 1, 1);


    test_fastmap ("((a{0,}\\b\\<)|b)", "ab", 0, 0);
    test_match ("((a{0,}\\b\\<)|b)", "b");
    TEST_REGISTERS ("((a{0,}\\b\\<)|b)", "b",
                    0, 1, 0, 1, 0, 0);

    test_fastmap ("((a{0,}\\b\\<)|b)*", "ab", 0, 0);
    test_match ("((a{0,}\\b\\<)|b)*", "b");
    TEST_REGISTERS ("((a{0,}\\b\\<)|b)*", "b",
                    0, 1, 0, 1, 0, 0);

    test_fastmap ("((a+?*{0,1}\\b\\<)|b)", "ab", 0, 0);
    test_match ("((a+?*{0,1}\\b\\<)|b)", "b");
    TEST_REGISTERS ("((a+?*{0,1}\\b\\<)|b)", "b",
                    0, 1, 0, 1, 0, 0);

    test_fastmap ("((a+?*{0,2}\\b\\<)|b)", "ab", 0, 0);
    test_match ("((a+?*{0,2}\\b\\<)|b)", "b");
    TEST_REGISTERS ("((a+?*{0,2}\\b\\<)|b)", "b",
                    0, 1, 0, 1, 0, 0);


    test_fastmap ("((a+?*{0,4095}\\b\\<)|b)", "ab", 0, 0);
    test_match ("((a+?*{0,4095}\\b\\<)|b)", "b");
    TEST_REGISTERS ("((a+?*{0,4095}\\b\\<)|b)", "b",
                    0, 1, 0, 1, 0, 0);

    test_fastmap ("((a+?*{0,5119}\\b\\<)|b)", "ab", 0, 0);
    test_match ("((a+?*{0,5119}\\b\\<)|b)", "b");
    TEST_REGISTERS ("((a+?*{0,5119}\\b\\<)|b)", "b",
                    0, 1, 0, 1, 0, 0);

    test_fastmap ("((a+?*{0,6143}\\b\\<)|b)", "ab", 0, 0);
    test_match ("((a+?*{0,6143}\\b\\<)|b)", "b");
    TEST_REGISTERS ("((a+?*{0,6143}\\b\\<)|b)", "b",
                    0, 1, 0, 1, 0, 0);

    test_fastmap ("((a+?*{0,8191}\\b\\<)|b)", "ab", 0, 0);
    test_match ("((a+?*{0,8191}\\b\\<)|b)", "b");
    TEST_REGISTERS ("((a+?*{0,8191}\\b\\<)|b)", "b",
                    0, 1, 0, 1, 0, 0);

    test_fastmap ("((a+?*{0,16383}\\b\\<)|b)", "ab", 0, 0);
    test_match ("((a+?*{0,16383}\\b\\<)|b)", "b");
    TEST_REGISTERS ("((a+?*{0,16383}\\b\\<)|b)", "b",
                    0, 1, 0, 1, 0, 0);


    test_fastmap ("((a+?*{0,}\\b\\<)|b)", "ab", 0, 0);
    test_match ("((a+?*{0,}\\b\\<)|b)", "b");
    TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)", "b",
                    0, 1, 0, 1, 0, 0);

    test_fastmap ("((a+?*{0,}\\b\\<)|b)*", "ab", 0, 0);
    test_match ("((a+?*{0,}\\b\\<)|b)*", "b");
    TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)*", "b",
                    0, 1, 0, 1, 0, 0);

    test_fastmap ("((a+?*{0,}\\b\\<)|b)*", "ab", 0, 0);
    test_match ("((a+?*{0,}\\b\\<)|b)*", "bb");
    TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)*", "bb",
                    0, 2, 1, 2, 0, 0);


    /* `*' after group.  */
    test_match ("(a*|b*)*c", "c");
    TEST_REGISTERS ("(a*|b*)*c", "c", 0, 1, 0, 0, -1, -1);

    test_match ("(a*|b*)*c", "ac");
    TEST_REGISTERS ("(a*|b*)*c", "ac", 0, 2, 0, 1, -1, -1);

    test_match ("(a*|b*)*c", "aac");
    TEST_REGISTERS ("(a*|b*)*c", "aac", 0, 3, 0, 2, -1, -1);

    test_match ("(a*|b*)*c", "bbc");
    TEST_REGISTERS ("(a*|b*)*c", "bbc", 0, 3, 0, 2, -1, -1);

    test_match ("(a*|b*)*c", "abc");
    TEST_REGISTERS ("(a*|b*)*c", "abc", 0, 3, 1, 2, -1, -1);

    /* No `*' after group.  */
    test_match ("(a*|b*)c", "c");
    TEST_REGISTERS ("(a*|b*)c", "c", 0, 1, 0, 0, -1, -1);

    test_match ("(a*|b*)c", "ac");
    TEST_REGISTERS ("(a*|b*)c", "ac", 0, 2, 0, 1, -1, -1);

    test_match ("(a*|b*)c", "bc");
    TEST_REGISTERS ("(a*|b*)c", "bc", 0, 2, 0, 1, -1, -1);

    test_match ("(a*|b*)c", "aac");
    TEST_REGISTERS ("(a*|b*)c", "aac", 0, 3, 0, 2, -1, -1);

    /* Same as above, but with no `*'s in alternatives.

    test_match ("(a|b)*c", "c");		/* `*' after group.  */
    TEST_REGISTERS ("(a|b)*c", "c", 0, 1, -1, -1, -1, -1);

    test_match ("(a|b)*c", "ac");
    TEST_REGISTERS ("(a|b)*c", "ac", 0, 2, 0, 1, -1, -1);

    test_match ("(a|b)*c", "bc");
    TEST_REGISTERS ("(a|b)*c", "bc", 0, 2, 0, 1, -1, -1);

    test_match ("(a|b)*c", "abc");
    TEST_REGISTERS ("(a|b)*c", "abc", 0, 3, 1, 2, -1, -1);


    test_match ("(a*|b*)c", "bbc");
    TEST_REGISTERS ("(a*|b*)c", "bbc", 0, 3, 0, 2, -1, -1);

    /* Complicated second alternative.  */

    test_match ("(a*|(b*)*)*c", "bc");
    TEST_REGISTERS ("(a*|(b*)*)*c", "bc", 0, 2, 0, 1, 0, 1);

    test_match ("(a*|(b*|c*)*)*d", "bd");
    TEST_REGISTERS ("(a*|(b*|c*)*)*d", "bd", 0, 2, 0, 1, 0, 1);

    test_match ("(a*|(b*|c*)*)*d", "bbd");
    TEST_REGISTERS ("(a*|(b*|c*)*)*d", "bbd", 0, 3, 0, 2, 0, 2);

    test_match ("(a*|(b*|c*)*)*d", "cd");
    TEST_REGISTERS ("(a*|(b*|c*)*)*d", "cd", 0, 2, 0, 1, 0, 1);

    test_match ("(a*|(b*|c*)*)*d", "ccd");
    TEST_REGISTERS ("(a*|(b*|c*)*)*d", "ccd", 0, 3, 0, 2, 0, 2);

    test_match ("(a*|b*|c*)*d", "aad");
    TEST_REGISTERS ("(a*|b*|c*)*d", "aad", 0, 3, 0, 2, 0, 2);

    test_match ("(a*|b*|c*)*d", "bbd");
    TEST_REGISTERS ("(a*|b*|c*)*d", "bbd", 0, 3, 0, 2, 0, 2);

    test_match ("(a*|b*|c*)*d", "ccd");
    TEST_REGISTERS ("(a*|b*|c*)*d", "ccd", 0, 3, 0, 2, 0, 2);

    /* Valid anchoring.  */
    valid_pattern ("a^");
    valid_pattern ("a^b");
    valid_pattern ("$a");
    valid_pattern ("a$b");
    valid_pattern ("foo^bar");
    valid_pattern ("foo$bar");
    valid_pattern ("(^)");
    valid_pattern ("($)");
    valid_pattern ("(^$)");

    /* These are the same (but valid) as those (invalid) in other_test.c.  */
    valid_pattern
    ("(((((((((((((((((((((((((((((((((a^)))))))))))))))))))))))))))))))))");
    valid_pattern
    ("((((((((((((((((((((((((((((((((($a)))))))))))))))))))))))))))))))))");
    valid_pattern ("\\(^a\\)");
    valid_pattern ("a\\|^b");
    valid_pattern ("\\w^a");
    valid_pattern ("\\W^a");
    valid_pattern ("(a^)");
    valid_pattern ("($a)");
    valid_pattern ("a(^b)");
    valid_pattern ("a$(b)");
    valid_pattern ("(a)^b");
    valid_pattern ("(a)$b");
    valid_pattern ("(a)(^b)");
    valid_pattern ("(a$)(b)");
    valid_pattern ("(a|b)^c");
    valid_pattern ("(a|b)$c");
    valid_pattern ("(a$|b)c");
    valid_pattern ("(a|b$)c");
    valid_pattern ("a(b|^c)");
    valid_pattern ("a(^b|c)");
    valid_pattern ("a$(b|c)");
    valid_pattern ("(a)(^b|c)");
    valid_pattern ("(a)(b|^c)");
    valid_pattern ("(b$|c)(a)");
    valid_pattern ("(b|c$)(a)");
    valid_pattern ("(a(^b|c))");
    valid_pattern ("(a(b|^c))");
    valid_pattern ("((b$|c)a)");
    valid_pattern ("((b|c$)a)");
    valid_pattern ("((^a|^b)^c)");
    valid_pattern ("(c$(a$|b$))");
    valid_pattern ("((^a|^b)^c)");
    valid_pattern ("((a$|b$)c)");
    valid_pattern ("(c$(a$|b$))");
    valid_pattern ("((^a|^b)|^c)^d");
    valid_pattern ("((a$|b$)|c$)d$");
    valid_pattern ("d$(c$|(a$|b$))");
    valid_pattern ("((^a|^b)|^c)(^d)");
    valid_pattern ("((a$|b$)|c$)(d$)");
    valid_pattern ("(d$)((a$|b$)|c$)");
    valid_pattern ("((^a|^b)|^c)((^d))");
    valid_pattern ("((a$|b$)|c$)((d$))");
    valid_pattern ("((d$))((a$|b$)|c$)");
    valid_pattern ("(((^a|^b))c|^d)^e");
    valid_pattern ("(((a$|b$))c|d$)$e$");
    valid_pattern ("e$(d$|c((a$|b$)))");
    valid_pattern ("(^a)((^b))");
    valid_pattern ("(a$)((b$))");
    valid_pattern ("((^a))(^b)");
    valid_pattern ("((a$))(b$)");
    valid_pattern ("((^a))((^b))");
    valid_pattern ("((a$))((b$))");
    valid_pattern ("((^a)^b)");
    valid_pattern ("((a$)b$)");
    valid_pattern ("(b$(a$))");
    valid_pattern ("(((^a)b)^c)");
    valid_pattern ("(((a$)b)c$)");
    valid_pattern ("(c$(b(a$)))");
    valid_pattern ("(((^a)b)c)^d");
    valid_pattern ("(((a$)b)c)d$");
    valid_pattern ("d$(c(b(a$)))");
    valid_pattern (".^a");
    valid_pattern ("a$.");
    valid_pattern ("[a]^b");
    valid_pattern ("b$[a]");
    valid_pattern ("\\(a$\\)");
    valid_pattern ("a$\\|b");
    valid_pattern ("(^a|^b)^c");
    valid_pattern ("c$(a$|b$)");
    valid_pattern ("(^a|^b)^|^c");
    valid_pattern ("(a$|b$)$|$c$");
    valid_pattern ("(a$|$b$)$|c$");
    valid_pattern ("($a$|b$)$|c$");
    valid_pattern ("$(a$|b$)$|c$");
    valid_pattern ("^c|d(^a|^b)");
    valid_pattern ("(^a|^b)|d^c");
    valid_pattern ("c$|(a$|b$)d");
    valid_pattern ("c$d|(a$|b$)");
    valid_pattern ("c(^a|^b)|^d");
    valid_pattern ("(a$|b$)c|d$");
    valid_pattern ("c(((^a|^b))|^d)e");
    valid_pattern ("(c((^a|^b))|^d)e");
    valid_pattern ("((c(^a|^b))|^d)e");
    valid_pattern ("(((^a|^b))|c^d)e");
    valid_pattern ("(((^a|^b))|^d)^e");
    valid_pattern ("(c$((a|b))|d)e$");
    valid_pattern ("(c((a$|b$))|d)e$");
    valid_pattern ("(c((a|b)$)|d)e$");
    valid_pattern ("(c((a|b))|d$)e$");
    valid_pattern ("^d(^c|e((a|b)))");
    valid_pattern ("^d(c|^e((a|b)))");
    valid_pattern ("^d(c|e(^(a|b)))");
    valid_pattern ("^d(c|e((^a|b)))");
    valid_pattern ("^d(c|e((a|^b)))");
    valid_pattern ("^d(c|e((a|b^)))");
    valid_pattern ("^d(c|e((a|b)^))");
    valid_pattern ("^d(c|e((a|b))^)");
    valid_pattern ("^d(c|e((a|b)))^");
    valid_pattern ("d$(c$|e((a$|b$)))");
    valid_pattern ("d(c$|e$((a$|b$)))");
    valid_pattern ("(((^a|^b))^c)|^de");
    valid_pattern ("(((^a|^b))c)|^d^e");
    valid_pattern ("(((a$|b))c$)|de$");
    valid_pattern ("(((a|b$))c$)|de$");
    valid_pattern ("(((a|b))c$)|d$e$");
    valid_pattern ("^d^e|^(c((a|b)))");
    valid_pattern ("^de|^(c^((a|b)))");
    valid_pattern ("^de|^(c(^(a|b)))");
    valid_pattern ("^de|^(c((^a|b)))");
    valid_pattern ("^de|^(c((a|^b)))");
    valid_pattern ("^de|(^c(^(a|b)))");
    valid_pattern ("^de|(^c((^a|b)))");
    valid_pattern ("^de|(^c((a|^b)))");
    valid_pattern ("de$|(c($(a|b)$))");
    valid_pattern ("de$|(c$((a|b)$))");
    valid_pattern ("de$|($c((a|b)$))");
    valid_pattern ("de$|$(c((a|b)$))");
    valid_pattern ("de$|(c($(a|b))$)");
    valid_pattern ("de$|(c$((a|b))$)");
    valid_pattern ("de$|$(c((a|b))$)");
    valid_pattern ("de$|(c($(a|b)))$");
    valid_pattern ("de$|(c$((a|b)))$");
    valid_pattern ("de$|($c((a|b)))$");
    valid_pattern ("de$|$(c((a|b)))$");
    valid_pattern ("^a(^b|c)|^d");
    valid_pattern ("^a(b|^c)|^d");
    valid_pattern ("^a(b|c^)|^d");
    valid_pattern ("^a(b|c)^|^d");
    valid_pattern ("a$(b$|c$)|d$");
    valid_pattern ("^d|^a(^b|c)");
    valid_pattern ("^d|^a(b|^c)");
    valid_pattern ("d$|a$(b$|c$)");
    valid_pattern ("^d|^(b|c)^a");
    valid_pattern ("d$|(b|c$)a$");
    valid_pattern ("d$|(b$|c)a$");
    valid_pattern ("^(a)^(b|c)|^d");
    valid_pattern ("^(a)(^b|c)|^d");
    valid_pattern ("^(a)(b|^c)|^d");
    valid_pattern ("(a)$(b|c)$|d$");
    valid_pattern ("(a$)(b|c)$|d$");
    valid_pattern ("(^a)(^b|c)|^d");
    valid_pattern ("(^a)(b|^c)|^d");
    valid_pattern ("(a)$(b$|c$)|d$");
    valid_pattern ("(a$)(b$|c$)|d$");
    valid_pattern ("^d|^(b|c)^(a)");
    valid_pattern ("^d|^(b|c)(^a)");
    valid_pattern ("d$|(b|c$)(a)$");
    valid_pattern ("d$|(b$|c)(a)$");
    valid_pattern ("^d|(^b|^c)^(a)");
    valid_pattern ("^d|(^b|^c)(^a)");
    valid_pattern ("d$|(b|c)$(a$)");
    valid_pattern ("d$|(b|c$)(a$)");
    valid_pattern ("d$|(b$|c)(a$)");
    valid_pattern ("^d|^(a)^(b|c)");
    valid_pattern ("^d|^(a)(^b|c)");
    valid_pattern ("^d|^(a)(b|^c)");
    valid_pattern ("^d|(^a)^(b|c)");
    valid_pattern ("^d|(^a)(^b|c)");
    valid_pattern ("^d|(^a)(b|^c)");
    valid_pattern ("d$|(a)$(b$|c$)");
    valid_pattern ("d$|(a$)(b$|c$)");
    valid_pattern ("((e^a|^b)|^c)|^d");
    valid_pattern ("((^a|e^b)|^c)|^d");
    valid_pattern ("((^a|^b)|e^c)|^d");
    valid_pattern ("((^a|^b)|^c)|e^d");
    valid_pattern ("d$e|(c$|(a$|b$))");
    valid_pattern ("d$|(c$e|(a$|b$))");
    valid_pattern ("d$|(c$|(a$e|b$))");
    valid_pattern ("d$|(c$|(a$|b$e))");
    valid_pattern ("d$|(c$|(a$|b$)e)");
    valid_pattern ("d$|(c$|(a$|b$))e");
    valid_pattern ("(a|b)^|c");
    valid_pattern ("(a|b)|c^");
    valid_pattern ("$(a|b)|c");
    valid_pattern ("(a|b)|$c");
    valid_pattern ("(a^|^b)|^c");
    valid_pattern ("(^a|b^)|^c");
    valid_pattern ("(^a|^b)|c^");
    valid_pattern ("($a|b$)|c$");
    valid_pattern ("(a$|$b)|c$");
    valid_pattern ("(a$|b$)|$c");
    valid_pattern ("c^|(^a|^b)");
    valid_pattern ("^c|(a^|^b)");
    valid_pattern ("^c|(^a|b^)");
    valid_pattern ("$c|(a$|b$)");
    valid_pattern ("c$|($a|b$)");
    valid_pattern ("c$|(a$|$b)");
    valid_pattern ("c^|^(a|b)");
    valid_pattern ("^c|(a|b)^");
    valid_pattern ("$c|(a|b)$");
    valid_pattern ("c$|$(a|b)");
    valid_pattern ("(a^|^b)c|^d");
    valid_pattern ("(^a|b^)c|^d");
    valid_pattern ("(^a|^b)c|d^");
    valid_pattern ("(^a|^b)^c|^d");
    valid_pattern ("(a|b)c$|$d");
    valid_pattern ("(a|b)$c$|d$");
    valid_pattern ("(a|b)$c$|d$");
    valid_pattern ("(a|b$)c$|d$");
    valid_pattern ("(a$|b)c$|d$");
    valid_pattern ("($a|b)c$|d$");
    valid_pattern ("$(a|b)c$|d$");
    valid_pattern ("^d|^c^(a|b)");
    valid_pattern ("^d|^c(^a|b)");
    valid_pattern ("^d|^c(a|^b)");
    valid_pattern ("^d|^c(a|b^)");
    valid_pattern ("^d|^c(a|b)^");
    valid_pattern ("$d|c(a$|b$)");
    valid_pattern ("d$|c($a$|b$)");
    valid_pattern ("d$|c$(a$|b$)");
    valid_pattern ("d$|$c(a$|b$)");

    valid_pattern ("(((a^|^b))c|^d)e");
    valid_pattern ("(((^a|b^))c|^d)e");
    valid_pattern ("(((^a|^b))^c|^d)e");
    valid_pattern ("((^(a|b))c|d^)e");
    valid_pattern ("(^((a|b))c|^d)^e");
    valid_pattern ("(^((a|b)^)c|^d)e");
    valid_pattern ("(^((a^|b))c|^d)e");
    valid_pattern ("(^((a|b^))c|^d)e");
    valid_pattern ("(^((a|b)^)c|^d)e");
    valid_pattern ("(^((a|b))^c|^d)e");
    valid_pattern ("(^((a|b))c^|^d)e");
    valid_pattern ("(^((a|b))c|^d^)e");
    valid_pattern ("(^((a|b))c|^d)^e");
    valid_pattern ("(((a|b))c|d)$e$");
    valid_pattern ("(((a|b))c|d$)e$");
    valid_pattern ("(((a|b))c|$d)e$");
    valid_pattern ("(((a|b))c$|d)e$");
    valid_pattern ("(((a|b))$c|d)e$");
    valid_pattern ("(((a|b)$)c|d)e$");
    valid_pattern ("(((a|b$))c|d)e$");
    valid_pattern ("(((a$|b))c|d)e$");
    valid_pattern ("((($a|b))c|d)e$");
    valid_pattern ("(($(a|b))c|d)e$");
    valid_pattern ("($((a|b))c|d)e$");
    valid_pattern ("$(((a|b))c|d)e$");
    valid_pattern ("(^((a|b)^)c|^d)e");
    valid_pattern ("(^((a|b))^c|^d)e");
    valid_pattern ("(^((a|b))c|^d^)e");
    valid_pattern ("(^((a|b))c|^d)^e");

    valid_pattern ("^e(^d|c((a|b)))");
    valid_pattern ("^e(d|^c((a|b)))");
    valid_pattern ("^e(d|c^((a|b)))");
    valid_pattern ("^e(d|c(^(a|b)))");
    valid_pattern ("^e(d|c((^a|b)))");
    valid_pattern ("^e(d|c((a|^b)))");
    valid_pattern ("^e(d|c((a|b^)))");
    valid_pattern ("^e(d|c((a|b)^))");
    valid_pattern ("^e(d|c((a|b))^)");
    valid_pattern ("^e(d|c((a|b)))^");
    valid_pattern ("e$(d$|c((a$|b$)))");
    valid_pattern ("e(d$|c$((a$|b$)))");
    valid_pattern ("e(d$|c($(a$|b$)))");
    valid_pattern ("e(d$|c(($a$|b$)))");
    valid_pattern ("e$(d$|c((a|b)$))");
    valid_pattern ("e($d$|c((a|b)$))");
    valid_pattern ("e(d$|$c((a|b)$))");
    valid_pattern ("e(d$|c$((a|b)$))");
    valid_pattern ("e(d$|c($(a|b)$))");
    valid_pattern ("e(d$|c(($a|b)$))");
    valid_pattern ("e(d$|c((a|$b)$))");
    valid_pattern ("e(d$|c((a$|$b$)))");

    valid_pattern ("e$(d$|c((a|b))$)");
    valid_pattern ("e($d$|c((a|b))$)");
    valid_pattern ("e(d$|$c((a|b))$)");
    valid_pattern ("e(d$|c$((a|b))$)");
    valid_pattern ("e(d$|c($(a|b))$)");
    valid_pattern ("e(d$|c(($a|b))$)");
    valid_pattern ("e(d$|c((a|$b))$)");
    valid_pattern ("e$(d$|c((a|b)))$");
    valid_pattern ("e($d$|c((a|b)))$");
    valid_pattern ("e(d$|$c((a|b)))$");
    valid_pattern ("e(d$|c$((a|b)))$");
    valid_pattern ("e(d$|c($(a|b)))$");
    valid_pattern ("e(d$|c(($a|b)))$");
    valid_pattern ("e(d$|c((a|$b)))$");
    valid_pattern ("(((^a|^b)^)c)|^de");
    valid_pattern ("(((^a|^b))^c)|^de");
    valid_pattern ("(((^a|^b))c)^|^de");
    valid_pattern ("$(((a|b))c$)|de$");
    valid_pattern ("($((a|b))c$)|de$");
    valid_pattern ("(($(a|b))c$)|de$");
    valid_pattern ("((($a|b))c$)|de$");
    valid_pattern ("(((a|$b))c$)|de$");
    valid_pattern ("(((a|b)$)c$)|de$");
    valid_pattern ("(((a|b))$c$)|de$");
    valid_pattern ("$(((a|b))c)$|de$");
    valid_pattern ("($((a|b))c)$|de$");
    valid_pattern ("(($(a|b))c)$|de$");
    valid_pattern ("((($a|b))c)$|de$");
    valid_pattern ("(((a|$b))c)$|de$");
    valid_pattern ("(((a|b)$)c)$|de$");
    valid_pattern ("(((a|b))$c)$|de$");
    valid_pattern ("^ed|^(c((a|b)))^");
    valid_pattern ("^ed|^(c((a|b))^)");
    valid_pattern ("^ed|^(c((a|b)^))");
    valid_pattern ("^ed|^(c((a|b^)))");
    valid_pattern ("^ed|^(c((a^|b)))");
    valid_pattern ("^ed|^(c((^a|b)))");
    valid_pattern ("^ed|^(c(^(a|b)))");
    valid_pattern ("^ed|^(c^((a|b)))");
    valid_pattern ("^ed|(^c((a|b)))^");
    valid_pattern ("^ed|(^c((a|b))^)");
    valid_pattern ("^ed|(^c((a|b)^))");
    valid_pattern ("^ed|(^c((a|b^)))");
    valid_pattern ("^ed|(^c((a|^b)))");
    valid_pattern ("^ed|(^c((a^|b)))");
    valid_pattern ("^ed|(^c((^a|b)))");
    valid_pattern ("^ed|(^c(^(a|b)))");
    valid_pattern ("^ed|(^c(^(a|b)))");
    valid_pattern ("^ed|(^c^((a|b)))");
    valid_pattern ("ed$|$(c((a|b)))$");
    valid_pattern ("ed$|($c((a|b)))$");
    valid_pattern ("ed$|(c$((a|b)))$");
    valid_pattern ("ed$|(c($(a|b)))$");
    valid_pattern ("ed$|(c(($a|b)))$");
    valid_pattern ("ed$|(c((a|$b)))$");
    valid_pattern ("ed$|$(c((a|b))$)");
    valid_pattern ("ed$|($c((a|b))$)");
    valid_pattern ("ed$|(c$((a|b))$)");
    valid_pattern ("ed$|(c($(a|b))$)");
    valid_pattern ("ed$|(c(($a|b))$)");
    valid_pattern ("ed$|(c((a|$b))$)");
    valid_pattern ("ed$|$(c((a|b)$))");
    valid_pattern ("ed$|($c((a|b)$))");
    valid_pattern ("ed$|(c$((a|b)$))");
    valid_pattern ("ed$|(c($(a|b)$))");
    valid_pattern ("ed$|(c(($a|b)$))");
    valid_pattern ("ed$|(c((a|$b)$))");
    valid_pattern ("ed$|$(c((a|b)$))");
    valid_pattern ("ed$|($c((a|b)$))");
    valid_pattern ("ed$|(c$((a|b)$))");
    valid_pattern ("ed$|(c($(a|b)$))");
    valid_pattern ("ed$|(c(($a|b)$))");
    valid_pattern ("ed$|(c((a|$b)$))");
    valid_pattern ("ed$|$(c((a|b)$))");
    valid_pattern ("ed$|($c((a|b)$))");
    valid_pattern ("ed$|(c$((a|b)$))");
    valid_pattern ("ed$|(c($(a|b)$))");
    valid_pattern ("ed$|(c(($a|b)$))");
    valid_pattern ("ed$|(c((a|$b)$))");
    valid_pattern ("ed$|$(c((a|b)$))");
    valid_pattern ("ed$|($c((a|b)$))");
    valid_pattern ("ed$|(c$((a|b)$))");
    valid_pattern ("ed$|(c($(a|b)$))");
    valid_pattern ("ed$|(c(($a|b)$))");
    valid_pattern ("ed$|(c((a|$b)$))");
    valid_pattern ("ed$|$(c((a|b)$))");
    valid_pattern ("ed$|($c((a|b)$))");
    valid_pattern ("ed$|(c$((a|b)$))");
    valid_pattern ("ed$|(c($(a|b)$))");
    valid_pattern ("ed$|(c(($a|b)$))");
    valid_pattern ("ed$|(c((a|$b)$))");
    valid_pattern ("ed$|$(c((a$|b$)))");
    valid_pattern ("ed$|($c((a$|b$)))");
    valid_pattern ("ed$|(c$((a$|b$)))");
    valid_pattern ("ed$|(c($(a$|b$)))");
    valid_pattern ("ed$|(c(($a$|b$)))");
    valid_pattern ("ed$|(c((a$|$b$)))");
    valid_pattern ("^a(b|c)^|^d");
    valid_pattern ("^a(b|c^)|^d");
    valid_pattern ("^a(b|^c)|^d");
    valid_pattern ("^a(b^|c)|^d");
    valid_pattern ("^a(^b|c)|^d");
    valid_pattern ("^a^(b|c)|^d");
    valid_pattern ("$a(b$|c$)|d$");
    valid_pattern ("a$(b$|c$)|d$");
    valid_pattern ("a($b$|c$)|d$");
    valid_pattern ("a(b$|$c$)|d$");
    valid_pattern ("a(b$|c$)|$d$");
    valid_pattern ("^(a^)(b|c)|^d");
    valid_pattern ("^(a)^(b|c)|^d");
    valid_pattern ("^(a)(^b|c)|^d");
    valid_pattern ("^(a)(b^|c)|^d");
    valid_pattern ("^(a)(b|^c)|^d");
    valid_pattern ("^(a)(b|c^)|^d");
    valid_pattern ("^(a)(b|c)^|^d");
    valid_pattern ("(^a^)(b|c)|^d");
    valid_pattern ("(^a)^(b|c)|^d");
    valid_pattern ("(^a)(^b|c)|^d");
    valid_pattern ("(^a)(b^|c)|^d");
    valid_pattern ("(^a)(b|^c)|^d");
    valid_pattern ("(^a)(b|c^)|^d");
    valid_pattern ("(^a)(b|c)^|^d");

    valid_pattern ("(a)(b$|c$)d$");
    valid_pattern ("(a)(b|$c)$|d$");
    valid_pattern ("(a)($b|c)$|d$");
    valid_pattern ("(a)$(b|c)$|d$");
    valid_pattern ("(a$)(b|c)$|d$");
    valid_pattern ("($a)(b|c)$|d$");
    valid_pattern ("$(a)(b|c)$|d$");
    valid_pattern ("(b|c)($a)$|d$");
    valid_pattern ("(b|c)$(a)$|d$");
    valid_pattern ("(b|c$)(a)$|d$");
    valid_pattern ("(b|$c)(a)$|d$");
    valid_pattern ("(b$|c)(a)$|d$");
    valid_pattern ("($b|c)(a)$|d$");
    valid_pattern ("$(b|c)(a)$|d$");
    valid_pattern ("(b|c)($a$)|d$");
    valid_pattern ("(b|c)$(a$)|d$");
    valid_pattern ("(b|c$)(a$)|d$");
    valid_pattern ("(b|$c)(a$)|d$");
    valid_pattern ("(b$|c)(a$)|d$");
    valid_pattern ("($b|c)(a$)|d$");
    valid_pattern ("$(b|c)(a$)|d$");
    valid_pattern ("(a)$(b$|c$)|d$");
    valid_pattern ("(a$)(b$|c$)|d$");
    valid_pattern ("($a)(b$|c$)|d$");
    valid_pattern ("$(a)(b$|c$)|d$");
    valid_pattern ("^d|^(b^|c)(a)");
    valid_pattern ("^d|^(b|c^)(a)");
    valid_pattern ("^d|^(b|c)^(a)");
    valid_pattern ("^d|^(b|c)(^a)");
    valid_pattern ("^d|^(b|c)(a^)");
    valid_pattern ("^d|^(b|c)(a)^");
    valid_pattern ("^d|(^b|^c^)(a)");
    valid_pattern ("^d|(^b|^c)^(a)");
    valid_pattern ("^d|(^b|^c)(^a)");
    valid_pattern ("^d|(^b|^c)(a^)");
    valid_pattern ("^d|(^b|^c)(a)^");
    valid_pattern ("d$|(b|c)($a$)");
    valid_pattern ("d$|(b|c)$(a$)");
    valid_pattern ("d$|(b|c$)(a$)");
    valid_pattern ("d$|(b$|c)(a$)");
    valid_pattern ("d$|($b|c)(a$)");
    valid_pattern ("d$|$(b|c)(a$)");
    valid_pattern ("d$|(b|c)($a)$");
    valid_pattern ("d$|(b|c)$(a)$");
    valid_pattern ("d$|(b|c$)(a)$");
    valid_pattern ("d$|(b$|c)(a)$");
    valid_pattern ("d$|($b|c)(a)$");
    valid_pattern ("d$|$(b|c)(a)$");
    valid_pattern ("^d|^(a^)(b|c)");
    valid_pattern ("^d|^(a)^(b|c)");
    valid_pattern ("^d|^(a)(^b|c)");
    valid_pattern ("^d|^(a)(b^|c)");
    valid_pattern ("^d|^(a)(b|^c)");
    valid_pattern ("^d|^(a)(b|c^)");
    valid_pattern ("^d|^(a)(b|c)^");
    valid_pattern ("^d|(^a^)(b|c)");
    valid_pattern ("^d|(^a)^(b|c)");
    valid_pattern ("^d|(^a)(^b|c)");
    valid_pattern ("^d|(^a)(b^|c)");
    valid_pattern ("^d|(^a)(b|^c)");
    valid_pattern ("^d|(^a)(b|c^)");
    valid_pattern ("^d|(^a)(b|c)^");
    valid_pattern ("d$|(a)$(b$|c$)");
    valid_pattern ("d$|(a$)(b$|c$)");
    valid_pattern ("d$|($a)(b$|c$)");
    valid_pattern ("d$|$(a)(b$|c$)");
    valid_pattern ("d$|(a)(b|$c)$");
    valid_pattern ("d$|(a)($b|c)$");
    valid_pattern ("d$|(a)$(b|c)$");
    valid_pattern ("d$|(a$)(b|c)$");
    valid_pattern ("d$|($a)(b|c)$");
    valid_pattern ("d$|$(a)(b|c)$");
    valid_pattern ("((^a|^b)|^c)|^d^");
    valid_pattern ("((^a|^b)|^c)^|^d");
    valid_pattern ("((^a|^b)|^c^)|^d");
    valid_pattern ("((^a|^b)^|^c)|^d");
    valid_pattern ("((^a|^b^)|^c)|^d");
    valid_pattern ("((^a^|^b)|^c)|^d");
    valid_pattern ("((a|b)|c)|$d$");
    valid_pattern ("((a|b)|$c)|d$");
    valid_pattern ("((a|$b)|c)|d$");
    valid_pattern ("(($a|b)|c)|d$");
    valid_pattern ("($(a|b)|c)|d$");
    valid_pattern ("$((a|b)|c)|d$");
    valid_pattern ("^d^|(c|(a|b))");
    valid_pattern ("^d|(c^|(a|b))");
    valid_pattern ("^d|(c|(a^|b))");
    valid_pattern ("^d|(c|(a|b^))");
    valid_pattern ("^d|(c|(a|b)^)");
    valid_pattern ("^d|(c|(a|b))^");
    valid_pattern ("d$|(c$|(a$|$b$))");
    valid_pattern ("d$|(c$|($a$|b$))");
    valid_pattern ("d$|($c$|(a$|b$))");
    valid_pattern ("d$|$(c$|(a$|b$))");
    valid_pattern ("$d$|(c$|(a$|b$))");
    valid_pattern ("d$|(c$|(a|$b)$)");
    valid_pattern ("d$|(c$|($a|b)$)");
    valid_pattern ("d$|($c$|(a|b)$)");
    valid_pattern ("d$|$(c$|(a|b)$)");
    valid_pattern ("$d$|(c$|(a|b)$)");
    valid_pattern ("d$|(c$|(a|$b))$");
    valid_pattern ("d$|(c$|($a|b))$");
    valid_pattern ("d$|($c$|(a|b))$");
    valid_pattern ("d$|$(c$|(a|b))$");
    valid_pattern ("$d$|(c$|(a|b))$");
    valid_pattern ("^c^|(^a|^b)");
    valid_pattern ("^c|(^a^|^b)");
    valid_pattern ("^c|(^a|^b^)");
    valid_pattern ("^c|(^a|^b)^");
    valid_pattern ("c$|(a$|$b$)");
    valid_pattern ("c$|($a$|b$)");
    valid_pattern ("c$|$(a$|b$)");
    valid_pattern ("$c$|(a$|b$)");
    valid_pattern ("^d^(c|e((a|b)))");
    valid_pattern ("^d(^c|e((a|b)))");
    valid_pattern ("^d(c^|e((a|b)))");
    valid_pattern ("^d(c|^e((a|b)))");
    valid_pattern ("^d(c|e^((a|b)))");
    valid_pattern ("^d(c|e(^(a|b)))");
    valid_pattern ("^d(c|e((^a|b)))");
    valid_pattern ("^d(c|e((a|^b)))");
    valid_pattern ("^d(c|e((a|b^)))");
    valid_pattern ("^d(c|e((a|b)^))");
    valid_pattern ("^d(c|e((a|b))^)");
    valid_pattern ("^d(c|e((a|b)))^");
    valid_pattern ("d(c$|e($(a$|b$)))");
    valid_pattern ("d(c$|e$((a$|b$)))");
    valid_pattern ("d(c$|$e((a$|b$)))");
    valid_pattern ("d($c$|e((a$|b$)))");
    valid_pattern ("d$(c$|e((a$|b$)))");
    valid_pattern ("$d(c$|e((a$|b$)))");
    valid_pattern ("^d|^a^(b|c)");
    valid_pattern ("^d|^a(^b|c)");
    valid_pattern ("^d|^a(b^|c)");
    valid_pattern ("^d|^a(b|^c)");
    valid_pattern ("^d|^a(b|c^)");
    valid_pattern ("^d|^a(b|c)^");
    valid_pattern ("d$|a($b$|c$)");
    valid_pattern ("d$|a$(b$|c$)");
    valid_pattern ("d$|$a(b$|c$)");
    valid_pattern ("$d$|a(b$|c$)");
    valid_pattern ("^d|^(b^|c)a");
    valid_pattern ("^d|^(b|c^)a");
    valid_pattern ("^d|^(b|c)^a");
    valid_pattern ("^d|^(b|c)a^");
    valid_pattern ("d$|(b|c)$a$");
    valid_pattern ("d$|(b|c$)a$");
    valid_pattern ("d$|(b|$c)a$");
    valid_pattern ("d$|(b$|c)a$");
    valid_pattern ("d$|($b|c)a$");
    valid_pattern ("d$|$(b|c)a$");
    valid_pattern ("$d$|(b|c)a$");

    /* xx Do these use all the valid_nonposix_pattern ones in other_test.c?  */

    TEST_SEARCH ("(^a|^b)c", "ac", 0, 2);
    TEST_SEARCH ("(^a|^b)c", "bc", 0, 2);
    TEST_SEARCH ("c(a$|b$)", "ca", 0, 2);
    TEST_SEARCH ("c(a$|b$)", "cb", 0, 2);
    TEST_SEARCH ("^(a|b)|^c", "ad", 0, 2);
    TEST_SEARCH ("^(a|b)|^c", "bd", 0, 2);
    TEST_SEARCH ("(a|b)$|c$", "da", 0, 2);
    TEST_SEARCH ("(a|b)$|c$", "db", 0, 2);
    TEST_SEARCH ("(a|b)$|c$", "dc", 0, 2);
    TEST_SEARCH ("(^a|^b)|^c", "ad", 0, 2);
    TEST_SEARCH ("(^a|^b)|^c", "bd", 0, 2);
    TEST_SEARCH ("(^a|^b)|^c", "cd", 0, 2);
    TEST_SEARCH ("(a$|b$)|c$", "da", 0, 2);
    TEST_SEARCH ("(a$|b$)|c$", "db", 0, 2);
    TEST_SEARCH ("(a$|b$)|c$", "dc", 0, 2);
    TEST_SEARCH ("^c|(^a|^b)", "ad", 0, 2);
    TEST_SEARCH ("^c|(^a|^b)", "bd", 0, 2);
    TEST_SEARCH ("^c|(^a|^b)", "cd", 0, 2);
    TEST_SEARCH ("c$|(a$|b$)", "da", 0, 2);
    TEST_SEARCH ("c$|(a$|b$)", "db", 0, 2);
    TEST_SEARCH ("c$|(a$|b$)", "dc", 0, 2);
    TEST_SEARCH ("^c|^(a|b)", "ad", 0, 2);
    TEST_SEARCH ("^c|^(a|b)", "bd", 0, 2);
    TEST_SEARCH ("^c|^(a|b)", "cd", 0, 2);
    TEST_SEARCH ("c$|(a|b)$", "da", 0, 2);
    TEST_SEARCH ("c$|(a|b)$", "db", 0, 2);
    TEST_SEARCH ("c$|(a|b)$", "dc", 0, 2);
    TEST_SEARCH ("(^a|^b)c|^d", "ace", 0, 3);
    TEST_SEARCH ("(^a|^b)c|^d", "bce", 0, 3);
    TEST_SEARCH ("(^a|^b)c|^d", "de", 0, 2);
    TEST_SEARCH ("(a|b)c$|d$", "eac", 0, 3);
    TEST_SEARCH ("(a|b)c$|d$", "ebc", 0, 3);
    TEST_SEARCH ("(a|b)c$|d$", "ed", 0, 3);
    TEST_SEARCH ("^d|^c(a|b)", "cae", 0, 3);
    TEST_SEARCH ("^d|^c(a|b)", "cbe", 0, 3);
    TEST_SEARCH ("^d|^c(a|b)", "de", 0, 3);
    TEST_SEARCH ("d$|c(a$|b$)", "eca", 0, 3);
    TEST_SEARCH ("d$|c(a$|b$)", "ecb", 0, 3);
    TEST_SEARCH ("d$|c(a$|b$)", "ed", 0, 3);

    TEST_SEARCH ("(((^a|^b))c|^d)e", "acef", 0, 4);
    TEST_SEARCH ("(((^a|^b))c|^d)e", "bcef", 0, 4);
    TEST_SEARCH ("(((^a|^b))c|^d)e", "def", 0, 3);

    TEST_SEARCH ("((^(a|b))c|^d)e", "acef", 0, 4);
    TEST_SEARCH ("((^(a|b))c|^d)e", "bcef", 0, 4);
    TEST_SEARCH ("((^(a|b))c|^d)e", "def", 0, 3);

    TEST_SEARCH ("(^((a|b))c|^d)e", "acef", 0, 4);
    TEST_SEARCH ("(^((a|b))c|^d)e", "bcef", 0, 4);
    TEST_SEARCH ("(^((a|b))c|^d)e", "def", 0, 3);

    TEST_SEARCH ("(((a|b))c|d)e$", "face", 0, 4);
    TEST_SEARCH ("(((a|b))c|d)e$", "fbce", 0, 4);
    TEST_SEARCH ("(((a|b))c|d)e$", "fde", 0, 3);

    TEST_SEARCH ("^e(d|c((a|b)))", "edf", 0, 3);
    TEST_SEARCH ("^e(d|c((a|b)))", "ecaf", 0, 4);
    TEST_SEARCH ("^e(d|c((a|b)))", "ecbf", 0, 4);

    TEST_SEARCH ("e(d$|c((a$|b$)))", "fed", 0, 3);
    TEST_SEARCH ("e(d$|c((a$|b$)))", "feca", 0, 4);
    TEST_SEARCH ("e(d$|c((a$|b$)))", "fecb", 0, 4);

    TEST_SEARCH ("e(d$|c((a|b)$))", "fed", 0, 3);
    TEST_SEARCH ("e(d$|c((a|b)$))", "feca", 0, 4);
    TEST_SEARCH ("e(d$|c((a|b)$))", "fecb", 0, 4);

    TEST_SEARCH ("e(d$|c((a|b))$)", "fed", 0, 3);
    TEST_SEARCH ("e(d$|c((a|b))$)", "feca", 0, 3);
    TEST_SEARCH ("e(d$|c((a|b))$)", "fecb", 0, 3);

    TEST_SEARCH ("e(d$|c((a|b)))$", "fed", 0, 3);
    TEST_SEARCH ("e(d$|c((a|b)))$", "feca", 0, 3);
    TEST_SEARCH ("e(d$|c((a|b)))$", "fecb", 0, 3);

    TEST_SEARCH ("(((^a|^b))c)|^de", "acf", 0, 3);
    TEST_SEARCH ("(((^a|^b))c)|^de", "bcf", 0, 3);
    TEST_SEARCH ("(((^a|^b))c)|^de", "def", 0, 3);

    TEST_SEARCH ("(((a|b))c$)|de$", "fac", 0, 3);
    TEST_SEARCH ("(((a|b))c$)|de$", "fbc", 0, 3);
    TEST_SEARCH ("(((a|b))c$)|de$", "fde", 0, 3);

    TEST_SEARCH ("(((a|b))c)$|de$", "fac", 0, 3);
    TEST_SEARCH ("(((a|b))c)$|de$", "fbc", 0, 3);
    TEST_SEARCH ("(((a|b))c)$|de$", "fde", 0, 3);

    TEST_SEARCH ("^ed|^(c((a|b)))", "edf", 0, 3);
    TEST_SEARCH ("^ed|^(c((a|b)))", "caf", 0, 3);
    TEST_SEARCH ("^ed|^(c((a|b)))", "cbf", 0, 3);

    TEST_SEARCH ("^ed|(^c((a|b)))", "edf", 0, 3);
    TEST_SEARCH ("^ed|(^c((a|b)))", "caf", 0, 3);
    TEST_SEARCH ("^ed|(^c((a|b)))", "cbf", 0, 3);

    TEST_SEARCH ("ed$|(c((a|b)))$", "fed", 0, 3);
    TEST_SEARCH ("ed$|(c((a|b)))$", "fca", 0, 3);
    TEST_SEARCH ("ed$|(c((a|b)))$", "fcb", 0, 3);

    TEST_SEARCH ("ed$|(c((a|b))$)", "fed", 0, 3);
    TEST_SEARCH ("ed$|(c((a|b))$)", "fca", 0, 3);
    TEST_SEARCH ("ed$|(c((a|b))$)", "fcb", 0, 3);

    TEST_SEARCH ("ed$|(c((a|b)$))", "fed", 0, 3);
    TEST_SEARCH ("ed$|(c((a|b)$))", "fca", 0, 3);
    TEST_SEARCH ("ed$|(c((a|b)$))", "fcb", 0, 3);

    TEST_SEARCH ("ed$|(c((a$|b$)))", "fed", 0, 3);
    TEST_SEARCH ("ed$|(c((a$|b$)))", "fca", 0, 3);
    TEST_SEARCH ("ed$|(c((a$|b$)))", "fcb", 0, 3);

    TEST_SEARCH ("^a(b|c)|^d", "abe", 0, 3);
    TEST_SEARCH ("^a(b|c)|^d", "ace", 0, 3);
    TEST_SEARCH ("^a(b|c)|^d", "df", 0, 2);

    TEST_SEARCH ("a(b$|c$)|d$", "fab", 0, 3);
    TEST_SEARCH ("a(b$|c$)|d$", "fac", 0, 3);
    TEST_SEARCH ("a(b$|c$)|d$", "fd", 0, 2);

    TEST_SEARCH ("^(a)(b|c)|^d", "abe", 0, 3);
    TEST_SEARCH ("^(a)(b|c)|^d", "ace", 0, 3);
    TEST_SEARCH ("^(a)(b|c)|^d", "df", 0, 2);

    TEST_SEARCH ("(^a)(b|c)|^d", "abe", 0, 3);
    TEST_SEARCH ("(^a)(b|c)|^d", "ace", 0, 3);
    TEST_SEARCH ("(^a)(b|c)|^d", "df", 0, 2);

    TEST_SEARCH ("(a)(b|c)$|d$", "fab", 0, 3);
    TEST_SEARCH ("(a)(b|c)$|d$", "fac", 0, 3);
    TEST_SEARCH ("(a)(b|c)$|d$", "fd", 0, 2);

    TEST_SEARCH ("(b|c)(a)$|d$", "fba", 0, 3);
    TEST_SEARCH ("(b|c)(a)$|d$", "fca", 0, 3);
    TEST_SEARCH ("(b|c)(a)$|d$", "fd", 0, 2);

    TEST_SEARCH ("(b|c)(a$)|d$", "fba", 0, 3);
    TEST_SEARCH ("(b|c)(a$)|d$", "fca", 0, 3);
    TEST_SEARCH ("(b|c)(a$)|d$", "fd", 0, 2);

    TEST_SEARCH ("(a)(b$|c$)|d$", "fab", 0, 3);
    TEST_SEARCH ("(a)(b$|c$)|d$", "fac", 0, 3);
    TEST_SEARCH ("(a)(b$|c$)|d$", "fd", 0, 2);

    TEST_SEARCH ("^d|^(b|c)(a)", "df", 0, 2);
    TEST_SEARCH ("^d|^(b|c)(a)", "baf", 0, 3);
    TEST_SEARCH ("^d|^(b|c)(a)", "caf", 0, 3);

    TEST_SEARCH ("^d|(^b|^c)(a)", "df", 0, 2);
    TEST_SEARCH ("^d|(^b|^c)(a)", "baf", 0, 3);
    TEST_SEARCH ("^d|(^b|^c)(a)", "caf", 0, 3);

    TEST_SEARCH ("d$|(b|c)(a$)", "fd", 0, 2);
    TEST_SEARCH ("d$|(b|c)(a$)", "fba", 0, 3);
    TEST_SEARCH ("d$|(b|c)(a$)", "fca", 0, 3);

    TEST_SEARCH ("d$|(b|c)(a)$", "fd", 0, 2);
    TEST_SEARCH ("d$|(b|c)(a)$", "fba", 0, 3);
    TEST_SEARCH ("d$|(b|c)(a)$", "fca", 0, 3);

    TEST_SEARCH ("d$|(b|c)(a$)", "fd", 0, 2);
    TEST_SEARCH ("d$|(b|c)(a$)", "fba", 0, 3);
    TEST_SEARCH ("d$|(b|c)(a$)", "fca", 0, 3);

    TEST_SEARCH ("^d|^(a)(b|c)", "df", 0, 2);
    TEST_SEARCH ("^d|^(a)(b|c)", "abf", 0, 3);
    TEST_SEARCH ("^d|^(a)(b|c)", "acf", 0, 3);

    TEST_SEARCH ("^d|(^a)(b|c)", "df", 0, 2);
    TEST_SEARCH ("^d|(^a)(b|c)", "abf", 0, 3);
    TEST_SEARCH ("^d|(^a)(b|c)", "acf", 0, 3);

    TEST_SEARCH ("d$|(a)(b$|c$)", "fd", 0, 2);
    TEST_SEARCH ("d$|(a)(b$|c$)", "fab", 0, 3);
    TEST_SEARCH ("d$|(a)(b$|c$)", "fac", 0, 3);

    TEST_SEARCH ("d$|(a)(b|c)$", "fd", 0, 2);
    TEST_SEARCH ("d$|(a)(b|c)$", "fab", 0, 3);
    TEST_SEARCH ("d$|(a)(b|c)$", "fac", 0, 3);

    TEST_SEARCH ("((^a|^b)|^c)|^d", "ae", 0, 2);
    TEST_SEARCH ("((^a|^b)|^c)|^d", "be", 0, 2);
    TEST_SEARCH ("((^a|^b)|^c)|^d", "ce", 0, 2);
    TEST_SEARCH ("((^a|^b)|^c)|^d", "de", 0, 2);

    TEST_SEARCH ("((a|b)|c)|d$", "ed", 0, 2);
    TEST_SEARCH ("((a|b)|c)|d$", "ea", 0, 2);
    TEST_SEARCH ("((a|b)|c)|d$", "eb", 0, 2);
    TEST_SEARCH ("((a|b)|c)|d$", "ec", 0, 2);

    TEST_SEARCH ("^d|(c|(a|b))", "de", 0, 2);

    TEST_SEARCH ("d$|(c$|(a$|b$))", "ed", 0, 2);
    TEST_SEARCH ("d$|(c$|(a$|b$))", "ec", 0, 2);
    TEST_SEARCH ("d$|(c$|(a$|b$))", "ea", 0, 2);
    TEST_SEARCH ("d$|(c$|(a$|b$))", "eb", 0, 2);

    TEST_SEARCH ("d$|(c$|(a|b)$)", "ed", 0, 2);
    TEST_SEARCH ("d$|(c$|(a|b)$)", "ec", 0, 2);
    TEST_SEARCH ("d$|(c$|(a|b)$)", "ea", 0, 2);
    TEST_SEARCH ("d$|(c$|(a|b)$)", "eb", 0, 2);

    TEST_SEARCH ("d$|(c$|(a|b))$", "ed", 0, 2);
    TEST_SEARCH ("d$|(c$|(a|b))$", "ec", 0, 2);
    TEST_SEARCH ("d$|(c$|(a|b))$", "ea", 0, 2);
    TEST_SEARCH ("d$|(c$|(a|b))$", "eb", 0, 2);

    test_match ("a|^b", "b");
    test_match ("a|b$", "b");
    test_match ("^b|a", "b");
    test_match ("b$|a", "b");
    test_match ("(^a)", "a");
    test_match ("(a$)", "a");
    TEST_SEARCH ("c|^ab", "aba", 0, 3);
    TEST_SEARCH ("c|ba$", "aba", 0, 3);
    TEST_SEARCH ("^ab|c", "aba", 0, 3);
    TEST_SEARCH ("ba$|c", "aba", 0, 3);
    TEST_SEARCH ("(^a)", "ab", 0, 2);
    TEST_SEARCH ("(a$)", "ba", 0, 2);

    TEST_SEARCH ("(^a$)", "a", 0, 1);
    TEST_SEARCH ("(^a)", "ab", 0, 2);
    TEST_SEARCH ("(b$)", "ab", 0, 2);

    /* Backtracking.  */
    /* Per POSIX D11.1 p. 108, leftmost longest match.  */
    test_match ("(wee|week)(knights|night)", "weeknights");

    test_match ("(fooq|foo)qbar", "fooqbar");
    test_match ("(fooq|foo)(qbarx|bar)", "fooqbarx");

    /* Take first alternative that does the longest match.  */
    test_all_registers ("(fooq|(foo)|(fo))((qbarx)|(oqbarx)|bar)", "fooqbarx",
                        "", 0, 8,  0, 3,  0, 3,  -1, -1,  3, 8,  3, 8,  -1, -1,  -1, -1, -1, -1,
                        -1, -1);

    test_match ("(fooq|foo)*qbar", "fooqbar");
    test_match ("(fooq|foo)*(qbar)", "fooqbar");
    test_match ("(fooq|foo)*(qbar)*", "fooqbar");

    test_match ("(fooq|fo|o)*qbar", "fooqbar");
    test_match ("(fooq|fo|o)*(qbar)", "fooqbar");
    test_match ("(fooq|fo|o)*(qbar)*", "fooqbar");

    test_match ("(fooq|fo|o)*(qbar|q)*", "fooqbar");
    test_match ("(fooq|foo)*(qbarx|bar)", "fooqbarx");
    test_match ("(fooq|foo)*(qbarx|bar)*", "fooqbarx");

    test_match ("(fooq|fo|o)+(qbar|q)+", "fooqbar");
    test_match ("(fooq|foo)+(qbarx|bar)", "fooqbarx");
    test_match ("(fooq|foo)+(qbarx|bar)+", "fooqbarx");

    /* Per Mike Haertel.  */
    test_match ("(foo|foobarfoo)(bar)*", "foobarfoo");

    /* Combination.  */
    test_match ("[ab]?c", "ac");
    test_match ("[ab]*c", "ac");
    test_match ("[ab]+c", "ac");
    test_match ("(a|b)?c", "ac");
    test_match ("(a|b)*c", "ac");
    test_match ("(a|b)+c", "ac");
    test_match ("(a*c)?b", "b");
    test_match ("(a*c)+b", "aacb");
    /* Registers.  */
    /* Per David A. Willcox.  */
    test_match ("a((b)|(c))d", "acd");
    test_all_registers ("a((b)|(c))d", "acd", "", 0, 3, 1, 2, -1, -1, 1, 2,
                        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);


    /* Extended regular expressions, continued; these don't match their strings.  */
    test_should_match = false;

#if 0
    /* Invalid use of special characters.  */
    /* These are not invalid anymore, since POSIX says the behavior is
       undefined, and we prefer context-independent to context-invalid.  */
    invalid_pattern (REG_BADRPT, "*");
    invalid_pattern (REG_BADRPT, "a|*");
    invalid_pattern (REG_BADRPT, "(*)");
    invalid_pattern (REG_BADRPT, "^*");
    invalid_pattern (REG_BADRPT, "+");
    invalid_pattern (REG_BADRPT, "a|+");
    invalid_pattern (REG_BADRPT, "(+)");
    invalid_pattern (REG_BADRPT, "^+");

    invalid_pattern (REG_BADRPT, "?");
    invalid_pattern (REG_BADRPT, "a|?");
    invalid_pattern (REG_BADRPT, "(?)");
    invalid_pattern (REG_BADRPT, "^?");

    invalid_pattern (REG_BADPAT, "|");
    invalid_pattern (REG_BADPAT, "a|");
    invalid_pattern (REG_BADPAT, "a||");
    invalid_pattern (REG_BADPAT, "(|a)");
    invalid_pattern (REG_BADPAT, "(a|)");

    invalid_pattern (REG_BADPAT, PARENS_TO_OPS ("(|)"));

    invalid_pattern (REG_BADRPT, "{1}");
    invalid_pattern (REG_BADRPT, "a|{1}");
    invalid_pattern (REG_BADRPT, "^{1}");
    invalid_pattern (REG_BADRPT, "({1})");

    invalid_pattern (REG_BADPAT, "|b");

    invalid_pattern (REG_BADRPT, "^{0,}*");
    invalid_pattern (REG_BADRPT, "$*");
    invalid_pattern (REG_BADRPT, "${0,}*");
#endif /* 0 */

    invalid_pattern (REG_EESCAPE, "\\");

    test_match ("a?b", "a");


    test_match ("a+", "");
    test_match ("a+b", "a");
    test_match ("a?", "b");

#if 0
    /* We make empty groups valid now, since they are undefined in POSIX.
      (13 Sep 92) */
    /* Subexpressions.  */
    invalid_pattern (REG_BADPAT, "()");
    invalid_pattern (REG_BADPAT, "a()");
    invalid_pattern (REG_BADPAT, "()b");
    invalid_pattern (REG_BADPAT, "a()b");
    invalid_pattern (REG_BADPAT, "()*");
    invalid_pattern (REG_BADPAT, "(()*");
#endif
    /* Invalid intervals.  */
    test_match ("a{2}*", "aaa");
    test_match ("a{2}?", "aaa");
    test_match ("a{2}+", "aaa");
    test_match ("a{2}{2}", "aaa");
    test_match ("a{1}{1}{2}", "aaa");
    test_match ("a{1}{1}{2}", "a");
    /* Invalid alternation.  */
    test_match ("a|b", "c");

    TEST_SEARCH ("c|^ba", "aba", 0, 3);
    TEST_SEARCH ("c|ab$", "aba", 0, 3);
    TEST_SEARCH ("^ba|c", "aba", 0, 3);
    TEST_SEARCH ("ab$|c", "aba", 0, 3);
    /* Invalid anchoring.  */
    TEST_SEARCH ("(^a)", "ba", 0, 2);
    TEST_SEARCH ("(b$)", "ba", 0, 2);

    printf ("\nFinished POSIX extended tests.\n");
}
Exemple #17
0
short  select_exports( short *type_ptr )
{
	int oset = 0 ;				/* slider offset in numbers of people	*/
	short done = FALSE ;
	short fdone ;
	short export = FALSE ;
	short button ;
	short m_x, m_y ;
	short dummy ;
	short obj_x, obj_y ;
	Filter filter ;
	short i, flag ;

	match_refs = (int *) pmalloc( sizeof (int) * next_person ) ;
	pcross_refs = (int *) pmalloc( sizeof (int) * next_person ) ;
	ccross_refs = (int *) pmalloc( sizeof (int) * next_couple ) ;

	total_people = 0 ;
	for( i=1; i<next_person; i++ )
	{
		if( people[i].birth_date != DELETED_DATE )
			matches[total_people++] = i ;
	}

	exp_selected = (char *) pmalloc( total_people ) ;

	if( !exp_selected || !match_refs || !pcross_refs || !ccross_refs )
	{	
		rsrc_form_alert( 1, NO_MEMORY ) ;
		if( exp_selected )  free( exp_selected ) ;
		if( match_refs )  free( match_refs ) ;
		if( pcross_refs )  free( pcross_refs ) ;
		if( ccross_refs ) free( ccross_refs ) ;
		return FALSE ;
	}

	qsort( matches, (size_t) total_people, (size_t) 4, pidx_compare ) ;

				/* initialise match_refs as not all of array is used	*/
	for( i=0; i<next_person; i++ )  match_refs[i] = -1 ;
				/* load array to get from reference to match position	*/
	for( i=0; i<total_people; i++ )  match_refs[matches[i]] = i ;

	for( i=0; i<total_people; i++ )  exp_selected[i] = FALSE ;

	if( total_people > 16 )
	{
		if( total_people < 256 )
			esel_ptr[ES_SLIDER].ob_height
					= esel_ptr[ES_SLIDE_RANGE].ob_height * 16 / total_people ;
		else
			esel_ptr[ES_SLIDER].ob_height
					= esel_ptr[ES_SLIDE_RANGE].ob_height / 16 ;
		set_slide( 0, total_people-16, esel_ptr,
										ES_SLIDER, ES_SLIDE_RANGE, app_modal_box() ) ;
	}
	else
	{
		esel_ptr[ES_SLIDER].ob_height = esel_ptr[ES_SLIDE_RANGE].ob_height ;
		set_slide( 0, 1, esel_ptr, ES_SLIDER, ES_SLIDE_RANGE, app_modal_box() ) ;
	}

	list_exportees( oset ) ;

	app_modal_init( esel_ptr, "Export", TITLED ) ;

	while( !done )
	{
		button = app_modal_do() ;
		button &= ~DOUBLE_CLICK ;

		if( button  && button != APP_MODAL_TERM )  esel_ptr[button].ob_state &= ~SELECTED ;

		switch( button )
		{
			case ES_SLIDER :
				if( total_people > 16 )
				{
					oset = move_slide( esel_ptr,
										ES_SLIDER, ES_SLIDE_RANGE, app_modal_box() ) ;
					oset = ( total_people - 16 ) * oset / 1000 ;
				}
				list_exportees( oset ) ;
				objc_draw( esel_ptr, ES_LIST, MAX_DEPTH, PTRS( app_modal_box() ) ) ;
				break ;
			case ES_UP :
				if( total_people > 16 && oset > 0 )
				{
					oset-- ;
					set_slide( oset, total_people-16, esel_ptr,
										ES_SLIDER, ES_SLIDE_RANGE, app_modal_box() ) ;
				}
				list_exportees( oset ) ;
				objc_draw( esel_ptr, ES_LIST, MAX_DEPTH, PTRS( app_modal_box() ) ) ;
				break ;
			case ES_DOWN :
				if( total_people > 16 && oset < total_people - 16 )
				{
					oset++ ;
					set_slide( oset, total_people - 16, esel_ptr,
										ES_SLIDER, ES_SLIDE_RANGE, app_modal_box() ) ;
				}
				list_exportees( oset ) ;
				objc_draw( esel_ptr, ES_LIST, MAX_DEPTH, PTRS( app_modal_box() ) ) ;
				break ;
			case ES_SLIDE_RANGE :
				if( total_people > 16 )
				{
					graf_mkstate( &m_x, &m_y, &dummy, &dummy ) ;
					objc_offset( esel_ptr, ES_SLIDER, &obj_x, &obj_y ) ;
					if( m_y > obj_y )
					{
						oset += 15 ;
						if( oset > total_people - 16 )  oset = total_people - 16 ;
					}
					else
					{
						oset -= 15 ;
						if( oset < 0 )  oset = 0 ;
					}
					set_slide( oset, total_people-16, esel_ptr,
									ES_SLIDER, ES_SLIDE_RANGE, app_modal_box() ) ;
				}
				list_exportees( oset ) ;
				objc_draw( esel_ptr, ES_LIST, MAX_DEPTH, PTRS( app_modal_box() ) ) ;
				break ;
			case ESEL0 :
			case ESEL1 :
			case ESEL2 :
			case ESEL3 :
			case ESEL4 :
			case ESEL5 :
			case ESEL6 :
			case ESEL7 :
			case ESEL8 :
			case ESEL9 :
			case ESEL10 :
			case ESEL11 :
			case ESEL12 :
			case ESEL13 :
			case ESEL14 :
			case ESEL15 :
				if( esel_ptr[ANCESTORS].ob_state & SELECTED )
				{
					ancestor_select( matches[button-ESEL0 + oset] ) ;
					esel_ptr[ANCESTORS].ob_state &= ~SELECTED ;
					esel_ptr[DESCENDANTS].ob_state &= ~SELECTED ;
					list_exportees( oset ) ;
					objc_draw( esel_ptr, ROOT, MAX_DEPTH, PTRS( app_modal_box() ) ) ;
				}
				else if( esel_ptr[DESCENDANTS].ob_state & SELECTED )
				{
					descendant_select( matches[button-ESEL0 + oset], 0, 0 ) ;
					esel_ptr[DESCENDANTS].ob_state &= ~SELECTED ;
					list_exportees( oset ) ;
					objc_draw( esel_ptr, ROOT, MAX_DEPTH, PTRS( app_modal_box() ) ) ;
				}
				else
				{
					if( !exp_selected[button-ESEL0 + oset] )
					{
						exp_selected[button-ESEL0 + oset] = TRUE ;
						esel_ptr[button].ob_state |= CHECKED ;
					}
					else
					{
						exp_selected[button-ESEL0 + oset] = FALSE ;
						esel_ptr[button].ob_state &= ~CHECKED ;
					}
					objc_draw( esel_ptr, button, MAX_DEPTH, PTRS( app_modal_box() ) ) ;
				}
				break ;
			case ES_SEL_ALL :
				for( i=0; i<total_people; i++ )  exp_selected[i] = TRUE ;
				list_exportees( oset ) ;
				objc_draw( esel_ptr, ES_LIST, MAX_DEPTH, PTRS( app_modal_box() ) ) ;
				objc_draw( esel_ptr, ES_SEL_ALL, MAX_DEPTH, PTRS( app_modal_box() ) ) ;
				break ;
			case ES_DSEL_ALL :
				for( i=0; i<total_people; i++ )  exp_selected[i] = FALSE ;
				list_exportees( oset ) ;
				objc_draw( esel_ptr, ES_LIST, MAX_DEPTH, PTRS( app_modal_box() ) ) ;
				objc_draw( esel_ptr, ES_DSEL_ALL, MAX_DEPTH, PTRS( app_modal_box() ) ) ;
				break ;
			case ES_FILTER :
				clear_efil_form() ;
				clear_form_flags() ;
				for( i = 0 ; i <= FL_NOT8 - FL_NOT1 ; i+= FL_NOT2 - FL_NOT1 )
				{
					set_to_ignore(FL_NOT1+i) ;
					flags_ptr[FL_NOT1+i].ob_state |= SELECTED ;
				}
				fdone = FALSE ;				/* loop until filter done	*/
				while( !fdone )
				{
					button = do_sub_form( efil_ptr, "Export Filter", EXP_HELP, TITLED ) ;
					switch( button )
					{
						case EXP_SEL :
						case EXP_DESEL :
							busy( BUSY_MORE ) ;
							update_filter( &filter, efil_form_addrs.efam_name,
								efil_form_addrs.eforename, efil_form_addrs.ebefore,
								efil_form_addrs.eafter, efil_form_addrs.eplace ) ;
							if( button == EXP_DESEL )  flag = FALSE ;
							else  flag = TRUE ;
							for( i=0; i<total_people; i++ )
							{
								if( test_match( &filter, matches[i] ) )
									exp_selected[i] = flag ;
							}
							busy( BUSY_LESS ) ;
						case EXP_CANCEL :
							fdone = TRUE ;
							break ;
						case EXP_FLAGS :
							do_sub_form( flags_ptr, "Filter Flags", FL_HELP, TITLED ) ;
							break ;
					}
				}
				list_exportees( oset ) ;
				break ;
			case ES_CANCEL :
			case APP_MODAL_TERM :
				done = TRUE ;
				break ;
			case ES_OK :
				export = TRUE ;
				done = TRUE ;
				break ;
			case ES_HELP :
				help( export_help ) ;
				objc_draw( esel_ptr, ES_HELP, 0, PTRS( app_modal_box() ) ) ;
				break ;
			default :
				break ;
		}
	}
	esel_ptr[ANCESTORS].ob_state &= ~SELECTED ;
	esel_ptr[DESCENDANTS].ob_state &= ~SELECTED ;

	if( esel_ptr[GEDCOM].ob_state & SELECTED )
		*type_ptr = GEDCOM_TYPE ;
	else if( esel_ptr[CSV].ob_state & SELECTED )
		*type_ptr = CSV_TYPE ;
	else  *type_ptr = FAMTREE_TYPE ;
	
	app_modal_end() ;

	return export ;
}
Exemple #18
0
inline void test_match(const std::string& re, const std::string& text)
{ test_match(re, text, text); }
/******************************************************************************
 *                                                                            *
 * Function: zbx_mock_test_entry                                              *
 *                                                                            *
 ******************************************************************************/
void	zbx_mock_test_entry(void **state)
{
	const char			*filter;
	zbx_prometheus_condition_test_t	*metric = NULL, *value = NULL;
	zbx_vector_ptr_t		labels;
	int				ret, expected_ret, index;
	char				*error = NULL;
	zbx_mock_handle_t		hmetric, hvalue, hlabels, hlabel;
	zbx_mock_error_t		mock_ret;

	ZBX_UNUSED(state);

	zbx_vector_ptr_create(&labels);

	filter = zbx_mock_get_parameter_string("in.filter");

	ret = zbx_prometheus_filter_parse(filter, &metric, &labels, &value, &error);
	expected_ret = zbx_mock_str_to_return_code(zbx_mock_get_parameter_string("out.return"));
	zbx_mock_assert_result_eq("prometheus filter parsing", expected_ret, ret);

	if (SUCCEED == ret)
	{
		if (ZBX_MOCK_SUCCESS != zbx_mock_parameter("out.metric", &hmetric))
			hmetric = -1;
		test_match("metric", hmetric, metric);

		if (ZBX_MOCK_SUCCESS != zbx_mock_parameter("out.value", &hvalue))
			hvalue = -1;
		test_match("value", hvalue, value);

		if (ZBX_MOCK_SUCCESS != zbx_mock_parameter("out.labels", &hlabels))
			hlabels = -1;

		if (-1 != hlabels && 0 == labels.values_num)
			fail_msg("expected to parse label filters");

		if (-1 == hlabels && 0 != labels.values_num)
			fail_msg("did not expect to parse label filters");

		if (-1 != hlabels)
		{
			index = 0;
			while (ZBX_MOCK_END_OF_VECTOR != (mock_ret = zbx_mock_vector_element(hlabels, &hlabel)) &&
					index < labels.values_num)
			{
				test_match("label", hlabel, labels.values[index]);
				index++;
			}

			if (ZBX_MOCK_END_OF_VECTOR != mock_ret)
				fail_msg("expected more than %d filter labels", index);

			if (index != labels.values_num)
				fail_msg("got more than the expected %d filter labels", index);
		}
	}

	if (NULL != metric)
		zbx_prometheus_condition_test_free(metric);
	if (NULL != value)
		zbx_prometheus_condition_test_free(value);

	zbx_vector_ptr_clear_ext(&labels, (zbx_clean_func_t)zbx_prometheus_condition_test_free);
	zbx_vector_ptr_destroy(&labels);

	zbx_free(error);
}
Exemple #20
0
int translate(struct sip_msg *msg, str input, str * output, dpl_id_p idp, str * attrs) {

	dpl_node_p rulep, rrulep;
	int string_res = -1, regexp_res = -1, bucket;

	if(!input.s || !input.len) {
		LM_ERR("invalid input string\n");
		return -1;
	}

	bucket = core_case_hash(&input, NULL, DP_INDEX_HASH_SIZE);

	/* try to match the input in the corresponding string bucket */
	for (rulep = idp->rule_hash[bucket].first_rule; rulep; rulep=rulep->next) {

		LM_DBG("Equal operator testing\n");

		if(rulep->match_exp.len != input.len)
			continue;

		LM_DBG("Comparing (input %.*s) with (rule %.*s) [%d] and timerec %.*s\n",
				input.len, input.s, rulep->match_exp.len, rulep->match_exp.s,
				rulep->match_flags, rulep->timerec.len, rulep->timerec.s);

		// Check for Time Period if Set
		if(rulep->parsed_timerec) {
			LM_DBG("Timerec exists for rule checking: %.*s\n", rulep->timerec.len, rulep->timerec.s);
			// Doesn't matches time period continue with next rule
			if(!check_time(rulep->parsed_timerec)) {
				LM_DBG("Time rule doesn't match: skip next!\n");
				continue;
			}
		}

		if (rulep->match_flags & DP_CASE_INSENSITIVE) {
			string_res = strncasecmp(rulep->match_exp.s,input.s,input.len);
		} else {
			string_res = strncmp(rulep->match_exp.s,input.s,input.len);
		}

		if (string_res == 0) {
			break;
		}
	}

	/* try to match the input in the regexp bucket */
	for (rrulep = idp->rule_hash[DP_INDEX_HASH_SIZE].first_rule; rrulep; rrulep=rrulep->next) {

		// Check for Time Period if Set
		if(rrulep->parsed_timerec) {
			LM_DBG("Timerec exists for rule checking: %.*s\n", rrulep->timerec.len, rrulep->timerec.s);
			// Doesn't matches time period continue with next rule
			if(!check_time(rrulep->parsed_timerec)) {
				LM_DBG("Time rule doesn't match: skip next!\n");
				continue;
			}
		}

		regexp_res = (test_match(input, rrulep->match_comp, matches, MAX_MATCHES)
					>= 0 ? 0 : -1);

		LM_DBG("Regex operator testing. Got result: %d\n", regexp_res);

		if (regexp_res == 0) {
			break;
		}
	}

	if (string_res != 0 && regexp_res != 0) {
		LM_DBG("No matching rule for input %.*s\n", input.len, input.s);
		return -1;
	}

	/* pick the rule with lowest table index if both match and prio are equal */
	if (string_res == 0 && regexp_res == 0) {
		if (rrulep->pr < rulep->pr) {
			rulep = rrulep;
		} else if (rrulep->pr == rulep->pr &&
		           rrulep->table_id < rulep->table_id) {
			rulep = rrulep;
		}
	}

	if (!rulep)
		rulep = rrulep;

	LM_DBG("Found a matching rule %p: pr %i, match_exp %.*s\n",
		rulep, rulep->pr, rulep->match_exp.len, rulep->match_exp.s);

	if(attrs){
		attrs->len = 0;
		attrs->s = 0;
		if(rulep->attrs.len>0) {
			LM_DBG("the rule's attrs are %.*s\n",
				rulep->attrs.len, rulep->attrs.s);
			if(rulep->attrs.len >= DP_MAX_ATTRS_LEN) {
				LM_ERR("EXCEEDED Max attribute length.\n");
				return -1;
			}
			attrs->s = dp_attrs_buf;
			memcpy(attrs->s, rulep->attrs.s, rulep->attrs.len*sizeof(char));
			attrs->len = rulep->attrs.len;
			attrs->s[attrs->len] = '\0';

			LM_DBG("the copied attributes are: %.*s\n",
				attrs->len, attrs->s);
		}
	}

	if(rule_translate(msg, input, rulep, output)!=0){
		LM_ERR("could not build the output\n");
		return -1;
	}

	return 0;
}
Exemple #21
0
int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
		str * result)
{
	int repl_nb, offset, match_nb;
	struct replace_with token;
	pcre * subst_comp;
	struct subst_expr * repl_comp;
	pv_value_t sv;
	str* uri;
	int capturecount;
	char *match_begin;
	int match_len;

	dp_output_buf[0] = '\0';
	result->s = dp_output_buf;
	result->len = 0;

	subst_comp 	= rule->subst_comp;
	repl_comp 	= rule->repl_comp;

	if(!repl_comp){
		LM_DBG("null replacement\n");
		return 0;
	}


	if(subst_comp){

		pcre_fullinfo(
		subst_comp,                   /* the compiled pattern */
		NULL,                 /* no extra data - we didn't study the pattern */
		PCRE_INFO_CAPTURECOUNT ,  /* number of named substrings */
		&capturecount);          /* where to put the answer */


		/*just in case something went wrong at load time*/
		if(repl_comp->max_pmatch > capturecount){
			LM_ERR("illegal access to the "
				"%i-th subexpr of the subst expr\n", repl_comp->max_pmatch);
			return -1;
		}

		/*search for the pattern from the compiled subst_exp*/
		if(test_match(string, rule->subst_comp,matches,MAX_MATCHES) <= 0){
			LM_ERR("the string %.*s "
				"matched the match_exp %.*s but not the subst_exp %.*s!\n",
				string.len, string.s,
				rule->match_exp.len, rule->match_exp.s,
				rule->subst_exp.len, rule->subst_exp.s);
			return -1;
		}
	}

	/*simply copy from the replacing string*/
	if(!subst_comp || (repl_comp->n_escapes <=0)){
		if(!repl_comp->replacement.s || repl_comp->replacement.len == 0){
			LM_ERR("invalid replacing string\n");
			goto error;
		}
		LM_DBG("simply replace the string, "
			"subst_comp %p, n_escapes %i\n",subst_comp, repl_comp->n_escapes);
		memcpy(result->s, repl_comp->replacement.s, repl_comp->replacement.len);
		result->len = repl_comp->replacement.len;
		result->s[result->len] = '\0';
		return 0;
	}

	/* offset- offset in the replacement string */
	result->len = repl_nb = offset = 0;

	while( repl_nb < repl_comp->n_escapes){
		token = repl_comp->replace[repl_nb];

		if(offset< token.offset){
			if((repl_comp->replacement.len < offset)||
				(result->len + token.offset -offset >= MAX_PHONE_NB_DIGITS)){
				LM_ERR("invalid length\n");
				goto error;
			}
			/*copy from the replacing string*/
			memcpy(result->s + result->len, repl_comp->replacement.s + offset,
					token.offset-offset);
			result->len += (token.offset - offset);
			offset += token.offset-offset; /*update the offset*/
		}

		switch(token.type) {
			case REPLACE_NMATCH:
				/*copy from the match subexpression*/
				match_nb = token.u.nmatch;

				match_begin = string.s + matches[2*match_nb];
				match_len = matches[2*match_nb+1] - matches[2*match_nb];

				if(result->len + match_len >= MAX_PHONE_NB_DIGITS){
					LM_ERR("overflow\n");
					goto error;
				}

				memcpy(result->s + result->len, match_begin, match_len);
				result->len += match_len;
				offset += token.size; /*update the offset*/
				break;

			case REPLACE_CHAR:
				if(result->len + 1>= MAX_PHONE_NB_DIGITS){
					LM_ERR("overflow\n");
					goto error;
				}
				*result->s=repl_comp->replace[repl_nb].u.c;
				result->len++;
				break;
			case REPLACE_URI:
				if ( msg== NULL || msg->first_line.type!=SIP_REQUEST){
					LM_CRIT("uri substitution attempt on no request"
						" message\n");
					break; /* ignore, we can continue */
				}
				uri= (msg->new_uri.s)?(&msg->new_uri):
					(&msg->first_line.u.request.uri);
				if(result->len+uri->len>=MAX_PHONE_NB_DIGITS){
					LM_ERR("overflow\n");
					goto error;
				}
				memcpy(result->s + result->len, uri->s, uri->len);
				result->len+=uri->len;
				break;
			case REPLACE_SPEC:
				if (msg== NULL) {
					LM_DBG("replace spec attempted on no message\n");
					break;
				}
			if(pv_get_spec_value(msg,
				&repl_comp->replace[repl_nb].u.spec, &sv)!=0){
					LM_CRIT( "item substitution returned error\n");
					break; /* ignore, we can continue */
				}
				if(result->len+sv.rs.len>=MAX_PHONE_NB_DIGITS){
					LM_ERR("ERROR:dialplan: rule_translate: overflow\n");
					goto error;
				}
				memcpy(result->s + result->len, sv.rs.s, sv.rs.len);
				result->len+=sv.rs.len;
				break;
			default:
				LM_CRIT("BUG: unknown type %d\n",
					repl_comp->replace[repl_nb].type);
				/* ignore it */
		}
		repl_nb++;
	}
	/* anything left? */
	if( repl_nb && token.offset+token.size < repl_comp->replacement.len){
		/*copy from the replacing string*/
		memcpy(result->s + result->len,
			repl_comp->replacement.s + token.offset+token.size,
			repl_comp->replacement.len -(token.offset+token.size) );
			result->len +=repl_comp->replacement.len-(token.offset+token.size);
	}

	result->s[result->len] = '\0';
	return 0;

error:
	result->s = 0;
	result->len = 0;
	return -1;
}