diff options
Diffstat (limited to 'lib/stdlib/test')
24 files changed, 785 insertions, 334 deletions
diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile index 29b8e28d3a..6aa09d7bd0 100644 --- a/lib/stdlib/test/Makefile +++ b/lib/stdlib/test/Makefile @@ -23,7 +23,6 @@ MODULES= \ dummy_via \ edlin_expand_SUITE \ epp_SUITE \ - erl_eval_helper \ erl_eval_SUITE \ erl_expand_records_SUITE \ erl_internal_SUITE \ diff --git a/lib/stdlib/test/base64_SUITE.erl b/lib/stdlib/test/base64_SUITE.erl index 7b8650f224..b28df94221 100644 --- a/lib/stdlib/test/base64_SUITE.erl +++ b/lib/stdlib/test/base64_SUITE.erl @@ -1,3 +1,4 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% @@ -179,7 +180,7 @@ mime_decode(Config) when is_list(Config) -> <<"o">> = base64:mime_decode(<<"b=w=====">>), %% Test misc white space and illegals with embedded padding <<"one">> = base64:mime_decode(<<" b~2=\r\n5()l===">>), - <<"on">> = base64:mime_decode(<<"\tb =2\"�4=�= ==">>), + <<"on">> = base64:mime_decode(<<"\tb =2\"¤4=¤= ==">>), <<"o">> = base64:mime_decode(<<"\nb=w=====">>), %% Two pads <<"Aladdin:open sesame">> = @@ -188,7 +189,7 @@ mime_decode(Config) when is_list(Config) -> <<"Hello World!!">> = base64:mime_decode(<<"SGVsb)(G8gV29ybGQ=h IQ= =">>), %% No pad <<"Aladdin:open sesam">> = - base64:mime_decode("QWxhZGRpbjpvcG�\")(VuIHNlc2Ft"), + base64:mime_decode("QWxhZGRpbjpvcG¤\")(VuIHNlc2Ft"), %% Encoded base 64 strings may be divided by non base 64 chars. %% In this cases whitespaces. <<"0123456789!@#0^&*();:<>,. []{}">> = @@ -222,7 +223,7 @@ mime_decode_to_string(Config) when is_list(Config) -> "o" = base64:mime_decode_to_string(<<"b=w=====">>), %% Test misc white space and illegals with embedded padding "one" = base64:mime_decode_to_string(<<" b~2=\r\n5()l===">>), - "on" = base64:mime_decode_to_string(<<"\tb =2\"�4=�= ==">>), + "on" = base64:mime_decode_to_string(<<"\tb =2\"¤4=¤= ==">>), "o" = base64:mime_decode_to_string(<<"\nb=w=====">>), %% Two pads "Aladdin:open sesame" = @@ -231,7 +232,7 @@ mime_decode_to_string(Config) when is_list(Config) -> "Hello World!!" = base64:mime_decode_to_string(<<"SGVsb)(G8gV29ybGQ=h IQ= =">>), %% No pad "Aladdin:open sesam" = - base64:mime_decode_to_string("QWxhZGRpbjpvcG�\")(VuIHNlc2Ft"), + base64:mime_decode_to_string("QWxhZGRpbjpvcG¤\")(VuIHNlc2Ft"), %% Encoded base 64 strings may be divided by non base 64 chars. %% In this cases whitespaces. "0123456789!@#0^&*();:<>,. []{}" = diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl index bac59a3107..9b6f628aa9 100644 --- a/lib/stdlib/test/binary_module_SUITE.erl +++ b/lib/stdlib/test/binary_module_SUITE.erl @@ -1,7 +1,8 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2012. 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 @@ -1331,9 +1332,9 @@ one_random_number(N) -> one_random(N) -> M = ((N - 1) rem 68) + 1, element(M,{$a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t, - $u,$v,$w,$x,$y,$z,$�,$�,$�,$A,$B,$C,$D,$E,$F,$G,$H, - $I,$J,$K,$L,$M,$N,$O,$P,$Q,$R,$S,$T,$U,$V,$W,$X,$Y,$Z,$�, - $�,$�,$0,$1,$2,$3,$4,$5,$6,$7,$8,$9}). + $u,$v,$w,$x,$y,$z,$å,$ä,$ö,$A,$B,$C,$D,$E,$F,$G,$H, + $I,$J,$K,$L,$M,$N,$O,$P,$Q,$R,$S,$T,$U,$V,$W,$X,$Y,$Z,$Å, + $Ä,$Ö,$0,$1,$2,$3,$4,$5,$6,$7,$8,$9}). random_number({Min,Max}) -> % Min and Max are *length* of number in % decimal positions diff --git a/lib/stdlib/test/digraph_SUITE.erl b/lib/stdlib/test/digraph_SUITE.erl index 1d1326d60e..ed01b32a59 100644 --- a/lib/stdlib/test/digraph_SUITE.erl +++ b/lib/stdlib/test/digraph_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-2012. 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 @@ -400,7 +400,7 @@ sane1(G) -> lists:foreach( fun(V) -> InEs = digraph:in_edges(G, V), - %% Nu har man *alla* inkanter f�r V + %% *All* in-edoges of V lists:foreach( fun(E) -> case digraph:edge(G, E) of diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl index 77c615d6d9..606bbbcbb2 100644 --- a/lib/stdlib/test/epp_SUITE.erl +++ b/lib/stdlib/test/epp_SUITE.erl @@ -25,7 +25,7 @@ variable_1/1, otp_4870/1, otp_4871/1, otp_5362/1, pmod/1, not_circular/1, skip_header/1, otp_6277/1, otp_7702/1, otp_8130/1, overload_mac/1, otp_8388/1, otp_8470/1, otp_8503/1, - otp_8562/1, otp_8665/1, otp_8911/1]). + otp_8562/1, otp_8665/1, otp_8911/1, otp_10302/1]). -export([epp_parse_erl_form/2]). @@ -67,7 +67,7 @@ all() -> {group, variable}, otp_4870, otp_4871, otp_5362, pmod, not_circular, skip_header, otp_6277, otp_7702, otp_8130, overload_mac, otp_8388, otp_8470, otp_8503, otp_8562, - otp_8665, otp_8911]. + otp_8665, otp_8911, otp_10302]. groups() -> [{upcase_mac, [], [upcase_mac_1, upcase_mac_2]}, @@ -582,12 +582,13 @@ otp_8130(suite) -> otp_8130(Config) when is_list(Config) -> true = os:putenv("epp_inc1", "stdlib"), Ts = [{otp_8130_1, - %% The scanner handles UNICODE in a special way. Hopefully - %% temporarily. <<"-define(M(A), ??A). " "t() -> " - " \"{ 34 , [ $1 , 2730 ] , \\\"34\\\" , X . a , 2730 }\" = " - " ?M({34,\"1\\x{aaa}\",\"34\",X.a,$\\x{aaa}}), ok. ">>, + " L = \"{ 34 , \\\"1\\\\x{AAA}\\\" , \\\"34\\\" , X . a , $\\\\x{AAA} }\", " + " R = ?M({34,\"1\\x{aaa}\",\"34\",X.a,$\\x{aaa}})," + " Lt = erl_scan:string(L, 1, [unicode])," + " Rt = erl_scan:string(R, 1, [unicode])," + " Lt = Rt, ok. ">>, ok}, {otp_8130_2, @@ -1284,6 +1285,75 @@ otp_8665(Config) when is_list(Config) -> ?line [] = compile(Config, Cs), ok. +otp_10302(doc) -> + "OTP-10302. Unicode characters scanner/parser."; +otp_10302(suite) -> + []; +otp_10302(Config) when is_list(Config) -> + %% Two messages (one too many). Keeps otp_4871 happy. + Cs = [{otp_8562, + <<"%% coding: utf-8\n \n \x{E4}">>, + {errors,[{3,epp,cannot_parse}, + {3,file_io_server,invalid_unicode}],[]}} + ], + [] = compile(Config, Cs), + Dir = ?config(priv_dir, Config), + File = filename:join(Dir, "otp_10302.erl"), + utf8 = encoding("coding: utf-8", File), + utf8 = encoding("coding: UTF-8", File), + latin1 = encoding("coding: Latin-1", File), + latin1 = encoding("coding: latin-1", File), + none = encoding_com("coding: utf-8", File), + none = encoding_com("\n\n%% coding: utf-8", File), + none = encoding_nocom("\n\n coding: utf-8", File), + utf8 = encoding_com("\n%% coding: utf-8", File), + utf8 = encoding_nocom("\n coding: utf-8", File), + none = encoding("coding: \nutf-8", File), + latin1 = encoding("Encoding : latin-1", File), + utf8 = encoding("ccoding: UTF-8", File), + utf8 = encoding("coding= utf-8", File), + utf8 = encoding_com(" %% coding= utf-8", File), + utf8 = encoding("coding = utf-8", File), + none = encoding("coding: utf-16 coding: utf-8", File), %first is bad + none = encoding("Coding: utf-8", File), %capital c + utf8 = encoding("-*- coding: utf-8 -*-", File), + utf8 = encoding("-*-coding= utf-8-*-", File), + utf8 = encoding("codingcoding= utf-8", File), + ok = prefix("coding: utf-8", File, utf8), + + "coding: latin-1" = epp:encoding_to_string(latin1), + "coding: utf-8" = epp:encoding_to_string(utf8), + true = lists:member(epp:default_encoding(), [latin1, utf8]), + + ok. + +prefix(S, File, Enc) -> + prefix(0, S, File, Enc). + +prefix(100, _S, _File, _) -> + ok; +prefix(N, S, File, Enc) -> + Enc = encoding(lists:duplicate(N, $\s) ++ S, File), + prefix(N+1, S, File, Enc). + +encoding(Enc, File) -> + E = encoding_com("%% " ++ Enc, File), + none = encoding_com(Enc, File), + E = encoding_nocom(Enc, File). + +encoding_com(Enc, File) -> + ok = file:write_file(File, Enc), + {ok, Fd} = file:open(File, [read]), + E = epp:set_encoding(Fd), + ok = file:close(Fd), + E = epp:read_encoding(File). + +encoding_nocom(Enc, File) -> + ok = file:write_file(File, Enc), + {ok, Fd} = file:open(File, [read]), + ok = file:close(Fd), + epp:read_encoding(File, [{in_comment_only, false}]). + check(Config, Tests) -> eval_tests(Config, fun check_test/2, Tests). diff --git a/lib/stdlib/test/erl_eval_SUITE.erl b/lib/stdlib/test/erl_eval_SUITE.erl index 47792d1052..04d49770cb 100644 --- a/lib/stdlib/test/erl_eval_SUITE.erl +++ b/lib/stdlib/test/erl_eval_SUITE.erl @@ -1160,24 +1160,6 @@ do_funs(LFH, EFH) -> concat(["begin F = fun(F, N) -> [", M, ":count_down(F,N) || X <-[1]] end, F(F,2) end."]), [[[0]]], ['F'], LFH, EFH), - - %% Tests for a bug found by the Dialyzer - used to crash. - case test_server:is_native(erl_eval) of - true -> - %% Parameterized modules are not supported by HiPE. - ok; - false -> - check(fun() -> Pmod = erl_eval_helper:new(42), Pmod:add(5) end, - "begin Pmod = erl_eval_helper:new(42), Pmod:add(5) end.", - 47, - ['Pmod'], LFH, EFH), - check(fun() -> Pmod = erl_eval_helper:new(42), - B = Pmod:add(7), B end, - "begin Pmod = erl_eval_helper:new(42), " - "B = Pmod:add(7), B end.", - 49, - ['B','Pmod'], LFH, EFH) - end, ok. count_down(F, N) when N > 0 -> diff --git a/lib/stdlib/test/erl_eval_helper.erl b/lib/stdlib/test/erl_eval_helper.erl deleted file mode 100644 index 6863b40108..0000000000 --- a/lib/stdlib/test/erl_eval_helper.erl +++ /dev/null @@ -1,28 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2010. 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 -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% - --module(erl_eval_helper, [Base]). - --export([add/1]). - -add(Arg) -> - Base+Arg. - - - diff --git a/lib/stdlib/test/erl_expand_records_SUITE.erl b/lib/stdlib/test/erl_expand_records_SUITE.erl index e248934e10..94b4397a9c 100644 --- a/lib/stdlib/test/erl_expand_records_SUITE.erl +++ b/lib/stdlib/test/erl_expand_records_SUITE.erl @@ -35,7 +35,7 @@ init_per_group/2,end_per_group/2, init_per_testcase/2, end_per_testcase/2]). --export([abstract_module/1, attributes/1, expr/1, guard/1, +-export([attributes/1, expr/1, guard/1, init/1, pattern/1, strict/1, update/1, otp_5915/1, otp_7931/1, otp_5990/1, otp_7078/1, otp_7101/1]). @@ -55,7 +55,7 @@ end_per_testcase(_Case, _Config) -> suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [abstract_module, attributes, expr, guard, init, + [attributes, expr, guard, init, pattern, strict, update, {group, tickets}]. groups() -> @@ -75,40 +75,12 @@ end_per_group(_GroupName, Config) -> Config. -abstract_module(doc) -> - "Compile an abstract module."; -abstract_module(suite) -> []; -abstract_module(Config) when is_list(Config) -> - %% erl_expand_records does not handle abstract modules. But anyway... - File = filename("param.erl", Config), - Beam = filename("param.beam", Config), - Test = <<"-module(param, [A, B]). - - -export([args/1]). - - args(C) -> - X = local(C), - Z = new(A, B), - {X, Z}. - - local(C) -> - module_info(C). - ">>, - - ?line ok = file:write_file(File, Test), - ?line {ok, param} = compile:file(File, [{outdir,?privdir}]), - - ?line ok = file:delete(File), - ?line ok = file:delete(Beam), - ok. - attributes(doc) -> "Import module and functions."; attributes(suite) -> []; attributes(Config) when is_list(Config) -> Ts = [ - <<"-import(erl_expand_records_SUITE). - -import(lists, [append/2, reverse/1]). + <<"-import(lists, [append/2, reverse/1]). -record(r, {a,b}). @@ -158,12 +130,12 @@ expr(Config) when is_list(Config) -> 2 = fun(X) -> X end(One + One), 3 = fun exprec_test:f/1(3), 4 = exprec_test:f(4), - 5 = ''.f(5), + 5 = f(5), L = receive {a,message,L0} -> L0 end, - case catch a.b.c:foo(bar) of + case catch a:foo(bar) of {'EXIT', _} -> ok end, _ = receive %Suppress warning. @@ -197,7 +169,7 @@ guard(suite) -> []; guard(Config) when is_list(Config) -> File = filename("guard.erl", Config), Beam = filename("guard.beam", Config), - Test = <<"-module(guard, [A, B]). + Test = <<"-module(guard). -export([t/1]). @@ -263,8 +235,7 @@ pattern(doc) -> pattern(suite) -> []; pattern(Config) when is_list(Config) -> Ts = [ - <<"-import(erl_expand_records_SUITE). - -import(lists, [append/2, reverse/1]). + <<"-import(lists, [append/2, reverse/1]). -record(r, {a,b}). @@ -292,10 +263,10 @@ pattern(Config) when is_list(Config) -> 21 = t(#r{a = #r{}}), 22 = t(2), 23 = t(#r{a = #r{}, b = b}), - 24 = t(a.b.c), + 24 = t(abc), ok. - t(a.b.c) -> + t(abc) -> 24; t($a) -> 2; diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index 90a37f6441..564f27a512 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -1732,7 +1732,7 @@ otp_5362(Config) when is_list(Config) -> {otp_5362_2, <<"-export([inline/0]). - -import(lists.foo, [a/1,b/1]). % b/1 is not used + -import(lists, [a/1,b/1]). % b/1 is not used -compile([{inline,{inl,7}}]). % undefined -compile([{inline,[{inl,17}]}]). % undefined @@ -1764,7 +1764,7 @@ otp_5362(Config) when is_list(Config) -> {6,erl_lint,{bad_inline,{inl,17}}}, {11,erl_lint,{undefined_function,{fipp,0}}}, {22,erl_lint,{bad_nowarn_unused_function,{and_not_used,2}}}], - [{3,erl_lint,{unused_import,{{b,1},'lists.foo'}}}, + [{3,erl_lint,{unused_import,{{b,1},lists}}}, {9,erl_lint,{unused_function,{foop,0}}}, {19,erl_lint,{unused_function,{not_used,0}}}, {23,erl_lint,{unused_function,{and_not_used,1}}}]}}, @@ -2187,27 +2187,9 @@ otp_5878(Config) when is_list(Config) -> ?line [] = run(Config, Ts), Abstr = <<"-module(lint_test, [A, B]). - - -export([args/1]). - - -record(r, {a = A, b = THIS}). % A and THIS are unbound - - %% param:args(compile,param:new(1,2)). - - args(C) -> - X = local(C), - Z = new(A, B), - F = fun(THIS) -> {x, A} end, % THIS unused and shadowed - {X, Z, THIS, F, #r{}}. - - local(C) -> - module_info(C). ">>, - ?line {error,[{5,erl_lint,{unbound_var,'A'}}, - {5,erl_lint,{unbound_var,'THIS'}}], - [{12,erl_lint,{unused_var,'THIS'}}, - {12,erl_lint,{shadowed_var,'THIS','fun'}}]} - = run_test2(Config, Abstr, [warn_unused_record]), + {errors,[{1,erl_lint,pmod_unsupported}],[]} = + run_test2(Config, Abstr, [warn_unused_record]), QLC1 = <<"-module(lint_test). -include_lib(\"stdlib/include/qlc.hrl\"). diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl index 64853ca078..37be61d665 100644 --- a/lib/stdlib/test/erl_pp_SUITE.erl +++ b/lib/stdlib/test/erl_pp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2011. All Rights Reserved. +%% Copyright Ericsson AB 2006-2012. 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 @@ -40,7 +40,7 @@ init_per_testcase/2, end_per_testcase/2]). -export([ func/1, call/1, recs/1, try_catch/1, if_then/1, - receive_after/1, bits/1, head_tail/1, package/1, + receive_after/1, bits/1, head_tail/1, cond1/1, block/1, case1/1, ops/1, messages/1, old_mnemosyne_syntax/1, import_export/1, misc_attrs/1, @@ -48,7 +48,8 @@ neg_indent/1, otp_6321/1, otp_6911/1, otp_6914/1, otp_8150/1, otp_8238/1, - otp_8473/1, otp_8522/1, otp_8567/1, otp_8664/1, otp_9147/1]). + otp_8473/1, otp_8522/1, otp_8567/1, otp_8664/1, otp_9147/1, + otp_10302/1]). %% Internal export. -export([ehook/6]). @@ -74,12 +75,12 @@ all() -> groups() -> [{expr, [], [func, call, recs, try_catch, if_then, receive_after, - bits, head_tail, package, cond1, block, case1, ops, + bits, head_tail, cond1, block, case1, ops, messages, old_mnemosyne_syntax]}, {attributes, [], [misc_attrs, import_export]}, {tickets, [], [otp_6321, otp_6911, otp_6914, otp_8150, otp_8238, - otp_8473, otp_8522, otp_8567, otp_8664, otp_9147]}]. + otp_8473, otp_8522, otp_8567, otp_8664, otp_9147, otp_10302]}]. init_per_suite(Config) -> Config. @@ -438,9 +439,6 @@ bits(Config) when is_list(Config) -> ?line ok = pp_expr(<<"<<{a,b}/binary>>">>), ?line ok = pp_expr(<<"<<{foo:bar(),b}/binary>>">>), ?line ok = pp_expr(<<"<<(foo:bar()):(foo:bar())/binary>>">>), - ?line ok = pp_expr(<<"<<(foo.bar)/binary>>">>), - ?line ok = pp_expr(<<"<<(foo.bar):all/binary>>">>), - ?line ok = pp_expr(<<"<<(foo.bar):(foo.bar)/binary>>">>), ok. head_tail(suite) -> @@ -462,17 +460,6 @@ head_tail(Config) when is_list(Config) -> ?line compile(Config, Ts), ok. -package(suite) -> - []; -package(Config) when is_list(Config) -> - Ts = [{package_1, - <<"t() -> a.b:foo().">>}, - {package_2, - <<"t() -> .lists:sort([]).">>} - ], - ?line compile(Config, Ts), - ok. - cond1(suite) -> []; cond1(Config) when is_list(Config) -> @@ -550,29 +537,9 @@ messages(Config) when is_list(Config) -> ?line true = "\n" =:= lists:flatten(erl_pp:form({eof,0})), ok. -old_mnemosyne_syntax(suite) -> - []; old_mnemosyne_syntax(Config) when is_list(Config) -> - %% Since we have kept the 'query' syntax and ':-' token, + %% Since we have kept the ':-' token, %% better test that we can pretty print it. - Q = {'query',6, - {lc,6, - {var,6,'X'}, - [{generate,6, - {var,6,'X'}, - {call,6,{atom,6,table},[{atom,6,tab}]}}, - {match,7, - {record_field,7,{var,7,'X'},{atom,7,foo}}, - {atom,7,bar}}]}}, - ?line "query\n" - " [ \n" % extra space... - " X ||\n" - " X <- table(tab),\n" - " X.foo = bar\n" - " ]\n" - "end" = - lists:flatten(erl_pp:expr(Q)), - R = {rule,12,sales,2, [{clause,12, [{var,12,'E'},{atom,12,employee}], @@ -614,13 +581,11 @@ misc_attrs(suite) -> []; misc_attrs(Config) when is_list(Config) -> ?line ok = pp_forms(<<"-module(m). ">>), - ?line ok = pp_forms(<<"-module(m.p, [A,B]). ">>), ?line ok = pp_forms(<<"-module(m, [Aafjlksfjdlsjflsdfjlsdjflkdsfjlk," "Blsjfdlslfjsdf]). ">>), ?line ok = pp_forms(<<"-export([]). ">>), ?line ok = pp_forms(<<"-export([foo/2, bar/0]). ">>), ?line ok = pp_forms(<<"-export([bar/0]). ">>), - ?line ok = pp_forms(<<"-import(.lists). ">>), ?line ok = pp_forms(<<"-import(lists, []). ">>), ?line ok = pp_forms(<<"-import(lists, [map/2]). ">>), ?line ok = pp_forms(<<"-import(lists, [map/2, foreach/2]). ">>), @@ -634,8 +599,12 @@ misc_attrs(Config) when is_list(Config) -> hook(suite) -> []; hook(Config) when is_list(Config) -> + F = fun(H) -> H end, + do_hook(F). + +do_hook(HookFun) -> Lc = parse_expr(binary_to_list(<<"[X || X <- [1,2,3]].">>)), - H = fun hook/4, + H = HookFun(fun hook/4), Expr = {call,0,{atom,0,fff},[{foo,Lc},{foo,Lc},{foo,Lc}]}, EChars = lists:flatten(erl_pp:expr(Expr, 0, H)), Call = {call,0,{atom,0,foo},[Lc]}, @@ -692,7 +661,7 @@ hook(Config) when is_list(Config) -> GChars2 = erl_pp:guard(G2), ?line true = GChars =:= lists:flatten(GChars2), - EH = {?MODULE, ehook, [foo,bar]}, + EH = HookFun({?MODULE, ehook, [foo,bar]}), XEChars = erl_pp:expr(Expr, -1, EH), ?line true = remove_indentation(EChars) =:= lists:flatten(XEChars), XEChars2 = erl_pp:expr(Expr, EH), @@ -1068,6 +1037,43 @@ otp_9147(Config) when is_list(Config) -> string:tokens(binary_to_list(Bin), "\n")), ok. +otp_10302(doc) -> + "OTP-10302. Unicode characters scanner/parser."; +otp_10302(suite) -> []; +otp_10302(Config) when is_list(Config) -> + Ts = [{uni_1, + <<"t() -> <<(<<\"abc\\x{aaa}\">>):3/binary>>.">>} + ], + compile(Config, Ts), + ok = pp_expr(<<"$\\x{aaa}">>), + ok = pp_expr(<<"\"1\\x{aaa}\"">>), + ok = pp_expr(<<"<<<<\"hej\">>/binary>>">>), + ok = pp_expr(<<"<< <<\"1\\x{aaa}\">>/binary>>">>), + + U = [{encoding,unicode}], + + do_hook(fun(H) -> [{hook,H}] end), + do_hook(fun(H) -> [{hook,H}]++U end), + + ok = pp_expr(<<"$\\x{aaa}">>, [{hook,fun hook/4}]), + + Opts = [{hook, fun unicode_hook/4},{encoding,unicode}], + Lc = parse_expr("[X || X <- [\"\x{400}\",\"\xFF\"]]."), + Expr = {call,0,{atom,0,fff},[{foo,{foo,Lc}},{foo,{foo,Lc}}]}, + EChars = lists:flatten(erl_pp:expr(Expr, 0, Opts)), + Call = {call,0,{atom,0,foo},[{call,0,{atom,0,foo},[Lc]}]}, + Expr2 = {call,0,{atom,0,fff},[Call,Call]}, + EChars2 = erl_pp:exprs([Expr2], U), + EChars = lists:flatten(EChars2), + [$\x{400},$\x{400}] = [C || C <- EChars, C > 255], + + ok = pp_forms(<<"function() -> {\"\x{400}\",$\x{400}}. "/utf8>>, U), + ok = pp_forms("function() -> {\"\x{400}\",$\x{400}}. ", []), + ok. + +unicode_hook({foo,E}, I, P, H) -> + erl_pp:expr({call,0,{atom,0,foo},[E]}, I, P, H). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% compile(Config, Tests) -> @@ -1137,9 +1143,11 @@ flat_expr(Expr) -> pp_forms(Bin) -> pp_forms(Bin, none). -pp_forms(Bin, Hook) -> - PP1 = (catch parse_and_pp_forms(binary_to_list(Bin), Hook)), - PP2 = (catch parse_and_pp_forms(PP1, Hook)), +pp_forms(Bin, Options) when is_binary(Bin) -> + pp_forms(to_list(Bin, Options), Options); +pp_forms(List, Options) when is_list(List) -> + PP1 = (catch parse_and_pp_forms(List, Options)), + PP2 = (catch parse_and_pp_forms(PP1, Options)), case PP1 =:= PP2 of % same line numbers true -> test_max_line(PP1); @@ -1147,8 +1155,8 @@ pp_forms(Bin, Hook) -> not_ok end. -parse_and_pp_forms(String, Hook) -> - lists:append(lists:map(fun(AF) -> erl_pp:form(AF, Hook) +parse_and_pp_forms(String, Options) -> + lists:append(lists:map(fun(AF) -> erl_pp:form(AF, Options) end, parse_forms(String))). parse_forms(Chars) -> @@ -1158,7 +1166,7 @@ parse_forms(Chars) -> parse_forms2([], _Cont, _Line, Forms) -> lists:reverse(Forms); parse_forms2(String, Cont0, Line, Forms) -> - case erl_scan:tokens(Cont0, String, Line) of + case erl_scan:tokens(Cont0, String, Line, [unicode]) of {done, {ok, Tokens, EndLine}, Chars} -> {ok, Form} = erl_parse:parse_form(Tokens), parse_forms2(Chars, [], EndLine, [Form | Forms]); @@ -1174,10 +1182,12 @@ pp_expr(Bin) -> pp_expr(Bin, none). %% Final dot is added. -pp_expr(Bin, Hook) -> - PP1 = (catch parse_and_pp_expr(binary_to_list(Bin), 0, Hook)), - PPneg = (catch parse_and_pp_expr(binary_to_list(Bin), -1, Hook)), - PP2 = (catch parse_and_pp_expr(PPneg, 0, Hook)), +pp_expr(Bin, Options) when is_binary(Bin) -> + pp_expr(to_list(Bin, Options), Options); +pp_expr(List, Options) when is_list(List) -> + PP1 = (catch parse_and_pp_expr(List, 0, Options)), + PPneg = (catch parse_and_pp_expr(List, -1, Options)), + PP2 = (catch parse_and_pp_expr(PPneg, 0, Options)), if PP1 =:= PP2 -> % same line numbers case @@ -1192,15 +1202,24 @@ pp_expr(Bin, Hook) -> not_ok end. -parse_and_pp_expr(String, Indent, Hook) -> +parse_and_pp_expr(String, Indent, Options) -> StringDot = lists:flatten(String) ++ ".", - erl_pp:expr(parse_expr(StringDot), Indent, Hook). + erl_pp:expr(parse_expr(StringDot), Indent, Options). parse_expr(Chars) -> - {ok, Tokens, _} = erl_scan:string(Chars), + {ok, Tokens, _} = erl_scan:string(Chars, 1, [unicode]), {ok, [Expr]} = erl_parse:parse_exprs(Tokens), Expr. +to_list(Bin, Options) when is_list(Options) -> + case proplists:get_value(encoding, Options) of + unicode -> unicode:characters_to_list(Bin); + encoding -> binary_to_list(Bin); + undefined -> binary_to_list(Bin) + end; +to_list(Bin, _Hook) -> + binary_to_list(Bin). + test_new_line(String) -> case string:chr(String, $\n) of 0 -> ok; diff --git a/lib/stdlib/test/erl_scan_SUITE.erl b/lib/stdlib/test/erl_scan_SUITE.erl index 4298b2c701..9a6b2f8f34 100644 --- a/lib/stdlib/test/erl_scan_SUITE.erl +++ b/lib/stdlib/test/erl_scan_SUITE.erl @@ -1,7 +1,8 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2011. All Rights Reserved. +%% Copyright Ericsson AB 1998-2012. 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 @@ -20,7 +21,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2]). --export([ error_1/1, error_2/1, iso88591/1, otp_7810/1]). +-export([ error_1/1, error_2/1, iso88591/1, otp_7810/1, otp_10302/1]). -import(lists, [nth/2,flatten/1]). -import(io_lib, [print/1]). @@ -59,7 +60,7 @@ end_per_testcase(_Case, Config) -> suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [{group, error}, iso88591, otp_7810]. + [{group, error}, iso88591, otp_7810, otp_10302]. groups() -> [{error, [], [error_1, error_2]}]. @@ -131,10 +132,10 @@ iso88591(Config) when is_list(Config) -> ?line ok = case catch begin %% Some atom and variable names - V1s = [$�,$�,$�,$�], - V2s = [$N,$�,$r], - A1s = [$h,$�,$r], - A2s = [$�,$r,$e], + V1s = [$Á,$á,$é,$ë], + V2s = [$N,$ä,$r], + A1s = [$h,$ä,$r], + A2s = [$ö,$r,$e], %% Test parsing atom and variable characters. {ok,Ts1,_} = erl_scan:string(V1s ++ " " ++ V2s ++ "\327" ++ @@ -196,7 +197,7 @@ otp_7810(Config) when is_list(Config) -> reserved_words() -> L = ['after', 'begin', 'case', 'try', 'cond', 'catch', 'andalso', 'orelse', 'end', 'fun', 'if', 'let', 'of', - 'query', 'receive', 'when', 'bnot', 'not', 'div', + 'receive', 'when', 'bnot', 'not', 'div', 'rem', 'band', 'and', 'bor', 'bxor', 'bsl', 'bsr', 'or', 'xor'], [begin @@ -214,8 +215,8 @@ atoms() -> ?line test_string("'a b'", [{atom,1,'a b'}]), ?line test_string("a", [{atom,1,a}]), ?line test_string("a@2", [{atom,1,a@2}]), - ?line test_string([39,65,200,39], [{atom,1,'A�'}]), - ?line test_string("�rlig �sten", [{atom,1,�rlig},{atom,1,�sten}]), + ?line test_string([39,65,200,39], [{atom,1,'AÈ'}]), + ?line test_string("ärlig östen", [{atom,1,ärlig},{atom,1,östen}]), ?line {ok,[{atom,_,'$a'}],{1,6}} = erl_scan:string("'$\\a'", {1,1}), ?line test("'$\\a'"), @@ -289,7 +290,7 @@ errors() -> ?line {error,{1,erl_scan,{string,$","str"}},1} = %" erl_scan:string("\"str"), %" ?line {error,{1,erl_scan,char},1} = erl_scan:string("$"), - ?line test_string([34,65,200,34], [{string,1,"A�"}]), + ?line test_string([34,65,200,34], [{string,1,"AÈ"}]), ?line test_string("\\", [{'\\',1}]), ?line {'EXIT',_} = (catch {foo, erl_scan:string('$\\a', {1,1})}), % type error @@ -354,7 +355,7 @@ dots() -> {".\n", {ok,[{dot,1}],2}}, {".%", {ok,[{dot,1}],1}}, {".\210",{ok,[{dot,1}],1}}, - {".% �h",{ok,[{dot,1}],1}}, + {".% öh",{ok,[{dot,1}],1}}, {".%\n", {ok,[{dot,1}],2}}, {".$", {error,{1,erl_scan,char},1}}, {".$\\", {error,{1,erl_scan,char},1}}, @@ -369,7 +370,7 @@ dots() -> ?line [{column,1},{length,1},{line,1},{text,"."}] = erl_scan:token_info(T2, [column, length, line, text]), ?line {ok,[{dot,_}=T3],{1,6}} = - erl_scan:string(".% �h", {1,1}, text), + erl_scan:string(".% öh", {1,1}, text), ?line [{column,1},{length,1},{line,1},{text,"."}] = erl_scan:token_info(T3, [column, length, line, text]), ?line {error,{{1,2},erl_scan,char},{1,3}} = @@ -472,11 +473,11 @@ chars() -> variables() -> - ?line test_string(" \237_Aou�eiy��", [{var,1,'_Aou�eiy��'}]), + ?line test_string(" \237_Aouåeiyäö", [{var,1,'_Aouåeiyäö'}]), ?line test_string("A_b_c@", [{var,1,'A_b_c@'}]), ?line test_string("V@2", [{var,1,'V@2'}]), - ?line test_string("ABD�", [{var,1,'ABD�'}]), - ?line test_string("�rlig �sten", [{var,1,'�rlig'},{var,1,'�sten'}]), + ?line test_string("ABDÀ", [{var,1,'ABDÀ'}]), + ?line test_string("Ärlig Östen", [{var,1,'Ärlig'},{var,1,'Östen'}]), ok. eof() -> @@ -823,7 +824,7 @@ unicode() -> ?line {ok,[{char,1,1}],1} = erl_scan:string([$$,$\\,$^,1089]), ?line {error,{1,erl_scan,Error},1} = erl_scan:string("\"qa\x{aaa}"), - ?line "unterminated string starting with \"qa\\x{AAA}\"" = + ?line "unterminated string starting with \"qa"++[2730]++"\"" = erl_scan:format_error(Error), ?line {error,{{1,1},erl_scan,_},{1,11}} = erl_scan:string("\"qa\\x{aaa}",{1,1}), @@ -887,9 +888,10 @@ unicode() -> {char,_,$d},{']',_}],{1,8}} = erl_scan:string(Str1, {1,1}), ?line test(Str1), Comment = "%% "++[1089], - ?line {ok,[{comment,1,[$%,$%,$\s,1089]}],1} = + %% Returned a comment In R15B03: + {error,{1,erl_scan,{illegal,character}},1} = erl_scan:string(Comment, 1, return), - ?line {ok,[{comment,_,[$%,$%,$\s,1089]}],{1,5}} = + {error,{{1,1},erl_scan,{illegal,character}},{1,5}} = erl_scan:string(Comment, {1,1}, return), ok. @@ -958,6 +960,182 @@ more_chars() -> erl_scan:string("$\\xg", {1,1}), ok. +otp_10302(doc) -> + "OTP-10302. Unicode characters scanner/parser."; +otp_10302(suite) -> + []; +otp_10302(Config) when is_list(Config) -> + %% From unicode(): + {error,{1,erl_scan,{illegal,atom}},1} = + erl_scan:string("'a"++[1089]++"b'", 1, unicode), + {error,{{1,1},erl_scan,{illegal,atom}},{1,12}} = + erl_scan:string("'qa\\x{aaa}'",{1,1},unicode), + + {ok,[{char,1,1089}],1} = erl_scan:string([$$,1089], 1, unicode), + {ok,[{char,1,1089}],1} = erl_scan:string([$$,$\\,1089],1,unicode), + + Qs = "$\\x{aaa}", + {ok,[{char,1,2730}],1} = erl_scan:string(Qs,1,unicode), + {ok,[Q2],{1,9}} = erl_scan:string(Qs,{1,1},[unicode,text]), + [{category,char},{column,1},{length,8}, + {line,1},{symbol,16#aaa},{text,Qs}] = + erl_scan:token_info(Q2), + + Tags = [category, column, length, line, symbol, text], + + U1 = "\"\\x{aaa}\"", + {ok,[T1],{1,10}} = erl_scan:string(U1, {1,1}, [unicode,text]), + [{category,string},{column,1},{length,9},{line,1}, + {symbol,[16#aaa]},{text,U1}] = erl_scan:token_info(T1, Tags), + + U2 = "\"\\x41\\x{fff}\\x42\"", + {ok,[{string,1,[65,4095,66]}],1} = erl_scan:string(U2, 1, unicode), + + U3 = "\"a\n\\x{fff}\n\"", + {ok,[{string,1,[97,10,4095,10]}],3} = erl_scan:string(U3, 1,unicode), + + U4 = "\"\\^\n\\x{aaa}\\^\n\"", + {ok,[{string,1,[10,2730,10]}],3} = erl_scan:string(U4, 1,[unicode]), + + Str1 = "\"ab" ++ [1089] ++ "cd\"", + {ok,[{string,1,[97,98,1089,99,100]}],1} = + erl_scan:string(Str1,1,unicode), + {ok,[{string,{1,1},[97,98,1089,99,100]}],{1,8}} = + erl_scan:string(Str1, {1,1},unicode), + + OK1 = 16#D800-1, + OK2 = 16#DFFF+1, + OK3 = 16#FFFE-1, + OK4 = 16#FFFF+1, + OKL = [OK1,OK2,OK3,OK4], + + Illegal1 = 16#D800, + Illegal2 = 16#DFFF, + Illegal3 = 16#FFFE, + Illegal4 = 16#FFFF, + IllegalL = [Illegal1,Illegal2,Illegal3,Illegal4], + + [{ok,[{comment,1,[$%,$%,$\s,OK]}],1} = + erl_scan:string("%% "++[OK], 1, [unicode,return]) || + OK <- OKL], + {ok,[{comment,_,[$%,$%,$\s,OK1]}],{1,5}} = + erl_scan:string("%% "++[OK1], {1,1}, [unicode,return]), + [{error,{1,erl_scan,{illegal,character}},1} = + erl_scan:string("%% "++[Illegal], 1, [unicode,return]) || + Illegal <- IllegalL], + {error,{{1,1},erl_scan,{illegal,character}},{1,5}} = + erl_scan:string("%% "++[Illegal1], {1,1}, [unicode,return]), + + [{ok,[],1} = erl_scan:string("%% "++[OK], 1, [unicode]) || + OK <- OKL], + {ok,[],{1,5}} = erl_scan:string("%% "++[OK1], {1,1}, [unicode]), + [{error,{1,erl_scan,{illegal,character}},1} = + erl_scan:string("%% "++[Illegal], 1, [unicode]) || + Illegal <- IllegalL], + {error,{{1,1},erl_scan,{illegal,character}},{1,5}} = + erl_scan:string("%% "++[Illegal1], {1,1}, [unicode]), + + [{ok,[{string,{1,1},[OK]}],{1,4}} = + erl_scan:string("\""++[OK]++"\"",{1,1},unicode) || + OK <- OKL], + [{error,{{1,2},erl_scan,{illegal,character}},{1,3}} = + erl_scan:string("\""++[OK]++"\"",{1,1},unicode) || + OK <- IllegalL], + + [{error,{{1,1},erl_scan,{illegal,character}},{1,2}} = + erl_scan:string([Illegal],{1,1},unicode) || + Illegal <- IllegalL], + + {ok,[{char,{1,1},OK1}],{1,3}} = + erl_scan:string([$$,OK1],{1,1},unicode), + {error,{{1,1},erl_scan,{illegal,character}},{1,2}} = + erl_scan:string([$$,Illegal1],{1,1},unicode), + + {ok,[{char,{1,1},OK1}],{1,4}} = + erl_scan:string([$$,$\\,OK1],{1,1},unicode), + {error,{{1,1},erl_scan,{illegal,character}},{1,4}} = + erl_scan:string([$$,$\\,Illegal1],{1,1},unicode), + + {ok,[{string,{1,1},[55295]}],{1,5}} = + erl_scan:string("\"\\"++[OK1]++"\"",{1,1},unicode), + {error,{{1,2},erl_scan,{illegal,character}},{1,4}} = + erl_scan:string("\"\\"++[Illegal1]++"\"",{1,1},unicode), + + {ok,[{char,{1,1},OK1}],{1,10}} = + erl_scan:string("$\\x{D7FF}",{1,1},unicode), + {error,{{1,1},erl_scan,{illegal,character}},{1,10}} = + erl_scan:string("$\\x{D800}",{1,1},unicode), + + %% Not erl_scan, but erl_parse. + {integer,0,1} = erl_parse:abstract(1), + Float = 3.14, {float,0,Float} = erl_parse:abstract(Float), + {nil,0} = erl_parse:abstract([]), + {bin,0, + [{bin_element,0,{integer,0,1},default,default}, + {bin_element,0,{integer,0,2},default,default}]} = + erl_parse:abstract(<<1,2>>), + {cons,0,{tuple,0,[{atom,0,a}]},{atom,0,b}} = + erl_parse:abstract([{a} | b]), + {string,0,"str"} = erl_parse:abstract("str"), + {cons,0, + {integer,0,$a}, + {cons,0,{integer,0,1024},{string,0,"c"}}} = + erl_parse:abstract("a"++[1024]++"c"), + + Line = 17, + {integer,Line,1} = erl_parse:abstract(1, Line), + Float = 3.14, {float,Line,Float} = erl_parse:abstract(Float, Line), + {nil,Line} = erl_parse:abstract([], Line), + {bin,Line, + [{bin_element,Line,{integer,Line,1},default,default}, + {bin_element,Line,{integer,Line,2},default,default}]} = + erl_parse:abstract(<<1,2>>, Line), + {cons,Line,{tuple,Line,[{atom,Line,a}]},{atom,Line,b}} = + erl_parse:abstract([{a} | b], Line), + {string,Line,"str"} = erl_parse:abstract("str", Line), + {cons,Line, + {integer,Line,$a}, + {cons,Line,{integer,Line,1024},{string,Line,"c"}}} = + erl_parse:abstract("a"++[1024]++"c", Line), + + Opts1 = [{line,17}], + {integer,Line,1} = erl_parse:abstract(1, Opts1), + Float = 3.14, {float,Line,Float} = erl_parse:abstract(Float, Opts1), + {nil,Line} = erl_parse:abstract([], Opts1), + {bin,Line, + [{bin_element,Line,{integer,Line,1},default,default}, + {bin_element,Line,{integer,Line,2},default,default}]} = + erl_parse:abstract(<<1,2>>, Opts1), + {cons,Line,{tuple,Line,[{atom,Line,a}]},{atom,Line,b}} = + erl_parse:abstract([{a} | b], Opts1), + {string,Line,"str"} = erl_parse:abstract("str", Opts1), + {cons,Line, + {integer,Line,$a}, + {cons,Line,{integer,Line,1024},{string,Line,"c"}}} = + erl_parse:abstract("a"++[1024]++"c", Opts1), + + [begin + {integer,Line,1} = erl_parse:abstract(1, Opts2), + Float = 3.14, {float,Line,Float} = erl_parse:abstract(Float, Opts2), + {nil,Line} = erl_parse:abstract([], Opts2), + {bin,Line, + [{bin_element,Line,{integer,Line,1},default,default}, + {bin_element,Line,{integer,Line,2},default,default}]} = + erl_parse:abstract(<<1,2>>, Opts2), + {cons,Line,{tuple,Line,[{atom,Line,a}]},{atom,Line,b}} = + erl_parse:abstract([{a} | b], Opts2), + {string,Line,"str"} = erl_parse:abstract("str", Opts2), + {string,Line,[97,1024,99]} = + erl_parse:abstract("a"++[1024]++"c", Opts2) + end || Opts2 <- [[{encoding,unicode},{line,Line}], + [{encoding,utf8},{line,Line}]]], + + {cons,0, + {integer,0,97}, + {cons,0,{integer,0,1024},{string,0,"c"}}} = + erl_parse:abstract("a"++[1024]++"c", [{encoding,latin1}]), + ok. + test_string(String, Expected) -> {ok, Expected, _End} = erl_scan:string(String), test(String). diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl index 5b592c65cc..3749d594f2 100644 --- a/lib/stdlib/test/escript_SUITE.erl +++ b/lib/stdlib/test/escript_SUITE.erl @@ -26,6 +26,7 @@ errors/1, strange_name/1, emulator_flags/1, + emulator_flags_no_shebang/1, module_script/1, beam_script/1, archive_script/1, @@ -34,7 +35,8 @@ create_and_extract/1, foldl/1, overflow/1, - verify_sections/3 + verify_sections/3, + unicode/1 ]). -include_lib("test_server/include/test_server.hrl"). @@ -44,9 +46,10 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [basic, errors, strange_name, emulator_flags, + emulator_flags_no_shebang, module_script, beam_script, archive_script, epp, create_and_extract, foldl, overflow, - archive_script_file_access]. + archive_script_file_access, unicode]. groups() -> []. @@ -149,6 +152,21 @@ emulator_flags(Config) when is_list(Config) -> ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +emulator_flags_no_shebang(Config) when is_list(Config) -> + Data = ?config(data_dir, Config), + Dir = filename:absname(Data), %Get rid of trailing slash. + %% Need run_with_opts, to always use "escript" explicitly + ?line run_with_opts(Dir, "", "emulator_flags_no_shebang -arg1 arg2 arg3", + [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n" + "nostick:[{nostick,[]}]\n" + "mnesia:[{mnesia,[\"dir\",\"a/directory\"]},{mnesia,[\"debug\",\"verbose\"]}]\n" + "ERL_FLAGS=false\n" + "unknown:[]\n" + "ExitCode:0">>]), + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Pick the source code from the emulator_flags script %% Generate a new escript with a module header @@ -810,6 +828,8 @@ normalize_sections(Sections) -> end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + foldl(Config) when is_list(Config) -> {NewFile, _FileInfo, _EmuArg, _Source, @@ -887,6 +907,20 @@ emulate_escript_foldl(Fun, Acc, File) -> {error, Reason} end. +unicode(Config) when is_list(Config) -> + Data = ?config(data_dir, Config), + Dir = filename:absname(Data), %Get rid of trailing slash. + run(Dir, "unicode1", + [<<"escript: exception error: an error occurred when evaluating" + " an arithmetic expression\n in operator '/'/2\n " + "called as <<170>> / <<170>>\nExitCode:127">>]), + run(Dir, "unicode2", + [<<"escript: exception error: an error occurred when evaluating" + " an arithmetic expression\n in operator '/'/2\n " + "called as <<\"\xaa\">> / <<\"\xaa\">>\nExitCode:127">>]), + run(Dir, "unicode3", [<<"ExitCode:0">>]), + ok. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% overflow(Config) when is_list(Config) -> diff --git a/lib/stdlib/test/escript_SUITE_data/emulator_flags_no_shebang b/lib/stdlib/test/escript_SUITE_data/emulator_flags_no_shebang new file mode 100644 index 0000000000..47d843ebe1 --- /dev/null +++ b/lib/stdlib/test/escript_SUITE_data/emulator_flags_no_shebang @@ -0,0 +1,10 @@ +%% -*- erlang -*- +%%! -nostick -mnesia dir a/directory -mnesia debug verbose + +main(MainArgs) -> + io:format("main:~p\n",[MainArgs]), + ErlArgs = init:get_arguments(), + io:format("nostick:~p\n",[[E || E <- ErlArgs, element(1, E) =:= nostick]]), + io:format("mnesia:~p\n", [[E || E <- ErlArgs, element(1, E) =:= mnesia]]), + io:format("ERL_FLAGS=~p\n", [os:getenv("ERL_FLAGS")]), + io:format("unknown:~p\n",[[E || E <- ErlArgs, element(1, E) =:= unknown]]). diff --git a/lib/stdlib/test/escript_SUITE_data/unicode1 b/lib/stdlib/test/escript_SUITE_data/unicode1 new file mode 100755 index 0000000000..a77574625e --- /dev/null +++ b/lib/stdlib/test/escript_SUITE_data/unicode1 @@ -0,0 +1,14 @@ +#!/usr/bin/env escript +%% -*- erlang -*- + +-export([main/1]). + +main(_) -> + ok = io:setopts([{encoding,unicode}]), + _D = erlang:system_flag(backtrace_depth, 0), + A = <<"\x{aa}">>, + S = lists:flatten(io_lib:format("~p/~p.", [A, A])), + {ok, Ts, _} = erl_scan:string(S, 1, [unicode]), + {ok, Es} = erl_parse:parse_exprs(Ts), + B = erl_eval:new_bindings(), + erl_eval:exprs(Es, B). diff --git a/lib/stdlib/test/escript_SUITE_data/unicode2 b/lib/stdlib/test/escript_SUITE_data/unicode2 new file mode 100755 index 0000000000..495188f6f0 --- /dev/null +++ b/lib/stdlib/test/escript_SUITE_data/unicode2 @@ -0,0 +1,14 @@ +#!/usr/bin/env escript +%% -*- erlang -*- + +-export([main/1]). + +main(_) -> + ok = io:setopts([{encoding,latin1}]), + _D = erlang:system_flag(backtrace_depth, 0), + A = <<"\x{aa}">>, + S = lists:flatten(io_lib:format("~p/~p.", [A, A])), + {ok, Ts, _} = erl_scan:string(S, 1, [unicode]), + {ok, Es} = erl_parse:parse_exprs(Ts), + B = erl_eval:new_bindings(), + erl_eval:exprs(Es, B). diff --git a/lib/stdlib/test/escript_SUITE_data/unicode3 b/lib/stdlib/test/escript_SUITE_data/unicode3 new file mode 100755 index 0000000000..944487dcae --- /dev/null +++ b/lib/stdlib/test/escript_SUITE_data/unicode3 @@ -0,0 +1,13 @@ +#!/usr/bin/env escript +%% -*- erlang; coding: utf-8 -*- + +-export([main/1]). + +main(_) -> + ok = io:setopts([{encoding,unicode}]), + Bin1 = <<"örn_Ѐ שלום-שלום+של 日本語">>, + + L = [246,114,110,95,1024,32,1513,1500,1493,1501,45,1513,1500,1493, + 1501,43,1513,1500,32,26085,26412,35486], + L = unicode:characters_to_list(Bin1, utf8), + ok. diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl index 74fcdcc7d2..521d7255ea 100644 --- a/lib/stdlib/test/io_SUITE.erl +++ b/lib/stdlib/test/io_SUITE.erl @@ -1,7 +1,8 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% Copyright Ericsson AB 1999-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 @@ -28,7 +29,7 @@ manpage/1, otp_6708/1, otp_7084/1, otp_7421/1, io_lib_collect_line_3_wb/1, cr_whitespace_in_string/1, io_fread_newlines/1, otp_8989/1, io_lib_fread_literal/1, - io_lib_print_binary_depth_one/1]). + io_lib_print_binary_depth_one/1, otp_10302/1]). %-define(debug, true). @@ -64,7 +65,7 @@ all() -> manpage, otp_6708, otp_7084, otp_7421, io_lib_collect_line_3_wb, cr_whitespace_in_string, io_fread_newlines, otp_8989, io_lib_fread_literal, - io_lib_print_binary_depth_one]. + io_lib_print_binary_depth_one, otp_10302]. groups() -> []. @@ -894,7 +895,7 @@ otp_6354(Config) when is_list(Config) -> ?line "\"\\b\\t\\n\\v\\f\\r\\e\250\"" = p([8,9,10,11,12,13,27,168], 1, 40, -1), % ?line "\"\\b\\t\\n\"\n \"\\v\\f\\r\"\n \"\\e\250\"" = - ?line "\"\\b\\t\\n\\v\\f\\r\\e�\"" = + ?line "\"\\b\\t\\n\\v\\f\\r\\e¨\"" = p([8,9,10,11,12,13,27,168], 1, 10, -1), ?line "\"\\b\\t\\n\\v\\f\\r\\e\250\"" = p([8,9,10,11,12,13,27,168], 1, 40, 100), @@ -2034,3 +2035,44 @@ io_lib_print_binary_depth_one(Suite) when is_list(Suite) -> ?line "<<...>>" = fmt("~W", [<<1:7>>, 1]), ?line "<<...>>" = fmt("~P", [<<1:7>>, 1]), ok. + +otp_10302(doc) -> + "OTP-10302. Unicode"; +otp_10302(Suite) when is_list(Suite) -> + "\"\x{400}\"" = pretty("\x{400}", -1), + "<<\"\x{400}\"/utf8>>" = pretty(<<"\x{400}"/utf8>>, -1), + + "<<\"\x{400}foo\"/utf8>>" = pretty(<<"\x{400}foo"/utf8>>, 2), + "<<\"äppl\"/utf8>>" = pretty(<<"äppl"/utf8>>, 2), + "<<\"äppl\"/utf8...>>" = pretty(<<"äpple"/utf8>>, 2), + "<<\"apel\">>" = pretty(<<"apel">>, 2), + "<<\"apel\"...>>" = pretty(<<"apelsin">>, 2), + "<<228,112,112,108>>" = fmt("~tp", [<<"äppl">>]), + "<<228,...>>" = fmt("~tP", [<<"äppl">>, 2]), + + Chars = lists:seq(0, 512), % just a few... + [] = [C || C <- Chars, S <- io_lib:write_unicode_char_as_latin1(C), + not is_latin1(S)], + L1 = [S || C <- Chars, S <- io_lib:write_unicode_char(C), + not is_latin1(S)], + L1 = lists:seq(256, 512), + + [] = [C || C <- Chars, S <- io_lib:write_unicode_string_as_latin1([C]), + not is_latin1(S)], + L2 = [S || C <- Chars, S <- io_lib:write_unicode_string([C]), + not is_latin1(S)], + L2 = lists:seq(256, 512), + + ok. + +pretty(Term, Depth) when is_integer(Depth) -> + Opts = [{column, 1}, {line_length, 20}, + {depth, Depth}, {max_chars, 60}, + {encoding, unicode}], + pretty(Term, Opts); +pretty(Term, Opts) when is_list(Opts) -> + R = io_lib_pretty:print(Term, Opts), + lists:flatten(io_lib:format("~ts", [R])). + +is_latin1(S) -> + S >= 0 andalso S =< 255. diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl index 17e69f7c1c..299daf0e42 100644 --- a/lib/stdlib/test/io_proto_SUITE.erl +++ b/lib/stdlib/test/io_proto_SUITE.erl @@ -736,7 +736,7 @@ binary_options(Config) when is_list(Config) -> {getline_re, ".*<<\"hej\\\\n\">>"}, {putline, "io:get_line('')."}, {putline, binary_to_list(<<"\345\344\366"/utf8>>)}, - {getline_re, ".*<<\""++binary_to_list(unicode:characters_to_binary(<<"\345\344\366"/utf8>>,latin1,utf8))++"\\\\n\">>"} + {getline_re, ".*<<\""++binary_to_list(<<"\345\344\366"/utf8>>)++"\\\\n\"/utf8>>"} ],[],[],"-oldshell"), ok. diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl index e3090e4a47..cac8309bd9 100644 --- a/lib/stdlib/test/qlc_SUITE.erl +++ b/lib/stdlib/test/qlc_SUITE.erl @@ -6062,21 +6062,6 @@ otp_6673(Config) when is_list(Config) -> ], ?line run(Config, Ts_RT), - %% Ulf Wiger provided a patch that makes QLC work with packages: - Dir = filename:join(?privdir, "p"), - ?line ok = filelib:ensure_dir(filename:join(Dir, ".")), - File = filename:join(Dir, "p.erl"), - ?line ok = file:write_file(File, - <<"-module(p.p).\n" - "-export([q/0]).\n" - "-include_lib(\"stdlib/include/qlc.hrl\").\n" - "q() ->\n" - " .qlc:q([X || X <- [1,2]]).">>), - ?line {ok, 'p.p'} = compile:file(File, [{outdir,Dir}]), - ?line code:purge('p.p'), - ?line {module, 'p.p'} = code:load_abs(filename:rootname(File), 'p.p'), - ?line [1,2] = qlc:e(p.p:q()), - ok. otp_6964(doc) -> diff --git a/lib/stdlib/test/re_SUITE.erl b/lib/stdlib/test/re_SUITE.erl index 8ee0a13f4c..500f5fadb9 100644 --- a/lib/stdlib/test/re_SUITE.erl +++ b/lib/stdlib/test/re_SUITE.erl @@ -1,3 +1,4 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% @@ -291,10 +292,10 @@ global_capture(Config) when is_list(Config) -> ?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]), + ?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), ok. @@ -314,17 +315,17 @@ replace_return(Config) when is_list(Config) -> Dog = ?t:timetrap(?t:minutes(3)), ?line {'EXIT',{badarg,_}} = (catch re:replace("na","(a","")), ?line <<"nasse">> = re:replace(<<"nisse">>,"i","a",[{return,binary}]), - ?line <<"ABC�XABCXA">> = re:replace("ABC\305abcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,binary}]), + ?line <<"ABCÅXABCXA">> = re:replace("ABC\305abcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,binary}]), - ?line [<<"ABC�">>, + ?line [<<"ABCÅ">>, <<"X">>, <<"ABC">>, <<"X">> | <<"A">> ] = - re:replace("ABC�abcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,iodata}]), - ?line "ABC�XABCXA" = re:replace("ABC�abcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,list},unicode]), - ?line <<65,66,67,195,133,88,65,66,67,88,65>> = re:replace("ABC�abcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,binary},unicode]), - ?line <<65,66,67,195,133,88,65,66,67,97,98,99,100,65>> = re:replace("ABC�abcdABCabcdA","a(?<FOO>bcd)","X",[{return,binary},unicode]), + re:replace("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,iodata}]), + ?line "ABCÅXABCXA" = re:replace("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,list},unicode]), + ?line <<65,66,67,195,133,88,65,66,67,88,65>> = re:replace("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[global,{return,binary},unicode]), + ?line <<65,66,67,195,133,88,65,66,67,97,98,99,100,65>> = re:replace("ABCÅabcdABCabcdA","a(?<FOO>bcd)","X",[{return,binary},unicode]), ?line <<"iXk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\9X",[{return,binary}]), ?line <<"jXk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\10X",[{return,binary}]), ?line <<"Xk">> = re:replace("abcdefghijk","(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)","\\11X",[{return,binary}]), diff --git a/lib/stdlib/test/re_testoutput1_replacement_test.erl b/lib/stdlib/test/re_testoutput1_replacement_test.erl index 69cb140e0d..8f8d8762ad 100644 --- a/lib/stdlib/test/re_testoutput1_replacement_test.erl +++ b/lib/stdlib/test/re_testoutput1_replacement_test.erl @@ -1,7 +1,8 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2012. 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 @@ -274,10 +275,10 @@ run() -> ?line <<"dthing">> = iolist_to_binary(re:replace("dthing","^[^]cde]","y\\1I&MoqRPG&GQa\\1l",[global])), ?line <<"ething">> = iolist_to_binary(re:replace("ething","^[^]cde]","AsxwUn\\1GqkWNdgRJk",[])), ?line <<"ething">> = iolist_to_binary(re:replace("ething","^[^]cde]","AsxwUn\\1GqkWNdgRJk",[global])), -?line <<"RornKmOnaFr�tWgtW">> = iolist_to_binary(re:replace("�","^\\�","R\\1o\\1r\\1nKmOnaFr&tWgtW",[])), -?line <<"RornKmOnaFr�tWgtW">> = iolist_to_binary(re:replace("�","^\\�","R\\1o\\1r\\1nKmOnaFr&tWgtW",[global])), -?line <<"ufbmbfOYuK�wf�E�dx">> = iolist_to_binary(re:replace("�","^�","ufbmbfOYuK&wf&E&\\1dx",[])), -?line <<"ufbmbfOYuK�wf�E�dx">> = iolist_to_binary(re:replace("�","^�","ufbmbfOYuK&wf&E&\\1dx",[global])), +?line <<"RornKmOnaFrtWgtW">> = iolist_to_binary(re:replace("","^\\","R\\1o\\1r\\1nKmOnaFr&tWgtW",[])), +?line <<"RornKmOnaFrtWgtW">> = iolist_to_binary(re:replace("","^\\","R\\1o\\1r\\1nKmOnaFr&tWgtW",[global])), +?line <<"ufbmbfOYuKÿwfÿEÿdx">> = iolist_to_binary(re:replace("ÿ","^ÿ","ufbmbfOYuK&wf&E&\\1dx",[])), +?line <<"ufbmbfOYuKÿwfÿEÿdx">> = iolist_to_binary(re:replace("ÿ","^ÿ","ufbmbfOYuK&wf&E&\\1dx",[global])), ?line <<"oAdJme0jw">> = iolist_to_binary(re:replace("0","^[0-9]+$","oAdJme\\1&jw",[])), ?line <<"oAdJme0jw">> = iolist_to_binary(re:replace("0","^[0-9]+$","oAdJme\\1&jw",[global])), ?line <<"1aoKN">> = iolist_to_binary(re:replace("1","^[0-9]+$","&aoKN",[])), @@ -14972,10 +14973,10 @@ def">> = iolist_to_binary(re:replace("abc def","abc$","M",[global])), ?line <<"abcWCabcSYXGPjRugTabcVGabcSX">> = iolist_to_binary(re:replace("abcS","(abc)\\123","\\1WC&YXGPjRugT\\1VG&X",[])), ?line <<"abcWCabcSYXGPjRugTabcVGabcSX">> = iolist_to_binary(re:replace("abcS","(abc)\\123","\\1WC&YXGPjRugT\\1VG&X",[global])), -?line <<"fabc�Uabc�UmiqabceCsabcabc�">> = iolist_to_binary(re:replace("abc�","(abc)\\223","f&U&Umiq\\1eCs\\1&",[])), -?line <<"fabc�Uabc�UmiqabceCsabcabc�">> = iolist_to_binary(re:replace("abc�","(abc)\\223","f&U&Umiq\\1eCs\\1&",[global])), -?line <<"JRFabcxnbabc�Vkabc�fWigQMuaY">> = iolist_to_binary(re:replace("abc�","(abc)\\323","JRF\\1xnb&Vk&fWigQMuaY",[])), -?line <<"JRFabcxnbabc�Vkabc�fWigQMuaY">> = iolist_to_binary(re:replace("abc�","(abc)\\323","JRF\\1xnb&Vk&fWigQMuaY",[global])), +?line <<"fabcUabcUmiqabceCsabcabc">> = iolist_to_binary(re:replace("abc","(abc)\\223","f&U&Umiq\\1eCs\\1&",[])), +?line <<"fabcUabcUmiqabceCsabcabc">> = iolist_to_binary(re:replace("abc","(abc)\\223","f&U&Umiq\\1eCs\\1&",[global])), +?line <<"JRFabcxnbabcÓVkabcÓfWigQMuaY">> = iolist_to_binary(re:replace("abcÓ","(abc)\\323","JRF\\1xnb&Vk&fWigQMuaY",[])), +?line <<"JRFabcxnbabcÓVkabcÓfWigQMuaY">> = iolist_to_binary(re:replace("abcÓ","(abc)\\323","JRF\\1xnb&Vk&fWigQMuaY",[global])), ?line <<"vgabc@QQ">> = iolist_to_binary(re:replace("abc@","(abc)\\100","vg&QQ",[])), ?line <<"vgabc@QQ">> = iolist_to_binary(re:replace("abc@","(abc)\\100","vg&QQ",[global])), ?line <<"abc@OkvNytabc@abcabc@a">> = iolist_to_binary(re:replace("abc@","(abc)\\100","&OkvNyt&\\1&a",[])), @@ -18343,24 +18344,24 @@ xb","(?!^)x","\\1tysI\\1v\\1BVwx\\1FOWG\\1&C",[multiline, ?line <<"cY">> = iolist_to_binary(re:replace("M","\\M","cY\\1",[global])), ?line <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b","yWOTIFhIX\\1H",[])), ?line <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(re:replace("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b","yWOTIFhIX\\1H",[global])), -?line <<"NREGularsRREGularWEYrVRr">> = iolist_to_binary(re:replace("REGular","(?i)reg(?:ul(?:[a�]|ae)r|ex)","N&\\1sR&WEYrVRr",[])), -?line <<"NREGularsRREGularWEYrVRr">> = iolist_to_binary(re:replace("REGular","(?i)reg(?:ul(?:[a�]|ae)r|ex)","N&\\1sR&WEYrVRr",[global])), -?line <<"G">> = iolist_to_binary(re:replace("regulaer","(?i)reg(?:ul(?:[a�]|ae)r|ex)","G",[])), -?line <<"G">> = iolist_to_binary(re:replace("regulaer","(?i)reg(?:ul(?:[a�]|ae)r|ex)","G",[global])), -?line <<"PSsXtwlmy">> = iolist_to_binary(re:replace("Regex","(?i)reg(?:ul(?:[a�]|ae)r|ex)","PSsXtwlmy",[])), -?line <<"PSsXtwlmy">> = iolist_to_binary(re:replace("Regex","(?i)reg(?:ul(?:[a�]|ae)r|ex)","PSsXtwlmy",[global])), -?line <<"regul�rmiYTi">> = iolist_to_binary(re:replace("regul�r","(?i)reg(?:ul(?:[a�]|ae)r|ex)","&miYTi\\1\\1",[])), -?line <<"regul�rmiYTi">> = iolist_to_binary(re:replace("regul�r","(?i)reg(?:ul(?:[a�]|ae)r|ex)","&miYTi\\1\\1",[global])), -?line <<"W�����rxh�����yUoaLOIegmSA">> = iolist_to_binary(re:replace("�����","����[�-��-�]+","W&rxh&yUoaL\\1OIegmS\\1A",[])), -?line <<"W�����rxh�����yUoaLOIegmSA">> = iolist_to_binary(re:replace("�����","����[�-��-�]+","W&rxh&yUoaL\\1OIegmS\\1A",[global])), -?line <<"F�����gnWPyHeh�����tXTQ">> = iolist_to_binary(re:replace("�����","����[�-��-�]+","F&gnWPyHe\\1h&tXTQ",[])), -?line <<"F�����gnWPyHeh�����tXTQ">> = iolist_to_binary(re:replace("�����","����[�-��-�]+","F&gnWPyHe\\1h&tXTQ",[global])), -?line <<"sHerHnAhAdx">> = iolist_to_binary(re:replace("�����","����[�-��-�]+","sHer\\1HnA\\1h\\1Adx",[])), -?line <<"sHerHnAhAdx">> = iolist_to_binary(re:replace("�����","����[�-��-�]+","sHer\\1HnA\\1h\\1Adx",[global])), -?line <<"trobAQoU�����n">> = iolist_to_binary(re:replace("�����","����[�-��-�]+","tr\\1obAQoU&n",[])), -?line <<"trobAQoU�����n">> = iolist_to_binary(re:replace("�����","����[�-��-�]+","tr\\1obAQoU&n",[global])), -?line <<"�XAZSd">> = iolist_to_binary(re:replace("�XAZXB","(?<=Z)X.","Sd",[])), -?line <<"�XAZSd">> = iolist_to_binary(re:replace("�XAZXB","(?<=Z)X.","Sd",[global])), +?line <<"NREGularsRREGularWEYrVRr">> = iolist_to_binary(re:replace("REGular","(?i)reg(?:ul(?:[aä]|ae)r|ex)","N&\\1sR&WEYrVRr",[])), +?line <<"NREGularsRREGularWEYrVRr">> = iolist_to_binary(re:replace("REGular","(?i)reg(?:ul(?:[aä]|ae)r|ex)","N&\\1sR&WEYrVRr",[global])), +?line <<"G">> = iolist_to_binary(re:replace("regulaer","(?i)reg(?:ul(?:[aä]|ae)r|ex)","G",[])), +?line <<"G">> = iolist_to_binary(re:replace("regulaer","(?i)reg(?:ul(?:[aä]|ae)r|ex)","G",[global])), +?line <<"PSsXtwlmy">> = iolist_to_binary(re:replace("Regex","(?i)reg(?:ul(?:[aä]|ae)r|ex)","PSsXtwlmy",[])), +?line <<"PSsXtwlmy">> = iolist_to_binary(re:replace("Regex","(?i)reg(?:ul(?:[aä]|ae)r|ex)","PSsXtwlmy",[global])), +?line <<"regulärmiYTi">> = iolist_to_binary(re:replace("regulär","(?i)reg(?:ul(?:[aä]|ae)r|ex)","&miYTi\\1\\1",[])), +?line <<"regulärmiYTi">> = iolist_to_binary(re:replace("regulär","(?i)reg(?:ul(?:[aä]|ae)r|ex)","&miYTi\\1\\1",[global])), +?line <<"WÅæåäàrxhÅæåäàyUoaLOIegmSA">> = iolist_to_binary(re:replace("Åæåäà","Åæåä[à-ÿÀ-ß]+","W&rxh&yUoaL\\1OIegmS\\1A",[])), +?line <<"WÅæåäàrxhÅæåäàyUoaLOIegmSA">> = iolist_to_binary(re:replace("Åæåäà","Åæåä[à-ÿÀ-ß]+","W&rxh&yUoaL\\1OIegmS\\1A",[global])), +?line <<"FÅæåäÿgnWPyHehÅæåäÿtXTQ">> = iolist_to_binary(re:replace("Åæåäÿ","Åæåä[à-ÿÀ-ß]+","F&gnWPyHe\\1h&tXTQ",[])), +?line <<"FÅæåäÿgnWPyHehÅæåäÿtXTQ">> = iolist_to_binary(re:replace("Åæåäÿ","Åæåä[à-ÿÀ-ß]+","F&gnWPyHe\\1h&tXTQ",[global])), +?line <<"sHerHnAhAdx">> = iolist_to_binary(re:replace("ÅæåäÀ","Åæåä[à-ÿÀ-ß]+","sHer\\1HnA\\1h\\1Adx",[])), +?line <<"sHerHnAhAdx">> = iolist_to_binary(re:replace("ÅæåäÀ","Åæåä[à-ÿÀ-ß]+","sHer\\1HnA\\1h\\1Adx",[global])), +?line <<"trobAQoUÅæåäßn">> = iolist_to_binary(re:replace("Åæåäß","Åæåä[à-ÿÀ-ß]+","tr\\1obAQoU&n",[])), +?line <<"trobAQoUÅæåäßn">> = iolist_to_binary(re:replace("Åæåäß","Åæåä[à-ÿÀ-ß]+","tr\\1obAQoU&n",[global])), +?line <<"XAZSd">> = iolist_to_binary(re:replace("XAZXB","(?<=Z)X.","Sd",[])), +?line <<"XAZSd">> = iolist_to_binary(re:replace("XAZXB","(?<=Z)X.","Sd",[global])), ?line <<"A">> = iolist_to_binary(re:replace("ab cd defg","ab cd (?x) de fg","\\1A\\1",[])), ?line <<"A">> = iolist_to_binary(re:replace("ab cd defg","ab cd (?x) de fg","\\1A\\1",[global])), ?line <<"fab cddefgLdtKCtPab cddefgxvVUHDah">> = iolist_to_binary(re:replace("ab cddefg","ab cd(?x) de fg","f&LdtKC\\1\\1tP&xvVUHDah",[])), diff --git a/lib/stdlib/test/re_testoutput1_split_test.erl b/lib/stdlib/test/re_testoutput1_split_test.erl index e86a04b008..4fc85b95c0 100644 --- a/lib/stdlib/test/re_testoutput1_split_test.erl +++ b/lib/stdlib/test/re_testoutput1_split_test.erl @@ -1,7 +1,8 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2010. All Rights Reserved. +%% Copyright Ericsson AB 2008-2012. 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 @@ -524,14 +525,14 @@ run() -> ?line <<"ething">> = iolist_to_binary(join(re:split("ething","^[^]cde]",[{parts, 2}]))), ?line <<"ething">> = iolist_to_binary(join(re:split("ething","^[^]cde]",[]))), -?line <<"">> = iolist_to_binary(join(re:split("�","^\\�",[trim]))), -?line <<":">> = iolist_to_binary(join(re:split("�","^\\�",[{parts, +?line <<"">> = iolist_to_binary(join(re:split("","^\\",[trim]))), +?line <<":">> = iolist_to_binary(join(re:split("","^\\",[{parts, 2}]))), -?line <<":">> = iolist_to_binary(join(re:split("�","^\\�",[]))), -?line <<"">> = iolist_to_binary(join(re:split("�","^�",[trim]))), -?line <<":">> = iolist_to_binary(join(re:split("�","^�",[{parts, +?line <<":">> = iolist_to_binary(join(re:split("","^\\",[]))), +?line <<"">> = iolist_to_binary(join(re:split("ÿ","^ÿ",[trim]))), +?line <<":">> = iolist_to_binary(join(re:split("ÿ","^ÿ",[{parts, 2}]))), -?line <<":">> = iolist_to_binary(join(re:split("�","^�",[]))), +?line <<":">> = iolist_to_binary(join(re:split("ÿ","^ÿ",[]))), ?line <<"">> = iolist_to_binary(join(re:split("0","^[0-9]+$",[trim]))), ?line <<":">> = iolist_to_binary(join(re:split("0","^[0-9]+$",[{parts, 2}]))), @@ -22879,14 +22880,14 @@ def","abc$",[]))), ?line <<":abc:">> = iolist_to_binary(join(re:split("abcS","(abc)\\123",[{parts, 2}]))), ?line <<":abc:">> = iolist_to_binary(join(re:split("abcS","(abc)\\123",[]))), -?line <<":abc">> = iolist_to_binary(join(re:split("abc�","(abc)\\223",[trim]))), -?line <<":abc:">> = iolist_to_binary(join(re:split("abc�","(abc)\\223",[{parts, +?line <<":abc">> = iolist_to_binary(join(re:split("abc","(abc)\\223",[trim]))), +?line <<":abc:">> = iolist_to_binary(join(re:split("abc","(abc)\\223",[{parts, 2}]))), -?line <<":abc:">> = iolist_to_binary(join(re:split("abc�","(abc)\\223",[]))), -?line <<":abc">> = iolist_to_binary(join(re:split("abc�","(abc)\\323",[trim]))), -?line <<":abc:">> = iolist_to_binary(join(re:split("abc�","(abc)\\323",[{parts, +?line <<":abc:">> = iolist_to_binary(join(re:split("abc","(abc)\\223",[]))), +?line <<":abc">> = iolist_to_binary(join(re:split("abcÓ","(abc)\\323",[trim]))), +?line <<":abc:">> = iolist_to_binary(join(re:split("abcÓ","(abc)\\323",[{parts, 2}]))), -?line <<":abc:">> = iolist_to_binary(join(re:split("abc�","(abc)\\323",[]))), +?line <<":abc:">> = iolist_to_binary(join(re:split("abcÓ","(abc)\\323",[]))), ?line <<":abc">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[trim]))), ?line <<":abc:">> = iolist_to_binary(join(re:split("abc@","(abc)\\100",[{parts, 2}]))), @@ -28929,42 +28930,42 @@ xb","(?!^)x",[multiline]))), ?line <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b",[{parts, 2}]))), ?line <<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">> = iolist_to_binary(join(re:split("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","(a+)*b",[]))), -?line <<"">> = iolist_to_binary(join(re:split("REGular","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[trim]))), -?line <<":">> = iolist_to_binary(join(re:split("REGular","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[{parts, +?line <<"">> = iolist_to_binary(join(re:split("REGular","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[trim]))), +?line <<":">> = iolist_to_binary(join(re:split("REGular","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[{parts, 2}]))), -?line <<":">> = iolist_to_binary(join(re:split("REGular","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[]))), -?line <<"">> = iolist_to_binary(join(re:split("regulaer","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[trim]))), -?line <<":">> = iolist_to_binary(join(re:split("regulaer","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[{parts, +?line <<":">> = iolist_to_binary(join(re:split("REGular","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[]))), +?line <<"">> = iolist_to_binary(join(re:split("regulaer","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[trim]))), +?line <<":">> = iolist_to_binary(join(re:split("regulaer","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[{parts, 2}]))), -?line <<":">> = iolist_to_binary(join(re:split("regulaer","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[]))), -?line <<"">> = iolist_to_binary(join(re:split("Regex","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[trim]))), -?line <<":">> = iolist_to_binary(join(re:split("Regex","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[{parts, +?line <<":">> = iolist_to_binary(join(re:split("regulaer","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[]))), +?line <<"">> = iolist_to_binary(join(re:split("Regex","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[trim]))), +?line <<":">> = iolist_to_binary(join(re:split("Regex","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[{parts, 2}]))), -?line <<":">> = iolist_to_binary(join(re:split("Regex","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[]))), -?line <<"">> = iolist_to_binary(join(re:split("regul�r","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[trim]))), -?line <<":">> = iolist_to_binary(join(re:split("regul�r","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[{parts, +?line <<":">> = iolist_to_binary(join(re:split("Regex","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[]))), +?line <<"">> = iolist_to_binary(join(re:split("regulär","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[trim]))), +?line <<":">> = iolist_to_binary(join(re:split("regulär","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[{parts, 2}]))), -?line <<":">> = iolist_to_binary(join(re:split("regul�r","(?i)reg(?:ul(?:[a�]|ae)r|ex)",[]))), -?line <<"">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[trim]))), -?line <<":">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[{parts, +?line <<":">> = iolist_to_binary(join(re:split("regulär","(?i)reg(?:ul(?:[aä]|ae)r|ex)",[]))), +?line <<"">> = iolist_to_binary(join(re:split("Åæåäà","Åæåä[à-ÿÀ-ß]+",[trim]))), +?line <<":">> = iolist_to_binary(join(re:split("Åæåäà","Åæåä[à-ÿÀ-ß]+",[{parts, 2}]))), -?line <<":">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[]))), -?line <<"">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[trim]))), -?line <<":">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[{parts, +?line <<":">> = iolist_to_binary(join(re:split("Åæåäà","Åæåä[à-ÿÀ-ß]+",[]))), +?line <<"">> = iolist_to_binary(join(re:split("Åæåäÿ","Åæåä[à-ÿÀ-ß]+",[trim]))), +?line <<":">> = iolist_to_binary(join(re:split("Åæåäÿ","Åæåä[à-ÿÀ-ß]+",[{parts, 2}]))), -?line <<":">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[]))), -?line <<"">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[trim]))), -?line <<":">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[{parts, +?line <<":">> = iolist_to_binary(join(re:split("Åæåäÿ","Åæåä[à-ÿÀ-ß]+",[]))), +?line <<"">> = iolist_to_binary(join(re:split("ÅæåäÀ","Åæåä[à-ÿÀ-ß]+",[trim]))), +?line <<":">> = iolist_to_binary(join(re:split("ÅæåäÀ","Åæåä[à-ÿÀ-ß]+",[{parts, 2}]))), -?line <<":">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[]))), -?line <<"">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[trim]))), -?line <<":">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[{parts, +?line <<":">> = iolist_to_binary(join(re:split("ÅæåäÀ","Åæåä[à-ÿÀ-ß]+",[]))), +?line <<"">> = iolist_to_binary(join(re:split("Åæåäß","Åæåä[à-ÿÀ-ß]+",[trim]))), +?line <<":">> = iolist_to_binary(join(re:split("Åæåäß","Åæåä[à-ÿÀ-ß]+",[{parts, 2}]))), -?line <<":">> = iolist_to_binary(join(re:split("�����","����[�-��-�]+",[]))), -?line <<"�XAZ">> = iolist_to_binary(join(re:split("�XAZXB","(?<=Z)X.",[trim]))), -?line <<"�XAZ:">> = iolist_to_binary(join(re:split("�XAZXB","(?<=Z)X.",[{parts, +?line <<":">> = iolist_to_binary(join(re:split("Åæåäß","Åæåä[à-ÿÀ-ß]+",[]))), +?line <<"XAZ">> = iolist_to_binary(join(re:split("XAZXB","(?<=Z)X.",[trim]))), +?line <<"XAZ:">> = iolist_to_binary(join(re:split("XAZXB","(?<=Z)X.",[{parts, 2}]))), -?line <<"�XAZ:">> = iolist_to_binary(join(re:split("�XAZXB","(?<=Z)X.",[]))), +?line <<"XAZ:">> = iolist_to_binary(join(re:split("XAZXB","(?<=Z)X.",[]))), ?line <<"">> = iolist_to_binary(join(re:split("ab cd defg","ab cd (?x) de fg",[trim]))), ?line <<":">> = iolist_to_binary(join(re:split("ab cd defg","ab cd (?x) de fg",[{parts, 2}]))), diff --git a/lib/stdlib/test/shell_SUITE.erl b/lib/stdlib/test/shell_SUITE.erl index d49416c150..f22df96697 100644 --- a/lib/stdlib/test/shell_SUITE.erl +++ b/lib/stdlib/test/shell_SUITE.erl @@ -28,8 +28,8 @@ refman_bit_syntax/1, progex_bit_syntax/1, progex_records/1, progex_lc/1, progex_funs/1, - otp_5990/1, otp_6166/1, otp_6554/1, otp_6785/1, - otp_7184/1, otp_7232/1, otp_8393/1]). + otp_5990/1, otp_6166/1, otp_6554/1, + otp_7184/1, otp_7232/1, otp_8393/1, otp_10302/1]). -export([ start_restricted_from_shell/1, start_restricted_on_command_line/1,restricted_local/1]). @@ -92,8 +92,8 @@ groups() -> [progex_bit_syntax, progex_records, progex_lc, progex_funs]}, {tickets, [], - [otp_5990, otp_6166, otp_6554, otp_6785, otp_7184, - otp_7232, otp_8393]}]. + [otp_5990, otp_6166, otp_6554, otp_7184, + otp_7232, otp_8393, otp_10302]}]. init_per_suite(Config) -> Config. @@ -108,7 +108,7 @@ end_per_group(_GroupName, Config) -> Config. --record(state, {bin, reply, leader}). +-record(state, {bin, reply, leader, unic = latin1}). start_restricted_from_shell(doc) -> @@ -374,15 +374,18 @@ records(Config) when is_list(Config) -> MS = ?MODULE_STRING, RR1 = "rr(" ++ MS ++ "). #state{}.", ?line "[state]\n" - "#state{bin = undefined,reply = undefined,leader = undefined}.\n" = + "#state{bin = undefined,reply = undefined,leader = undefined,\n" + " unic = latin1}.\n" = t(RR1), RR2 = "rr(" ++ MS ++ ",[state]). #state{}.", ?line "[state]\n" - "#state{bin = undefined,reply = undefined,leader = undefined}.\n" = + "#state{bin = undefined,reply = undefined,leader = undefined,\n" + " unic = latin1}.\n" = t(RR2), RR3 = "rr(" ++ MS ++ ",'_'). #state{}.", ?line "[state]\n" - "#state{bin = undefined,reply = undefined,leader = undefined}.\n" = + "#state{bin = undefined,reply = undefined,leader = undefined,\n" + " unic = latin1}.\n" = t(RR3), RR4 = "rr(" ++ MS ++ ", '_', {d,test1}).", ?line [[state]] = scan(RR4), @@ -2540,19 +2543,6 @@ otp_6554(Config) when is_list(Config) -> ok. -otp_6785(doc) -> - "OTP-6785. Parameterized modules."; -otp_6785(suite) -> []; -otp_6785(Config) when is_list(Config) -> - MFile = filename:join(?config(priv_dir, Config), "parameterized.erl"), - Contents = <<"-module(parameterized, [A]). " - "-export([test/0]). " - "test() -> A. ">>, - ?line ok = compile_file(Config, MFile, Contents, []), - ?line (parameterized:new(adsf)):test(), - file:delete(MFile), - ok. - otp_7184(doc) -> "OTP-7184. Propagate exit signals from dying evaluator process."; otp_7184(suite) -> []; @@ -2748,6 +2738,143 @@ prompt_err(B) -> S = string:strip(S2, both, $"), string:strip(S, right, $.). +otp_10302(doc) -> + "OTP-10302. Unicode."; +otp_10302(suite) -> []; +otp_10302(Config) when is_list(Config) -> + Test1 = + <<"begin + io:setopts([{encoding,utf8}]), + [1024] = \"\\x{400}\", + rd(rec, {a = \"\\x{400}\"}), + ok = rl(rec) + end.">>, + "-record(rec,{a = \"\x{400}\"}).\nok.\n" = t(Test1), + + Test3 = + <<"io:setopts([{encoding,utf8}]). + rd(rec, {a = \"\\x{400}\"}). + ok = rp(#rec{}).">>, + "ok.\nrec\n#rec{a = \"\x{400}\"}.\nok.\n" = t(Test3), + + Test4 = + <<"io:setopts([{encoding,utf8}]). + A = [1024] = \"\\x{400}\". + b(). + h().">>, + + "ok.\n\"\x{400}\"\nA = \"\x{400}\".\nok.\n" + "1: io:setopts([{encoding,utf8}])\n-> ok.\n" + "2: A = [1024] = \"\x{400}\"\n-> \"\x{400}\"\n" + "3: b()\n-> ok.\nok.\n" = t(Test4), + + Test5 = + <<"begin + io:setopts([{encoding,utf8}]), + results(0), + A = [1024] = \"\\x{400}\", + b(), + h() + end.">>, + "A = \"\x{400}\".\nok.\n" = t(Test5), + + %% One $" is "lost": + true = + "\x{400}\": command not found" =:= + prompt_err({<<"io:setopts([{encoding,utf8}]). v(\"\x{400}\")."/utf8>>, + unicode}), + + "ok.\ndefault\n* Bad prompt function: \"\x{400}\".\n" = + t({<<"io:setopts([{encoding,utf8}]). " + "shell:prompt_func(\"\x{400}\")."/utf8>>, + unicode}), + _ = shell:prompt_func(default), + + %% Test lib:format_exception() (cf. OTP-6554) + Test6 = + <<"begin + A = <<\"\\xaa\">>, + S = lists:flatten(io_lib:format(\"~p/~p.\", [A, A])), + {ok, Ts, _} = erl_scan:string(S, 1, [unicode]), + {ok, Es} = erl_parse:parse_exprs(Ts), + B = erl_eval:new_bindings(), + erl_eval:exprs(Es, B) + end.">>, + + "** exception error: an error occurred when evaluating" + " an arithmetic expression\n in operator '/'/2\n" + " called as <<\"\xaa\">> / <<\"\xaa\">>.\n" = t(Test6), + Test7 = + <<"io:setopts([{encoding,utf8}]). + A = <<\"\\xaa\">>, + S = lists:flatten(io_lib:format(\"~p/~p.\", [A, A])), + {ok, Ts, _} = erl_scan:string(S, 1, [unicode]), + {ok, Es} = erl_parse:parse_exprs(Ts), + B = erl_eval:new_bindings(), + erl_eval:exprs(Es, B).">>, + + "ok.\n** exception error: an error occurred when evaluating" + " an arithmetic expression\n in operator '/'/2\n" + " called as <<170>> / <<170>>.\n" = t(Test7), + Test8 = + <<"begin + A = [1089], + S = lists:flatten(io_lib:format(\"~tp/~tp.\", [A, A])), + {ok, Ts, _} = erl_scan:string(S, 1, [unicode]), + {ok, Es} = erl_parse:parse_exprs(Ts), + B = erl_eval:new_bindings(), + erl_eval:exprs(Es, B) + end.">>, + "** exception error: an error occurred when evaluating" + " an arithmetic expression\n in operator '/'/2\n" + " called as [1089] / [1089].\n" = t(Test8), + Test9 = + <<"io:setopts([{encoding,utf8}]). + A = [1089], + S = lists:flatten(io_lib:format(\"~tp/~tp.\", [A, A])), + {ok, Ts, _} = erl_scan:string(S, 1, [unicode]), + {ok, Es} = erl_parse:parse_exprs(Ts), + B = erl_eval:new_bindings(), + erl_eval:exprs(Es, B).">>, + + "ok.\n** exception error: an error occurred when evaluating" + " an arithmetic expression\n in operator '/'/2\n" + " called as \"\x{441}\" / \"\x{441}\".\n" = t(Test9), + Test10 = + <<"A = {\"1\\xaa\", + $\\xaa, + << <<\"hi\">>/binary >>, + <<\"1\xaa\">>}, + fun(a) -> true end(A).">>, + "** exception error: no function clause matching \n" + " erl_eval:'-inside-an-interpreted-fun-'" + "({\"1\xc2\xaa\",170,<<\"hi\">>,\n " + " <<\"1\xc2\xaa\">>}) .\n" = t(Test10), + Test11 = + <<"io:setopts([{encoding,utf8}]). + A = {\"1\\xaa\", + $\\xaa, + << <<\"hi\">>/binary >>, + <<\"1\xaa\">>}, + fun(a) -> true end(A).">>, + + "ok.\n** exception error: no function clause matching \n" + " erl_eval:'-inside-an-interpreted-fun-'" + "({\"1\xaa\",170,<<\"hi\">>,\n " + " <<\"1\xaa\"/utf8>>}) .\n" = t(Test11), + Test12 = <<"fun(a, b) -> false end(65, [1089]).">>, + "** exception error: no function clause matching \n" + " erl_eval:'-inside-an-interpreted-fun-'(65,[1089])" + " .\n" = t(Test12), + Test13 = + <<"io:setopts([{encoding,utf8}]). + fun(a, b) -> false end(65, [1089]).">>, + "ok.\n** exception error: no function clause matching \n" + " erl_eval:'-inside-an-interpreted-fun-'(65,\"\x{441}\")" + " .\n" = t(Test13), + + ok. + scan(B) -> F = fun(Ts) -> case erl_parse:parse_term(Ts) of @@ -2761,7 +2888,7 @@ scan(B) -> scan(t(B), F). scan(S0, F) -> - case erl_scan:tokens([], S0, 1) of + case erl_scan:tokens([], S0, 1, [unicode]) of {done,{ok,Ts,_},S} -> [F(Ts) | scan(S, F)]; _Else -> @@ -2769,29 +2896,36 @@ scan(S0, F) -> end. t({Node,Bin}) when is_atom(Node),is_binary(Bin) -> - t0(Bin, fun() -> start_new_shell(Node) end); + t0({Bin,latin1}, fun() -> start_new_shell(Node) end); t(Bin) when is_binary(Bin) -> - t0(Bin, fun() -> start_new_shell() end); + t0({Bin,latin1}, fun() -> start_new_shell() end); +t({Bin,Enc}) when is_binary(Bin), is_atom(Enc) -> + t0({Bin,Enc}, fun() -> start_new_shell() end); t(L) -> t(list_to_binary(L)). -t0(Bin, F) -> +t0({Bin,Enc}, F) -> %% Spawn a process so that io_request messages do not interfer. P = self(), - C = spawn(fun() -> t1(P, Bin, F) end), + C = spawn(fun() -> t1(P, {Bin, Enc}, F) end), receive {C, R} -> R end. -t1(Parent, Bin, F) -> - %% io:format("*** Testing ~s~n", [binary_to_list(Bin)]), - S = #state{bin = Bin, reply = [], leader = group_leader()}, +t1(Parent, {Bin,Enc}, F) -> + io:format("*** Testing ~s~n", [binary_to_list(Bin)]), + S = #state{bin = Bin, unic = Enc, reply = [], leader = group_leader()}, group_leader(self(), self()), _Shell = F(), try server_loop(S) catch exit:R -> Parent ! {self(), R}; - throw:{?MODULE,LoopReply} -> + throw:{?MODULE,LoopReply,latin1} -> L0 = binary_to_list(list_to_binary(LoopReply)), [$\n | L1] = lists:dropwhile(fun(X) -> X =/= $\n end, L0), + Parent ! {self(), dotify(L1)}; + throw:{?MODULE,LoopReply,_Uni} -> + Tmp = unicode:characters_to_binary(LoopReply), + L0 = unicode:characters_to_list(Tmp), + [$\n | L1] = lists:dropwhile(fun(X) -> X =/= $\n end, L0), Parent ! {self(), dotify(L1)} after group_leader(S#state.leader, self()) end. @@ -2835,7 +2969,7 @@ do_io_request(Req, From, S, ReplyAs) -> case io_requests([Req], [], S) of {_Status,{eof,_},S1} -> io_reply(From, ReplyAs, {error,terminated}), - throw({?MODULE,S1#state.reply}); + throw({?MODULE,S1#state.reply,S1#state.unic}); {_Status,Reply,S1} -> io_reply(From, ReplyAs, Reply), S1 @@ -2858,13 +2992,34 @@ io_requests([], [Rs|Cont], S) -> io_requests([], [], S) -> {ok,ok,S}. +io_request({setopts, Opts}, S) -> + #state{unic = OldEnc, bin = Bin} = S, + NewEnc = case proplists:get_value(encoding, Opts) of + undefined -> OldEnc; + utf8 -> unicode; + New -> New + end, + NewBin = case {OldEnc, NewEnc} of + {E, E} -> Bin; + {latin1, _} -> + unicode:characters_to_binary(Bin, latin1, unicode); + {_, latin1} -> + unicode:characters_to_binary(Bin, unicode, latin1); + {_, _} -> Bin + end, + {ok, ok, S#state{unic = NewEnc, bin = NewBin}}; +io_request(getopts, S) -> + {ok,[{encoding,S#state.unic}],S}; io_request({get_geometry,columns}, S) -> {ok,80,S}; io_request({get_geometry,rows}, S) -> {ok,24,S}; io_request({put_chars,Chars}, S) -> {ok,ok,S#state{reply = [S#state.reply | Chars]}}; -io_request({put_chars,_,Chars}, S) -> +io_request({put_chars,latin1,Chars}, S) -> + {ok,ok,S#state{reply = [S#state.reply | Chars]}}; +io_request({put_chars,unicode,Chars0}, S) -> + Chars = unicode:characters_to_list(Chars0), {ok,ok,S#state{reply = [S#state.reply | Chars]}}; io_request({put_chars,Mod,Func,Args}, S) -> case catch apply(Mod, Func, Args) of @@ -2890,9 +3045,12 @@ get_until_loop(M, F, As, S, {more,Cont}, Enc) -> 0 -> get_until_loop(M, F, As, S, catch apply(M, F, [Cont,eof|As]), Enc); + _ when S#state.unic =:= latin1 -> + get_until_loop(M, F, As, S#state{bin = <<>>}, + catch apply(M, F, [Cont,binary_to_list(Bin)|As]), Enc); _ -> get_until_loop(M, F, As, S#state{bin = <<>>}, - catch apply(M, F, [Cont,binary_to_list(Bin)|As]), Enc) + catch apply(M, F, [Cont,unicode:characters_to_list(Bin)|As]), Enc) end; get_until_loop(_M, _F, _As, S, {done,Res,Buf}, Enc) -> {ok,Res,S#state{bin = buf2bin(Buf, Enc)}}; @@ -2903,6 +3061,8 @@ buf2bin(eof,_) -> <<>>; buf2bin(Buf,latin1) -> list_to_binary(Buf); +buf2bin(Buf,utf8) -> + unicode:characters_to_binary(Buf,unicode,unicode); buf2bin(Buf,unicode) -> unicode:characters_to_binary(Buf,unicode,unicode). diff --git a/lib/stdlib/test/string_SUITE.erl b/lib/stdlib/test/string_SUITE.erl index 6969c095a0..96e653985f 100644 --- a/lib/stdlib/test/string_SUITE.erl +++ b/lib/stdlib/test/string_SUITE.erl @@ -1,7 +1,8 @@ +%% -*- coding: utf-8 -*- %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% Copyright Ericsson AB 2004-2012. 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 @@ -473,8 +474,8 @@ to_upper_to_lower(suite) -> to_upper_to_lower(doc) -> []; to_upper_to_lower(Config) when is_list(Config) -> - ?line "1234ABCDEF���=" = string:to_upper("1234abcdef���="), - ?line "����������abc()" = string:to_lower("����������abc()"), + ?line "1234ABCDEFÅÄÖ=" = string:to_upper("1234abcdefåäö="), + ?line "éèíúùòóåäöabc()" = string:to_lower("ÉÈÍÚÙÒÓÅÄÖabc()"), ?line All = lists:seq(0, 255), ?line UC = string:to_upper(All), |