aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/common_test/src/common_test.app.src2
-rw-r--r--lib/common_test/src/ct_webtool.erl2
-rw-r--r--lib/common_test/src/test_server_ctrl.erl2
-rw-r--r--lib/common_test/src/vts.erl2
-rw-r--r--lib/debugger/src/dbg_ieval.erl2
-rw-r--r--lib/debugger/test/int_eval_SUITE.erl9
-rw-r--r--lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl4
-rw-r--r--lib/observer/src/cdv_html_wx.erl6
-rw-r--r--lib/observer/src/observer.app.src5
-rw-r--r--lib/observer/src/observer_procinfo.erl2
-rw-r--r--lib/public_key/src/pubkey_cert.erl95
-rw-r--r--lib/public_key/src/public_key.app.src2
-rw-r--r--lib/public_key/src/public_key.erl2
-rw-r--r--lib/ssl/doc/src/ssl_crl_cache.xml6
-rw-r--r--lib/ssl/src/ssl.app.src2
-rw-r--r--lib/ssl/src/ssl_crl_cache.erl10
-rw-r--r--lib/stdlib/src/io_lib.erl58
-rw-r--r--lib/stdlib/src/io_lib_format.erl7
-rw-r--r--lib/stdlib/test/io_SUITE.erl31
19 files changed, 111 insertions, 138 deletions
diff --git a/lib/common_test/src/common_test.app.src b/lib/common_test/src/common_test.app.src
index 0aa4aacf16..9becde110b 100644
--- a/lib/common_test/src/common_test.app.src
+++ b/lib/common_test/src/common_test.app.src
@@ -92,7 +92,7 @@
"sasl-2.4.2",
"snmp-5.1.2",
"ssh-4.0",
- "stdlib-3.4",
+ "stdlib-3.5",
"syntax_tools-1.7",
"tools-2.8",
"xmerl-1.3.8"
diff --git a/lib/common_test/src/ct_webtool.erl b/lib/common_test/src/ct_webtool.erl
index 82aa78fc4b..c7174b13f5 100644
--- a/lib/common_test/src/ct_webtool.erl
+++ b/lib/common_test/src/ct_webtool.erl
@@ -771,7 +771,7 @@ fill_out(Nr)->
%Controls whether the user selected a tool to start
%----------------------------------------------------------------------
get_tools(Input)->
- case httpd:parse_query(Input) of
+ case uri_string:dissect_query(Input) of
[]->
no_tools;
Tools->
diff --git a/lib/common_test/src/test_server_ctrl.erl b/lib/common_test/src/test_server_ctrl.erl
index 3a454a1e84..a76c8c12de 100644
--- a/lib/common_test/src/test_server_ctrl.erl
+++ b/lib/common_test/src/test_server_ctrl.erl
@@ -5739,7 +5739,7 @@ uri_encode_comp([Char|Chars],Encoding) ->
Reserved = sets:is_element(Char, reserved()),
case (Char>127 andalso Encoding==latin1) orelse Reserved of
true ->
- [ $% | http_util:integer_to_hexlist(Char)] ++
+ [ $% | integer_to_list(Char, 16)] ++
uri_encode_comp(Chars,Encoding);
false ->
[Char | uri_encode_comp(Chars,Encoding)]
diff --git a/lib/common_test/src/vts.erl b/lib/common_test/src/vts.erl
index 83fcde2f48..2bf3e82ade 100644
--- a/lib/common_test/src/vts.erl
+++ b/lib/common_test/src/vts.erl
@@ -919,7 +919,7 @@ get_input_data(Input,Key)->
end.
parse(Input) ->
- httpd:parse_query(Input).
+ uri_string:dissect_query(Input).
vts_integer_to_list(X) when is_atom(X) ->
atom_to_list(X);
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index b0db8228e5..9840cebc1a 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -1033,7 +1033,7 @@ expr({send,Line,To0,Msg0}, Bs0, Ieval0) ->
%% Binary
expr({bin,Line,Fs}, Bs0, Ieval0) ->
- Ieval = Ieval0#ieval{line=Line},
+ Ieval = Ieval0#ieval{line=Line,top=false},
try
eval_bits:expr_grp(Fs, Bs0,
fun (E, B) -> expr(E, B, Ieval) end,
diff --git a/lib/debugger/test/int_eval_SUITE.erl b/lib/debugger/test/int_eval_SUITE.erl
index 27ca4852b5..da1d6734f8 100644
--- a/lib/debugger/test/int_eval_SUITE.erl
+++ b/lib/debugger/test/int_eval_SUITE.erl
@@ -29,7 +29,8 @@
bifs_outside_erlang/1, spawning/1, applying/1,
catch_and_throw/1, external_call/1, test_module_info/1,
apply_interpreted_fun/1, apply_uninterpreted_fun/1,
- interpreted_exit/1, otp_8310/1, stacktrace/1, maps/1]).
+ interpreted_exit/1, otp_8310/1, stacktrace/1, maps/1,
+ call_inside_binary/1]).
%% Helpers.
-export([applier/3]).
@@ -45,7 +46,8 @@ all() ->
[bifs_outside_erlang, spawning, applying,
catch_and_throw, external_call, test_module_info,
apply_interpreted_fun, apply_uninterpreted_fun,
- interpreted_exit, otp_8310, stacktrace, maps].
+ interpreted_exit, otp_8310, stacktrace, maps,
+ call_inside_binary].
groups() ->
[].
@@ -275,6 +277,9 @@ maps(Config) when is_list(Config) ->
[#{hello := 0, price := 0}] = spawn_eval(fun () -> ?IM:update_in_fun() end),
ok.
+call_inside_binary(Config) when is_list(Config) ->
+ <<"1">> = ?IM:call_inside_binary(fun erlang:integer_to_binary/1),
+ ok.
do_eval(Config, Mod) ->
DataDir = proplists:get_value(data_dir, Config),
diff --git a/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl b/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl
index ca7929c10b..384d61f051 100644
--- a/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl
+++ b/lib/debugger/test/int_eval_SUITE_data/my_int_eval_module.erl
@@ -31,6 +31,7 @@
-export([f/1, f_try/1, f_catch/1]).
-export([otp_5837/1, otp_8310/0]).
-export([empty_map_update/1, update_in_fun/0]).
+-export([call_inside_binary/1]).
%% Internal exports.
-export([echo/2,my_subtract/2,catch_a_ball/0,throw_a_ball/0]).
@@ -248,3 +249,6 @@ empty_map_update(Map) -> Map#{}.
update_in_fun() ->
lists:map(fun (X) -> X#{price := 0} end, [#{hello => 0, price => nil}]).
+
+call_inside_binary(Fun) ->
+ <<(Fun(1))/binary>>.
diff --git a/lib/observer/src/cdv_html_wx.erl b/lib/observer/src/cdv_html_wx.erl
index 4b43b6a840..77a9d3207b 100644
--- a/lib/observer/src/cdv_html_wx.erl
+++ b/lib/observer/src/cdv_html_wx.erl
@@ -94,21 +94,21 @@ handle_event(#wx{event=#wxHtmlLink{type=command_html_link_clicked,
case Target of
"#Binary?" ++ BinSpec ->
[{"offset",Off},{"size",Size},{"pos",Pos}] =
- httpd:parse_query(BinSpec),
+ uri_string:dissect_query(BinSpec),
Id = {cdv, {list_to_integer(Off),
list_to_integer(Size),
list_to_integer(Pos)}},
expand(Id,cdv_bin_cb,State);
"#OBSBinary?" ++ BinSpec ->
[{"key1",Preview},{"key2",Size},{"key3",Hash}] =
- httpd:parse_query(BinSpec),
+ uri_string:dissect_query(BinSpec),
Id = {obs, {Tab, {list_to_integer(Preview),
list_to_integer(Size),
list_to_integer(Hash)}}},
expand(Id,cdv_bin_cb,State);
"#Term?" ++ TermKeys ->
[{"key1",Key1},{"key2",Key2},{"key3",Key3}] =
- httpd:parse_query(TermKeys),
+ uri_string:dissect_query(TermKeys),
Id = {cdv, {Tab,{list_to_integer(Key1),
list_to_integer(Key2),
list_to_integer(Key3)}}},
diff --git a/lib/observer/src/observer.app.src b/lib/observer/src/observer.app.src
index f682e3dc7b..cd4aa2e299 100644
--- a/lib/observer/src/observer.app.src
+++ b/lib/observer/src/observer.app.src
@@ -65,8 +65,7 @@
{registered, []},
{applications, [kernel, stdlib]},
{env, []},
- {runtime_dependencies, ["wx-1.2","stdlib-3.4","runtime_tools-1.8.14",
- "kernel-3.0","inets-5.10","et-1.5",
- "erts-7.0"]}]}.
+ {runtime_dependencies, ["wx-1.2","stdlib-3.5","runtime_tools-1.8.14",
+ "kernel-3.0","et-1.5","erts-7.0"]}]}.
diff --git a/lib/observer/src/observer_procinfo.erl b/lib/observer/src/observer_procinfo.erl
index 6b761cb2ff..6a85d29c1e 100644
--- a/lib/observer/src/observer_procinfo.erl
+++ b/lib/observer/src/observer_procinfo.erl
@@ -148,7 +148,7 @@ handle_event(#wx{event=#wxHtmlLink{linkInfo=#wxHtmlLinkInfo{href=Href}}},
observer ! {open_link, Href},
{noreply, State};
Callback ->
- [{"key1",Key1},{"key2",Key2},{"key3",Key3}] = httpd:parse_query(Rest),
+ [{"key1",Key1},{"key2",Key2},{"key3",Key3}] = uri_string:dissect_query(Rest),
Id = {obs, {T,{list_to_integer(Key1),
list_to_integer(Key2),
list_to_integer(Key3)}}},
diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl
index c433a96585..c0d7b9be8e 100644
--- a/lib/public_key/src/pubkey_cert.erl
+++ b/lib/public_key/src/pubkey_cert.erl
@@ -371,23 +371,23 @@ match_name(directoryName, DirName, [PermittedName | Rest]) ->
match_name(fun is_rdnSeq/2, DirName, PermittedName, Rest);
match_name(uniformResourceIdentifier, URI, [PermittedName | Rest]) ->
- case split_uri(URI) of
- incomplete ->
- false;
- {_, _, Host, _, _} ->
- PN = case split_uri(PermittedName) of
- {_, _, PNhost, _, _} -> PNhost;
+ case uri_string:normalize(URI, [return_map]) of
+ #{host := Host} ->
+ PN = case uri_string:normalize(PermittedName, [return_map]) of
+ #{host := PNhost} -> PNhost;
_X -> PermittedName
end,
- match_name(fun is_valid_host_or_domain/2, Host, PN, Rest)
+ match_name(fun is_valid_host_or_domain/2, Host, PN, Rest);
+ _ ->
+ false
end;
match_name(emailAddress, Name, [PermittedName | Rest]) ->
Fun = fun(Email, PermittedEmail) ->
- is_valid_email_address(Email, PermittedEmail,
- string:tokens(PermittedEmail,"@"))
- end,
- match_name(Fun, Name, PermittedName, Rest);
+ is_valid_email_address(Email, PermittedEmail,
+ string:tokens(PermittedEmail,"@"))
+ end,
+ match_name(Fun, Name, PermittedName, Rest);
match_name(dNSName, Name, [PermittedName | Rest]) ->
Fun = fun(Domain, [$.|Domain]) -> true;
@@ -868,75 +868,12 @@ is_valid_subject_alt_name({otherName, #'AnotherName'{}}) ->
is_valid_subject_alt_name({_, _}) ->
false.
-is_ip_address(Address) ->
- case inet_parse:address(Address) of
- {ok, _} ->
- true;
- _ ->
- false
- end.
-
-is_fully_qualified_name(_Name) ->
- true.
-
is_valid_uri(AbsURI) ->
- case split_uri(AbsURI) of
- incomplete ->
- false;
- {StrScheme, _, Host, _, _} ->
- case string:to_lower(StrScheme) of
- Scheme when Scheme =:= "http"; Scheme =:= "ftp" ->
- is_valid_host(Host);
- _ ->
- false
- end
- end.
-
-is_valid_host(Host) ->
- case is_ip_address(Host) of
- true ->
- true;
- false ->
- is_fully_qualified_name(Host)
- end.
-
-%% Could have a more general split URI in stdlib? Maybe when
-%% regexs are improved. Needed also in inets!
-split_uri(Uri) ->
- case split_uri(Uri, ":", {error, no_scheme}, 1, 1) of
- {error, no_scheme} ->
- incomplete;
- {StrScheme, "//" ++ URIPart} ->
- {Authority, PathQuery} =
- split_auth_path(URIPart),
- {UserInfo, HostPort} =
- split_uri(Authority, "@", {"", Authority}, 1, 1),
- {Host, Port} =
- split_uri(HostPort, ":", {HostPort, dummy_port}, 1, 1),
- {StrScheme, UserInfo, Host, Port, PathQuery}
- end.
-
-split_auth_path(URIPart) ->
- case split_uri(URIPart, "/", URIPart, 1, 0) of
- Split = {_, _} ->
- Split;
- URIPart ->
- case split_uri(URIPart, "\\?", URIPart, 1, 0) of
- Split = {_, _} ->
- Split;
- URIPart ->
- {URIPart,""}
- end
- end.
-
-split_uri(UriPart, SplitChar, NoMatchResult, SkipLeft, SkipRight) ->
- case re:run(UriPart, SplitChar) of
- {match,[{Start, _}]} ->
- StrPos = Start + 1,
- {string:substr(UriPart, 1, StrPos - SkipLeft),
- string:substr(UriPart, StrPos + SkipRight, length(UriPart))};
- nomatch ->
- NoMatchResult
+ case uri_string:normalize(AbsURI, [return_map]) of
+ #{scheme := _} ->
+ true;
+ _ ->
+ false
end.
is_rdnSeq({rdnSequence,[]}, {rdnSequence,[none]}) ->
diff --git a/lib/public_key/src/public_key.app.src b/lib/public_key/src/public_key.app.src
index dbd732c384..5833141e87 100644
--- a/lib/public_key/src/public_key.app.src
+++ b/lib/public_key/src/public_key.app.src
@@ -14,7 +14,7 @@
{applications, [asn1, crypto, kernel, stdlib]},
{registered, []},
{env, []},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-6.0","crypto-3.8",
+ {runtime_dependencies, ["stdlib-3.5","kernel-3.0","erts-6.0","crypto-3.8",
"asn1-3.0"]}
]
}.
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 034126655c..931901640a 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -1456,7 +1456,7 @@ ascii_to_lower(String) ->
verify_hostname_extract_fqdn_default({dns_id,S}) ->
S;
verify_hostname_extract_fqdn_default({uri_id,URI}) ->
- {ok,{https,_,Host,_,_,_}} = http_uri:parse(URI),
+ #{scheme := "https", host := Host} = uri_string:normalize(URI, [return_map]),
Host.
diff --git a/lib/ssl/doc/src/ssl_crl_cache.xml b/lib/ssl/doc/src/ssl_crl_cache.xml
index 7a67de3971..738487759a 100644
--- a/lib/ssl/doc/src/ssl_crl_cache.xml
+++ b/lib/ssl/doc/src/ssl_crl_cache.xml
@@ -40,7 +40,7 @@
<name>delete(Entries) -> ok | {error, Reason} </name>
<fsummary> </fsummary>
<type>
- <v> Entries = <seealso marker="inets:http_uri">http_uri:uri() </seealso> | {file, string()} | {der, [<seealso
+ <v> Entries = <seealso marker="stdlib:uri_string">uri_string:uri_string()</seealso> | {file, string()} | {der, [<seealso
marker="public_key:public_key"> public_key:der_encoded() </seealso>]}</v>
<v> Reason = term()</v>
</type>
@@ -55,7 +55,7 @@
<type>
<v> CRLSrc = {file, string()} | {der, [ <seealso
marker="public_key:public_key"> public_key:der_encoded() </seealso> ]}</v>
- <v> URI = <seealso marker="inets:http_uri">http_uri:uri() </seealso> </v>
+ <v> URI = <seealso marker="stdlib:uri_string">uri_string:uri_string() </seealso> </v>
<v> Reason = term()</v>
</type>
<desc>
@@ -63,4 +63,4 @@
</desc>
</func>
</funcs>
-</erlref> \ No newline at end of file
+</erlref>
diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src
index 3c6cd254c1..3962d1fc2c 100644
--- a/lib/ssl/src/ssl.app.src
+++ b/lib/ssl/src/ssl.app.src
@@ -62,5 +62,5 @@
{applications, [crypto, public_key, kernel, stdlib]},
{env, []},
{mod, {ssl_app, []}},
- {runtime_dependencies, ["stdlib-3.2","public_key-1.5","kernel-6.0",
+ {runtime_dependencies, ["stdlib-3.5","public_key-1.5","kernel-6.0",
"erts-10.0","crypto-4.2", "inets-5.10.7"]}]}.
diff --git a/lib/ssl/src/ssl_crl_cache.erl b/lib/ssl/src/ssl_crl_cache.erl
index 8817b0c884..66f46da75f 100644
--- a/lib/ssl/src/ssl_crl_cache.erl
+++ b/lib/ssl/src/ssl_crl_cache.erl
@@ -92,8 +92,8 @@ delete({der, CRLs}) ->
ssl_manager:delete_crls({?NO_DIST_POINT, CRLs});
delete(URI) ->
- case http_uri:parse(URI) of
- {ok, {http, _, _ , _, Path,_}} ->
+ case uri_string:normalize(URI, [return_map]) of
+ #{scheme := "http", path := Path} ->
ssl_manager:delete_crls(string:trim(Path, leading, "/"));
_ ->
{error, {only_http_distribution_points_supported, URI}}
@@ -103,8 +103,8 @@ delete(URI) ->
%%% Internal functions
%%--------------------------------------------------------------------
do_insert(URI, CRLs) ->
- case http_uri:parse(URI) of
- {ok, {http, _, _ , _, Path,_}} ->
+ case uri_string:normalize(URI, [return_map]) of
+ #{scheme := "http", path := Path} ->
ssl_manager:insert_crls(string:trim(Path, leading, "/"), CRLs);
_ ->
{error, {only_http_distribution_points_supported, URI}}
@@ -161,7 +161,7 @@ http_get(URL, Rest, CRLDbInfo, Timeout) ->
cache_lookup(_, undefined) ->
[];
cache_lookup(URL, {{Cache, _}, _}) ->
- {ok, {_, _, _ , _, Path,_}} = http_uri:parse(URL),
+ #{path := Path} = uri_string:normalize(URL, [return_map]),
case ssl_pkix_db:lookup(string:trim(Path, leading, "/"), Cache) of
undefined ->
[];
diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl
index cacd9f2524..e37c13093b 100644
--- a/lib/stdlib/src/io_lib.erl
+++ b/lib/stdlib/src/io_lib.erl
@@ -931,7 +931,7 @@ limit_term(Term, Depth) ->
limit(_, 0) -> '...';
limit([H|T]=L, D) ->
if
- D =:= 1 -> '...';
+ D =:= 1 -> ['...'];
true ->
case printable_list(L) of
true -> L;
@@ -944,7 +944,7 @@ limit(Term, D) when is_map(Term) ->
limit({}=T, _D) -> T;
limit(T, D) when is_tuple(T) ->
if
- D =:= 1 -> '...';
+ D =:= 1 -> {'...'};
true ->
list_to_tuple([limit(element(1, T), D-1)|
limit_tail(tl(tuple_to_list(T)), D-1)])
@@ -961,32 +961,29 @@ limit_tail(Other, D) ->
%% Cannot limit maps properly since there is no guarantee that
%% maps:from_list() creates a map with the same internal ordering of
-%% the selected associations as in Map.
+%% the selected associations as in Map. Instead of subtracting one
+%% from the depth as the map associations are traversed (as is done
+%% for tuples and lists), the same depth is applied to each and every
+%% (returned) association.
limit_map(Map, D) ->
- limit_map(maps:iterator(Map), D, []).
+ %% Keep one extra association to make sure the final ',...' is included.
+ limit_map_body(maps:iterator(Map), D + 1, D, []).
-limit_map(_I, 0, Acc) ->
+limit_map_body(_I, 0, _D0, Acc) ->
maps:from_list(Acc);
-limit_map(I, D, Acc) ->
+limit_map_body(I, D, D0, Acc) ->
case maps:next(I) of
{K, V, NextI} ->
- limit_map(NextI, D-1, [{K,V} | Acc]);
+ limit_map_body(NextI, D-1, D0, [limit_map_assoc(K, V, D0) | Acc]);
none ->
maps:from_list(Acc)
end.
-%% maps:from_list(limit_map_body(erts_internal:maps_to_list(Map, D), D)).
+limit_map_assoc(K, V, D) ->
+ %% Keep keys as are to avoid creating duplicated keys.
+ {K, limit(V, D - 1)}.
-%% limit_map_body(_, 0) -> [{'...', '...'}];
-%% limit_map_body([], _) -> [];
-%% limit_map_body([{K,V}], D) -> [limit_map_assoc(K, V, D)];
-%% limit_map_body([{K,V}|KVs], D) ->
-%% [limit_map_assoc(K, V, D) | limit_map_body(KVs, D-1)].
-
-%% limit_map_assoc(K, V, D) ->
-%% {limit(K, D-1), limit(V, D-1)}.
-
-limit_bitstring(B, _D) -> B. %% Keeps all printable binaries.
+limit_bitstring(B, _D) -> B. % Keeps all printable binaries.
test_limit(_, 0) -> throw(limit);
test_limit([H|T]=L, D) when is_integer(D) ->
@@ -1022,18 +1019,21 @@ test_limit_tuple(T, I, Sz, D) ->
test_limit(element(I, T), D-1),
test_limit_tuple(T, I+1, Sz, D-1).
-test_limit_map(_Map, _D) -> ok.
-%% test_limit_map_body(erts_internal:maps_to_list(Map, D), D).
+test_limit_map(Map, D) ->
+ test_limit_map_body(maps:iterator(Map), D).
-%% test_limit_map_body(_, 0) -> throw(limit);
-%% test_limit_map_body([], _) -> ok;
-%% test_limit_map_body([{K,V}], D) -> test_limit_map_assoc(K, V, D);
-%% test_limit_map_body([{K,V}|KVs], D) ->
-%% test_limit_map_assoc(K, V, D),
-%% test_limit_map_body(KVs, D-1).
+test_limit_map_body(_I, 0) -> throw(limit); % cannot happen
+test_limit_map_body(I, D) ->
+ case maps:next(I) of
+ {K, V, NextI} ->
+ test_limit_map_assoc(K, V, D),
+ test_limit_map_body(NextI, D-1);
+ none ->
+ ok
+ end.
-%% test_limit_map_assoc(K, V, D) ->
-%% test_limit(K, D-1),
-%% test_limit(V, D-1).
+test_limit_map_assoc(K, V, D) ->
+ test_limit(K, D - 1),
+ test_limit(V, D - 1).
test_limit_bitstring(_, _) -> ok.
diff --git a/lib/stdlib/src/io_lib_format.erl b/lib/stdlib/src/io_lib_format.erl
index e345810ca0..2ef4e517d8 100644
--- a/lib/stdlib/src/io_lib_format.erl
+++ b/lib/stdlib/src/io_lib_format.erl
@@ -95,7 +95,7 @@ print([]) ->
[].
print(C, F, Ad, P, Pad, Encoding, Strings) ->
- [$~] ++ print_field_width(F, Ad) ++ print_precision(P) ++
+ [$~] ++ print_field_width(F, Ad) ++ print_precision(P, Pad) ++
print_pad_char(Pad) ++ print_encoding(Encoding) ++
print_strings(Strings) ++ [C].
@@ -103,8 +103,9 @@ print_field_width(none, _Ad) -> "";
print_field_width(F, left) -> integer_to_list(-F);
print_field_width(F, right) -> integer_to_list(F).
-print_precision(none) -> "";
-print_precision(P) -> [$. | integer_to_list(P)].
+print_precision(none, $\s) -> "";
+print_precision(none, _Pad) -> "."; % pad must be second dot
+print_precision(P, _Pad) -> [$. | integer_to_list(P)].
print_pad_char($\s) -> ""; % default, no need to make explicit
print_pad_char(Pad) -> [$., Pad].
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl
index 45363c0592..ac61e3753b 100644
--- a/lib/stdlib/test/io_SUITE.erl
+++ b/lib/stdlib/test/io_SUITE.erl
@@ -2005,6 +2005,7 @@ writes(N, F1) ->
format_string(_Config) ->
%% All but padding is tested by fmt/2.
+ "xxxxxxxsss" = fmt("~10..xs", ["sss"]),
"xxxxxxsssx" = fmt("~10.4.xs", ["sss"]),
"xxxxxxsssx" = fmt("~10.4.*s", [$x, "sss"]),
ok.
@@ -2384,19 +2385,36 @@ limit_term(_Config) ->
{_, 2} = limt({a,b,c,[d,e]}, 2),
{_, 2} = limt({a,b,c,[d,e]}, 3),
{_, 2} = limt({a,b,c,[d,e]}, 4),
+ T0 = [1|{a,b,c}],
+ {_, 2} = limt(T0, 2),
+ {_, 2} = limt(T0, 3),
+ {_, 2} = limt(T0, 4),
{_, 1} = limt(<<"foo">>, 18),
+ {_, 2} = limt({"",[1,2]}, 3),
+ {_, 2} = limt({"",{1,2}}, 3),
+ true = limt_pp({"123456789012345678901234567890",{1,2}}, 3),
ok = blimt(<<"123456789012345678901234567890">>),
+ true = limt_pp(<<"123456789012345678901234567890">>, 3),
+ {_, 2} = limt({<<"kljlkjsl">>,[1,2,3,4]}, 4),
{_, 1} = limt(<<7:3>>, 2),
{_, 1} = limt(<<7:21>>, 2),
{_, 1} = limt([], 2),
{_, 1} = limt({}, 2),
+ {_, 1} = limt({"", ""}, 4),
{_, 1} = limt(#{}, 2),
- {_, 1} = limt(#{[] => {}}, 2),
+ {_, 2} = limt(#{[] => {}}, 1),
+ {_, 2} = limt(#{[] => {}}, 2),
{_, 1} = limt(#{[] => {}}, 3),
T = #{[] => {},[a] => [b]},
- {_, 1} = limt(T, 2),
+ {_, 1} = limt(T, 0),
+ {_, 2} = limt(T, 1),
+ {_, 2} = limt(T, 2),
{_, 1} = limt(T, 3),
{_, 1} = limt(T, 4),
+ T2 = #{[] => {},{} => []},
+ {_, 2} = limt(T2, 1),
+ {_, 2} = limt(T2, 2),
+ {_, 1} = limt(T2, 3),
ok.
blimt(Binary) ->
@@ -2430,3 +2448,12 @@ limt(Term, Depth) when is_integer(Depth) ->
form(Term, Depth) ->
lists:flatten(io_lib:format("~W", [Term, Depth])).
+
+limt_pp(Term, Depth) when is_integer(Depth) ->
+ T1 = io_lib:limit_term(Term, Depth),
+ S = pp(Term, Depth),
+ S1 = pp(T1, Depth),
+ S1 =:= S.
+
+pp(Term, Depth) ->
+ lists:flatten(io_lib:format("~P", [Term, Depth])).