diff options
Diffstat (limited to 'lib/stdlib/test/re_SUITE.erl')
-rw-r--r-- | lib/stdlib/test/re_SUITE.erl | 643 |
1 files changed, 312 insertions, 331 deletions
diff --git a/lib/stdlib/test/re_SUITE.erl b/lib/stdlib/test/re_SUITE.erl index d78d6153da..c9ef9da990 100644 --- a/lib/stdlib/test/re_SUITE.erl +++ b/lib/stdlib/test/re_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2013. All Rights Reserved. +%% Copyright Ericsson AB 2008-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -24,16 +24,18 @@ run_options/1,combined_options/1,replace_autogen/1, global_capture/1,replace_input_types/1,replace_return/1, split_autogen/1,split_options/1,split_specials/1, - error_handling/1,pcre_cve_2008_2371/1, + error_handling/1,pcre_cve_2008_2371/1,re_version/1, pcre_compile_workspace_overflow/1,re_infinite_loop/1, re_backwards_accented/1,opt_dupnames/1,opt_all_names/1,inspect/1, opt_no_start_optimize/1,opt_never_utf/1,opt_ucp/1, match_limit/1,sub_binaries/1,copt/1]). --include_lib("test_server/include/test_server.hrl"). +-include_lib("common_test/include/ct.hrl"). -include_lib("kernel/include/file.hrl"). -suite() -> [{ct_hooks,[ts_install_cth]}]. +suite() -> + [{ct_hooks,[ts_install_cth]}, + {timetrap,{minutes,3}}]. all() -> [pcre, compile_options, run_options, combined_options, @@ -43,7 +45,7 @@ all() -> pcre_compile_workspace_overflow, re_infinite_loop, re_backwards_accented, opt_dupnames, opt_all_names, inspect, opt_no_start_optimize,opt_never_utf,opt_ucp, - match_limit, sub_binaries]. + match_limit, sub_binaries, re_version]. groups() -> []. @@ -61,264 +63,255 @@ end_per_group(_GroupName, Config) -> Config. -pcre(doc) -> - ["Run all applicable tests from the PCRE testsuites."]; +%% Run all applicable tests from the PCRE testsuites. pcre(Config) when is_list(Config) -> - Dog = ?t:timetrap(?t:minutes(3)), - RootDir = ?config(data_dir, Config), + RootDir = proplists:get_value(data_dir, Config), Res = run_pcre_tests:test(RootDir), 0 = lists:sum([ X || {X,_,_} <- Res ]), - ?t:timetrap_cancel(Dog), {comment,Res}. -compile_options(doc) -> - ["Test all documented compile options"]; +%% Test all documented compile options. compile_options(Config) when is_list(Config) -> - ?line ok = ctest("ABDabcdABCD","abcd",[],true,{match,[{3,4}]}), - ?line ok = ctest("ABDabcdABCD","abcd",[anchored],true,nomatch), - ?line ok = ctest("ABDabcdABCD",".*abcd",[anchored],true,{match,[{0,7}]}), - ?line ok = ctest("ABCabcdABC","ABCD",[],true,nomatch), - ?line ok = ctest("ABCabcdABC","ABCD",[caseless],true,{match,[{3,4}]}), - ?line ok = ctest("abcdABC\n","ABC$",[],true,{match,[{4,3}]}), - ?line ok = ctest("abcdABC\n","ABC$",[dollar_endonly],true,nomatch), - ?line ok = ctest("abcdABC\n","ABC.",[],true,nomatch), - ?line ok = ctest("abcdABC\n","ABC.",[dotall],true,{match,[{4,4}]}), - ?line ok = ctest("abcdABCD","ABC .",[],true,nomatch), - ?line ok = ctest("abcdABCD","ABC .",[extended],true,{match,[{4,4}]}), - ?line ok = ctest("abcd\nABCD","ABC",[],true,{match,[{5,3}]}), - ?line ok = ctest("abcd\nABCD","ABC",[firstline],true,nomatch), - ?line ok = ctest("abcd\nABCD","^ABC",[],true,nomatch), - ?line ok = ctest("abcd\nABCD","^ABC",[multiline],true,{match,[{5,3}]}), - ?line ok = ctest("abcdABCD","(ABC)",[],true,{match,[{4,3},{4,3}]}), - ?line ok = ctest("abcdABCD","(ABC)",[no_auto_capture],true,{match,[{4,3}]}), - ?line ok = ctest(notused,"(?<FOO>ABC)|(?<FOO>DEF)",[],false,notused), - ?line ok = ctest("abcdABCD","(?<FOO>ABC)|(?<FOO>DEF)",[dupnames],true,{match,[{4,3},{4,3}]}), - ?line ok = ctest("abcdABCDabcABCD","abcd.*D",[],true,{match,[{0,15}]}), - ?line ok = ctest("abcdABCDabcABCD","abcd.*D",[ungreedy],true,{match,[{0,8}]}), - ?line ok = ctest("abcdABCabcABC\nD","abcd.*D",[],true,nomatch), - ?line ok = ctest("abcdABCabcABC\nD","abcd.*D",[{newline,cr}],true,{match,[{0,15}]}), - ?line ok = ctest("abcdABCabcABC\rD","abcd.*D",[],true,{match,[{0,15}]}), - ?line ok = ctest("abcdABCabcABC\rD","abcd.*D",[{newline,lf}],true,{match,[{0,15}]}), - ?line ok = ctest("abcdABCabcd\r\n","abcd$",[{newline,lf}],true,nomatch), - ?line ok = ctest("abcdABCabcd\r\n","abcd$",[{newline,cr}],true,nomatch), - ?line ok = ctest("abcdABCabcd\r\n","abcd$",[{newline,crlf}],true,{match,[{7,4}]}), - - ?line ok = ctest("abcdABCabcd\r","abcd$",[{newline,crlf}],true,nomatch), - ?line ok = ctest("abcdABCabcd\n","abcd$",[{newline,crlf}],true,nomatch), - ?line ok = ctest("abcdABCabcd\r\n","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), - - ?line ok = ctest("abcdABCabcd\r","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), - ?line ok = ctest("abcdABCabcd\n","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), + ok = ctest("ABDabcdABCD","abcd",[],true,{match,[{3,4}]}), + ok = ctest("ABDabcdABCD","abcd",[anchored],true,nomatch), + ok = ctest("ABDabcdABCD",".*abcd",[anchored],true,{match,[{0,7}]}), + ok = ctest("ABCabcdABC","ABCD",[],true,nomatch), + ok = ctest("ABCabcdABC","ABCD",[caseless],true,{match,[{3,4}]}), + ok = ctest("abcdABC\n","ABC$",[],true,{match,[{4,3}]}), + ok = ctest("abcdABC\n","ABC$",[dollar_endonly],true,nomatch), + ok = ctest("abcdABC\n","ABC.",[],true,nomatch), + ok = ctest("abcdABC\n","ABC.",[dotall],true,{match,[{4,4}]}), + ok = ctest("abcdABCD","ABC .",[],true,nomatch), + ok = ctest("abcdABCD","ABC .",[extended],true,{match,[{4,4}]}), + ok = ctest("abcd\nABCD","ABC",[],true,{match,[{5,3}]}), + ok = ctest("abcd\nABCD","ABC",[firstline],true,nomatch), + ok = ctest("abcd\nABCD","^ABC",[],true,nomatch), + ok = ctest("abcd\nABCD","^ABC",[multiline],true,{match,[{5,3}]}), + ok = ctest("abcdABCD","(ABC)",[],true,{match,[{4,3},{4,3}]}), + ok = ctest("abcdABCD","(ABC)",[no_auto_capture],true,{match,[{4,3}]}), + ok = ctest(notused,"(?<FOO>ABC)|(?<FOO>DEF)",[],false,notused), + ok = ctest("abcdABCD","(?<FOO>ABC)|(?<FOO>DEF)",[dupnames],true,{match,[{4,3},{4,3}]}), + ok = ctest("abcdABCDabcABCD","abcd.*D",[],true,{match,[{0,15}]}), + ok = ctest("abcdABCDabcABCD","abcd.*D",[ungreedy],true,{match,[{0,8}]}), + ok = ctest("abcdABCabcABC\nD","abcd.*D",[],true,nomatch), + ok = ctest("abcdABCabcABC\nD","abcd.*D",[{newline,cr}],true,{match,[{0,15}]}), + ok = ctest("abcdABCabcABC\rD","abcd.*D",[],true,{match,[{0,15}]}), + ok = ctest("abcdABCabcABC\rD","abcd.*D",[{newline,lf}],true,{match,[{0,15}]}), + ok = ctest("abcdABCabcd\r\n","abcd$",[{newline,lf}],true,nomatch), + ok = ctest("abcdABCabcd\r\n","abcd$",[{newline,cr}],true,nomatch), + ok = ctest("abcdABCabcd\r\n","abcd$",[{newline,crlf}],true,{match,[{7,4}]}), + + ok = ctest("abcdABCabcd\r","abcd$",[{newline,crlf}],true,nomatch), + ok = ctest("abcdABCabcd\n","abcd$",[{newline,crlf}],true,nomatch), + ok = ctest("abcdABCabcd\r\n","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), + + ok = ctest("abcdABCabcd\r","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), + ok = ctest("abcdABCabcd\n","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), ok. -run_options(doc) -> - ["Test all documented run specific options"]; +%% Test all documented run specific options. run_options(Config) when is_list(Config) -> - ?line rtest("ABCabcdABC","abc",[],[],true), - ?line rtest("ABCabcdABC","abc",[anchored],[],false), - % Anchored in run overrides unanchored in compilation - ?line rtest("ABCabcdABC","abc",[],[anchored],false), - - ?line rtest("","a?b?",[],[],true), - ?line rtest("","a?b?",[],[notempty],false), - - ?line rtest("abc","^a",[],[],true), - ?line rtest("abc","^a",[],[notbol],false), - ?line rtest("ab\nc","^a",[multiline],[],true), - ?line rtest("ab\nc","^a",[multiline],[notbol],false), - ?line rtest("ab\nc","^c",[multiline],[notbol],true), - - ?line rtest("abc","c$",[],[],true), - ?line rtest("abc","c$",[],[noteol],false), - - ?line rtest("ab\nc","b$",[multiline],[],true), - ?line rtest("ab\nc","c$",[multiline],[],true), - ?line rtest("ab\nc","b$",[multiline],[noteol],true), - ?line rtest("ab\nc","c$",[multiline],[noteol],false), - - ?line rtest("abc","ab",[],[{offset,0}],true), - ?line rtest("abc","ab",[],[{offset,1}],false), - - ?line rtest("abcdABCabcABC\nD","abcd.*D",[],[],false), - ?line rtest("abcdABCabcABC\nD","abcd.*D",[],[{newline,cr}],true), - ?line rtest("abcdABCabcABC\rD","abcd.*D",[],[],true), - ?line rtest("abcdABCabcABC\rD","abcd.*D",[{newline,cr}],[{newline,lf}],true), - ?line rtest("abcdABCabcd\r\n","abcd$",[],[{newline,lf}],false), - ?line rtest("abcdABCabcd\r\n","abcd$",[],[{newline,cr}],false), - ?line rtest("abcdABCabcd\r\n","abcd$",[],[{newline,crlf}],true), - - ?line rtest("abcdABCabcd\r","abcd$",[],[{newline,crlf}],false), - ?line rtest("abcdABCabcd\n","abcd$",[],[{newline,crlf}],false), - ?line rtest("abcdABCabcd\r\n","abcd$",[],[{newline,anycrlf}],true), - - ?line rtest("abcdABCabcd\r","abcd$",[],[{newline,anycrlf}],true), - ?line rtest("abcdABCabcd\n","abcd$",[],[{newline,anycrlf}],true), - - ?line {ok,MP} = re:compile(".*(abcd).*"), - ?line {match,[{0,10},{3,4}]} = re:run("ABCabcdABC",MP,[]), - ?line {match,[{0,10},{3,4}]} = re:run("ABCabcdABC",MP,[{capture,all}]), - ?line {match,[{0,10},{3,4}]} = re:run("ABCabcdABC",MP,[{capture,all,index}]), - ?line {match,["ABCabcdABC","abcd"]} = re:run("ABCabcdABC",MP,[{capture,all,list}]), - ?line {match,[<<"ABCabcdABC">>,<<"abcd">>]} = re:run("ABCabcdABC",MP,[{capture,all,binary}]), - ?line {match,[{0,10}]} = re:run("ABCabcdABC",MP,[{capture,first}]), - ?line {match,[{0,10}]} = re:run("ABCabcdABC",MP,[{capture,first,index}]), ?line {match,["ABCabcdABC"]} = re:run("ABCabcdABC",MP,[{capture,first,list}]), - ?line {match,[<<"ABCabcdABC">>]} = re:run("ABCabcdABC",MP,[{capture,first,binary}]), - - ?line {match,[{3,4}]} = re:run("ABCabcdABC",MP,[{capture,all_but_first}]), - ?line {match,[{3,4}]} = re:run("ABCabcdABC",MP,[{capture,all_but_first,index}]), - ?line {match,["abcd"]} = re:run("ABCabcdABC",MP,[{capture,all_but_first,list}]), - ?line {match,[<<"abcd">>]} = re:run("ABCabcdABC",MP,[{capture,all_but_first,binary}]), - - ?line match = re:run("ABCabcdABC",MP,[{capture,none}]), - ?line match = re:run("ABCabcdABC",MP,[{capture,none,index}]), - ?line match = re:run("ABCabcdABC",MP,[{capture,none,list}]), - ?line match = re:run("ABCabcdABC",MP,[{capture,none,binary}]), - - ?line {ok,MP2} = re:compile(".*(?<FOO>abcd).*"), - ?line {match,[{3,4}]} = re:run("ABCabcdABC",MP2,[{capture,[1]}]), - ?line {match,[{3,4}]} = re:run("ABCabcdABC",MP2,[{capture,['FOO']}]), - ?line {match,[{3,4}]} = re:run("ABCabcdABC",MP2,[{capture,["FOO"]}]), - ?line {match,["abcd"]} = re:run("ABCabcdABC",MP2,[{capture,["FOO"],list}]), - ?line {match,[<<"abcd">>]} = re:run("ABCabcdABC",MP2,[{capture,["FOO"],binary}]), - - ?line {match,[{-1,0}]} = re:run("ABCabcdABC",MP2,[{capture,[200]}]), - ?line {match,[{-1,0}]} = re:run("ABCabcdABC",MP2,[{capture,['BAR']}]), - ?line {match,[""]} = re:run("ABCabcdABC",MP2,[{capture,[200],list}]), - ?line {match,[""]} = re:run("ABCabcdABC",MP2,[{capture,['BAR'],list}]), - ?line {match,[<<>>]} = re:run("ABCabcdABC",MP2,[{capture,[200],binary}]), - ?line {match,[<<>>]} = re:run("ABCabcdABC",MP2,[{capture,['BAR'],binary}]), - - ?line {ok, MP3} = re:compile(".*((?<FOO>abdd)|a(..d)).*"), - ?line {match,[{0,10},{3,4},{-1,0},{4,3}]} = re:run("ABCabcdABC",MP3,[]), - ?line {match,[{0,10},{3,4},{-1,0},{4,3}]} = re:run("ABCabcdABC",MP3,[{capture,all,index}]), - ?line {match,[<<"ABCabcdABC">>,<<"abcd">>,<<>>,<<"bcd">>]} = re:run("ABCabcdABC",MP3,[{capture,all,binary}]), - ?line {match,["ABCabcdABC","abcd",[],"bcd"]} = re:run("ABCabcdABC",MP3,[{capture,all,list}]), + rtest("ABCabcdABC","abc",[],[],true), + rtest("ABCabcdABC","abc",[anchored],[],false), + %% Anchored in run overrides unanchored in compilation + rtest("ABCabcdABC","abc",[],[anchored],false), + + rtest("","a?b?",[],[],true), + rtest("","a?b?",[],[notempty],false), + + rtest("abc","^a",[],[],true), + rtest("abc","^a",[],[notbol],false), + rtest("ab\nc","^a",[multiline],[],true), + rtest("ab\nc","^a",[multiline],[notbol],false), + rtest("ab\nc","^c",[multiline],[notbol],true), + + rtest("abc","c$",[],[],true), + rtest("abc","c$",[],[noteol],false), + + rtest("ab\nc","b$",[multiline],[],true), + rtest("ab\nc","c$",[multiline],[],true), + rtest("ab\nc","b$",[multiline],[noteol],true), + rtest("ab\nc","c$",[multiline],[noteol],false), + + rtest("abc","ab",[],[{offset,0}],true), + rtest("abc","ab",[],[{offset,1}],false), + + rtest("abcdABCabcABC\nD","abcd.*D",[],[],false), + rtest("abcdABCabcABC\nD","abcd.*D",[],[{newline,cr}],true), + rtest("abcdABCabcABC\rD","abcd.*D",[],[],true), + rtest("abcdABCabcABC\rD","abcd.*D",[{newline,cr}],[{newline,lf}],true), + rtest("abcdABCabcd\r\n","abcd$",[],[{newline,lf}],false), + rtest("abcdABCabcd\r\n","abcd$",[],[{newline,cr}],false), + rtest("abcdABCabcd\r\n","abcd$",[],[{newline,crlf}],true), + + rtest("abcdABCabcd\r","abcd$",[],[{newline,crlf}],false), + rtest("abcdABCabcd\n","abcd$",[],[{newline,crlf}],false), + rtest("abcdABCabcd\r\n","abcd$",[],[{newline,anycrlf}],true), + + rtest("abcdABCabcd\r","abcd$",[],[{newline,anycrlf}],true), + rtest("abcdABCabcd\n","abcd$",[],[{newline,anycrlf}],true), + + {ok,MP} = re:compile(".*(abcd).*"), + {match,[{0,10},{3,4}]} = re:run("ABCabcdABC",MP,[]), + {match,[{0,10},{3,4}]} = re:run("ABCabcdABC",MP,[{capture,all}]), + {match,[{0,10},{3,4}]} = re:run("ABCabcdABC",MP,[{capture,all,index}]), + {match,["ABCabcdABC","abcd"]} = re:run("ABCabcdABC",MP,[{capture,all,list}]), + {match,[<<"ABCabcdABC">>,<<"abcd">>]} = re:run("ABCabcdABC",MP,[{capture,all,binary}]), + {match,[{0,10}]} = re:run("ABCabcdABC",MP,[{capture,first}]), + {match,[{0,10}]} = re:run("ABCabcdABC",MP,[{capture,first,index}]), ?line {match,["ABCabcdABC"]} = re:run("ABCabcdABC",MP,[{capture,first,list}]), + {match,[<<"ABCabcdABC">>]} = re:run("ABCabcdABC",MP,[{capture,first,binary}]), + + {match,[{3,4}]} = re:run("ABCabcdABC",MP,[{capture,all_but_first}]), + {match,[{3,4}]} = re:run("ABCabcdABC",MP,[{capture,all_but_first,index}]), + {match,["abcd"]} = re:run("ABCabcdABC",MP,[{capture,all_but_first,list}]), + {match,[<<"abcd">>]} = re:run("ABCabcdABC",MP,[{capture,all_but_first,binary}]), + + match = re:run("ABCabcdABC",MP,[{capture,none}]), + match = re:run("ABCabcdABC",MP,[{capture,none,index}]), + match = re:run("ABCabcdABC",MP,[{capture,none,list}]), + match = re:run("ABCabcdABC",MP,[{capture,none,binary}]), + + {ok,MP2} = re:compile(".*(?<FOO>abcd).*"), + {match,[{3,4}]} = re:run("ABCabcdABC",MP2,[{capture,[1]}]), + {match,[{3,4}]} = re:run("ABCabcdABC",MP2,[{capture,['FOO']}]), + {match,[{3,4}]} = re:run("ABCabcdABC",MP2,[{capture,["FOO"]}]), + {match,["abcd"]} = re:run("ABCabcdABC",MP2,[{capture,["FOO"],list}]), + {match,[<<"abcd">>]} = re:run("ABCabcdABC",MP2,[{capture,["FOO"],binary}]), + + {match,[{-1,0}]} = re:run("ABCabcdABC",MP2,[{capture,[200]}]), + {match,[{-1,0}]} = re:run("ABCabcdABC",MP2,[{capture,['BAR']}]), + {match,[""]} = re:run("ABCabcdABC",MP2,[{capture,[200],list}]), + {match,[""]} = re:run("ABCabcdABC",MP2,[{capture,['BAR'],list}]), + {match,[<<>>]} = re:run("ABCabcdABC",MP2,[{capture,[200],binary}]), + {match,[<<>>]} = re:run("ABCabcdABC",MP2,[{capture,['BAR'],binary}]), + + {ok, MP3} = re:compile(".*((?<FOO>abdd)|a(..d)).*"), + {match,[{0,10},{3,4},{-1,0},{4,3}]} = re:run("ABCabcdABC",MP3,[]), + {match,[{0,10},{3,4},{-1,0},{4,3}]} = re:run("ABCabcdABC",MP3,[{capture,all,index}]), + {match,[<<"ABCabcdABC">>,<<"abcd">>,<<>>,<<"bcd">>]} = re:run("ABCabcdABC",MP3,[{capture,all,binary}]), + {match,["ABCabcdABC","abcd",[],"bcd"]} = re:run("ABCabcdABC",MP3,[{capture,all,list}]), ok. - - -combined_options(doc) -> - ["Test compile options given directly to run"]; + + +%% Test the version is retorned correctly +re_version(_Config) -> + Version = re:version(), + {match,[Version]} = re:run(Version,"^[0-9]\\.[0-9]{2} 20[0-9]{2}-[0-9]{2}-[0-9]{2}",[{capture,all,binary}]), + ok. + + + +%% Test compile options given directly to run. combined_options(Config) when is_list(Config) -> - ?line ok = crtest("ABDabcdABCD","abcd",[],true,{match,[{3,4}]}), - ?line ok = crtest("ABDabcdABCD","abcd",[anchored],true,nomatch), - ?line ok = crtest("ABDabcdABCD",".*abcd",[anchored],true,{match,[{0,7}]}), - ?line ok = crtest("ABCabcdABC","ABCD",[],true,nomatch), - ?line ok = crtest("ABCabcdABC","ABCD",[caseless],true,{match,[{3,4}]}), - ?line ok = crtest("abcdABC\n","ABC$",[],true,{match,[{4,3}]}), - ?line ok = crtest("abcdABC\n","ABC$",[dollar_endonly],true,nomatch), - ?line ok = crtest("abcdABC\n","ABC.",[],true,nomatch), - ?line ok = crtest("abcdABC\n","ABC.",[dotall],true,{match,[{4,4}]}), - ?line ok = crtest("abcdABCD","ABC .",[],true,nomatch), - ?line ok = crtest("abcdABCD","ABC .",[extended],true,{match,[{4,4}]}), - ?line ok = crtest("abcd\nABCD","ABC",[],true,{match,[{5,3}]}), - ?line ok = crtest("abcd\nABCD","ABC",[firstline],true,nomatch), - ?line ok = crtest("abcd\nABCD","^ABC",[],true,nomatch), - ?line ok = crtest("abcd\nABCD","^ABC",[multiline],true,{match,[{5,3}]}), - ?line ok = crtest("abcdABCD","(ABC)",[],true,{match,[{4,3},{4,3}]}), - ?line ok = crtest("abcdABCD","(ABC)",[no_auto_capture],true,{match,[{4,3}]}), - ?line ok = crtest(notused,"(?<FOO>ABC)|(?<FOO>DEF)",[],false,notused), - ?line ok = crtest("abcdABCD","(?<FOO>ABC)|(?<FOO>DEF)",[dupnames],true,{match,[{4,3},{4,3}]}), - ?line ok = crtest("abcdABCDabcABCD","abcd.*D",[],true,{match,[{0,15}]}), - ?line ok = crtest("abcdABCDabcABCD","abcd.*D",[ungreedy],true,{match,[{0,8}]}), - ?line ok = ctest("abcdABCabcABC\nD","abcd.*D",[],true,nomatch), - ?line ok = crtest("abcdABCabcABC\nD","abcd.*D",[{newline,cr}],true,{match,[{0,15}]}), - ?line ok = crtest("abcdABCabcABC\rD","abcd.*D",[],true,{match,[{0,15}]}), - ?line ok = crtest("abcdABCabcABC\rD","abcd.*D",[{newline,lf}],true,{match,[{0,15}]}), - ?line ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,lf}],true,nomatch), - ?line ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,cr}],true,nomatch), - ?line ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,crlf}],true,{match,[{7,4}]}), - - ?line ok = crtest("abcdABCabcd\r","abcd$",[{newline,crlf}],true,nomatch), - ?line ok = crtest("abcdABCabcd\n","abcd$",[{newline,crlf}],true,nomatch), - ?line ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), - - ?line ok = crtest("abcdABCabcd\r","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), - ?line ok = crtest("abcdABCabcd\n","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), - - ?line ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,anycrlf},{capture,all,list}],true,{match,["abcd"]}), - - ?line ok = crtest("abcdABCabcd\r","abcd$",[{newline,anycrlf},{capture,all,list}],true,{match,["abcd"]}), - - ?line ok = crtest("abcdABCabcd\n","abcd$",[{newline,anycrlf},{capture,all,list}],true,{match,["abcd"]}), - - ?line ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,anycrlf},{capture,all,binary}],true,{match,[<<"abcd">>]}), - - ?line ok = crtest("abcdABCabcd\r","abcd$",[{newline,anycrlf},{capture,all,binary}],true,{match,[<<"abcd">>]}), - ?line ok = crtest("abcdABCabcd\n","abcd$",[{newline,anycrlf},{capture,all,binary}],true,{match,[<<"abcd">>]}), - - % Check that unique run-options fail in compile only case: - ?line {'EXIT',{badarg,_}} = (catch re:compile("abcd$",[{newline,anycrlf},{capture,all,binary}])), - ?line {'EXIT',{badarg,_}} = (catch re:compile("abcd$",[{newline,anycrlf},{offset,3}])), - ?line {'EXIT',{badarg,_}} = (catch re:compile("abcd$",[{newline,anycrlf},notempty])), - ?line {'EXIT',{badarg,_}} = (catch re:compile("abcd$",[{newline,anycrlf},notbol])), - ?line {'EXIT',{badarg,_}} = (catch re:compile("abcd$",[{newline,anycrlf},noteol])), - - - ?line {match,_} = re:run("abcdABCabcd\r\n","abcd$",[{newline,crlf}]), - ?line nomatch = re:run("abcdABCabcd\r\nefgh","abcd$",[{newline,crlf}]), - ?line {match,_} = re:run("abcdABCabcd\r\nefgh","abcd$",[{newline,crlf},multiline]), - ?line nomatch = re:run("abcdABCabcd\r\nefgh","efgh$",[{newline,crlf},multiline,noteol]), - ?line {match,_} = re:run("abcdABCabcd\r\nefgh","abcd$",[{newline,crlf},multiline,noteol]), - ?line {match,_} = re:run("abcdABCabcd\r\nefgh","^abcd",[{newline,crlf},multiline,noteol]), - ?line nomatch = re:run("abcdABCabcd\r\nefgh","^abcd",[{newline,crlf},multiline,notbol]), - ?line {match,_} = re:run("abcdABCabcd\r\nefgh","^efgh",[{newline,crlf},multiline,notbol]), - ?line {match,_} = re:run("ABC\nD","[a-z]*",[{newline,crlf}]), - ?line nomatch = re:run("ABC\nD","[a-z]*",[{newline,crlf},notempty]), + ok = crtest("ABDabcdABCD","abcd",[],true,{match,[{3,4}]}), + ok = crtest("ABDabcdABCD","abcd",[anchored],true,nomatch), + ok = crtest("ABDabcdABCD",".*abcd",[anchored],true,{match,[{0,7}]}), + ok = crtest("ABCabcdABC","ABCD",[],true,nomatch), + ok = crtest("ABCabcdABC","ABCD",[caseless],true,{match,[{3,4}]}), + ok = crtest("abcdABC\n","ABC$",[],true,{match,[{4,3}]}), + ok = crtest("abcdABC\n","ABC$",[dollar_endonly],true,nomatch), + ok = crtest("abcdABC\n","ABC.",[],true,nomatch), + ok = crtest("abcdABC\n","ABC.",[dotall],true,{match,[{4,4}]}), + ok = crtest("abcdABCD","ABC .",[],true,nomatch), + ok = crtest("abcdABCD","ABC .",[extended],true,{match,[{4,4}]}), + ok = crtest("abcd\nABCD","ABC",[],true,{match,[{5,3}]}), + ok = crtest("abcd\nABCD","ABC",[firstline],true,nomatch), + ok = crtest("abcd\nABCD","^ABC",[],true,nomatch), + ok = crtest("abcd\nABCD","^ABC",[multiline],true,{match,[{5,3}]}), + ok = crtest("abcdABCD","(ABC)",[],true,{match,[{4,3},{4,3}]}), + ok = crtest("abcdABCD","(ABC)",[no_auto_capture],true,{match,[{4,3}]}), + ok = crtest(notused,"(?<FOO>ABC)|(?<FOO>DEF)",[],false,notused), + ok = crtest("abcdABCD","(?<FOO>ABC)|(?<FOO>DEF)",[dupnames],true,{match,[{4,3},{4,3}]}), + ok = crtest("abcdABCDabcABCD","abcd.*D",[],true,{match,[{0,15}]}), + ok = crtest("abcdABCDabcABCD","abcd.*D",[ungreedy],true,{match,[{0,8}]}), + ok = ctest("abcdABCabcABC\nD","abcd.*D",[],true,nomatch), + ok = crtest("abcdABCabcABC\nD","abcd.*D",[{newline,cr}],true,{match,[{0,15}]}), + ok = crtest("abcdABCabcABC\rD","abcd.*D",[],true,{match,[{0,15}]}), + ok = crtest("abcdABCabcABC\rD","abcd.*D",[{newline,lf}],true,{match,[{0,15}]}), + ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,lf}],true,nomatch), + ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,cr}],true,nomatch), + ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,crlf}],true,{match,[{7,4}]}), + + ok = crtest("abcdABCabcd\r","abcd$",[{newline,crlf}],true,nomatch), + ok = crtest("abcdABCabcd\n","abcd$",[{newline,crlf}],true,nomatch), + ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), + + ok = crtest("abcdABCabcd\r","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), + ok = crtest("abcdABCabcd\n","abcd$",[{newline,anycrlf}],true,{match,[{7,4}]}), + + ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,anycrlf},{capture,all,list}],true,{match,["abcd"]}), + + ok = crtest("abcdABCabcd\r","abcd$",[{newline,anycrlf},{capture,all,list}],true,{match,["abcd"]}), + + ok = crtest("abcdABCabcd\n","abcd$",[{newline,anycrlf},{capture,all,list}],true,{match,["abcd"]}), + + ok = crtest("abcdABCabcd\r\n","abcd$",[{newline,anycrlf},{capture,all,binary}],true,{match,[<<"abcd">>]}), + + ok = crtest("abcdABCabcd\r","abcd$",[{newline,anycrlf},{capture,all,binary}],true,{match,[<<"abcd">>]}), + ok = crtest("abcdABCabcd\n","abcd$",[{newline,anycrlf},{capture,all,binary}],true,{match,[<<"abcd">>]}), + + %% Check that unique run-options fail in compile only case: + {'EXIT',{badarg,_}} = (catch re:compile("abcd$",[{newline,anycrlf},{capture,all,binary}])), + {'EXIT',{badarg,_}} = (catch re:compile("abcd$",[{newline,anycrlf},{offset,3}])), + {'EXIT',{badarg,_}} = (catch re:compile("abcd$",[{newline,anycrlf},notempty])), + {'EXIT',{badarg,_}} = (catch re:compile("abcd$",[{newline,anycrlf},notbol])), + {'EXIT',{badarg,_}} = (catch re:compile("abcd$",[{newline,anycrlf},noteol])), + + + {match,_} = re:run("abcdABCabcd\r\n","abcd$",[{newline,crlf}]), + nomatch = re:run("abcdABCabcd\r\nefgh","abcd$",[{newline,crlf}]), + {match,_} = re:run("abcdABCabcd\r\nefgh","abcd$",[{newline,crlf},multiline]), + nomatch = re:run("abcdABCabcd\r\nefgh","efgh$",[{newline,crlf},multiline,noteol]), + {match,_} = re:run("abcdABCabcd\r\nefgh","abcd$",[{newline,crlf},multiline,noteol]), + {match,_} = re:run("abcdABCabcd\r\nefgh","^abcd",[{newline,crlf},multiline,noteol]), + nomatch = re:run("abcdABCabcd\r\nefgh","^abcd",[{newline,crlf},multiline,notbol]), + {match,_} = re:run("abcdABCabcd\r\nefgh","^efgh",[{newline,crlf},multiline,notbol]), + {match,_} = re:run("ABC\nD","[a-z]*",[{newline,crlf}]), + nomatch = re:run("ABC\nD","[a-z]*",[{newline,crlf},notempty]), ok. -replace_autogen(doc) -> - ["Test replace with autogenerated erlang module"]; +%% Test replace with autogenerated erlang module. replace_autogen(Config) when is_list(Config) -> - Dog = ?t:timetrap(?t:minutes(3)), re_testoutput1_replacement_test:run(), - ?t:timetrap_cancel(Dog), ok. -global_capture(doc) -> - ["Tests capture options together with global searching"]; +%% Test capture options together with global searching. global_capture(Config) when is_list(Config) -> - Dog = ?t:timetrap(?t:minutes(3)), - ?line {match,[{3,4}]} = re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,[1]}]), - ?line {match,[{10,4}]} = re:run("ABCabcdABCabcdA",".*(?<FOO>abcd).*",[{capture,[1]}]), - ?line {match,[[{10,4}]]} = re:run("ABCabcdABCabcdA",".*(?<FOO>abcd).*",[global,{capture,[1]}]), - ?line {match,[{3,4}]} = re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,['FOO']}]), - ?line {match,[{10,4}]} = re:run("ABCabcdABCabcdA",".*(?<FOO>abcd).*",[{capture,['FOO']}]), - ?line {match,[[{10,4}]]} = re:run("ABCabcdABCabcdA",".*(?<FOO>abcd).*",[global,{capture,['FOO']}]), - ?line {match,[[{3,4},{3,4}],[{10,4},{10,4}]]} = re:run("ABCabcdABCabcdA","(?<FOO>abcd)",[global]), - ?line {match,[[{3,4},{3,4}],[{10,4},{10,4}]]} = re:run("ABCabcdABCabcdA","(?<FOO>abcd)",[global,{capture,all}]), - ?line {match,[[{3,4},{3,4}],[{10,4},{10,4}]]} = re:run("ABCabcdABCabcdA","(?<FOO>abcd)",[global,{capture,all,index}]), - ?line {match,[[{3,4}],[{10,4}]]} = re:run("ABCabcdABCabcdA","(?<FOO>abcd)",[global,{capture,first}]), - ?line {match,[[{3,4}],[{10,4}]]} = re:run("ABCabcdABCabcdA","(?<FOO>abcd)",[global,{capture,all_but_first}]), - ?line {match,[[<<"bcd">>],[<<"bcd">>]]} = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,all_but_first,binary}]), - ?line {match,[["bcd"],["bcd"]]} = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,all_but_first,list}]), - ?line {match,[["abcd","bcd"],["abcd","bcd"]]} = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,all,list}]), - ?line {match,[[<<"abcd">>,<<"bcd">>],[<<"abcd">>,<<"bcd">>]]} = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,all,binary}]), - ?line {match,[[{3,4},{4,3}],[{10,4},{11,3}]]} = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,all,index}]), - ?line match = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,none,index}]), - ?line match = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,none,binary}]), - ?line match = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,none,list}]), - ?line {match,[[<<195,133,98,99,100>>,<<"bcd">>],[<<"abcd">>,<<"bcd">>]]} = re:run("ABCÅbcdABCabcdA",".(?<FOO>bcd)",[global,{capture,all,binary},unicode]), - ?line {match,[["Åbcd","bcd"],["abcd","bcd"]]} = re:run(<<"ABC",8#303,8#205,"bcdABCabcdA">>,".(?<FOO>bcd)",[global,{capture,all,list},unicode]), - ?line {match,[["Åbcd","bcd"],["abcd","bcd"]]} = re:run("ABCÅbcdABCabcdA",".(?<FOO>bcd)",[global,{capture,all,list},unicode]), - ?line {match,[[{3,5},{5,3}],[{11,4},{12,3}]]} = re:run("ABCÅbcdABCabcdA",".(?<FOO>bcd)",[global,{capture,all,index},unicode]), - ?t:timetrap_cancel(Dog), + {match,[{3,4}]} = re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,[1]}]), + {match,[{10,4}]} = re:run("ABCabcdABCabcdA",".*(?<FOO>abcd).*",[{capture,[1]}]), + {match,[[{10,4}]]} = re:run("ABCabcdABCabcdA",".*(?<FOO>abcd).*",[global,{capture,[1]}]), + {match,[{3,4}]} = re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,['FOO']}]), + {match,[{10,4}]} = re:run("ABCabcdABCabcdA",".*(?<FOO>abcd).*",[{capture,['FOO']}]), + {match,[[{10,4}]]} = re:run("ABCabcdABCabcdA",".*(?<FOO>abcd).*",[global,{capture,['FOO']}]), + {match,[[{3,4},{3,4}],[{10,4},{10,4}]]} = re:run("ABCabcdABCabcdA","(?<FOO>abcd)",[global]), + {match,[[{3,4},{3,4}],[{10,4},{10,4}]]} = re:run("ABCabcdABCabcdA","(?<FOO>abcd)",[global,{capture,all}]), + {match,[[{3,4},{3,4}],[{10,4},{10,4}]]} = re:run("ABCabcdABCabcdA","(?<FOO>abcd)",[global,{capture,all,index}]), + {match,[[{3,4}],[{10,4}]]} = re:run("ABCabcdABCabcdA","(?<FOO>abcd)",[global,{capture,first}]), + {match,[[{3,4}],[{10,4}]]} = re:run("ABCabcdABCabcdA","(?<FOO>abcd)",[global,{capture,all_but_first}]), + {match,[[<<"bcd">>],[<<"bcd">>]]} = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,all_but_first,binary}]), + {match,[["bcd"],["bcd"]]} = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,all_but_first,list}]), + {match,[["abcd","bcd"],["abcd","bcd"]]} = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,all,list}]), + {match,[[<<"abcd">>,<<"bcd">>],[<<"abcd">>,<<"bcd">>]]} = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,all,binary}]), + {match,[[{3,4},{4,3}],[{10,4},{11,3}]]} = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,all,index}]), + match = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,none,index}]), + match = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,none,binary}]), + match = re:run("ABCabcdABCabcdA","a(?<FOO>bcd)",[global,{capture,none,list}]), + {match,[[<<195,133,98,99,100>>,<<"bcd">>],[<<"abcd">>,<<"bcd">>]]} = re:run("ABCÅbcdABCabcdA",".(?<FOO>bcd)",[global,{capture,all,binary},unicode]), + {match,[["Åbcd","bcd"],["abcd","bcd"]]} = re:run(<<"ABC",8#303,8#205,"bcdABCabcdA">>,".(?<FOO>bcd)",[global,{capture,all,list},unicode]), + {match,[["Åbcd","bcd"],["abcd","bcd"]]} = re:run("ABCÅbcdABCabcdA",".(?<FOO>bcd)",[global,{capture,all,list},unicode]), + {match,[[{3,5},{5,3}],[{11,4},{12,3}]]} = re:run("ABCÅbcdABCabcdA",".(?<FOO>bcd)",[global,{capture,all,index},unicode]), ok. -replace_input_types(doc) -> - ["Tests replace with different input types"]; +%% Test replace with different input types. replace_input_types(Config) when is_list(Config) -> - Dog = ?t:timetrap(?t:minutes(3)), - ?line <<"abcd">> = re:replace("abcd","Z","X",[{return,binary},unicode]), - ?line <<"abcd">> = re:replace("abcd","\x{400}","X",[{return,binary},unicode]), - ?line <<"a",208,128,"cd">> = re:replace(<<"abcd">>,"b","\x{400}",[{return,binary},unicode]), - ?t:timetrap_cancel(Dog), + <<"abcd">> = re:replace("abcd","Z","X",[{return,binary},unicode]), + <<"abcd">> = re:replace("abcd","\x{400}","X",[{return,binary},unicode]), + <<"a",208,128,"cd">> = re:replace(<<"abcd">>,"b","\x{400}",[{return,binary},unicode]), ok. -replace_return(doc) -> - ["Tests return options of replace together with global searching"]; +%% Test return options of replace together with global searching. replace_return(Config) when is_list(Config) -> - Dog = ?t:timetrap(?t:minutes(3)), {'EXIT',{badarg,_}} = (catch re:replace("na","(a","")), ok = replacetest(<<"nisse">>,"i","a",[{return,binary}],<<"nasse">>), ok = replacetest("ABC\305abcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,binary}],<<"ABCÅXABCXA">>), @@ -339,7 +332,6 @@ replace_return(Config) when is_list(Config) -> ok = replacetest("a\x{400}bcd","d","X",[global,{return,binary},unicode],<<"a",208,128,"bcX">>), ok = replacetest("a\x{400}bcd","Z","X",[global,{return,list},unicode],"a\x{400}bcd"), ok = replacetest("a\x{400}bcd","Z","X",[global,{return,binary},unicode],<<"a",208,128,"bcd">>), - ?t:timetrap_cancel(Dog), ok. rtest(Subj, RE, Copt, Ropt, true) -> @@ -412,18 +404,13 @@ copt(ungreedy) -> true; copt(unicode) -> true; copt(_) -> false. -split_autogen(doc) -> - ["Test split with autogenerated erlang module"]; +%% Test split with autogenerated erlang module. split_autogen(Config) when is_list(Config) -> - Dog = ?t:timetrap(?t:minutes(3)), re_testoutput1_split_test:run(), - ?t:timetrap_cancel(Dog), ok. -split_options(doc) -> - ["Test special options to split."]; +%% Test special options to split. split_options(Config) when is_list(Config) -> - Dog = ?t:timetrap(?t:minutes(1)), ok = splittest("a b c ","( )",[group,trim],[[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>]]), ok = splittest("a b c ","( )",[group,{parts,0}],[[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>]]), ok = splittest("a b c ","( )",[{parts,infinity},group],[[<<"a">>,<<" ">>],[<<"b">>,<<" ">>],[<<"c">>,<<" ">>],[<<>>]]), @@ -439,27 +426,23 @@ split_options(Config) when is_list(Config) -> {'EXIT',{badarg,_}} = (catch re:split("a b c d","( +)",[{parts,banan}])), {'EXIT',{badarg,_}} = (catch re:split("a b c d","( +)",[{capture,all}])), {'EXIT',{badarg,_}} = (catch re:split("a b c d","( +)",[{capture,[],binary}])), - % Parts 0 is equal to no parts specification (implicit strip) + %% Parts 0 is equal to no parts specification (implicit strip) ok = splittest("a b c d","( *)",[{parts,0},{return,list}],["a"," ","b"," ","c"," ","d"]), - ?t:timetrap_cancel(Dog), ok. - + join([]) -> []; join([A]) -> [A]; join([H|T]) -> [H,<<":">>|join(T)]. -split_specials(doc) -> - ["Some special cases of split that are easy to get wrong."]; +%% Some special cases of split that are easy to get wrong. split_specials(Config) when is_list(Config) -> %% More or less just to remember these icky cases - Dog = ?t:timetrap(?t:minutes(1)), - ?line <<"::abd:f">> = + <<"::abd:f">> = iolist_to_binary(join(re:split("abdf","^(?!(ab)de|x)(abd)(f)",[trim]))), - ?line <<":abc2xyzabc3">> = + <<":abc2xyzabc3">> = iolist_to_binary(join(re:split("abc1abc2xyzabc3","\\Aabc.",[trim]))), - ?t:timetrap_cancel(Dog), ok. - + %% Test that errors are handled correctly by the erlang code. error_handling(_Config) -> @@ -470,26 +453,26 @@ error_handling(_Config) -> false -> error_handling() end. - + error_handling() -> - % This test checks the exception tuples manufactured in the erlang - % code to hide the trapping from the user at least when it comes to errors - Dog = ?t:timetrap(?t:minutes(1)), - % The malformed precomiled RE is detected after - % the trap to re:grun from grun, in the grun function clause - % that handles precompiled expressions + %% This test checks the exception tuples manufactured in the erlang + %% code to hide the trapping from the user at least when it comes to errors + + %% The malformed precomiled RE is detected after + %% the trap to re:grun from grun, in the grun function clause + %% that handles precompiled expressions {'EXIT',{badarg,[{re,run,["apa",{1,2,3,4},[global]],_}, {?MODULE,error_handling,0,_} | _]}} = (catch re:run("apa",{1,2,3,4},[global])), - % An invalid capture list will also cause a badarg late, - % but with a non pre compiled RE, the exception should be thrown by the - % grun function clause that handles RE's compiled implicitly by - % the run/3 BIF before trapping. + %% An invalid capture list will also cause a badarg late, + %% but with a non pre compiled RE, the exception should be thrown by the + %% grun function clause that handles RE's compiled implicitly by + %% the run/3 BIF before trapping. {'EXIT',{badarg,[{re,run,["apa","p",[{capture,[1,{a}]},global]],_}, {?MODULE,error_handling,0,_} | _]}} = (catch re:run("apa","p",[{capture,[1,{a}]},global])), - % And so the case of a precompiled expression together with - % a compile-option (binary and list subject): + %% And so the case of a precompiled expression together with + %% a compile-option (binary and list subject): {ok,RE} = re:compile("(p)"), {match,[[{1,1},{1,1}]]} = re:run(<<"apa">>,RE,[global]), {match,[[{1,1},{1,1}]]} = re:run("apa",RE,[global]), @@ -509,7 +492,7 @@ error_handling() -> {error, {compile, {_,_}}} = re:run("apa","(p",[report_errors]), {'EXIT',{badarg,_}} = (catch re:run("apa","(p",[global])), {error, {compile, {_,_}}} = re:run("apa","(p",[report_errors,global]), - % Badly formed options + %% Badly formed options {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,["global"])), {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[{offset,-1}])), {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[{offset,ett}])), @@ -536,7 +519,7 @@ error_handling() -> {'EXIT',{badarg,_}} = (catch re:run(<<"apa",2:2>>,<<"(p)">>,[{capture,[0,1],binary}])), <<_:4,Temp:3/binary,_:4>> = <<38,23,6,18>>, {match,[{1,1},{1,1}]} = re:run(Temp,<<"(p)">>,[]), % Unaligned works - % The replace errors: + %% The replace errors: {'EXIT',{badarg,[{re,replace,["apa",{1,2,3,4},"X",[]],_}, {?MODULE,error_handling,0,_} | _]}} = (catch re:replace("apa",{1,2,3,4},"X",[])), @@ -572,13 +555,13 @@ error_handling() -> (catch iolist_to_binary(re:replace("apa","p","X", [{return,banana}]))), {'EXIT',{badarg,_}} = (catch re:replace("apa","(p","X",[])), - % Badarg, not compile error. + %% Badarg, not compile error. {'EXIT',{badarg,[{re,replace, ["apa","(p","X",[{return,banana}]],_}, {?MODULE,error_handling,0,_} | _]}} = (catch iolist_to_binary(re:replace("apa","(p","X", [{return,banana}]))), - % And the split errors: + %% And the split errors: [<<"a">>,<<"a">>] = (catch re:split("apa","p",[])), [<<"a">>,<<"p">>,<<"a">>] = (catch re:split("apa",RE,[])), {'EXIT',{badarg,[{re,split,["apa","p",[report_errors]],_}, @@ -618,34 +601,37 @@ error_handling() -> {?MODULE,error_handling,0,_} | _]}} = (catch re:split("apa",RE,[banana])), {'EXIT',{badarg,_}} = (catch re:split("apa","(p")), - %Exception on bad argument, not compilation error + %%Exception on bad argument, not compilation error {'EXIT',{badarg,[{re,split, ["apa", "(p", [banana]],_}, {?MODULE,error_handling,0,_} | _]}} = (catch re:split("apa","(p",[banana])), - ?t:timetrap_cancel(Dog), ok. - -pcre_cve_2008_2371(doc) -> - "Fix as in http://vcs.pcre.org/viewvc?revision=360&view=revision"; + +%% Fix as in http://vcs.pcre.org/viewvc?revision=360&view=revision pcre_cve_2008_2371(Config) when is_list(Config) -> %% Make sure it doesn't crash the emulator. re:compile(<<"(?i)[\xc3\xa9\xc3\xbd]|[\xc3\xa9\xc3\xbdA]">>, [unicode]), ok. -pcre_compile_workspace_overflow(doc) -> - "Patch from http://vcs.pcre.org/viewvc/code/trunk/pcre_compile.c?r1=504&r2=505&view=patch"; +%% Patch from +%% http://vcs.pcre.org/viewvc/code/trunk/pcre_compile.c?r1=504&r2=505&view=patch pcre_compile_workspace_overflow(Config) when is_list(Config) -> N = 819, - ?line {error,{"internal error: overran compiling workspace",799}} = - re:compile([lists:duplicate(N, $(), lists:duplicate(N, $))]), - ok. -re_infinite_loop(doc) -> - "Make sure matches that really loop infinitely actually fail"; + ExpStr = "Got expected error: ", + case re:compile([lists:duplicate(N, $(), lists:duplicate(N, $))]) of + {error, {"regular expression is too complicated" = Str,799}} -> + {comment, ExpStr ++ Str}; + {error, {"parentheses are too deeply nested (stack check)" = Str, _No}} -> + {comment, ExpStr ++ Str}; + Other -> + ?t:fail({unexpected, Other}) + end. + +%% Make sure matches that really loop infinitely actually fail. re_infinite_loop(Config) when is_list(Config) -> - Dog = ?t:timetrap(?t:minutes(1)), Str = "http:/www.flickr.com/slideShow/index.gne?group_id=&user_id=69845378@N0", EMail_regex = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+" @@ -657,20 +643,17 @@ re_infinite_loop(Config) when is_list(Config) -> nomatch = re:run(Str, EMail_regex, [global]), {error,match_limit} = re:run(Str, EMail_regex,[report_errors]), {error,match_limit} = re:run(Str, EMail_regex,[report_errors,global]), - ?t:timetrap_cancel(Dog), ok. -re_backwards_accented(doc) -> - "Check for nasty bug where accented graphemes can make PCRE back past " - "beginning of subject"; + +%% Check for nasty bug where accented graphemes can make PCRE back +%% past beginning of subject. re_backwards_accented(Config) when is_list(Config) -> - Dog = ?t:timetrap(?t:minutes(1)), - ?line match = re:run(<<65,204,128,65,204,128,97,98,99>>, - <<"\\X?abc">>, - [unicode,{capture,none}]), - ?t:timetrap_cancel(Dog), + match = re:run(<<65,204,128,65,204,128,97,98,99>>, + <<"\\X?abc">>, + [unicode,{capture,none}]), ok. -opt_dupnames(doc) -> - "Check correct handling of dupnames option to re"; + +%% Check correct handling of dupnames option to re. opt_dupnames(Config) when is_list(Config) -> Days = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"], _ = [ begin @@ -704,9 +687,9 @@ opt_dupnames(Config) when is_list(Config) -> "(?<DN>Sat)(?:urday)?", [dupnames, {capture, ['Skrap','DN','Skrap2'],index}]), {match,[{-1,0},{0,3},{-1,0}]} = re:run("Wednesday","(?<Skrap>.)(?<DN>Mon|Fri|Sun)(?:day)?(?<Skrap2>.)|" - "(?<DN>Tue)(?:sday)?|(?<DN>Wed)nesday|(?<DN>Thu)(?:rsday)?|" - "(?<DN>Sat)(?:urday)?", - [dupnames, {capture, ['Skrap','DN','Skrap2'],index}]), + "(?<DN>Tue)(?:sday)?|(?<DN>Wed)nesday|(?<DN>Thu)(?:rsday)?|" + "(?<DN>Sat)(?:urday)?", + [dupnames, {capture, ['Skrap','DN','Skrap2'],index}]), nomatch = re:run("Wednsday","(?<Skrap>.)(?<DN>Mon|Fri|Sun)(?:day)?(?<Skrap2>.)|" "(?<DN>Tue)(?:sday)?|(?<DN>Wed)nesday|(?<DN>Thu)(?:rsday)?|" "(?<DN>Sat)(?:urday)?", @@ -758,8 +741,7 @@ opt_dupnames(Config) when is_list(Config) -> "h","a","n","T","e","then"],binary}]), ok. -opt_all_names(doc) -> - "Test capturing of all_names"; +%% Test capturing of all_names. opt_all_names(Config) when is_list(Config) -> Days = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"], {match,[{1,3},{0,1},{7,1}]} = re:run("SMondayX","(?<Skrap>.)(?<DN>Mon|Fri|Sun)(?:day)?(?<Skrap2>.)|" @@ -767,10 +749,10 @@ opt_all_names(Config) when is_list(Config) -> "(?<DN>Sat)(?:urday)?", [dupnames, {capture, all_names,index}]), {match,[{0,3},{-1,0},{-1,0}]} = re:run("Wednesday","(?<Skrap>.)(?<DN>Mon|Fri|Sun)(?:day)?(?<Skrap2>.)|" - "(?<DN>Tue)(?:sday)?|(?<DN>Wed)nesday|(?<DN>Thu)(?:rsday)?|" - "(?<DN>Sat)(?:urday)?", - [dupnames, {capture, all_names,index}]), - + "(?<DN>Tue)(?:sday)?|(?<DN>Wed)nesday|(?<DN>Thu)(?:rsday)?|" + "(?<DN>Sat)(?:urday)?", + [dupnames, {capture, all_names,index}]), + _ = [ begin {match,[{0,3}]} = re:run(Day, @@ -809,7 +791,7 @@ opt_all_names(Config) when is_list(Config) -> {match,[[<<>>,<<>>,<<"C">>], [<<>>,<<>>,<<"C">>], [<<>>,<<>>,<<"C">>]]} = re:run("CCC","(?<A>A)|(?<B>B)|(?<C>C)", - [global,{capture, all_names, binary}]), + [global,{capture, all_names, binary}]), {match,[[<<"C">>,<<>>], [<<>>,<<"B">>], [<<"C">>,<<>>]]} = re:run("CBC","(?<A>A)|(?<B>B)|(?<A>C)", @@ -831,8 +813,7 @@ opt_all_names(Config) when is_list(Config) -> [dupnames,{capture,all_names,binary}]), ok. -inspect(doc) -> - "Test the minimal inspect function"; +%% Test the minimal inspect function. inspect(Config) when is_list(Config)-> {ok,MP} = re:compile("(?<A>A)|(?<B>B)|(?<C>C)."), {namelist,[<<"A">>,<<"B">>,<<"C">>]} = re:inspect(MP,namelist), @@ -845,15 +826,13 @@ inspect(Config) when is_list(Config)-> {'EXIT',{badarg,_}} = (catch re:inspect({re_pattern,3,0,0,<<"kalle",2:2>>},namelist)), ok. -opt_no_start_optimize(doc) -> - "Test that the no_start_optimize compilation flag works"; +%% Test that the no_start_optimize compilation flag works. opt_no_start_optimize(Config) when is_list(Config) -> {match, [{3,3}]} = re:run("DEFABC","(*COMMIT)ABC",[]), % Start optimization makes this result wrong! nomatch = re:run("DEFABC","(*COMMIT)ABC",[no_start_optimize]), % This is the correct result... ok. -opt_never_utf(doc) -> - "Check that the never_utf option works"; +%% Check that the never_utf option works. opt_never_utf(Config) when is_list(Config) -> {match,[{0,3}]} = re:run("ABC","ABC",[never_utf]), {match,[{0,3}]} = re:run("ABC","(*UTF)ABC",[]), @@ -867,29 +846,29 @@ opt_never_utf(Config) when is_list(Config) -> {error,_} = (catch re:compile("(*UTF)ABC",[never_utf])), {error,_} = (catch re:compile("(*UTF8)ABC",[never_utf])), ok. -opt_ucp(doc) -> - "Check that the ucp option is passed to PCRE"; + +%% Check that the ucp option is passed to PCRE. opt_ucp(Config) when is_list(Config) -> {match,[{0,1}]} = re:run([$a],"\\w",[unicode]), {match,[{0,2}]} = re:run([229],"\\w",[unicode]), % Latin1 works without UCP, as we have a default - % Latin1 table + %% Latin1 table nomatch = re:run([1024],"\\w",[unicode]), % Latin1 word characters only, 1024 is not latin1 {match,[{0,2}]} = re:run([1024],"\\w",[unicode,ucp]), % Any Unicode word character works with 'ucp' ok. -match_limit(doc) -> - "Check that the match_limit and match_limit_recursion options work"; + +%% Check that the match_limit and match_limit_recursion options work. match_limit(Config) when is_list(Config) -> nomatch = re:run("aaaaaaaaaaaaaz","(a+)*zz",[]), nomatch = re:run("aaaaaaaaaaaaaz","(a+)*zz",[{match_limit,3000}]), nomatch = re:run("aaaaaaaaaaaaaz","(a+)*zz",[{match_limit_recursion,10}]), nomatch = re:run("aaaaaaaaaaaaaz","(a+)*zz",[report_errors]), {error,match_limit} = re:run("aaaaaaaaaaaaaz","(a+)*zz",[{match_limit,3000}, - report_errors]), + report_errors]), {error,match_limit_recursion} = re:run("aaaaaaaaaaaaaz","(a+)*zz",[{match_limit_recursion,10}, report_errors]), {error,match_limit} = re:run("aaaaaaaaaaaaaz","(a+)*zz",[{match_limit,3000}, - report_errors,global]), + report_errors,global]), {error,match_limit_recursion} = re:run("aaaaaaaaaaaaaz","(a+)*zz",[{match_limit_recursion,10}, report_errors,global]), @@ -902,9 +881,9 @@ match_limit(Config) when is_list(Config) -> "aaaaaaaaaaaaaz" = re:replace("aaaaaaaaaaaaaz","(a+)*zz","!", [{match_limit,3000},{return,list}]), {'EXIT', {badarg,_}} = (catch re:replace("aaaaaaaaaaaaaz","(a+)*zz","!", - [{match_limit_recursion,-1},{return,list}])), + [{match_limit_recursion,-1},{return,list}])), {'EXIT', {badarg,_}} = (catch re:replace("aaaaaaaaaaaaaz","(a+)*zz","!", - [{match_limit,-1},{return,list}])), + [{match_limit,-1},{return,list}])), {'EXIT', {badarg,_}} = (catch re:run("aaaaaaaaaaaaaz","(a+)*zz", [{match_limit_recursion,-1}, report_errors,global])), @@ -912,14 +891,16 @@ match_limit(Config) when is_list(Config) -> [{match_limit,-1}, report_errors,global])), ok. -sub_binaries(doc) -> - "test that we get sub-binaries if subject is a binary and we " - "capture binaries"; +%% Test that we get sub-binaries if subject is a binary and we capture +%% binaries. sub_binaries(Config) when is_list(Config) -> - Bin = list_to_binary(lists:seq(1,255)), - {match,[B,C]}=re:run(Bin,"(a)",[{capture,all,binary}]), - 255 = binary:referenced_byte_size(B), - 255 = binary:referenced_byte_size(C), - {match,[D]}=re:run(Bin,"(a)",[{capture,[1],binary}]), - 255 = binary:referenced_byte_size(D), + %% The GC can auto-convert tiny sub-binaries to heap binaries, so we + %% extract large sequences to make the test more stable. + Bin = << <<I>> || I <- lists:seq(1, 4096) >>, + {match,[B,C]}=re:run(Bin,"a(.+)$",[{capture,all,binary}]), + true = byte_size(B) =/= byte_size(C), + 4096 = binary:referenced_byte_size(B), + 4096 = binary:referenced_byte_size(C), + {match,[D]}=re:run(Bin,"a(.+)$",[{capture,[1],binary}]), + 4096 = binary:referenced_byte_size(D), ok. |