File 5017-Allow-non-indented-empty-content-lines.patch of Package erlang
From 8eb331cfdc77294417330efe4daf06c0cf3e2496 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Fri, 1 Sep 2023 11:04:23 +0200
Subject: [PATCH 7/8] Allow non-indented empty content lines
Besides containing precisely the defined indentation,
an empty content line is allowed to be completely empty.
This is to adhere to common editor's conventions;
lines with only white space is frowned upon.
---
lib/stdlib/src/erl_scan.erl | 28 ++++++---
lib/stdlib/test/erl_scan_SUITE.erl | 92 ++++++++++++++++++++++++++++--
2 files changed, 106 insertions(+), 14 deletions(-)
diff --git a/lib/stdlib/src/erl_scan.erl b/lib/stdlib/src/erl_scan.erl
index d03579d87b..ff7107d948 100644
--- a/lib/stdlib/src/erl_scan.erl
+++ b/lib/stdlib/src/erl_scan.erl
@@ -961,6 +961,11 @@ scan_tqstring_finish(Cs, St, Line, Col, Toks, Tqs, IndentR) ->
%% IndentR :: Indentation characters, reversed
#tqs{ line = Line0, col = Col0, content_r = ContentR } = Tqs,
NcontentR = strip_last_line_newline_r(ContentR),
+ %% NcontentR is now the string's content lines
+ %% including the characters after the opening quote sequence
+ %% (the 0:th line?), in reversed order, each line reversed.
+ %% Newline has been stripped from the last content line,
+ %% all others has newline characters as from the input.
case
tqstring_finish(lists:reverse(IndentR), NcontentR, Line-1)
of
@@ -996,16 +1001,16 @@ strip_last_line_newline_r([LastLineR|ContentR]) ->
strip_newline_r("\n\r"++Rcs) -> Rcs;
strip_newline_r("\n"++Rcs) -> Rcs.
-%% Strip indentation from all content lines but the first,
-%% which contains the characters after the start quote chars,
-%% check that they are white space.
-%%
%% Loop from last to first line and remember the last error,
%% so the last error that is found will be the one reported,
%% that is: the first in the string.
%%
-%% Build the string content by prepending all indentation stripped
-%% lines onto the string: Content.
+%% Build the string content one line at the time by first
+%% prepending the line to Content and then spripping
+%% the defined indentation.
+%%
+%% For the first (0:th) line, strip the newline and then
+%% check that it contains only white space
%%
tqstring_finish(Indent, ContentR, Line) ->
tqstring_finish(Indent, ContentR, Line, undefined, "").
@@ -1035,10 +1040,17 @@ tqstring_finish(
tqstring_finish(Indent, StringsR, Line-1, Nerror, "")
end.
-%% Strip indentation
+%% Strip the defined indentation from the string content
%%
strip_indent(Indent, Cs) ->
- strip_indent(Indent, Cs, 1).
+ case Cs of
+ %% Allow empty content lines to have no indentation
+ "\r\n"++_ -> Cs;
+ "\n"++_ -> Cs;
+ "" -> Cs; % The last newline is stripped
+ _ ->
+ strip_indent(Indent, Cs, 1)
+ end.
%%
strip_indent([C|Indent], [C|Cs], Col) ->
strip_indent(Indent, Cs, Col+1); % Strip
diff --git a/lib/stdlib/test/erl_scan_SUITE.erl b/lib/stdlib/test/erl_scan_SUITE.erl
index a9462dbb72..666e746f8e 100644
--- a/lib/stdlib/test/erl_scan_SUITE.erl
+++ b/lib/stdlib/test/erl_scan_SUITE.erl
@@ -1314,12 +1314,72 @@ triple_quoted_string(Config) when is_list(Config) ->
"\n"
"\"\"\""),
+ {ok,[{string,1,""}],3} =
+ erl_scan:string(
+ "\"\"\"\n"
+ " \n"
+ " \"\"\""),
+
+ {ok,[{string,1,""}],3} =
+ erl_scan:string(
+ "\"\"\"\n"
+ "\n"
+ " \"\"\""),
+
+ {ok,[{string,1,""}],3} =
+ erl_scan:string(
+ "\"\"\"\r\n"
+ " \r\n"
+ " \"\"\""),
+
+ {error,{{2,2},erl_scan,indentation},{3,6}} =
+ erl_scan:string(
+ "\"\"\"\n"
+ " \n" % One space too little indentation
+ " \"\"\"", {1,1}, []),
+
{ok,[{string,1,"\n"}],4} =
erl_scan:string(
"\"\"\"\n"
- "\n\n"
+ "\n"
+ "\n"
"\"\"\""),
+ {ok,[{string,1,"\r\n"}],4} =
+ erl_scan:string(
+ "\"\"\"\n"
+ " \r\n"
+ " \n"
+ " \"\"\""),
+
+ {ok,[{string,1,"\n"}],4} =
+ erl_scan:string(
+ "\"\"\"\n"
+ " \n"
+ "\r\n"
+ " \"\"\""),
+
+ {ok,[{string,1,"\r\n"}],4} =
+ erl_scan:string(
+ "\"\"\"\n"
+ "\r\n"
+ " \n"
+ " \"\"\""),
+
+ {error,{{3,2},erl_scan,indentation},{4,6}} =
+ erl_scan:string(
+ "\"\"\"\n"
+ " \n"
+ " \r\n"
+ " \"\"\"", {1,1}, []),
+
+ {error,{{2,3},erl_scan,indentation},{4,7}} =
+ erl_scan:string(
+ "\"\"\"\n"
+ " \n" % One space too little indentation
+ " \r\n"
+ " \"\"\"", {1,1}, []),
+
{ok,[{string,1,"CR LF"}],3} =
erl_scan:string(
"\"\"\" \t\r\n"
@@ -1342,6 +1402,24 @@ triple_quoted_string(Config) when is_list(Config) ->
" string\r\n"
" \"\"\""),
+ {ok,
+ [{string,1,
+ "this is a string\r\n"
+ "\n"
+ "\r\n"
+ "with three empty lines\n"
+ "\r\n"}],
+ 8} =
+ erl_scan:string(
+ "\"\"\"\r\n"
+ " this is a string\r\n"
+ "\n"
+ " \r\n"
+ " with three empty lines\n"
+ "\r\n"
+ "\n"
+ " \"\"\""),
+
{ok,[{string,1," this is a\n very long\n string"}],5} =
erl_scan:string(
"\"\"\"\n"
@@ -1398,32 +1476,34 @@ triple_quoted_string(Config) when is_list(Config) ->
{error,{{1,4},erl_scan,white_space},{2,4}} =
erl_scan:string(
- "\"\"\"foo\n"
+ "\"\"\"foo\n" % Only white-space allowed after opening quote seq
"\"\"\"", {1,1}, []),
{error,{{2,2},erl_scan,indentation},{3,6}} =
erl_scan:string(
"\"\"\"\n"
- " foo\n"
+ " foo\n" % One space too little indentation
" \"\"\"", {1,1}, []),
{error,{{2,8},erl_scan,indentation},{3,12}} =
erl_scan:string(
"\"\"\"\n"
- " \tfoo\n"
+ " \tfoo\n" % The tab shoud be a space
" \"\"\"", {1,1}, []),
{error,{{1,1},erl_scan,{string,{$",3},"\n\tx\n\t\"\""}},{3,4}} =
erl_scan:string(
"\"\"\"\n"
"\tx\n"
- "\t\"\"", {1,1}, []),
+ "\t\"\"", % Lacking one double-quote char in closing seq
+ {1,1}, []),
{error,{{3,4},erl_scan,{string,$",[]}},{3,5}} =
erl_scan:string(
"\"\"\"\n"
"x\n"
- "\"\"\"\"", {1,1}, []),
+ "\"\"\"\"", % A string starts at the last char but never ends
+ {1,1}, []),
ok.
--
2.35.3