diff options
Diffstat (limited to 'lib/stdlib')
-rw-r--r-- | lib/stdlib/doc/src/re.xml | 10 | ||||
-rw-r--r-- | lib/stdlib/src/erl_lint.erl | 63 | ||||
-rw-r--r-- | lib/stdlib/src/re.erl | 7 | ||||
-rw-r--r-- | lib/stdlib/test/beam_lib_SUITE.erl | 4 | ||||
-rw-r--r-- | lib/stdlib/test/erl_lint_SUITE.erl | 52 | ||||
-rw-r--r-- | lib/stdlib/test/io_proto_SUITE.erl | 271 | ||||
-rw-r--r-- | lib/stdlib/test/re_SUITE.erl | 14 |
7 files changed, 139 insertions, 282 deletions
diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml index aadb5beaba..078ca0e38c 100644 --- a/lib/stdlib/doc/src/re.xml +++ b/lib/stdlib/doc/src/re.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2007</year> - <year>2016</year> + <year>2017</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -79,6 +79,14 @@ <funcs> <func> + <name name="version" arity="0"/> + <fsummary>Gives the PCRE version of the system in a string format</fsummary> + <desc> + <p>The return of this function is a string with the PCRE version of the system that was used in the Erlang/OTP compilation.</p> + </desc> + </func> + + <func> <name name="compile" arity="1"/> <fsummary>Compile a regular expression into a match program</fsummary> <desc> diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index 0789f5dfb7..78b7a0e751 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -404,6 +404,10 @@ format_error({not_exported_opaque, {TypeName, Arity}}) -> format_error({underspecified_opaque, {TypeName, Arity}}) -> io_lib:format("opaque type ~w~s is underspecified and therefore meaningless", [TypeName, gen_type_paren(Arity)]); +format_error({bad_dialyzer_attribute,Term}) -> + io_lib:format("badly formed dialyzer attribute: ~w", [Term]); +format_error({bad_dialyzer_option,Term}) -> + io_lib:format("unknown dialyzer warning option: ~w", [Term]); %% --- obsolete? unused? --- format_error({format_error, {Fmt, Args}}) -> io_lib:format(Fmt, Args). @@ -796,8 +800,7 @@ attribute_state(Form, St) -> %% State' %% Allow for record, type and opaque type definitions and spec %% declarations to be intersperced within function definitions. -%% Dialyzer attributes are also allowed everywhere, but are not -%% checked at all. +%% Dialyzer attributes are also allowed everywhere. function_state({attribute,L,record,{Name,Fields}}, St) -> record_def(L, Name, Fields, St); @@ -883,7 +886,8 @@ post_traversal_check(Forms, St0) -> StD = check_on_load(StC), StE = check_unused_records(Forms, StD), StF = check_local_opaque_types(StE), - check_callback_information(StF). + StG = check_dialyzer_attribute(Forms, StF), + check_callback_information(StG). %% check_behaviour(State0) -> State %% Check that the behaviour attribute is valid. @@ -3116,6 +3120,59 @@ check_local_opaque_types(St) -> end, dict:fold(FoldFun, St, Ts). +check_dialyzer_attribute(Forms, St0) -> + Vals = [{L,V} || + {attribute,L,dialyzer,Val} <- Forms, + V0 <- lists:flatten([Val]), + V <- case V0 of + {O,F} -> + [{A,B} || + A <- lists:flatten([O]), + B <- lists:flatten([F])]; + T -> [T] + end], + {Wellformed, Bad} = + lists:partition(fun ({_,{Option,FA}}) when is_atom(Option) -> + is_fa(FA); + ({_,Option}) when is_atom(Option) -> true; + (_) -> false + end, Vals), + St1 = foldl(fun ({L,Term}, St) -> + add_error(L, {bad_dialyzer_attribute,Term}, St) + end, St0, Bad), + DefFunctions = (gb_sets:to_list(St0#lint.defined) -- pseudolocals()), + Fun = fun ({L,{Option,FA}}, St) -> + case is_function_dialyzer_option(Option) of + true -> + case lists:member(FA, DefFunctions) of + true -> St; + false -> + add_error(L, {undefined_function,FA}, St) + end; + false -> + add_error(L, {bad_dialyzer_option,Option}, St) + end; + ({L,Option}, St) -> + case is_module_dialyzer_option(Option) of + true -> St; + false -> + add_error(L, {bad_dialyzer_option,Option}, St) + end + end, + foldl(Fun, St1, Wellformed). + +is_function_dialyzer_option(nowarn_function) -> true; +is_function_dialyzer_option(Option) -> + is_module_dialyzer_option(Option). + +is_module_dialyzer_option(Option) -> + lists:member(Option, + [no_return,no_unused,no_improper_lists,no_fun_app, + no_match,no_opaque,no_fail_call,no_contracts, + no_behaviours,no_undefined_callbacks,unmatched_returns, + error_handling,race_conditions,no_missing_calls, + specdiffs,overspecs,underspecs,unknown]). + %% icrt_clauses(Clauses, In, ImportVarTable, State) -> %% {UpdVt,State}. diff --git a/lib/stdlib/src/re.erl b/lib/stdlib/src/re.erl index 52d3c35608..28aab7b590 100644 --- a/lib/stdlib/src/re.erl +++ b/lib/stdlib/src/re.erl @@ -33,7 +33,12 @@ %%% BIFs --export([compile/1, compile/2, run/2, run/3, inspect/2]). +-export([version/0, compile/1, compile/2, run/2, run/3, inspect/2]). + +-spec version() -> binary(). + +version() -> + erlang:nif_error(undef). -spec compile(Regexp) -> {ok, MP} | {error, ErrSpec} when Regexp :: iodata(), diff --git a/lib/stdlib/test/beam_lib_SUITE.erl b/lib/stdlib/test/beam_lib_SUITE.erl index 279e15f703..1baf7d0a94 100644 --- a/lib/stdlib/test/beam_lib_SUITE.erl +++ b/lib/stdlib/test/beam_lib_SUITE.erl @@ -240,7 +240,7 @@ do_error(BeamFile, ACopy) -> verify(missing_chunk, beam_lib:chunks(BF3, [imports])), BF4 = set_byte(ACopy, BeamFile, AbstractStart+10, 17), verify(invalid_chunk, beam_lib:chunks(BF4, [abstract_code])), - BF5 = set_byte(ACopy, BeamFile, AttributesStart+10, 17), + BF5 = set_byte(ACopy, BeamFile, AttributesStart+8, 17), verify(invalid_chunk, beam_lib:chunks(BF5, [attributes])), BF6 = set_byte(ACopy, BeamFile, 1, 17), @@ -251,7 +251,7 @@ do_error(BeamFile, ACopy) -> BF8 = set_byte(ACopy, BeamFile, 13, 17), verify(missing_chunk, beam_lib:chunks(BF8, ["AtU8"])), - BF9 = set_byte(ACopy, BeamFile, CompileInfoStart+10, 17), + BF9 = set_byte(ACopy, BeamFile, CompileInfoStart+8, 17), verify(invalid_chunk, beam_lib:chunks(BF9, [compile_info])). diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index fd7de65302..c469624fb4 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -64,8 +64,8 @@ predef/1, maps/1,maps_type/1,maps_parallel_match/1, otp_11851/1,otp_11879/1,otp_13230/1, - record_errors/1, otp_xxxxx/1, - non_latin1_module/1]). + record_errors/1, otp_11879_cont/1, + non_latin1_module/1, otp_14323/1]). suite() -> [{ct_hooks,[ts_install_cth]}, @@ -85,7 +85,7 @@ all() -> too_many_arguments, basic_errors, bin_syntax_errors, predef, maps, maps_type, maps_parallel_match, otp_11851, otp_11879, otp_13230, - record_errors, otp_xxxxx, non_latin1_module]. + record_errors, otp_11879_cont, non_latin1_module, otp_14323]. groups() -> [{unused_vars_warn, [], @@ -3875,7 +3875,7 @@ record_errors(Config) when is_list(Config) -> {3,erl_lint,{redefine_field,r,a}}],[]}}], run(Config, Ts). -otp_xxxxx(Config) -> +otp_11879_cont(Config) -> Ts = [{constraint1, <<"-export([t/1]). -spec t(X) -> X when is_subtype(integer()). @@ -3942,6 +3942,50 @@ do_non_latin1_module(Mod) -> ok. +%% OTP-14323: Check the dialyzer attribute. +otp_14323(Config) -> + Ts = [ + {otp_14323_1, + <<"-import(mod, [m/1]). + + -export([f/0, g/0, h/0]). + + -dialyzer({nowarn_function,module_info/0}). % undefined function + -dialyzer({nowarn_function,record_info/2}). % undefined function + -dialyzer({nowarn_function,m/1}). % undefined function + + -dialyzer(nowarn_function). % unknown option + -dialyzer(1). % badly formed + -dialyzer(malformed). % unkonwn option + -dialyzer({malformed,f/0}). % unkonwn option + -dialyzer({nowarn_function,a/1}). % undefined function + -dialyzer({nowarn_function,{a,-1}}). % badly formed + + -dialyzer([no_return, no_match]). + -dialyzer({nowarn_function, f/0}). + -dialyzer(no_improper_lists). + -dialyzer([{nowarn_function, [f/0]}, no_improper_lists]). + -dialyzer({no_improper_lists, g/0}). + -dialyzer({[no_return, no_match], [g/0, h/0]}). + + f() -> a. + g() -> b. + h() -> c.">>, + [], + {errors,[{5,erl_lint,{undefined_function,{module_info,0}}}, + {6,erl_lint,{undefined_function,{record_info,2}}}, + {7,erl_lint,{undefined_function,{m,1}}}, + {9,erl_lint,{bad_dialyzer_option,nowarn_function}}, + {10,erl_lint,{bad_dialyzer_attribute,1}}, + {11,erl_lint,{bad_dialyzer_option,malformed}}, + {12,erl_lint,{bad_dialyzer_option,malformed}}, + {13,erl_lint,{undefined_function,{a,1}}}, + {14,erl_lint,{bad_dialyzer_attribute, + {nowarn_function,{a,-1}}}}], + []}}], + [] = run(Config, Ts), + ok. + run(Config, Tests) -> F = fun({N,P,Ws,E}, BadL) -> case catch run_test(Config, P, Ws) of diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl index db321d7490..4cc4e3292c 100644 --- a/lib/stdlib/test/io_proto_SUITE.erl +++ b/lib/stdlib/test/io_proto_SUITE.erl @@ -26,15 +26,14 @@ -export([init_per_testcase/2, end_per_testcase/2]). -export([setopts_getopts/1,unicode_options/1,unicode_options_gen/1, - binary_options/1, bc_with_r12/1, - bc_with_r12_gl/1, read_modes_gl/1,bc_with_r12_ogl/1, + binary_options/1, read_modes_gl/1, read_modes_ogl/1, broken_unicode/1,eof_on_pipe/1,unicode_prompt/1]). -export([io_server_proxy/1,start_io_server_proxy/0, proxy_getall/1, proxy_setnext/2, proxy_quit/1]). %% For spawn --export([toerl_server/3,hold_the_line/3,answering_machine1/3, +-export([toerl_server/3,answering_machine1/3, answering_machine2/3]). -export([uprompt/1]). @@ -79,8 +78,7 @@ suite() -> all() -> [setopts_getopts, unicode_options, unicode_options_gen, - binary_options, bc_with_r12, bc_with_r12_gl, - bc_with_r12_ogl, read_modes_gl, read_modes_ogl, + binary_options, read_modes_gl, read_modes_ogl, broken_unicode, eof_on_pipe, unicode_prompt]. groups() -> @@ -742,263 +740,7 @@ binary_options(Config) when is_list(Config) -> ],[],[],"-oldshell"), ok. -%% Test io protocol compatibility with R12 nodes. -bc_with_r12(Config) when is_list(Config) -> - case test_server:is_release_available("r12b") of - true -> bc_with_r12_1(Config); - false -> {skip,"No R12B found"} - end. - -bc_with_r12_1(Config) -> - PA = filename:dirname(code:which(?MODULE)), - Name1 = io_proto_r12_1, - N1 = list_to_atom(atom_to_list(Name1) ++ "@" ++ hostname()), - test_server:start_node(Name1, peer, [{args, "-pz \""++PA++"\""}, - {erl,[{release,"r12b"}]}]), - DataDir = proplists:get_value(data_dir,Config), - FileName1 = filename:join([DataDir,"testdata_latin1.dat"]), - TestDataLine1 = [229,228,246], - TestDataLine2 = [197,196,214], - SPid1 = rpc:call(N1,erlang,spawn,[?MODULE,hold_the_line,[self(),FileName1,[read]]]), - {ok,F1} = receive - {SPid1,Res1} -> - Res1 - after 5000 -> - exit(timeout) - end, - TestDataLine1 = chomp(io:get_line(F1,'')), - SPid1 ! die, - receive after 1000 -> ok end, - SPid2 = rpc:call(N1,erlang,spawn,[?MODULE,hold_the_line,[self(),FileName1,[read,binary]]]), - {ok,F2} = receive - {SPid2,Res2} -> - Res2 - after 5000 -> - exit(timeout) - end, - TestDataLine1BinUtf = unicode:characters_to_binary(TestDataLine1), - TestDataLine1BinLatin = list_to_binary(TestDataLine1), - TestDataLine2BinUtf = unicode:characters_to_binary(TestDataLine2), - TestDataLine2BinLatin = list_to_binary(TestDataLine2), - TestDataLine1BinUtf = chomp(io:get_line(F2,'')), - TestDataLine2BinUtf = chomp(io:get_line(F2,'')), - %%io:format(standard_error,"Exec:~s\r\n",[rpc:call(N1,os,find_executable,["erl"])]), - %%io:format(standard_error,"Io:~s\r\n",[rpc:call(N1,code,which,[io])]), - %%io:format(standard_error,"File_io_server:~s\r\n",[rpc:call(N1,code,which,[file_io_server])]), - file:position(F2,0), - TestDataLine1BinLatin = chomp(rpc:call(N1,io,get_line,[F2,''])), - TestDataLine2BinUtf = chomp(io:get_line(F2,'')), - file:position(F2,0), - TestDataLine1BinUtf = chomp(io:get_line(F2,'')), - TestDataLine2BinLatin = chomp(rpc:call(N1,io,get_line,[F2,''])), - eof = chomp(rpc:call(N1,io,get_line,[F2,''])), - file:position(F2,0), - TestDataLine1BinLatin = rpc:call(N1,io,get_chars,[F2,'',3]), - io:get_chars(F2,'',1), - TestDataLine2BinLatin = chomp(rpc:call(N1,io,get_line,[F2,''])), - file:position(F2,0), - {ok,[TestDataLine1]} = io:fread(F2,'',"~s"), - {ok,[TestDataLine2]} = rpc:call(N1,io,fread,[F2,'',"~s"]), - - DataLen1 = length(TestDataLine1), - DataLen2 = length(TestDataLine2), - file:position(F2,0), - {ok,TestDataLine1BinLatin} = file:read(F2,DataLen1), - {ok,_} = file:read(F2,1), - {ok,TestDataLine2BinLatin} = rpc:call(N1,file,read,[F2,DataLen2]), - {ok,_} = file:read(F2,1), - eof = rpc:call(N1,file,read,[F2,1]), - %% As r12 has a bug when setting options with setopts, we need - %% to reopen the file... - SPid2 ! die, - receive after 1000 -> ok end, - SPid3 = rpc:call(N1,erlang,spawn,[?MODULE,hold_the_line,[self(),FileName1,[read]]]), - {ok,F3} = receive - {SPid3,Res3} -> - Res3 - after 5000 -> - exit(timeout) - end, - - file:position(F3,0), - {ok,[TestDataLine1]} = io:fread(F3,'',"~s"), - {ok,[TestDataLine2]} = rpc:call(N1,io,fread,[F3,'',"~s"]), - - - file:position(F3,0), - {ok,TestDataLine1} = file:read(F3,DataLen1), - {ok,_} = file:read(F3,1), - {ok,TestDataLine2} = rpc:call(N1,file,read,[F3,DataLen2]), - {ok,_} = file:read(F3,1), - eof = rpc:call(N1,file,read,[F3,1]), - - - %% So, lets do it all again, but the other way around - {ok,F4} = file:open(FileName1,[read]), - TestDataLine1 = chomp(io:get_line(F4,'')), - file:position(F4,0), - io:setopts(F4,[binary]), - TestDataLine1BinUtf = chomp(io:get_line(F4,'')), - TestDataLine2BinUtf = chomp(io:get_line(F4,'')), - file:position(F4,0), - TestDataLine1BinUtf = chomp(io:get_line(F4,'')), - TestDataLine2BinUtf = chomp(io:get_line(F4,'')), - file:position(F4,0), - TestDataLine1BinUtf = chomp(io:get_line(F4,'')), - TestDataLine2BinLatin = chomp(rpc:call(N1,io,get_line,[F4,''])), - file:position(F4,0), - TestDataLine1BinLatin = chomp(rpc:call(N1,io,get_line,[F4,''])), - TestDataLine2BinUtf = chomp(io:get_line(F4,'')), - eof = chomp(rpc:call(N1,io,get_line,[F4,''])), - file:position(F4,0), - TestDataLine1BinLatin = rpc:call(N1,io,get_chars,[F4,'',3]), - io:get_chars(F4,'',1), - TestDataLine2BinLatin = chomp(rpc:call(N1,io,get_line,[F4,''])), - file:position(F4,0), - {ok,[TestDataLine1]} = io:fread(F4,'',"~s"), - {ok,[TestDataLine2]} = rpc:call(N1,io,fread,[F4,'',"~s"]), - file:position(F4,0), - {ok,TestDataLine1BinLatin} = file:read(F4,DataLen1), - {ok,_} = file:read(F4,1), - {ok,TestDataLine2BinLatin} = rpc:call(N1,file,read,[F4,DataLen2]), - {ok,_} = file:read(F4,1), - eof = rpc:call(N1,file,read,[F4,1]), - io:setopts(F4,[list]), - - file:position(F4,0), - {ok,[TestDataLine1]} = io:fread(F4,'',"~s"), - {ok,[TestDataLine2]} = rpc:call(N1,io,fread,[F4,'',"~s"]), - - - file:position(F4,0), - {ok,TestDataLine1} = file:read(F4,DataLen1), - {ok,_} = file:read(F4,1), - {ok,TestDataLine2} = rpc:call(N1,file,read,[F4,DataLen2]), - {ok,_} = file:read(F4,1), - eof = rpc:call(N1,file,read,[F4,1]), - - file:close(F4), - test_server:stop_node(N1), - ok. - -hold_the_line(Parent,Filename,Options) -> - Parent ! {self(), file:open(Filename,Options)}, - receive - die -> - ok - end. - - -%% Test io protocol compatibility with R12 nodes (terminals). -bc_with_r12_gl(Config) when is_list(Config) -> - case test_server:is_release_available("r12b") of - true -> - case get_progs() of - {error,Reason} -> - {skip, Reason}; - _ -> - bc_with_r12_gl_1(Config,answering_machine1) - end; - false -> - {skip,"No R12B found"} - end. - -%% Test io protocol compatibility with R12 nodes (oldshell). -bc_with_r12_ogl(Config) when is_list(Config) -> - case test_server:is_release_available("r12b") of - true -> - case get_progs() of - {error,Reason} -> - {skip, Reason}; - _ -> - bc_with_r12_gl_1(Config,answering_machine2) - end; - false -> - {skip,"No R12B found"} - end. - -bc_with_r12_gl_1(_Config,Machine) -> - PA = filename:dirname(code:which(?MODULE)), - Name1 = io_proto_r12_gl_1, - N1 = list_to_atom(atom_to_list(Name1) ++ "@" ++ hostname()), - test_server:start_node(Name1, peer, [{args, "-pz \""++PA++"\""}, - {erl,[{release,"r12b"}]}]), - TestDataLine1 = [229,228,246], - TestDataLine1BinUtf = unicode:characters_to_binary(TestDataLine1), - TestDataLine1BinLatin = list_to_binary(TestDataLine1), - - {ok,N2List} = create_nodename(), - MyNodeList = atom2list(node()), - register(io_proto_suite,self()), - AM1 = spawn(?MODULE,Machine, - [MyNodeList, "io_proto_suite", N2List]), - - GL = receive X when is_pid(X) -> X end, - %% get_line - "Hej\n" = rpc:call(N1,io,get_line,[GL,"Prompt\n"]), - io:setopts(GL,[binary]), - io:format(GL,"Okej~n",[]), - <<"Hej\n">> = rpc:call(N1,io,get_line,[GL,"Prompt\n"]), - io:setopts(GL,[{encoding,latin1}]), - io:format(GL,"Okej~n",[]), - TestDataLine1BinLatin = chomp(rpc:call(N1,io,get_line,[GL,"Prompt\n"])), - io:format(GL,"Okej~n",[]), - TestDataLine1BinUtf = chomp(io:get_line(GL,"Prompt\n")), - io:setopts(GL,[{encoding,unicode}]), - - io:format(GL,"Okej~n",[]), - TestDataLine1BinLatin = chomp(rpc:call(N1,io,get_line,[GL,"Prompt\n"])), - io:format(GL,"Okej~n",[]), - TestDataLine1BinUtf = chomp(io:get_line(GL,"Prompt\n")), - io:setopts(GL,[list]), - io:format(GL,"Okej~n",[]), - - %%get_chars - "Hej" = rpc:call(N1,io,get_chars,[GL,"Prompt\n",3]), - io:setopts(GL,[binary]), - io:format(GL,"Okej~n",[]), - <<"Hej">> = rpc:call(N1,io,get_chars,[GL,"Prompt\n",3]), - io:setopts(GL,[{encoding,latin1}]), - io:format(GL,"Okej~n",[]), - TestDataLine1BinLatin = rpc:call(N1,io,get_chars,[GL,"Prompt\n",3]), - io:format(GL,"Okej~n",[]), - TestDataLine1BinUtf = io:get_chars(GL,"Prompt\n",3), - io:setopts(GL,[{encoding,unicode}]), - - io:format(GL,"Okej~n",[]), - TestDataLine1BinLatin = rpc:call(N1,io,get_chars,[GL,"Prompt\n",3]), - io:format(GL,"Okej~n",[]), - TestDataLine1BinUtf = io:get_chars(GL,"Prompt\n",3), - io:setopts(GL,[list]), - io:format(GL,"Okej~n",[]), - %%fread - {ok,["Hej"]} = rpc:call(N1,io,fread,[GL,"Prompt\n","~s"]), - io:setopts(GL,[binary]), - io:format(GL,"Okej~n",[]), - {ok,["Hej"]} = rpc:call(N1,io,fread,[GL,"Prompt\n","~s"]), - io:setopts(GL,[{encoding,latin1}]), - io:format(GL,"Okej~n",[]), - {ok,[TestDataLine1]} = rpc:call(N1,io,fread,[GL,"Prompt\n","~s"]), - io:format(GL,"Okej~n",[]), - {ok,[TestDataLine1]} = io:fread(GL,"Prompt\n","~s"), - io:setopts(GL,[{encoding,unicode}]), - io:format(GL,"Okej~n",[]), - {ok,[TestDataLine1]} = rpc:call(N1,io,fread,[GL,"Prompt\n","~s"]), - io:format(GL,"Okej~n",[]), - {ok,[TestDataLine1]} = io:fread(GL,"Prompt\n","~s"), - io:setopts(GL,[list]), - io:format(GL,"Okej~n",[]), - - - receive - {AM1,done} -> - ok - after 5000 -> - exit(timeout) - end, - test_server:stop_node(N1), - ok. answering_machine1(OthNode,OthReg,Me) -> @@ -1900,13 +1642,6 @@ convert(Data, latin1, binary) -> {error, {cannot_convert, unicode, latin1}} end. -hostname() -> - from($@, atom_to_list(node())). - -from(H, [H | T]) -> T; -from(H, [_ | T]) -> from(H, T); -from(_, []) -> []. - atom2list(A) -> lists:flatten(io_lib:format("~w", [A])). diff --git a/lib/stdlib/test/re_SUITE.erl b/lib/stdlib/test/re_SUITE.erl index a76ded5f60..71f86e32e5 100644 --- a/lib/stdlib/test/re_SUITE.erl +++ b/lib/stdlib/test/re_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2016. All Rights Reserved. +%% Copyright Ericsson AB 2008-2017. 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,7 +24,7 @@ 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, @@ -45,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() -> []. @@ -194,6 +194,14 @@ run_options(Config) when is_list(Config) -> +%% 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) -> ok = crtest("ABDabcdABCD","abcd",[],true,{match,[{3,4}]}), |