aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/test/re_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib/test/re_SUITE.erl')
-rw-r--r--lib/stdlib/test/re_SUITE.erl483
1 files changed, 396 insertions, 87 deletions
diff --git a/lib/stdlib/test/re_SUITE.erl b/lib/stdlib/test/re_SUITE.erl
index 500f5fadb9..87763cbf92 100644
--- a/lib/stdlib/test/re_SUITE.erl
+++ b/lib/stdlib/test/re_SUITE.erl
@@ -1,8 +1,7 @@
-%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +24,10 @@
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,
- pcre_compile_workspace_overflow/1,re_infinite_loop/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]).
-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
@@ -37,7 +39,10 @@ all() ->
replace_autogen, global_capture, replace_input_types,
replace_return, split_autogen, split_options,
split_specials, error_handling, pcre_cve_2008_2371,
- pcre_compile_workspace_overflow, re_infinite_loop].
+ 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].
groups() ->
[].
@@ -469,115 +474,152 @@ error_handling() ->
% The malformed precomiled RE is detected after
% the trap to re:grun from grun, in the grun function clause
% that handles precompiled expressions
- ?line {'EXIT',{badarg,[{re,run,["apa",{1,2,3,4},[global]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'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.
- ?line {'EXIT',{badarg,[{re,run,["apa","p",[{capture,[1,{a}]},global]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'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):
- ?line {ok,RE} = re:compile("(p)"),
- ?line {match,[[{1,1},{1,1}]]} = re:run(<<"apa">>,RE,[global]),
- ?line {match,[[{1,1},{1,1}]]} = re:run("apa",RE,[global]),
- ?line {'EXIT',{badarg,[{re,run,
- [<<"apa">>,
- {re_pattern,1,0,_},
- [global,unicode]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {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]),
+ {'EXIT',{badarg,[{re,run,
+ [<<"apa">>,
+ {re_pattern,1,0,_,_},
+ [global,unicode]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:run(<<"apa">>,RE,[global,unicode])),
- ?line {'EXIT',{badarg,[{re,run,
- ["apa",
- {re_pattern,1,0,_},
- [global,unicode]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,run,
+ ["apa",
+ {re_pattern,1,0,_,_},
+ [global,unicode]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:run("apa",RE,[global,unicode])),
- ?line {'EXIT',{badarg,_}} = (catch re:run("apa","(p",[])),
- ?line {'EXIT',{badarg,_}} = (catch re:run("apa","(p",[global])),
+ {'EXIT',{badarg,_}} = (catch re:run("apa","(p",[])),
+ {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
+ {'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}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[{captore,[1,2],binary}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[{capture,[1,2],binary,list}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[{capture,[1,2],bunary}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[{capture,{1,2},binary}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[{newline,3}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[{newline,apa}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[{njuline,cr}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[{<<"newline">>,cr}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[global|dupnames])),
+ {'EXIT',{badarg,_}} = (catch re:run([<<"ap">>|$a],RE,[])), % Not an IO-list
+ {'EXIT',{badarg,_}} = (catch re:compile([<<"ap">>|$a],[])), % Not an IO-list
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,[{capture,[0|1],binary}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,
+ [{capture,[<<"apa">>|1],binary}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,RE,
+ [{capture,[[<<"ap">>|$a]],binary}])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,[<<"(p">>|41],[])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,{re_pattern,3,0,0,[]},[])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,{re_pattern,3,0,0,<<"apa">>},[])),
+ {'EXIT',{badarg,_}} = (catch re:run(<<"apa">>,{re_pattern,3,0,0,<<"apa",3:2>>},[])),
+ {'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:
- ?line {'EXIT',{badarg,[{re,replace,["apa",{1,2,3,4},"X",[]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,replace,["apa",{1,2,3,4},"X",[]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:replace("apa",{1,2,3,4},"X",[])),
- ?line {'EXIT',{badarg,[{re,replace,["apa",{1,2,3,4},"X",[global]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,replace,["apa",{1,2,3,4},"X",[global]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:replace("apa",{1,2,3,4},"X",[global])),
- ?line {'EXIT',{badarg,[{re,replace,
- ["apa",
- {re_pattern,1,0,_},
- "X",
- [unicode]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,replace,
+ ["apa",
+ {re_pattern,1,0,_,_},
+ "X",
+ [unicode]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:replace("apa",RE,"X",[unicode])),
- ?line <<"aXa">> = iolist_to_binary(re:replace("apa","p","X",[])),
- ?line {'EXIT',{badarg,[{re,replace,
- ["apa","p","X",[{capture,all,binary}]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ <<"aXa">> = iolist_to_binary(re:replace("apa","p","X",[])),
+ {'EXIT',{badarg,[{re,replace,
+ ["apa","p","X",[report_errors]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch iolist_to_binary(re:replace("apa","p","X",
- [{capture,all,binary}]))),
- ?line {'EXIT',{badarg,[{re,replace,
- ["apa","p","X",[{capture,all}]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ [report_errors]))),
+ {'EXIT',{badarg,[{re,replace,
+ ["apa","p","X",[{capture,all,binary}]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch iolist_to_binary(re:replace("apa","p","X",
- [{capture,all}]))),
- ?line {'EXIT',{badarg,[{re,replace,
- ["apa","p","X",[{return,banana}]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ [{capture,all,binary}]))),
+ {'EXIT',{badarg,[{re,replace,
+ ["apa","p","X",[{capture,all}]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch iolist_to_binary(re:replace("apa","p","X",
- [{return,banana}]))),
- ?line {'EXIT',{badarg,_}} = (catch re:replace("apa","(p","X",[])),
+ [{capture,all}]))),
+ {'EXIT',{badarg,[{re,replace,
+ ["apa","p","X",[{return,banana}]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
+ (catch iolist_to_binary(re:replace("apa","p","X",
+ [{return,banana}]))),
+ {'EXIT',{badarg,_}} = (catch re:replace("apa","(p","X",[])),
% Badarg, not compile error.
- ?line {'EXIT',{badarg,[{re,replace,
- ["apa","(p","X",[{return,banana}]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,replace,
+ ["apa","(p","X",[{return,banana}]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch iolist_to_binary(re:replace("apa","(p","X",
- [{return,banana}]))),
+ [{return,banana}]))),
% And the split errors:
- ?line [<<"a">>,<<"a">>] = (catch re:split("apa","p",[])),
- ?line [<<"a">>,<<"p">>,<<"a">>] = (catch re:split("apa",RE,[])),
- ?line {'EXIT',{badarg,[{re,split,["apa","p",[global]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ [<<"a">>,<<"a">>] = (catch re:split("apa","p",[])),
+ [<<"a">>,<<"p">>,<<"a">>] = (catch re:split("apa",RE,[])),
+ {'EXIT',{badarg,[{re,split,["apa","p",[report_errors]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
+ (catch re:split("apa","p",[report_errors])),
+ {'EXIT',{badarg,[{re,split,["apa","p",[global]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:split("apa","p",[global])),
- ?line {'EXIT',{badarg,[{re,split,["apa","p",[{capture,all}]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,split,["apa","p",[{capture,all}]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:split("apa","p",[{capture,all}])),
- ?line {'EXIT',{badarg,[{re,split,["apa","p",[{capture,all,binary}]],_},
- {?MODULE, error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,split,["apa","p",[{capture,all,binary}]],_},
+ {?MODULE, error_handling,0,_} | _]}} =
(catch re:split("apa","p",[{capture,all,binary}])),
- ?line {'EXIT',{badarg,[{re,split,["apa",{1,2,3,4},[]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,split,["apa",{1,2,3,4},[]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:split("apa",{1,2,3,4})),
- ?line {'EXIT',{badarg,[{re,split,["apa",{1,2,3,4},[]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,split,["apa",{1,2,3,4},[]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:split("apa",{1,2,3,4},[])),
- ?line {'EXIT',{badarg,[{re,split,
- ["apa",
- RE,
- [unicode]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,split,
+ ["apa",
+ RE,
+ [unicode]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:split("apa",RE,[unicode])),
- ?line {'EXIT',{badarg,[{re,split,
- ["apa",
- RE,
- [{return,banana}]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,split,
+ ["apa",
+ RE,
+ [{return,banana}]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:split("apa",RE,[{return,banana}])),
- ?line {'EXIT',{badarg,[{re,split,
- ["apa",
- RE,
- [banana]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,split,
+ ["apa",
+ RE,
+ [banana]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:split("apa",RE,[banana])),
- ?line {'EXIT',{badarg,_}} = (catch re:split("apa","(p")),
+ {'EXIT',{badarg,_}} = (catch re:split("apa","(p")),
%Exception on bad argument, not compilation error
- ?line {'EXIT',{badarg,[{re,split,
- ["apa",
- "(p",
- [banana]],_},
- {?MODULE,error_handling,0,_} | _]}} =
+ {'EXIT',{badarg,[{re,split,
+ ["apa",
+ "(p",
+ [banana]],_},
+ {?MODULE,error_handling,0,_} | _]}} =
(catch re:split("apa","(p",[banana])),
?t:timetrap_cancel(Dog),
ok.
@@ -600,13 +642,280 @@ re_infinite_loop(doc) ->
"Make sure matches that really loop infinitely actually fail";
re_infinite_loop(Config) when is_list(Config) ->
Dog = ?t:timetrap(?t:minutes(1)),
- ?line Str =
+ Str =
"http:/www.flickr.com/slideShow/index.gne?group_id=&user_id=69845378@N0",
- ?line EMail_regex = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+"
+ EMail_regex = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+"
++ "(\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*"
++ "@.*([a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+"
++ "([a-zA-Z]{2}|com|org|net|gov|mil"
++ "|biz|info|mobi|name|aero|jobs|museum)",
- ?line nomatch = re:run(Str, EMail_regex),
+ nomatch = re:run(Str, EMail_regex),
+ 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";
+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),
+ ok.
+opt_dupnames(doc) ->
+ "Check correct handling of dupnames option to re";
+opt_dupnames(Config) when is_list(Config) ->
+ Days = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],
+ _ = [ begin
+ Short = lists:sublist(Day,3),
+ {match,[Short]} =
+ re:run(Day,
+ "(?<DN>Mon|Fri|Sun)(?:day)?|(?<DN>Tue)(?:sday)?|"
+ "(?<DN>Wed)(?:nesday)?|(?<DN>Thu)(?:rsday)?|"
+ "(?<DN>Sat)(?:urday)?",
+ [dupnames, {capture, ['DN'], list}])
+ end || Day <- Days ],
+ _ = [ begin
+ Short = list_to_binary(lists:sublist(Day,3)),
+ {match,[Short]} =
+ re:run(Day,
+ "(?<DN>Mon|Fri|Sun)(?:day)?|(?<DN>Tue)(?:sday)?|"
+ "(?<DN>Wed)(?:nesday)?|(?<DN>Thu)(?:rsday)?|"
+ "(?<DN>Sat)(?:urday)?",
+ [dupnames, {capture, ['DN'], binary}])
+ end || Day <- Days ],
+ _ = [ begin
+ {match,[{0,3}]} =
+ re:run(Day,
+ "(?<DN>Mon|Fri|Sun)(?:day)?|(?<DN>Tue)(?:sday)?|"
+ "(?<DN>Wed)(?:nesday)?|(?<DN>Thu)(?:rsday)?|"
+ "(?<DN>Sat)(?:urday)?",
+ [dupnames, {capture, ['DN'], index}])
+ end || Day <- Days ],
+ {match,[{0,1},{1,3},{7,1}]} = re:run("SMondayX","(?<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}]),
+ {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}]),
+ nomatch = re:run("Wednsday","(?<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}]),
+ {match,[<<>>]} = re:run("Subject","b",[dupnames,{capture,['B'],binary}]),
+ {match,[<<"S">>,<<"u">>,<<"b">>,<<"j">>,<<"e">>,<<"c">>,
+ <<"t">>,<<"I">>,<<"s">>,<<"M">>,<<"o">>,<<"r">>,<<"e">>,
+ <<"T">>,<<"h">>,<<"a">>,<<"n">>,<<"T">>,<<"e">>,<<"n">>]} =
+ re:run("SubjectIsMoreThanTen",
+ "(?<S>S)(?<u>u)(?<b>b)(?<j>j)(?<e>e)(?<c>c)(?<t>t)"
+ "(?<I>I)(?<s>s)(?<M>M)(?<o>o)(?<r>r)(?<e>e)(?<T>T)"
+ "(?<h>h)(?<a>a)(?<n>n)(?<T>T)(?<e>e)(?<n>n)",
+ [dupnames,{capture,['S','u','b','j','e','c','t',
+ 'I','s','M','o','r','e','T',
+ 'h','a','n','T','e','n'],binary}]),
+ {match,[<<"S">>,<<"u">>,<<"b">>,<<"j">>,<<"e">>,<<"c">>,
+ <<"t">>,<<"I">>,<<"s">>,<<"M">>,<<"o">>,<<"r">>,<<"e">>,
+ <<"T">>,<<"h">>,<<"a">>,<<"n">>,<<"T">>,<<"e">>,<<"n">>]} =
+ re:run("SubjectIsMoreThanTen",
+ "(?<S>S)(?<u>u)(?<b>b)(?<j>j)(?<e>e)(?<c>c)(?<t>t)"
+ "(?<I>I)(?<s>s)(?<M>M)(?<o>o)(?<r>r)(?<e>e)(?<T>T)"
+ "(?<h>h)(?<a>a)(?<n>n)(?<T>T)(?<e>e)(?<n>n)",
+ [dupnames,
+ {capture,all_but_first,list},
+ {capture,['S','u','b','j','e','c','t',
+ 'I','s','M','o','r','e','T',
+ 'h','a','n','T','e','n'],binary}]),
+ {match,[<<"S">>,<<"u">>,<<"b">>,<<"j">>,<<"e">>,<<"c">>,
+ <<"t">>,<<"I">>,<<"s">>,<<"M">>,<<"o">>,<<"r">>,<<"e">>,
+ <<"T">>,<<"h">>,<<"a">>,<<"n">>,<<"T">>,<<"e">>,<<"n">>]} =
+ re:run("SubjectIsMoreThanTen",
+ "(?<S>S)(?<u>u)(?<b>b)(?<j>j)(?<e>e)(?<c>c)(?<t>t)"
+ "(?<I>I)(?<s>s)(?<M>M)(?<o>o)(?<r>r)(?<e>e)(?<T>T)"
+ "(?<h>h)(?<a>a)(?<n>n)(?<T>T)(?<e>e)(?<n>n)",
+ [dupnames,
+ {capture,["S","u","b","j","e","c","t",
+ "I","s","M","o","r","e","T",
+ "h","a","n","T","e","n"],binary}]),
+ {match,[<<"S">>,<<"u">>,<<"b">>,<<"j">>,<<"e">>,<<"c">>,
+ <<"t">>,<<"I">>,<<"s">>,<<"M">>,<<"o">>,<<"r">>,<<"e">>,
+ <<"T">>,<<"h">>,<<"a">>,<<"n">>,<<"T">>,<<"e">>,<<"n">>]} =
+ re:run("SubjectIsMoreThanTen",
+ "(?<S>S)(?<u>u)(?<b>b)(?<j>j)(?<e>e)(?<c>c)(?<t>t)"
+ "(?<I>I)(?<s>s)(?<M>M)(?<o>o)(?<r>r)(?<e>e)(?<T>T)"
+ "(?<h>h)(?<a>a)(?<n>n)(?<T>T)(?<e>e)(?<then>n)",
+ [dupnames,
+ {capture,["S","u","b","j","e","c","t",
+ "I","s","M","o","r","e","T",
+ "h","a","n","T","e","then"],binary}]),
+ ok.
+
+opt_all_names(doc) ->
+ "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>.)|"
+ "(?<DN>Tue)(?:sday)?|(?<DN>Wed)nesday|(?<DN>Thu)(?:rsday)?|"
+ "(?<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}]),
+
+ _ = [ begin
+ {match,[{0,3}]} =
+ re:run(Day,
+ "(?<DN>Mon|Fri|Sun)(?:day)?|(?<DN>Tue)(?:sday)?|"
+ "(?<DN>Wed)(?:nesday)?|(?<DN>Thu)(?:rsday)?|"
+ "(?<DN>Sat)(?:urday)?",
+ [dupnames, {capture, all_names, index}])
+ end || Day <- Days ],
+ _ = [ begin
+ match =
+ re:run(Day,
+ "(Mon|Fri|Sun)(?:day)?|(Tue)(?:sday)?|"
+ "(Wed)(?:nesday)?|(Thu)(?:rsday)?|"
+ "(Sat)(?:urday)?",
+ [dupnames, {capture, all_names, index}])
+ end || Day <- Days ],
+ {match,[{0,1},{-1,0},{-1,0}]} = re:run("A","(?<A>A)|(?<B>B)|(?<C>C)",[{capture, all_names, index}]),
+ {match,[{-1,0},{0,1},{-1,0}]} = re:run("B","(?<A>A)|(?<B>B)|(?<C>C)",[{capture, all_names, index}]),
+ {match,[{-1,0},{-1,0},{0,1}]} = re:run("C","(?<A>A)|(?<B>B)|(?<C>C)",[{capture, all_names, index}]),
+ {match,[<<"A">>,<<>>,<<>>]} = re:run("A","(?<A>A)|(?<B>B)|(?<C>C)",[{capture, all_names, binary}]),
+ {match,[<<>>,<<"B">>,<<>>]} = re:run("B","(?<A>A)|(?<B>B)|(?<C>C)",[{capture, all_names, binary}]),
+ {match,[<<>>,<<>>,<<"C">>]} = re:run("C","(?<A>A)|(?<B>B)|(?<C>C)",[{capture, all_names, binary}]),
+ {match,["A",[],[]]} = re:run("A","(?<A>A)|(?<B>B)|(?<C>C)",[{capture, all_names, list}]),
+ {match,[[],"B",[]]} = re:run("B","(?<A>A)|(?<B>B)|(?<C>C)",[{capture, all_names, list}]),
+ {match,[[],[],"C"]} = re:run("C","(?<A>A)|(?<B>B)|(?<C>C)",[{capture, all_names, list}]),
+ {match,[{-1,0},{-1,0},{0,1}]} = re:run("A","(?<C>A)|(?<B>B)|(?<A>C)",[{capture, all_names, index}]),
+ {match,[{-1,0},{0,1},{-1,0}]} = re:run("B","(?<C>A)|(?<B>B)|(?<A>C)",[{capture, all_names, index}]),
+ {match,[{0,1},{-1,0},{-1,0}]} = re:run("C","(?<C>A)|(?<B>B)|(?<A>C)",[{capture, all_names, index}]),
+ {match,[<<>>,<<>>,<<"A">>]} = re:run("A","(?<C>A)|(?<B>B)|(?<A>C)",[{capture, all_names, binary}]),
+ {match,[<<>>,<<>>,<<"A">>]} = re:run("A","(?<C>A)|(?<B>B)|(?<A>C)",[{capture, all_but_first, binary},{capture, all_names, binary}]),
+ {match,[<<>>,<<"B">>,<<>>]} = re:run("B","(?<C>A)|(?<B>B)|(?<A>C)",[{capture, all_names, binary}]),
+ {match,[<<"C">>,<<>>,<<>>]} = re:run("C","(?<C>A)|(?<B>B)|(?<A>C)",[{capture, all_names, binary}]),
+ {match,[[],[],"A"]} = re:run("A","(?<C>A)|(?<B>B)|(?<A>C)",[{capture, all_names, list}]),
+ {match,[[],"B",[]]} = re:run("B","(?<C>A)|(?<B>B)|(?<A>C)",[{capture, all_names, list}]),
+ {match,["C",[],[]]} = re:run("C","(?<C>A)|(?<B>B)|(?<A>C)",[{capture, all_names, list}]),
+ {match,[[<<>>,<<>>,<<"C">>],
+ [<<>>,<<>>,<<"C">>],
+ [<<>>,<<>>,<<"C">>]]} = re:run("CCC","(?<A>A)|(?<B>B)|(?<C>C)",
+ [global,{capture, all_names, binary}]),
+ {match,[[<<"C">>,<<>>],
+ [<<>>,<<"B">>],
+ [<<"C">>,<<>>]]} = re:run("CBC","(?<A>A)|(?<B>B)|(?<A>C)",
+ [global,dupnames,{capture, all_names, binary}]),
+ {match,[[]]} = re:run("ABCE","(?<A>D)|(?<B>E)|(?<A>F)",[dupnames,{capture,['A'],list}]),
+ {match,["D"]} = re:run("ABCDE","(?<A>D)|(?<B>E)|(?<A>F)",[dupnames,{capture,['A'],list}]),
+ {match,["F"]} = re:run("ABCFE","(?<A>D)|(?<B>E)|(?<A>F)",[dupnames,{capture,['A'],list}]),
+ {match,["F",[]]} = re:run("ABCFE","(?<A>D)|(?<B>E)|(?<A>F)",[dupnames,{capture,['A','B'],list}]),
+ {match,[[],"E"]} = re:run("ABCE","(?<A>D)|(?<B>E)|(?<A>F)",[dupnames,{capture,['A','B'],list}]),
+ {match,[[],"E"]} = re:run("ABCE","(?<A>D)|(?<B>E)|(?<A>F)",[dupnames,{capture,all_names,list}]),
+ {match,[{-1,0},{3,1}]} = re:run("ABCE","(?<A>D)|(?<B>E)|(?<A>F)",[dupnames,{capture,all_names,index}]),
+ match = re:run("Subject","b",[dupnames,{capture,all_names,binary}]),
+ {match,[<<"I">>,<<"M">>,<<"S">>,<<"T">>,<<"a">>,<<"b">>,
+ <<"c">>,<<"e">>,<<"h">>,<<"j">>,<<"n">>,<<"o">>,<<"r">>,
+ <<"s">>,<<"t">>,<<"u">>]} =
+ re:run("SubjectIsMoreThanTen","(?<S>S)(?<u>u)(?<b>b)(?<j>j)"
+ "(?<e>e)(?<c>c)(?<t>t)(?<I>I)(?<s>s)(?<M>M)(?<o>o)(?<r>r)"
+ "(?<e>e)(?<T>T)(?<h>h)(?<a>a)(?<n>n)(?<T>T)(?<e>e)(?<n>n)",
+ [dupnames,{capture,all_names,binary}]),
+ ok.
+
+inspect(doc) ->
+ "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),
+ {ok,MPD} = re:compile("(?<A>A)|(?<B>B)|(?<A>C).",[dupnames]),
+ {namelist,[<<"A">>,<<"B">>]} = re:inspect(MPD,namelist),
+ {ok,MPN} = re:compile("(A)|(B)|(C)."),
+ {namelist,[]} = re:inspect(MPN,namelist),
+ {'EXIT',{badarg,_}} = (catch re:inspect(MPD,namelistk)),
+ {'EXIT',{badarg,_}} = (catch re:inspect({re_pattern,3,0,0,<<"kalle">>},namelist)),
+ {'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";
+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";
+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",[]),
+ {ok,_} = re:compile("(*UTF)ABC"),
+ {ok,_} = re:compile("(*UTF)ABC",[unicode]),
+ {ok,_} = re:compile("(*UTF8)ABC"),
+ {'EXIT',{badarg,_}} = (catch re:run("ABC","ABC",[unicode,never_utf])),
+ {'EXIT',{badarg,_}} = (catch re:run("ABC","(*UTF)ABC",[never_utf])),
+ {'EXIT',{badarg,_}} = (catch re:run("ABC","(*UTF8)ABC",[never_utf])),
+ {error,_} = (catch re:compile("ABC",[unicode,never_utf])),
+ {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";
+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
+ 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";
+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]),
+ {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]),
+ {error,match_limit_recursion} =
+ re:run("aaaaaaaaaaaaaz","(a+)*zz",[{match_limit_recursion,10},
+ report_errors,global]),
+ ["aaaaaaaaaaaaaz"] = re:split("aaaaaaaaaaaaaz","(a+)*zz",
+ [{match_limit_recursion,10},{return,list}]),
+ ["aaaaaaaaaaaaaz"] = re:split("aaaaaaaaaaaaaz","(a+)*zz",
+ [{match_limit,3000},{return,list}]),
+ "aaaaaaaaaaaaaz" = re:replace("aaaaaaaaaaaaaz","(a+)*zz","!",
+ [{match_limit_recursion,10},{return,list}]),
+ "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}])),
+ {'EXIT', {badarg,_}} = (catch re:replace("aaaaaaaaaaaaaz","(a+)*zz","!",
+ [{match_limit,-1},{return,list}])),
+ {'EXIT', {badarg,_}} = (catch re:run("aaaaaaaaaaaaaz","(a+)*zz",
+ [{match_limit_recursion,-1},
+ report_errors,global])),
+ {'EXIT', {badarg,_}} = (catch re:run("aaaaaaaaaaaaaz","(a+)*zz",
+ [{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";
+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),
+ ok.