Skip to content

Commit

Permalink
Merge pull request #957 from pguyot/w47/fix-format-atoms
Browse files Browse the repository at this point in the history
Fix encoding of atoms with format

Closes #923

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
  • Loading branch information
bettio committed Nov 22, 2023
2 parents 3b8e85e + 6c169ba commit 0615929
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
57 changes: 56 additions & 1 deletion libs/estdlib/src/io_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,14 @@ format_string(Format, T) ->
format_spw(Format, T).

%% @private
format_spw(_Format, T) when is_atom(T) ->
format_spw(#format{control = s}, T) when is_atom(T) ->
erlang:atom_to_list(T);
format_spw(_Format, T) when is_atom(T) ->
AtomStr = erlang:atom_to_list(T),
case atom_requires_quotes(T, AtomStr) of
false -> AtomStr;
true -> [$', AtomStr, $']
end;
format_spw(#format{control = s, mod = t} = Format, T) when is_binary(T) ->
case unicode:characters_to_list(T, utf8) of
L when is_list(L) -> L;
Expand Down Expand Up @@ -287,6 +293,55 @@ format_spw(Format, T) when is_map(T) ->
$}
].

%% We will probably need to add 'maybe' with OTP 27
-define(RESERVED_KEYWORDS, [
'after',
'and',
'andalso',
'band',
'begin',
'bnot',
'bor',
'bsl',
'bsr',
'bxor',
'case',
'catch',
'cond',
'div',
'end',
'fun',
'if',
'let',
'not',
'of',
'or',
'orelse',
'receive',
'rem',
'try',
'when',
'xor'
]).

%% @private
atom_requires_quotes(Atom, AtomStr) ->
case lists:member(Atom, ?RESERVED_KEYWORDS) of
true -> true;
false -> atom_requires_quotes0(AtomStr)
end.

atom_requires_quotes0([C | _T]) when C < $a orelse C > $z -> true;
atom_requires_quotes0([_C | T]) -> atom_requires_quotes1(T).

atom_requires_quotes1([]) -> false;
atom_requires_quotes1([$@ | T]) -> atom_requires_quotes1(T);
atom_requires_quotes1([$_ | T]) -> atom_requires_quotes1(T);
atom_requires_quotes1([C | T]) when C >= $A andalso C =< $Z -> atom_requires_quotes1(T);
atom_requires_quotes1([C | T]) when C >= $0 andalso C =< $9 -> atom_requires_quotes1(T);
atom_requires_quotes1([C | T]) when C >= $a andalso C =< $z -> atom_requires_quotes1(T);
atom_requires_quotes1(_) -> true.

%% @private
format_integer(#format{control = C, precision = Precision0}, T0) when
is_integer(T0) andalso (C =:= '#' orelse C =:= '+')
Expand Down
12 changes: 12 additions & 0 deletions tests/libs/estdlib/test_io_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,18 @@ test() ->
),

?ASSERT_MATCH(?FLT(io_lib:format("~p", [foo])), "foo"),
?ASSERT_MATCH(?FLT(io_lib:format("~p", ['-foo'])), "'-foo'"),
?ASSERT_MATCH(?FLT(io_lib:format("~p", ['try'])), "'try'"),
?ASSERT_MATCH(?FLT(io_lib:format("~p", ['maybe'])), "maybe"),
?ASSERT_MATCH(?FLT(io_lib:format("~w", [foo])), "foo"),
?ASSERT_MATCH(?FLT(io_lib:format("~w", ['-foo'])), "'-foo'"),
?ASSERT_MATCH(?FLT(io_lib:format("~w", ['try'])), "'try'"),
?ASSERT_MATCH(?FLT(io_lib:format("~w", ['maybe'])), "maybe"),
?ASSERT_MATCH(?FLT(io_lib:format("~s", [foo])), "foo"),
?ASSERT_MATCH(?FLT(io_lib:format("~s", ['-foo'])), "-foo"),
?ASSERT_MATCH(?FLT(io_lib:format("~s", ['try'])), "try"),
?ASSERT_MATCH(?FLT(io_lib:format("~s", ['maybe'])), "maybe"),

?ASSERT_MATCH(?FLT(io_lib:format("\t~p", [bar])), "\tbar"),

?ASSERT_MATCH(
Expand Down

0 comments on commit 0615929

Please sign in to comment.