diff options
32 files changed, 367 insertions, 214 deletions
diff --git a/bootstrap/lib/compiler/ebin/cerl_inline.beam b/bootstrap/lib/compiler/ebin/cerl_inline.beam Binary files differindex 0d7a4c0e87..3fa8c7d69f 100644 --- a/bootstrap/lib/compiler/ebin/cerl_inline.beam +++ b/bootstrap/lib/compiler/ebin/cerl_inline.beam diff --git a/bootstrap/lib/compiler/ebin/v3_core.beam b/bootstrap/lib/compiler/ebin/v3_core.beam Binary files differindex 7e2960fda2..7410397300 100644 --- a/bootstrap/lib/compiler/ebin/v3_core.beam +++ b/bootstrap/lib/compiler/ebin/v3_core.beam diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index ff237b6a78..755c5e6882 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -3934,7 +3934,7 @@ BIF_RETTYPE halt_2(BIF_ALIST_2) { Sint code; Eterm optlist = BIF_ARG_2; - int flush = 0; + int flush = 1; for (optlist = BIF_ARG_2; is_list(optlist); diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c index 53c779b1be..b69e31f784 100644 --- a/erts/etc/unix/run_erl.c +++ b/erts/etc/unix/run_erl.c @@ -1142,6 +1142,14 @@ static void daemon_init(void) sf_close(i); } + /* Necessary on some platforms */ + + open("/dev/null", O_RDONLY); /* Order is important! */ + open("/dev/null", O_WRONLY); + open("/dev/null", O_WRONLY); + + errno = 0; /* if set by open */ + OPEN_SYSLOG(); run_daemon = 1; } diff --git a/erts/include/internal/gcc/ethread.h b/erts/include/internal/gcc/ethread.h index fcfdc39441..365a3535cf 100644 --- a/erts/include/internal/gcc/ethread.h +++ b/erts/include/internal/gcc/ethread.h @@ -25,6 +25,9 @@ #ifndef ETHREAD_GCC_H__ #define ETHREAD_GCC_H__ +#if defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32) \ + || defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64) + #ifndef ETHR_MEMBAR # include "ethr_membar.h" #endif @@ -46,3 +49,5 @@ #endif #endif + +#endif diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl index f5355bfefe..bd37b690b6 100644 --- a/lib/common_test/src/ct_logs.erl +++ b/lib/common_test/src/ct_logs.erl @@ -446,6 +446,8 @@ tc_print(Category,Importance,Format,Args) -> ct_util:get_verbosity('$unspecified'); {error,bad_invocation} -> ?MAX_VERBOSITY; + {error,_Failure} -> + ?MAX_VERBOSITY; Val -> Val end, @@ -690,14 +692,15 @@ logger_loop(State) -> false -> %% Group leader is dead, so write to the %% CtLog or unexpected_io log instead - unexpected_io(Pid,Category,List,State), + unexpected_io(Pid,Category,Importance, + List,State), logger_loop(State) end; {ct_log,_Fd,TCGLs} -> %% If category is ct_internal then write %% to ct_log, else write to unexpected_io %% log - unexpected_io(Pid,Category,List,State), + unexpected_io(Pid,Category,Importance,List,State), logger_loop(State#logger_state{ tc_groupleaders = TCGLs}) end; @@ -798,7 +801,7 @@ print_to_log(sync, FromPid, Category, TCGL, List, State) -> IoFun = create_io_fun(FromPid, State), io:format(TCGL,"~ts", [lists:foldl(IoFun, [], List)]); true -> - unexpected_io(FromPid,Category,List,State) + unexpected_io(FromPid,Category,?MAX_IMPORTANCE,List,State) end, State; @@ -814,7 +817,8 @@ print_to_log(async, FromPid, Category, TCGL, List, State) -> end; true -> fun() -> - unexpected_io(FromPid,Category,List,State) + unexpected_io(FromPid,Category,?MAX_IMPORTANCE, + List,State) end end, case State#logger_state.async_print_jobs of @@ -3066,10 +3070,20 @@ html_encoding(latin1) -> html_encoding(utf8) -> "utf-8". -unexpected_io(Pid,ct_internal,List,#logger_state{ct_log_fd=Fd}=State) -> +unexpected_io(Pid,ct_internal,_Importance,List,State) -> IoFun = create_io_fun(Pid,State), - io:format(Fd, "~ts", [lists:foldl(IoFun, [], List)]); -unexpected_io(Pid,_Category,List,State) -> + io:format(State#logger_state.ct_log_fd, "~ts", + [lists:foldl(IoFun, [], List)]); +unexpected_io(Pid,Category,Importance,List,State) -> IoFun = create_io_fun(Pid,State), Data = io_lib:format("~ts", [lists:foldl(IoFun, [], List)]), - test_server_io:print_unexpected(Data). + %% if unexpected io comes in during startup or shutdown, test_server + %% might not be running - if so (noproc exit), simply print to + %% stdout instead (will result in double printouts when pal is used) + try test_server_io:print_unexpected(Data) of + _ -> + ok + catch + _:{noproc,_} -> tc_print(Category,Importance,Data,[]); + _:Reason -> exit(Reason) + end. diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl index 68e76c2396..abda87c2cd 100644 --- a/lib/common_test/src/ct_util.erl +++ b/lib/common_test/src/ct_util.erl @@ -286,14 +286,23 @@ get_start_dir() -> %% handle verbosity outside ct_util_server (let the client read %% the verbosity table) to avoid possible deadlock situations set_verbosity(Elem = {_Category,_Level}) -> - ets:insert(?verbosity_table, Elem), - ok. + try ets:insert(?verbosity_table, Elem) of + _ -> + ok + catch + _:Reason -> + {error,Reason} + end. + get_verbosity(Category) -> - case ets:lookup(?verbosity_table, Category) of + try ets:lookup(?verbosity_table, Category) of [{Category,Level}] -> Level; _ -> undefined + catch + _:Reason -> + {error,Reason} end. loop(Mode,TestData,StartDir) -> diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl index 6bcac12326..4132995bf6 100644 --- a/lib/common_test/test/ct_test_support.erl +++ b/lib/common_test/test/ct_test_support.erl @@ -36,6 +36,8 @@ verify_events/3, verify_events/4, reformat/2, log_events/4, join_abs_dirs/2]). +-export([start_slave/3, slave_stop/1]). + -export([ct_test_halt/1]). -include_lib("kernel/include/file.hrl"). @@ -66,10 +68,14 @@ init_per_suite(Config, Level) -> start_slave(Config, Level). -start_slave(Config,Level) -> +start_slave(Config, Level) -> + start_slave(ct, Config, Level). + +start_slave(NodeName, Config, Level) -> [_,Host] = string:tokens(atom_to_list(node()), "@"), - test_server:format(0, "Trying to start ~s~n", ["ct@"++Host]), - case slave:start(Host, ct, []) of + test_server:format(0, "Trying to start ~s~n", + [atom_to_list(NodeName)++"@"++Host]), + case slave:start(Host, NodeName, []) of {error,Reason} -> test_server:fail(Reason); {ok,CTNode} -> @@ -77,7 +83,7 @@ start_slave(Config,Level) -> IsCover = test_server:is_cover(), if IsCover -> cover:start(CTNode); - true-> + true -> ok end, diff --git a/lib/common_test/test/ct_verbosity_SUITE.erl b/lib/common_test/test/ct_verbosity_SUITE.erl index 32488b1db9..1aa71953ec 100644 --- a/lib/common_test/test/ct_verbosity_SUITE.erl +++ b/lib/common_test/test/ct_verbosity_SUITE.erl @@ -53,9 +53,19 @@ init_per_suite(Config) -> end_per_suite(Config) -> ct_test_support:end_per_suite(Config). +init_per_testcase(no_crashing, Config) -> + Opts = ct_test_support:start_slave(ctX, Config, 50), + XNode = proplists:get_value(ct_node, Opts), + ct:pal("Node ~p started!", [XNode]), + [{xnode,XNode} | Config]; init_per_testcase(TestCase, Config) -> ct_test_support:init_per_testcase(TestCase, Config). +end_per_testcase(no_crashing, Config) -> + XNode = proplists:get_value(xnode, Config), + ct_test_support:slave_stop(XNode), + ct:pal("Node ~p stopped!", [XNode]), + ok; end_per_testcase(TestCase, Config) -> ct_test_support:end_per_testcase(TestCase, Config). @@ -72,7 +82,8 @@ all() -> combine_categories, testspec_only, merge_with_testspec, - possible_deadlock + possible_deadlock, + no_crashing ]. %%-------------------------------------------------------------------- @@ -189,6 +200,19 @@ possible_deadlock(Config) -> %%%----------------------------------------------------------------- +%%% +no_crashing(Config) -> + XNode = proplists:get_value(xnode, Config), + ok = rpc:call(XNode, ct, print, ["hello",[]]), + ok = rpc:call(XNode, ct, pal, ["hello",[]]), + ok = rpc:call(XNode, ct, log, ["hello",[]]), + Data = io_lib:format("hello", []), + {badrpc,{'EXIT',{noproc,_}}} = + (catch rpc:call(XNode, test_server_io, print_unexpected, [Data])), + ok. + + +%%%----------------------------------------------------------------- %%% HELP FUNCTIONS %%%----------------------------------------------------------------- diff --git a/lib/compiler/src/cerl_inline.erl b/lib/compiler/src/cerl_inline.erl index 2e7554c1ff..c6de63c69f 100644 --- a/lib/compiler/src/cerl_inline.erl +++ b/lib/compiler/src/cerl_inline.erl @@ -52,7 +52,7 @@ clause_pats/1, clause_vars/1, concrete/1, cons_hd/1, cons_tl/1, data_arity/1, data_es/1, data_type/1, fun_body/1, fun_vars/1, get_ann/1, int_val/1, - is_c_atom/1, is_c_cons/1, is_c_fun/1, is_c_int/1, + is_c_atom/1, is_c_cons/1, is_c_fname/1, is_c_int/1, is_c_list/1, is_c_seq/1, is_c_tuple/1, is_c_var/1, is_data/1, is_literal/1, is_literal_term/1, let_arg/1, let_body/1, let_vars/1, letrec_body/1, letrec_defs/1, @@ -1578,7 +1578,7 @@ make_let_binding_1(R, E, S) -> %% completely. copy(R, Opnd, E, Ctxt, Env, S) -> - case is_c_var(E) of + case is_c_var(E) andalso not is_c_fname(E) of true -> %% The operand reduces to another variable - get its %% ref-structure and attempt to propagate further. @@ -1628,12 +1628,12 @@ copy_var(R, Ctxt, Env, S) -> end. copy_1(R, Opnd, E, Ctxt, Env, S) -> - %% Fun-expression (lambdas) are a bit special; they are copyable, - %% but should preferably not be duplicated, so they should not be - %% copy propagated except into application contexts, where they can - %% be inlined. - case is_c_fun(E) of - true -> + case type(E) of + 'fun' -> + %% Fun-expression (lambdas) are a bit special; they are copyable, + %% but should preferably not be duplicated, so they should not be + %% copy propagated except into application contexts, where they can + %% be inlined. case Ctxt of #app{} -> %% First test if the operand is "outer-pending"; if @@ -1649,7 +1649,28 @@ copy_1(R, Opnd, E, Ctxt, Env, S) -> _ -> residualize_var(R, S) end; - false -> + var -> + %% Variables at this point only refer to local functions; they are + %% copyable but can't appear in guards, so they should not be + %% copy propagated except into application contexts, where they can + %% be inlined. + case Ctxt of + #app{} -> + %% First test if the operand is "outer-pending"; if + %% so, don't inline. + case st__test_outer_pending(Opnd#opnd.loc, S) of + false -> + R1 = env__get(var_name(E), Opnd#opnd.env), + copy_var(R1, Ctxt, Env, S); + true -> + %% Cyclic reference forced inlining to stop + %% (avoiding infinite unfolding). + residualize_var(R, S) + end; + _ -> + residualize_var(R, S) + end; + _ -> %% We have no other cases to handle here residualize_var(R, S) end. diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index d6fdcb2b21..1195937d91 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -956,7 +956,8 @@ lc_tq(Line, E, [Fil0|Qs0], Mc, St0) -> args=[], clauses=[#iclause{anno=LAnno,pats=[], guard=Gs,body=Lps ++ [Lc]}], - fc=#iclause{anno=LAnno,pats=[],guard=[],body=[Mc]}}, + fc=#iclause{anno=LAnno#a{anno=[compiler_generated|LA]}, + pats=[],guard=[],body=[Mc]}}, [],St2}; false -> {Lc,Lps,St1} = lc_tq(Line, E, Qs0, Mc, St0), @@ -1101,7 +1102,8 @@ bc_tq1(Line, E, [Fil0|Qs0], AccVar, St0) -> clauses=[#iclause{anno=LAnno, pats=[], guard=Gs,body=Bps ++ [Bc]}], - fc=#iclause{anno=LAnno,pats=[],guard=[],body=[AccVar]}}, + fc=#iclause{anno=LAnno#a{anno=[compiler_generated|LA]}, + pats=[],guard=[],body=[AccVar]}}, [],St}; false -> {Bc,Bps,St1} = bc_tq1(Line, E, Qs0, AccVar, St0), diff --git a/lib/compiler/test/inline_SUITE.erl b/lib/compiler/test/inline_SUITE.erl index d9b92766e4..e5c2d4f73a 100644 --- a/lib/compiler/test/inline_SUITE.erl +++ b/lib/compiler/test/inline_SUITE.erl @@ -36,7 +36,7 @@ all() -> groups() -> [{p,test_lib:parallel(), - [attribute,bsdecode,bsdes,barnes2,decode1,smith, + [attribute,bsdecode,bsdes,barnes2,decode1,smith,fname, itracer,pseudoknot,comma_splitter,lists,really_inlined,otp_7223, coverage]}]. @@ -84,6 +84,7 @@ attribute(Config) when is_list(Config) -> ?comp(itracer). ?comp(pseudoknot). ?comp(comma_splitter). +?comp(fname). try_inline(Mod, Config) -> Node = ?config(testing_node, Config), diff --git a/lib/compiler/test/inline_SUITE_data/fname.erl b/lib/compiler/test/inline_SUITE_data/fname.erl new file mode 100644 index 0000000000..7ad4446bf3 --- /dev/null +++ b/lib/compiler/test/inline_SUITE_data/fname.erl @@ -0,0 +1,29 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 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 +%% 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(fname). +-export([?MODULE/0]). + +?MODULE() -> + F = fun bar/1, + G = lists:last([(fun (X) when F =:= X -> X end)]), + F = G(F), + ok. + +bar(X) -> + X. diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl index f00bfe663b..810b2b48c9 100644 --- a/lib/compiler/test/warnings_SUITE.erl +++ b/lib/compiler/test/warnings_SUITE.erl @@ -37,7 +37,7 @@ -export([pattern/1,pattern2/1,pattern3/1,pattern4/1, guard/1,bad_arith/1,bool_cases/1,bad_apply/1, - files/1,effect/1,bin_opt_info/1,bin_construction/1]). + files/1,effect/1,bin_opt_info/1,bin_construction/1, comprehensions/1]). % Default timetrap timeout (set in init_per_testcase). -define(default_timeout, ?t:minutes(2)). @@ -61,7 +61,7 @@ groups() -> [{p,test_lib:parallel(), [pattern,pattern2,pattern3,pattern4,guard, bad_arith,bool_cases,bad_apply,files,effect, - bin_opt_info,bin_construction]}]. + bin_opt_info,bin_construction,comprehensions]}]. init_per_suite(Config) -> Config. @@ -536,6 +536,16 @@ bin_construction(Config) when is_list(Config) -> ok. +comprehensions(Config) when is_list(Config) -> + Ts = [{tautologic_guards, + <<" + f() -> [ true || true ]. + g() -> << <<1>> || true >>. + ">>, + [], []}], + run(Config, Ts), + ok. + %%% %%% End of test cases. %%% diff --git a/lib/diameter/doc/src/diameter_dict.xml b/lib/diameter/doc/src/diameter_dict.xml index 4fcde495b3..8bf4a14240 100644 --- a/lib/diameter/doc/src/diameter_dict.xml +++ b/lib/diameter/doc/src/diameter_dict.xml @@ -609,7 +609,9 @@ UTF8String() = [integer()] <p> List elements are the UTF-8 encodings of the individual characters in the string. -Invalid codepoints will result in encode/decode failure.</p> +Invalid codepoints will result in encode/decode failure. +On encode, a UTF8String() can be specified as a binary, or as a nested +list of binaries and codepoints.</p> <marker id="DiameterIdentity"/> <pre> diff --git a/lib/diameter/src/base/diameter_types.erl b/lib/diameter/src/base/diameter_types.erl index 9ae289034c..8c07e84777 100644 --- a/lib/diameter/src/base/diameter_types.erl +++ b/lib/diameter/src/base/diameter_types.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2010-2011. All Rights Reserved. +%% Copyright Ericsson AB 2010-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 @@ -250,13 +250,10 @@ 'Address'(encode, zero) -> <<0:48>>; -'Address'(decode, <<1:16, B/binary>>) - when size(B) == 4 -> - list_to_tuple(binary_to_list(B)); - -'Address'(decode, <<2:16, B/binary>>) - when size(B) == 16 -> - list_to_tuple(v6dec(B, [])); +'Address'(decode, <<A:16, B/binary>>) + when 1 == A, 4 == size(B); + 2 == A, 16 == size(B) -> + list_to_tuple([N || <<N:A/unit:8>> <= B]); 'Address'(decode, <<A:16, _/binary>> = B) when 1 == A; @@ -264,30 +261,10 @@ ?INVALID_LENGTH(B); 'Address'(encode, T) -> - ipenc(diameter_lib:ipaddr(T)). - -ipenc(T) - when is_tuple(T), size(T) == 4 -> - B = list_to_binary(tuple_to_list(T)), - <<1:16, B/binary>>; - -ipenc(T) - when is_tuple(T), size(T) == 8 -> - B = v6enc(lists:reverse(tuple_to_list(T)), <<>>), - <<2:16, B/binary>>. - -v6dec(<<N:16, B/binary>>, Acc) -> - v6dec(B, [N | Acc]); - -v6dec(<<>>, Acc) -> - lists:reverse(Acc). - -v6enc([N | Rest], B) - when ?UINT(16,N) -> - v6enc(Rest, <<N:16, B/binary>>); - -v6enc([], B) -> - B. + Ns = tuple_to_list(diameter_lib:ipaddr(T)), %% length 4 or 8 + A = length(Ns) div 4, %% 1 or 2 + B = << <<N:A/unit:8>> || N <- Ns >>, + <<A:16, B/binary>>. %% -------------------- @@ -354,36 +331,13 @@ v6enc([], B) -> %% -------------------- 'UTF8String'(decode, Bin) -> - udec(Bin, []); + tl([0|_] = unicode:characters_to_list([0, Bin])); %% assert list return 'UTF8String'(encode = M, zero) -> 'UTF8String'(M, []); 'UTF8String'(encode, S) -> - uenc(S, []). - -udec(<<>>, Acc) -> - lists:reverse(Acc); - -udec(<<C/utf8, Rest/binary>>, Acc) -> - udec(Rest, [C | Acc]). - -uenc(E, Acc) - when E == []; - E == <<>> -> - list_to_binary(lists:reverse(Acc)); - -uenc(<<C/utf8, Rest/binary>>, Acc) -> - uenc(Rest, [<<C/utf8>> | Acc]); - -uenc([[] | Rest], Acc) -> - uenc(Rest, Acc); - -uenc([[H|T] | Rest], Acc) -> - uenc([H, T | Rest], Acc); - -uenc([C | Rest], Acc) -> - uenc(Rest, [<<C/utf8>> | Acc]). + <<_/binary>> = unicode:characters_to_binary(S). %% assert binary return %% -------------------- diff --git a/lib/diameter/test/diameter_codec_test.erl b/lib/diameter/test/diameter_codec_test.erl index 24d4c7665e..295d23912b 100644 --- a/lib/diameter/test/diameter_codec_test.erl +++ b/lib/diameter/test/diameter_codec_test.erl @@ -1,3 +1,4 @@ +%% coding: utf-8 %% %% %CopyrightBegin% %% @@ -19,7 +20,9 @@ -module(diameter_codec_test). --compile(export_all). +-export([base/0, + gen/1, + lib/0]). %% %% Test encode/decode of dictionary-related modules. @@ -38,37 +41,34 @@ %% Interface. base() -> - [] = run([{?MODULE, [base, T]} || T <- [zero, decode]]). + [] = run([[fun base/1, T] || T <- [zero, decode]]). gen(Mod) -> Fs = [{Mod, F, []} || F <- [name, id, vendor_id, vendor_name]], - [] = run(Fs ++ [{?MODULE, [gen, Mod, T]} || T <- [messages, - command_codes, - avp_types, - grouped, - enum, - import_avps, - import_groups, - import_enums]]). + [] = run(Fs ++ [[fun gen/2, Mod, T] || T <- [messages, + command_codes, + avp_types, + grouped, + enum, + import_avps, + import_groups, + import_enums]]). lib() -> - Vs = {_,_} = values('Address'), - [] = run([[fun lib/2, N, Vs] || N <- [1,2]]). + Vs = {_,_,_} = values('Address'), + [] = run([[fun lib/2, N, Vs] || N <- [{1, true}, {3, false}]]). %% =========================================================================== %% Internal functions. -lib(N, {_,_} = T) -> - B = 1 == N rem 2, - [] = run([[fun lib/2, A, B] || A <- element(N,T)]); +lib({N,B}, {_,_,_} = T) -> + [] = run([[fun lib/2, A, B] || A <- element(N,T), is_tuple(A)]); lib(IP, B) -> - LA = tuple_to_list(IP), - {SA,Fun} = ip(LA), - [] = run([[fun lib/4, IP, B, Fun, A] || A <- [IP, SA]]). + [] = run([[fun lib/3, IP, B, A] || A <- [IP, ntoa(tuple_to_list(IP))]]). -lib(IP, B, Fun, A) -> - try Fun(A) of +lib(IP, B, A) -> + try diameter_lib:ipaddr(A) of IP when B -> ok catch @@ -76,12 +76,12 @@ lib(IP, B, Fun, A) -> ok end. -ip([_,_,_,_] = A) -> +ntoa([_,_,_,_] = A) -> [$.|S] = lists:append(["." ++ integer_to_list(N) || N <- A]), - {S, fun diameter_lib:ipaddr/1}; -ip([_,_,_,_,_,_,_,_] = A) -> + S; +ntoa([_,_,_,_,_,_,_,_] = A) -> [$:|S] = lists:flatten([":" ++ io_lib:format("~.16B", [N]) || N <- A]), - {S, fun diameter_lib:ipaddr/1}. + S. %% ------------------------------------------------------------------------ %% base/1 @@ -90,7 +90,7 @@ ip([_,_,_,_,_,_,_,_] = A) -> %% ------------------------------------------------------------------------ base(T) -> - [] = run([{?MODULE, [base, T, F]} || F <- types()]). + [] = run([[fun base/2, T, F] || F <- types()]). %% Ensure that 'zero' values encode only zeros. base(zero = T, F) -> @@ -100,32 +100,23 @@ base(zero = T, F) -> %% Ensure that we can decode what we encode and vice-versa, and that %% we can't decode invalid values. base(decode, F) -> - {Eq, Vs, Ns} = b(values(F)), - [] = run([{?MODULE, [base_decode, F, Eq, V]} || V <- Vs]), - [] = run([{?MODULE, [base_invalid, F, Eq, V]} || V <- Ns]). + {Ts, Fs, Is} = values(F), + [] = run([[fun base_decode/3, F, true, V] || V <- Ts]), + [] = run([[fun base_decode/3, F, false, V] || V <- Fs]), + [] = run([[fun base_invalid/2, F, V] || V <- Is]). base_decode(F, Eq, Value) -> d(fun(X,V) -> diameter_types:F(X,V) end, Eq, Value). -base_invalid(F, Eq, Value) -> +base_invalid(F, Value) -> try - base_decode(F, Eq, Value), + base_decode(F, false, Value), exit(nok) catch error: _ -> ok end. -b({_,_,_} = T) -> - T; -b({B,Vs}) - when is_atom(B) -> - {B,Vs,[]}; -b({Vs,Ns}) -> - {true, Vs, Ns}; -b(Vs) -> - {true, Vs, []}. - types() -> [F || {F,2} <- diameter_types:module_info(exports)]. @@ -136,7 +127,7 @@ types() -> %% ------------------------------------------------------------------------ gen(M, T) -> - [] = run(lists:map(fun(X) -> {?MODULE, [gen, M, T, X]} end, + [] = run(lists:map(fun(X) -> [fun gen/3, M, T, X] end, fetch(T, dict(M)))). fetch(T, Spec) -> @@ -197,18 +188,20 @@ gen(M, enum = T, {Name, ED}) gen(M, T, {?A(Name), lists:map(fun({E,D}) -> {?A(E), D} end, ED)}); gen(M, enum, {Name, ED}) -> - [] = run([{?MODULE, [enum, M, Name, T]} || T <- ED]); + [] = run([[fun enum/3, M, Name, T] || T <- ED]); gen(M, Tag, {_Mod, L}) -> T = retag(Tag), - [] = run([{?MODULE, [gen, M, T, I]} || I <- L]). + [] = run([[fun gen/3, M, T, I] || I <- L]). %% avp_decode/3 avp_decode(Mod, Type, Name) -> - {Eq, Vs, _} = b(values(Type, Name, Mod)), - [] = run([{?MODULE, [avp_decode, Mod, Name, Type, Eq, V]} - || V <- v(Vs)]). + {Ts, Fs, _} = values(Type, Name, Mod), + [] = run([[fun avp_decode/5, Mod, Name, Type, true, V] + || V <- v(Ts)]), + [] = run([[fun avp_decode/5, Mod, Name, Type, false, V] + || V <- v(Fs)]). avp_decode(Mod, Name, Type, Eq, Value) -> d(fun(X,V) -> avp(Mod, X, V, Name, Type) end, Eq, Value). @@ -250,7 +243,7 @@ v(N, Ord, E, Acc) -> arity(M, Name, Rname) -> Rec = M:'#new-'(Rname), - [] = run([{?MODULE, [arity, M, Name, F, Rec]} + [] = run([[fun arity/4, M, Name, F, Rec] || F <- M:'#info-'(Rname, fields)]). arity(M, Name, AvpName, Rec) -> @@ -299,68 +292,93 @@ z(B) -> %% tested.) values('OctetString' = T) -> - {["", atom_to_list(T)], [-1, 256]}; + {["", atom_to_list(T)], + [], + [-1, 256]}; values('Integer32') -> Mx = (1 bsl 31) - 1, Mn = -1*Mx, - {[Mn, 0, random(Mn,Mx), Mx], [Mn - 1, Mx + 1]}; + {[Mn, 0, random(Mn,Mx), Mx], + [], + [Mn - 1, Mx + 1]}; values('Integer64') -> Mx = (1 bsl 63) - 1, Mn = -1*Mx, - {[Mn, 0, random(Mn,Mx), Mx], [Mn - 1, Mx + 1]}; + {[Mn, 0, random(Mn,Mx), Mx], + [], + [Mn - 1, Mx + 1]}; values('Unsigned32') -> M = (1 bsl 32) - 1, - {[0, random(M), M], [-1, M + 1]}; + {[0, random(M), M], + [], + [-1, M + 1]}; values('Unsigned64') -> M = (1 bsl 64) - 1, - {[0, random(M), M], [-1, M + 1]}; + {[0, random(M), M], + [], + [-1, M + 1]}; values('Float32') -> E = (1 bsl 8) - 2, F = (1 bsl 23) - 1, <<Mx:32/float>> = <<0:1, E:8, F:23>>, <<Mn:32/float>> = <<1:1, E:8, F:23>>, - {[0.0, infinity, '-infinity', Mx, Mn], [0]}; + {[0.0, infinity, '-infinity', Mx, Mn], + [], + [0]}; values('Float64') -> E = (1 bsl 11) - 2, F = (1 bsl 52) - 1, <<Mx:64/float>> = <<0:1, E:11, F:52>>, <<Mn:64/float>> = <<1:1, E:11, F:52>>, - {[0.0, infinity, '-infinity', Mx, Mn], [0]}; + {[0.0, infinity, '-infinity', Mx, Mn], + [], + [0]}; values('Address') -> {[{255,0,random(16#FF),1}, {65535,0,0,random(16#FFFF),0,0,0,1}], - [{256,0,0,1}, {65536,0,0,0,0,0,0,1}]}; + ["127.0.0.1", "FFFF:FF::1.2.3.4"], + [{256,0,0,1}, {65536,0,0,0,0,0,0,1}, "256.0.0.1", "10000::1"]}; values('DiameterIdentity') -> - {["x", "diameter.com"], [""]}; + {["x", "diameter.com"], + [], + [""]}; values('DiameterURI') -> - {false, ["aaa" ++ S ++ "://diameter.se" ++ P ++ Tr ++ Pr - || S <- ["", "s"], - P <- ["", ":1234"], - Tr <- ["" | [";transport=" ++ X - || X <- ["tcp", "sctp", "udp"]]], - Pr <- ["" | [";protocol=" ++ X - || X <- ["diameter","radius","tacacs+"]]]]}; + {[], + ["aaa" ++ S ++ "://diameter.se" ++ P ++ Tr ++ Pr + || S <- ["", "s"], + P <- ["", ":1234"], + Tr <- ["" | [";transport=" ++ X + || X <- ["tcp", "sctp", "udp"]]], + Pr <- ["" | [";protocol=" ++ X + || X <- ["diameter","radius","tacacs+"]]]], + []}; values(T) when T == 'IPFilterRule'; T == 'QoSFilterRule' -> - ["deny in 0 from 127.0.0.1 to 10.0.0.1"]; + {["deny in 0 from 127.0.0.1 to 10.0.0.1"], + [], + []}; %% RFC 3629 defines the UTF-8 encoding of U+0000 through U+10FFFF with the %% exception of U+D800 through U+DFFF. values('UTF8String') -> + S = "ᚠᚢᚦᚨᚱᚲ", + B = unicode:characters_to_binary(S), {[[], + S, lists:seq(0,16#1FF), [0,16#D7FF,16#E000,16#10FFFF], [random(16#D7FF), random(16#E000,16#10FFFF)]], + [B, [B, S, hd(S)], [S, B]], [[-1], [16#D800], [16#DFFF], @@ -372,6 +390,7 @@ values('Time') -> {{2036,2,7},{6,28,15}}, {{2036,2,7},{6,28,16}}, %% 19000101T000000 + 2 bsl 31 {{2104,2,26},{9,42,23}}], + [], [{{1968,1,20},{3,14,7}}, {{2104,2,26},{9,42,24}}]}. %% 19000101T000000 + 3 bsl 31 @@ -382,18 +401,24 @@ values('Time') -> values('Enumerated', Name, Mod) -> {_Name, Vals} = lists:keyfind(?S(Name), 1, types(enum, Mod)), - lists:map(fun({_,N}) -> N end, Vals); + {lists:map(fun({_,N}) -> N end, Vals), + [], + []}; values('Grouped', Name, Mod) -> Rname = Mod:name2rec(Name), Rec = Mod:'#new-'(Rname), Avps = Mod:'#info-'(Rname, fields), - Enum = diameter_enum:combine(lists:map(fun({_,Vs,_}) -> to_enum(Vs) end, + Enum = diameter_enum:combine(lists:map(fun({Vs,_,_}) -> to_enum(Vs) end, [values(F, Mod) || F <- Avps])), - {false, diameter_enum:append(group(Mod, Name, Rec, Avps, Enum))}; + {[], + diameter_enum:append(group(Mod, Name, Rec, Avps, Enum)), + []}; values(_, 'Framed-IP-Address', _) -> - [{127,0,0,1}]; + {[{127,0,0,1}], + [], + []}; values(Type, _, _) -> values(Type). @@ -407,12 +432,14 @@ to_enum(E) -> %% values/2 values('AVP', _) -> - {true, [#diameter_avp{code = 0, data = <<0>>}], []}; + {[#diameter_avp{code = 0, data = <<0>>}], + [], + []}; values(Name, Mod) -> Avps = types(avp_types, Mod), {_Name, _Code, Type, _Flags} = lists:keyfind(?S(Name), 1, Avps), - b(values(?A(Type), Name, Mod)). + values(?A(Type), Name, Mod). %% group/5 %% diff --git a/lib/eunit/include/eunit.hrl b/lib/eunit/include/eunit.hrl index 8ebdb6ba16..84242a09aa 100644 --- a/lib/eunit/include/eunit.hrl +++ b/lib/eunit/include/eunit.hrl @@ -102,7 +102,7 @@ %% X gets a new, local binding. %% (Note that lowercase 'let' is a reserved word.) -ifndef(LET). --define(LET(X,Y,Z), ((fun(X)->(Z)end)(Y))). +-define(LET(X,Y,Z), begin ((fun(X)->(Z)end)(Y)) end). -endif. %% It is important that testing code is short and readable. @@ -110,13 +110,13 @@ %% Compare: case f(X) of true->g(X); false->h(X) end %% and: ?IF(f(X), g(Y), h(Z)) -ifndef(IF). --define(IF(B,T,F), (case (B) of true->(T); false->(F) end)). +-define(IF(B,T,F), begin (case (B) of true->(T); false->(F) end) end). -endif. %% This macro yields 'true' if the value of E matches the guarded %% pattern G, otherwise 'false'. -ifndef(MATCHES). --define(MATCHES(G,E), (case (E) of G -> true; _ -> false end)). +-define(MATCHES(G,E), begin (case (E) of G -> true; _ -> false end) end). -endif. %% This macro can be used at any time to check whether or not the code @@ -140,6 +140,7 @@ %% for clauses that cannot match, even if the expression is a constant. -undef(assert). -define(assert(BoolExpr), + begin ((fun () -> case (BoolExpr) of true -> ok; @@ -152,7 +153,8 @@ _ -> {not_a_boolean,__V} end}]}) end - end)())). + end)()) + end). -endif. -define(assertNot(BoolExpr), ?assert(not (BoolExpr))). @@ -168,6 +170,7 @@ -define(assertMatch(Guard, Expr), ok). -else. -define(assertMatch(Guard, Expr), + begin ((fun () -> case (Expr) of Guard -> ok; @@ -178,7 +181,8 @@ {pattern, (??Guard)}, {value, __V}]}) end - end)())). + end)()) + end). -endif. -define(_assertMatch(Guard, Expr), ?_test(?assertMatch(Guard, Expr))). @@ -187,6 +191,7 @@ -define(assertNotMatch(Guard, Expr), ok). -else. -define(assertNotMatch(Guard, Expr), + begin ((fun () -> __V = (Expr), case __V of @@ -198,7 +203,8 @@ {value, __V}]}); _ -> ok end - end)())). + end)()) + end). -endif. -define(_assertNotMatch(Guard, Expr), ?_test(?assertNotMatch(Guard, Expr))). @@ -208,6 +214,7 @@ -define(assertEqual(Expect, Expr), ok). -else. -define(assertEqual(Expect, Expr), + begin ((fun (__X) -> case (Expr) of __X -> ok; @@ -218,7 +225,8 @@ {expected, __X}, {value, __V}]}) end - end)(Expect))). + end)(Expect)) + end). -endif. -define(_assertEqual(Expect, Expr), ?_test(?assertEqual(Expect, Expr))). @@ -227,6 +235,7 @@ -define(assertNotEqual(Unexpected, Expr), ok). -else. -define(assertNotEqual(Unexpected, Expr), + begin ((fun (__X) -> case (Expr) of __X -> erlang:error({assertNotEqual_failed, @@ -236,7 +245,8 @@ {value, __X}]}); _ -> ok end - end)(Unexpected))). + end)(Unexpected)) + end). -endif. -define(_assertNotEqual(Unexpected, Expr), ?_test(?assertNotEqual(Unexpected, Expr))). @@ -247,6 +257,7 @@ -define(assertException(Class, Term, Expr), ok). -else. -define(assertException(Class, Term, Expr), + begin ((fun () -> try (Expr) of __V -> erlang:error({assertException_failed, @@ -271,7 +282,8 @@ {__C, __T, erlang:get_stacktrace()}}]}) end - end)())). + end)()) + end). -endif. -define(assertError(Term, Expr), ?assertException(error, Term, Expr)). @@ -291,6 +303,7 @@ -define(assertNotException(Class, Term, Expr), ok). -else. -define(assertNotException(Class, Term, Expr), + begin ((fun () -> try (Expr) of _ -> ok @@ -316,7 +329,8 @@ _ -> ok end end - end)())). + end)()) + end). -endif. -define(_assertNotException(Class, Term, Expr), ?_test(?assertNotException(Class, Term, Expr))). @@ -327,6 +341,7 @@ %% these can be used for simply running commands in a controlled way -define(_cmd_(Cmd), (eunit_lib:command(Cmd))). -define(cmdStatus(N, Cmd), + begin ((fun () -> case ?_cmd_(Cmd) of {(N), __Out} -> __Out; @@ -337,7 +352,8 @@ {expected_status,(N)}, {status,__N}]}) end - end)())). + end)()) + end). -define(_cmdStatus(N, Cmd), ?_test(?cmdStatus(N, Cmd))). -define(cmd(Cmd), ?cmdStatus(0, Cmd)). -define(_cmd(Cmd), ?_test(?cmd(Cmd))). @@ -348,6 +364,7 @@ -define(assertCmdStatus(N, Cmd), ok). -else. -define(assertCmdStatus(N, Cmd), + begin ((fun () -> case ?_cmd_(Cmd) of {(N), _} -> ok; @@ -358,7 +375,8 @@ {expected_status,(N)}, {status,__N}]}) end - end)())). + end)()) + end). -endif. -define(assertCmd(Cmd), ?assertCmdStatus(0, Cmd)). @@ -366,6 +384,7 @@ -define(assertCmdOutput(T, Cmd), ok). -else. -define(assertCmdOutput(T, Cmd), + begin ((fun () -> case ?_cmd_(Cmd) of {_, (T)} -> ok; @@ -376,7 +395,8 @@ {expected_output,(T)}, {output,__T}]}) end - end)())). + end)()) + end). -endif. -define(_assertCmdStatus(N, Cmd), ?_test(?assertCmdStatus(N, Cmd))). @@ -394,26 +414,30 @@ -define(debugTime(S, E), (E)). -else. -define(debugMsg(S), - (begin - io:fwrite(user, <<"~s:~w:~w: ~s\n">>, - [?FILE, ?LINE, self(), S]), - ok - end)). + begin + io:fwrite(user, <<"~s:~w:~w: ~s\n">>, + [?FILE, ?LINE, self(), S]), + ok + end). -define(debugHere, (?debugMsg("<-"))). -define(debugFmt(S, As), (?debugMsg(io_lib:format((S), (As))))). -define(debugVal(E), + begin ((fun (__V) -> ?debugFmt(<<"~s = ~P">>, [(??E), __V, 15]), __V - end)(E))). + end)(E)) + end). -define(debugTime(S, E), + begin ((fun () -> {__T0, _} = statistics(wall_clock), __V = (E), {__T1, _} = statistics(wall_clock), ?debugFmt(<<"~s: ~.3f s">>, [(S), (__T1-__T0)/1000]), __V - end)())). + end)()) + end). -endif. diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml index 741f2abaef..d9a27e7d1e 100644 --- a/lib/inets/doc/src/httpc.xml +++ b/lib/inets/doc/src/httpc.xml @@ -300,11 +300,11 @@ filename() = string() process or to a file. When streaming to the calling process using the option <c>self</c> the following stream messages will be sent to that process: <c>{http, {RequestId, - stream_start, Headers}, {http, {RequestId, stream, - BinBodyPart}, {http, {RequestId, stream_end, Headers}</c>. When + stream_start, Headers}}, {http, {RequestId, stream, + BinBodyPart}}, {http, {RequestId, stream_end, Headers}}</c>. When streaming to to the calling processes using the option <c>{self, once}</c> the first message will have an additional - element e.i. <c>{http, {RequestId, stream_start, Headers, Pid}</c>, + element e.i. <c>{http, {RequestId, stream_start, Headers, Pid}}</c>, this is the process id that should be used as an argument to <c>http:stream_next/1</c> to trigger the next message to be sent to the calling process. </p> diff --git a/lib/inets/doc/src/httpd.xml b/lib/inets/doc/src/httpd.xml index 8438961511..4210aea3ec 100644 --- a/lib/inets/doc/src/httpd.xml +++ b/lib/inets/doc/src/httpd.xml @@ -251,14 +251,14 @@ </item> <marker id="prop_max_uri"></marker> - <tag>{max_uri, integer()}</tag> + <tag>{max_uri_size, integer()}</tag> <item> <p>Limits the size of the HTTP request URI. By default there is no limit. </p> </item> <marker id="prop_max_keep_alive_req"></marker> - <tag>{max_keep_alive_requests, integer()}</tag> + <tag>{max_keep_alive_request, integer()}</tag> <item> <p>The number of request that a client can do on one connection. When the server has responded to the number of @@ -406,7 +406,7 @@ bytes begins with url-path is mapped to local files that begins with directory-filename, for example: - <code>{alias, {"/image", "/ftp/pub/image"}</code> + <code>{alias, {"/image", "/ftp/pub/image"}}</code> and an access to http://your.server.org/image/foo.gif would refer to the file /ftp/pub/image/foo.gif. </p> @@ -421,7 +421,7 @@ bytes by re:replace/3 to produce a path in the local filesystem. For example: - <code>{re_write, {"^/[~]([^/]+)(.*)$", "/home/\\1/public\\2"}</code> + <code>{re_write, {"^/[~]([^/]+)(.*)$", "/home/\\1/public\\2"}}</code> and an access to http://your.server.org/~bob/foo.gif would refer to the file /home/bob/public/foo.gif. @@ -468,7 +468,7 @@ bytes scripts. URLs with a path beginning with url-path are mapped to scripts beginning with directory-filename, for example: - <code>{script_alias, {"/cgi-bin/", "/web/cgi-bin/"}</code> + <code>{script_alias, {"/cgi-bin/", "/web/cgi-bin/"}}</code> and an access to http://your.server.org/cgi-bin/foo would cause the server to run the script /web/cgi-bin/foo. </p> @@ -483,7 +483,7 @@ bytes scripts. URLs with a path beginning with url-path are mapped to scripts beginning with directory-filename, for example: - <code>{script_re_write, {"^/cgi-bin/(\\d+)/", "/web/\\1/cgi-bin/"}</code> + <code>{script_re_write, {"^/cgi-bin/(\\d+)/", "/web/\\1/cgi-bin/"}}</code> and an access to http://your.server.org/cgi-bin/17/foo would cause the server to run the script /web/17/cgi-bin/foo. </p> @@ -517,7 +517,7 @@ bytes the standard CGI PATH_INFO and PATH_TRANSLATED environment variables. - <code>{action, {"text/plain", "/cgi-bin/log_and_deliver_text"}</code> + <code>{action, {"text/plain", "/cgi-bin/log_and_deliver_text"}}</code> </p> </item> @@ -532,7 +532,7 @@ bytes the standard CGI PATH_INFO and PATH_TRANSLATED environment variables. - <code>{script, {"PUT", "/cgi-bin/put"}</code> + <code>{script, {"PUT", "/cgi-bin/put"}}</code> </p> </item> @@ -549,7 +549,7 @@ bytes scheme scripts. A matching URL is mapped into a specific module and function. For example: - <code>{erl_script_alias, {"/cgi-bin/example", [httpd_example]} + <code>{erl_script_alias, {"/cgi-bin/example", [httpd_example]}} </code> and a request to @@ -632,7 +632,7 @@ bytes </item> <marker id="prop_edlog"></marker> - <tag>{error_disk_log, internal | external}</tag> + <tag>{error_disk_log, path()}</tag> <item> <p>Defines the filename of the (disk_log(3)) error log file to be used to log server errors. If the filename does not begin @@ -706,7 +706,7 @@ bytes For example: - <code>{allow_from, ["123.34.56.11", "150.100.23"] </code> + <code>{allow_from, ["123.34.56.11", "150.100.23"]}</code> The host 123.34.56.11 and all machines on the 150.100.23 subnet are allowed access. </p> @@ -719,7 +719,7 @@ bytes which should be denied access to a given directory. For example: - <code>{deny_from, ["123.34.56.11", "150.100.23"] </code> + <code>{deny_from, ["123.34.56.11", "150.100.23"]}</code> The host 123.34.56.11 and all machines on the 150.100.23 subnet are not allowed access. </p> @@ -835,7 +835,7 @@ bytes <p><em>Security properties - requires mod_security </em></p> <marker id="prop_sec_dir"></marker> - <p><em>{security_directory, {path(), [{property(), term()}]}</em></p> + <p><em>{security_directory, {path(), [{property(), term()}]}}</em></p> <marker id="props_sdir"></marker> <p>Here follows the valid properties for security directories</p> @@ -1067,7 +1067,7 @@ bytes <fsummary>Called for each request to the Web server.</fsummary> <type> <v>OldData = list()</v> - <v>NewData = [{response,{StatusCode,Body}}] | [{response,{response,Head,Body}}] | [{response,{already_sent,Statuscode,Size}] </v> + <v>NewData = [{response,{StatusCode,Body}}] | [{response,{response,Head,Body}}] | [{response,{already_sent,Statuscode,Size}}] </v> <v>StausCode = integer()</v> <v>Body = io_list() | nobody | {Fun, Arg}</v> <v>Head = [HeaderOption]</v> diff --git a/lib/inets/doc/src/httpd_util.xml b/lib/inets/doc/src/httpd_util.xml index 9f290084d2..9218ee91e2 100644 --- a/lib/inets/doc/src/httpd_util.xml +++ b/lib/inets/doc/src/httpd_util.xml @@ -337,10 +337,10 @@ <func> <name>rfc1123_date() -> RFC1123Date</name> - <name>rfc1123_date({{YYYY,MM,DD},{Hour,Min,Sec}}}) -> RFC1123Date</name> + <name>rfc1123_date({{YYYY,MM,DD},{Hour,Min,Sec}}) -> RFC1123Date</name> <fsummary>Return the current date in RFC 1123 format.</fsummary> <type> - <v>YYYY = MM = DD = Hour = Min =Sec = integer()</v> + <v>YYYY = MM = DD = Hour = Min = Sec = integer()</v> <v>RFC1123Date = string()</v> </type> <desc> diff --git a/lib/inets/doc/src/mod_alias.xml b/lib/inets/doc/src/mod_alias.xml index 265a1b8e76..b38be5db28 100644 --- a/lib/inets/doc/src/mod_alias.xml +++ b/lib/inets/doc/src/mod_alias.xml @@ -118,7 +118,7 @@ </func> <func> - <name>real_script_name(ConfigDB,RequestURI,ScriptAliases) -> Ret</name> + <name>real_script_name(ConfigDB, RequestURI, ScriptAliases) -> Ret</name> <fsummary>Expand a request uri using ScriptAlias config directives.</fsummary> <type> <v>ConfigDB = config_db()</v> @@ -129,7 +129,7 @@ </type> <desc> <marker id="real_script_name"></marker> - <p><c>real_name/3</c> traverses <c>ScriptAliases</c>, + <p><c>real_script_name/3</c> traverses <c>ScriptAliases</c>, typically extracted from <c>ConfigDB</c>, and matches each <c>FakeName</c> with <c>RequestURI</c>. If a match is found <c>FakeName</c> is replaced with <c>RealName</c> in the diff --git a/lib/inets/doc/src/notes_history.xml b/lib/inets/doc/src/notes_history.xml index bd59c1ba47..4162ab97bb 100644 --- a/lib/inets/doc/src/notes_history.xml +++ b/lib/inets/doc/src/notes_history.xml @@ -834,7 +834,7 @@ <list type="bulleted"> <item> <p>[ftp, client] - A new option {progress, {CBmodule, - CBFunction, InitProgressTerm} has been added to allow + CBFunction, InitProgressTerm}} has been added to allow users to create things such as progress bars in there GUI's. The option affects ftp:send/[3,4] and ftp:recv/[3,4].</p> diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index 7cd98914d1..254dfbf034 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -76,11 +76,11 @@ FFFF::192.168.42.2 {16#3ffe,16#b80,16#1f8d,16#2,16#204,16#acff,16#fe17,16#bf38} fe80::204:acff:fe17:bf38 {16#fe80,0,0,0,0,16#204,16#acff,16#fe17,16#bf38}</code> - <p>A function that may be useful is <c>inet_parse:address/1</c>:</p> + <p>A function that may be useful is <seealso marker="#parse_address/1">parse_address/1</seealso>:</p> <pre> -1> <input>inet_parse:address("192.168.42.2").</input> +1> <input>inet:parse_address("192.168.42.2").</input> {ok,{192,168,42,2}} -2> <input>inet_parse:address("FFFF::192.168.42.2").</input> +2> <input>inet:parse_address("FFFF::192.168.42.2").</input> {ok,{65535,0,0,0,0,0,49320,10754}}</pre> </description> @@ -375,6 +375,13 @@ fe80::204:acff:fe17:bf38 </desc> </func> <func> + <name name="ntoa" arity="1" /> + <fsummary>Convert IPv6 / IPV4 adress to ascii</fsummary> + <desc> + <p>Parses an <a href="#type-ip_address">ip_address()</a> and returns an IPv4 or IPv6 address string.</p> + </desc> + </func> + <func> <name name="parse_ipv4_address" arity="1" /> <fsummary>Parse an IPv4 address</fsummary> <desc> diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index 3ea530a366..5749027acd 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -32,7 +32,7 @@ ip/1, stats/0, options/0, pushf/3, popf/1, close/1, gethostname/0, gethostname/1, parse_ipv4_address/1, parse_ipv6_address/1, parse_ipv4strict_address/1, - parse_ipv6strict_address/1, parse_address/1, parse_strict_address/1]). + parse_ipv6strict_address/1, parse_address/1, parse_strict_address/1, ntoa/1]). -export([connect_options/2, listen_options/2, udp_options/2, sctp_options/2]). @@ -529,6 +529,13 @@ getservbyname(Name, Protocol) when is_atom(Name) -> Error -> Error end. +-spec ntoa(IpAddress) -> + {ok, Address} | {error, einval} when + Address :: string(), + IpAddress :: ip_address(). +ntoa(Addr) -> + inet_parse:ntoa(Addr). + -spec parse_ipv4_address(Address) -> {ok, IPv4Address} | {error, einval} when Address :: string(), diff --git a/lib/kernel/src/inet_parse.erl b/lib/kernel/src/inet_parse.erl index 619c78a6ca..98bd8d386c 100644 --- a/lib/kernel/src/inet_parse.erl +++ b/lib/kernel/src/inet_parse.erl @@ -722,7 +722,9 @@ ntoa({0,0,0,0,0,16#ffff,A,B}) -> "::FFFF:" ++ dig_to_dec(A) ++ "." ++ dig_to_dec(B); ntoa({_,_,_,_,_,_,_,_}=T) -> %% Find longest sequence of zeros, at least 2, to replace with "::" - ntoa(tuple_to_list(T), []). + ntoa(tuple_to_list(T), []); +ntoa(_) -> + {error, einval}. %% Find first double zero ntoa([], R) -> diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl index ced6f47bfe..0e7e7d2031 100644 --- a/lib/kernel/src/rpc.erl +++ b/lib/kernel/src/rpc.erl @@ -407,7 +407,7 @@ cast(Node, Mod, Fun, Args) -> true. -%% Asynchronous broadcast, returns nothing, it's just send'n prey +%% Asynchronous broadcast, returns nothing, it's just send 'n' pray -spec abcast(Name, Msg) -> abcast when Name :: atom(), Msg :: term(). diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl index 62ba95e1a3..46c8c0b88b 100644 --- a/lib/kernel/test/inet_SUITE.erl +++ b/lib/kernel/test/inet_SUITE.erl @@ -226,7 +226,7 @@ t_gethostbyname_v6(Config) when is_list(Config) -> h_addr_list = [IP4]} = HEnt4, {ok,IP46} = inet_parse:ipv6_address( - "::ffff:" ++ inet_parse:ntoa(IP4)), + "::ffff:" ++ inet:ntoa(IP4)), check_elems( [{HEnt#hostent.h_name,[Name,FullName]}]) end, @@ -246,7 +246,7 @@ t_gethostbyname_v6(Config) when is_list(Config) -> h_addr_list = [IP4F]} = HEnt4F, {ok,IP46F} = inet_parse:ipv6_address( - "::ffff:" ++ inet_parse:ntoa(IP4F)), + "::ffff:" ++ inet:ntoa(IP4F)), check_elems( [{HEntF#hostent.h_name,[Name,FullName]}]) end; diff --git a/lib/os_mon/c_src/ferrule.c b/lib/os_mon/c_src/ferrule.c index 744f302b2d..c55f594f34 100644 --- a/lib/os_mon/c_src/ferrule.c +++ b/lib/os_mon/c_src/ferrule.c @@ -50,7 +50,7 @@ #define FDS_STDIN 0 #define FDS_PIPE 1 -main(int argc, char *argv[]) +int main(int argc, char *argv[]) /* usage: ferrule ownpath */ { int i, pipe_fd; diff --git a/lib/os_mon/c_src/mod_syslog.c b/lib/os_mon/c_src/mod_syslog.c index 87fbfbac22..b1bbf80b2a 100644 --- a/lib/os_mon/c_src/mod_syslog.c +++ b/lib/os_mon/c_src/mod_syslog.c @@ -47,7 +47,7 @@ #define TRUE 1 #define WAIT 1 -main(int argc, char *argv[]) +int main(int argc, char *argv[]) /* usage: mod_syslog mode ownpath syslogconf */ { int syslogd_pid, n_lines_copied=0; @@ -128,6 +128,7 @@ main(int argc, char *argv[]) make_exit(PIPE_NOT_FOUND); else */ make_exit(OK); + return 0; } void make_exit(int exit_code) diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl index b18d3dc0c0..7f65131f67 100644 --- a/lib/stdlib/src/gen_server.erl +++ b/lib/stdlib/src/gen_server.erl @@ -217,7 +217,7 @@ reply({To, Tag}, Reply) -> catch To ! {Tag, Reply}. %% ----------------------------------------------------------------- -%% Asyncronous broadcast, returns nothing, it's just send'n prey +%% Asynchronous broadcast, returns nothing, it's just send 'n' pray %%----------------------------------------------------------------- abcast(Name, Request) when is_atom(Name) -> do_abcast([node() | nodes()], Name, cast_msg(Request)). diff --git a/lib/xmerl/doc/src/xmerl_ug.xmlsrc b/lib/xmerl/doc/src/xmerl_ug.xmlsrc index 8a0805020e..10c770c400 100644 --- a/lib/xmerl/doc/src/xmerl_ug.xmlsrc +++ b/lib/xmerl/doc/src/xmerl_ug.xmlsrc @@ -409,9 +409,9 @@ Data = specification but the basic functionality. For all details see the <seealso marker="xmerl_xs">reference manual</seealso></p> <p>First, some words about the xmerl_xs functionality:</p> - <p>You need to wright template functions to be able to control + <p>You need to write template functions to be able to control what kind of output you want. Thus if you want to encapsulate a - <c>bike</c> element in <p> tags you simply wright a + <c>bike</c> element in <p> tags you simply write a function:</p> <pre> template(E = #xmlElement{name='bike'}) -> |