Skip to content

Commit 6874eb7

Browse files
author
José Valim
committed
Deprecate octal and upcase char syntaxes
1 parent 404e95b commit 6874eb7

File tree

15 files changed

+198
-116
lines changed

15 files changed

+198
-116
lines changed

lib/elixir/lib/file.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ defmodule File do
679679
end
680680

681681
defp change_mode_windows(path, file_info) do
682-
case File.chmod(path, (elem(file_info, 7) + 0200)) do
682+
case File.chmod(path, (elem(file_info, 7) + 0o200)) do
683683
:ok -> F.delete(path)
684684
{:error, _reason} = error -> error
685685
end

lib/elixir/lib/inspect.ex

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -212,29 +212,28 @@ defimpl Inspect, for: BitString do
212212

213213
@doc false
214214
# Also used by Regex
215-
def escape_char(char) when char in ?\000..?\377,
216-
do: octify(char)
217-
218-
def escape_char(char), do: hexify(char)
215+
def escape_char(0) do
216+
<<?\\, ?0>>
217+
end
219218

220-
defp octify(byte) do
221-
<< hi :: size(2), mi :: size(3), lo :: size(3) >> = << byte >>
222-
<< ?\\, ?0 + hi, ?0 + mi, ?0 + lo >>
219+
def escape_char(char) when char < 0x100 do
220+
<<a::4, b::4>> = <<char::size(8)>>
221+
<<?\\, ?x, to_hex(a), to_hex(b)>>
223222
end
224223

225-
defp hexify(char) when char < 0x10000 do
224+
def escape_char(char) when char < 0x10000 do
226225
<<a::4, b::4, c::4, d::4>> = <<char::size(16)>>
227226
<<?\\, ?x, ?{, to_hex(a), to_hex(b), to_hex(c), to_hex(d), ?}>>
228227
end
229228

230-
defp hexify(char) when char < 0x1000000 do
229+
def escape_char(char) when char < 0x1000000 do
231230
<<a::4, b::4, c::4, d::4, e::4, f::4>> = <<char::size(24)>>
232231
<<?\\, ?x, ?{, to_hex(a), to_hex(b), to_hex(c),
233232
to_hex(d), to_hex(e), to_hex(f), ?}>>
234233
end
235234

236235
defp to_hex(c) when c in 0..9, do: ?0+c
237-
defp to_hex(c) when c in 10..15, do: ?a+c-10
236+
defp to_hex(c) when c in 10..15, do: ?A+c-10
238237

239238
defp append(<<h, t :: binary>>, binary), do: append(t, << binary :: binary, h >>)
240239
defp append(<<>>, binary), do: binary

lib/elixir/lib/kernel.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,7 @@ defmodule Kernel do
14181418
"<<111, 108, 195, 161, 0>>"
14191419
14201420
iex> inspect("olá" <> <<0>>, binaries: :as_strings)
1421-
"\"olá\\000\""
1421+
"\"olá\\0\""
14221422
14231423
iex> inspect("olá", binaries: :as_binaries)
14241424
"<<111, 108, 195, 161>>"

lib/elixir/lib/macro.ex

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,9 @@ defmodule Macro do
312312
single- and double-quoted strings. Check `unescape_string/2`
313313
for information on how to customize the escaping map.
314314
315-
In this setup, Elixir will escape the following: `\a`, `\b`,
316-
`\d`, `\e`, `\f`, `\n`, `\r`, `\s`, `\t` and `\v`. Octals are
317-
also escaped according to the latin1 set they represent.
315+
In this setup, Elixir will escape the following: `\0`, `\a`, `\b`,
316+
`\d`, `\e`, `\f`, `\n`, `\r`, `\s`, `\t` and `\v`. Hexadecimals
317+
are also supported via `\xNN` and `\x{NN...}` syntax.
318318
319319
This function is commonly used on sigil implementations
320320
(like `~r`, `~s` and others) which receive a raw, unescaped
@@ -345,6 +345,7 @@ defmodule Macro do
345345
representing the codepoint of the character it wants to unescape.
346346
Here is the default mapping function implemented by Elixir:
347347
348+
def unescape_map(?0), do: ?0
348349
def unescape_map(?a), do: ?\a
349350
def unescape_map(?b), do: ?\b
350351
def unescape_map(?d), do: ?\d
@@ -355,20 +356,14 @@ defmodule Macro do
355356
def unescape_map(?s), do: ?\s
356357
def unescape_map(?t), do: ?\t
357358
def unescape_map(?v), do: ?\v
359+
def unescape_map(?x), do: true
358360
def unescape_map(e), do: e
359361
360362
If the `unescape_map` function returns `false`. The char is
361363
not escaped and `\` is kept in the char list.
362364
363-
## Octals
364-
365-
Octals will by default be escaped unless the map function
366-
returns `false` for `?0`.
367-
368-
## Hex
369-
370-
Hexadecimals will by default be escaped unless the map function
371-
returns `false` for `?x`.
365+
Hexadecimals will be escaped if the map function returns `true`
366+
for `?x`.
372367
373368
## Examples
374369

lib/elixir/lib/string.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ defmodule String do
129129
@spec printable?(t) :: boolean
130130

131131
def printable?(<< h :: utf8, t :: binary >>)
132-
when h in ?\040..?\176
132+
when h in 0x20..0x7E
133133
when h in 0xA0..0xD7FF
134134
when h in 0xE000..0xFFFD
135135
when h in 0x10000..0x10FFFF do
@@ -801,10 +801,10 @@ defmodule String do
801801
## Examples
802802
803803
iex> String.chunk(<<?a, ?b, ?c, 0>>, :valid)
804-
["abc\000"]
804+
["abc\0"]
805805
806806
iex> String.chunk(<<?a, ?b, ?c, 0, 0x0ffff::utf8>>, :valid)
807-
["abc\000", <<0x0ffff::utf8>>]
807+
["abc\0", <<0x0ffff::utf8>>]
808808
809809
iex> String.chunk(<<?a, ?b, ?c, 0, 0x0ffff::utf8>>, :printable)
810810
["abc", <<0, 0x0ffff::utf8>>]

lib/elixir/src/elixir_interpolation.erl

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,42 +75,88 @@ unescape_chars(String) ->
7575

7676
unescape_chars(String, Map) ->
7777
Octals = Map($0) /= false,
78-
Hex = Map($x) /= false,
78+
Hex = Map($x) == true,
7979
unescape_chars(String, Map, Octals, Hex, <<>>).
8080

81+
%% Deprecated
82+
8183
unescape_chars(<<$\\,A,B,C,Rest/binary>>, Map, true, Hex, Acc) when ?is_octal(A), A =< $3, ?is_octal(B), ?is_octal(C) ->
84+
io:format(standard_error, "warning: octals inside strings/sigils/chars are deprecated, got: \\~ts~n", [<<A, B, C>>]),
8285
append_escaped(Rest, Map, [A,B,C], true, Hex, Acc, 8);
8386

8487
unescape_chars(<<$\\,A,B,Rest/binary>>, Map, true, Hex, Acc) when ?is_octal(A), ?is_octal(B) ->
88+
io:format(standard_error, "warning: octals inside strings/sigils/chars are deprecated, got: \\~ts~n", [<<A, B>>]),
8589
append_escaped(Rest, Map, [A,B], true, Hex, Acc, 8);
8690

91+
unescape_chars(<<$\\,$0,Rest/binary>>, Map, true, Hex, Acc) ->
92+
append_escaped(Rest, Map, [$0], true, Hex, Acc, 8);
93+
8794
unescape_chars(<<$\\,A,Rest/binary>>, Map, true, Hex, Acc) when ?is_octal(A) ->
95+
io:format(standard_error, "warning: octals inside strings/sigils/chars are deprecated, got: \\~ts~n", [<<A>>]),
8896
append_escaped(Rest, Map, [A], true, Hex, Acc, 8);
8997

90-
unescape_chars(<<$\\,P,A,B,Rest/binary>>, Map, Octal, true, Acc) when (P == $x orelse P == $X), ?is_hex(A), ?is_hex(B) ->
98+
unescape_chars(<<$\\,$X,A,B,Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B) ->
99+
io:format(standard_error, "warning: \\X inside strings/sigils/chars is deprecated, please use \\x instead~n", []),
91100
append_escaped(Rest, Map, [A,B], Octal, true, Acc, 16);
92101

93-
unescape_chars(<<$\\,P,A,Rest/binary>>, Map, Octal, true, Acc) when (P == $x orelse P == $X), ?is_hex(A) ->
102+
unescape_chars(<<$\\,$X,A,Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A) ->
103+
io:format(standard_error, "warning: \\X inside strings/sigils/chars is deprecated, please use \\x instead~n", []),
94104
append_escaped(Rest, Map, [A], Octal, true, Acc, 16);
95105

96-
unescape_chars(<<$\\,P,${,A,$},Rest/binary>>, Map, Octal, true, Acc) when (P == $x orelse P == $X), ?is_hex(A) ->
106+
unescape_chars(<<$\\,$X,${,A,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A) ->
107+
io:format(standard_error, "warning: \\X inside strings/sigils/chars is deprecated, please use \\x instead~n", []),
97108
append_escaped(Rest, Map, [A], Octal, true, Acc, 16);
98109

99-
unescape_chars(<<$\\,P,${,A,B,$},Rest/binary>>, Map, Octal, true, Acc) when (P == $x orelse P == $X), ?is_hex(A), ?is_hex(B) ->
110+
unescape_chars(<<$\\,$X,${,A,B,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B) ->
111+
io:format(standard_error, "warning: \\X inside strings/sigils/chars is deprecated, please use \\x instead~n", []),
100112
append_escaped(Rest, Map, [A,B], Octal, true, Acc, 16);
101113

102-
unescape_chars(<<$\\,P,${,A,B,C,$},Rest/binary>>, Map, Octal, true, Acc) when (P == $x orelse P == $X), ?is_hex(A), ?is_hex(B), ?is_hex(C) ->
114+
unescape_chars(<<$\\,$X,${,A,B,C,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B), ?is_hex(C) ->
115+
io:format(standard_error, "warning: \\X inside strings/sigils/chars is deprecated, please use \\x instead~n", []),
103116
append_escaped(Rest, Map, [A,B,C], Octal, true, Acc, 16);
104117

105-
unescape_chars(<<$\\,P,${,A,B,C,D,$},Rest/binary>>, Map, Octal, true, Acc) when (P == $x orelse P == $X), ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D) ->
118+
unescape_chars(<<$\\,$X,${,A,B,C,D,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D) ->
119+
io:format(standard_error, "warning: \\X inside strings/sigils/chars is deprecated, please use \\x instead~n", []),
106120
append_escaped(Rest, Map, [A,B,C,D], Octal, true, Acc, 16);
107121

108-
unescape_chars(<<$\\,P,${,A,B,C,D,E,$},Rest/binary>>, Map, Octal, true, Acc) when (P == $x orelse P == $X), ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D), ?is_hex(E) ->
109-
append_escaped(Rest, Map, [A,B,C,D,E], Octal, true, Acc, 16);
122+
unescape_chars(<<$\\,$X,${,A,B,C,D,E,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D), ?is_hex(E) ->
123+
io:format(standard_error, "warning: \\X inside strings/sigils/chars is deprecated, please use \\x instead~n", []),
124+
append_escaped(Rest, Map, [A,B,C,D,E], Octal, true, Acc, 16);
110125

111-
unescape_chars(<<$\\,P,${,A,B,C,D,E,F,$},Rest/binary>>, Map, Octal, true, Acc) when (P == $x orelse P == $X), ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D), ?is_hex(E), ?is_hex(F) ->
126+
unescape_chars(<<$\\,$X,${,A,B,C,D,E,F,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D), ?is_hex(E), ?is_hex(F) ->
127+
io:format(standard_error, "warning: \\X inside strings/sigils/chars is deprecated, please use \\x instead~n", []),
112128
append_escaped(Rest, Map, [A,B,C,D,E,F], Octal, true, Acc, 16);
113129

130+
%% End of deprecated
131+
132+
unescape_chars(<<$\\,$x,A,B,Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B) ->
133+
append_escaped(Rest, Map, [A,B], Octal, true, Acc, 16);
134+
135+
unescape_chars(<<$\\,$x,A,Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A) ->
136+
append_escaped(Rest, Map, [A], Octal, true, Acc, 16);
137+
138+
unescape_chars(<<$\\,$x,${,A,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A) ->
139+
append_escaped(Rest, Map, [A], Octal, true, Acc, 16);
140+
141+
unescape_chars(<<$\\,$x,${,A,B,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B) ->
142+
append_escaped(Rest, Map, [A,B], Octal, true, Acc, 16);
143+
144+
unescape_chars(<<$\\,$x,${,A,B,C,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B), ?is_hex(C) ->
145+
append_escaped(Rest, Map, [A,B,C], Octal, true, Acc, 16);
146+
147+
unescape_chars(<<$\\,$x,${,A,B,C,D,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D) ->
148+
append_escaped(Rest, Map, [A,B,C,D], Octal, true, Acc, 16);
149+
150+
unescape_chars(<<$\\,$x,${,A,B,C,D,E,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D), ?is_hex(E) ->
151+
append_escaped(Rest, Map, [A,B,C,D,E], Octal, true, Acc, 16);
152+
153+
unescape_chars(<<$\\,$x,${,A,B,C,D,E,F,$},Rest/binary>>, Map, Octal, true, Acc) when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D), ?is_hex(E), ?is_hex(F) ->
154+
append_escaped(Rest, Map, [A,B,C,D,E,F], Octal, true, Acc, 16);
155+
156+
unescape_chars(<<$\\,$x,_/binary>>, _Map, _Octal, true, _Acc) ->
157+
Msg = <<"missing hex sequence after \\x">>,
158+
error('Elixir.ArgumentError':exception([{message,Msg}]));
159+
114160
unescape_chars(<<$\\,Escaped,Rest/binary>>, Map, Octals, Hex, Acc) ->
115161
case Map(Escaped) of
116162
false -> unescape_chars(Rest, Map, Octals, Hex, <<Acc/binary, $\\, Escaped>>);
@@ -134,6 +180,7 @@ append_escaped(Rest, Map, List, Octal, Hex, Acc, Base) ->
134180

135181
% Unescape Helpers
136182

183+
unescape_map($0) -> 0;
137184
unescape_map($a) -> 7;
138185
unescape_map($b) -> $\b;
139186
unescape_map($d) -> $\d;
@@ -144,6 +191,7 @@ unescape_map($r) -> $\r;
144191
unescape_map($s) -> $\s;
145192
unescape_map($t) -> $\t;
146193
unescape_map($v) -> $\v;
194+
unescape_map($x) -> true;
147195
unescape_map(E) -> E.
148196

149197
% Extract Helpers

0 commit comments

Comments
 (0)