From 2990325d5ae7f7fd119aea540a2edae4f97e76d9 Mon Sep 17 00:00:00 2001 From: Hans Bolinder Date: Tue, 27 Sep 2016 12:50:21 +0200 Subject: parsetools: Correct counting of newlines See https://bugs.erlang.org/browse/ERL-263 The fix in commit c9bc5c94 of PR-431 (https://github.com/erlang/otp/pull/431) introduced new problems. --- lib/parsetools/include/leexinc.hrl | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'lib/parsetools/include') diff --git a/lib/parsetools/include/leexinc.hrl b/lib/parsetools/include/leexinc.hrl index 2657fdcfaa..b4449607cb 100644 --- a/lib/parsetools/include/leexinc.hrl +++ b/lib/parsetools/include/leexinc.hrl @@ -36,8 +36,10 @@ string(Ics0, L0, Tcs, Ts) -> string_cont(Ics1, L1, yyaction(A, Alen, Tcs, L0), Ts); {reject,_Alen,Tlen,_Ics1,L1,_S1} -> % After a non-accepting state {error,{L0,?MODULE,{illegal,yypre(Tcs, Tlen+1)}},L1}; - {A,Alen,_Tlen,_Ics1,_L1,_S1} -> - string_cont(yysuf(Tcs, Alen), L0, yyaction(A, Alen, Tcs, L0), Ts) + {A,Alen,Tlen,_Ics1,L1,_S1} -> + Tcs1 = yysuf(Tcs, Alen), + L2 = adjust_line(Tlen, Alen, Tcs1, L1), + string_cont(Tcs1, L2, yyaction(A, Alen, Tcs, L0), Ts) end. %% string_cont(RestChars, Line, Token, Tokens) @@ -107,8 +109,10 @@ token(S0, Ics0, L0, Tcs, Tlen0, Tline, A0, Alen0) -> {reject,_Alen1,Tlen1,Ics1,L1,_S1} -> % No token match Error = {Tline,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, {done,{error,Error,L1},Ics1}; - {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> % Use last accept match - token_cont(yysuf(Tcs, Alen1), L0, yyaction(A1, Alen1, Tcs, Tline)) + {A1,Alen1,Tlen1,_Ics1,L1,_S1} -> % Use last accept match + Tcs1 = yysuf(Tcs, Alen1), + L2 = adjust_line(Tlen1, Alen1, Tcs1, L1), + token_cont(Tcs1, L2, yyaction(A1, Alen1, Tcs, Tline)) end. %% token_cont(RestChars, Line, Token) @@ -181,9 +185,11 @@ tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Ts, A0, Alen0) -> %% Skip rest of tokens. Error = {L1,?MODULE,{illegal,yypre(Tcs, Tlen1+1)}}, skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); - {A1,Alen1,_Tlen1,_Ics1,_L1,_S1} -> + {A1,Alen1,Tlen1,_Ics1,L1,_S1} -> Token = yyaction(A1, Alen1, Tcs, Tline), - tokens_cont(yysuf(Tcs, Alen1), L0, Token, Ts) + Tcs1 = yysuf(Tcs, Alen1), + L2 = adjust_line(Tlen1, Alen1, Tcs1, L1), + tokens_cont(Tcs1, L2, Token, Ts) end. %% tokens_cont(RestChars, Line, Token, Tokens) @@ -235,9 +241,11 @@ skip_tokens(S0, Ics0, L0, Tcs, Tlen0, Tline, Error, A0, Alen0) -> {done,{error,Error,L1},eof}; {reject,_Alen1,Tlen1,_Ics1,L1,_S1} -> skip_tokens(yysuf(Tcs, Tlen1+1), L1, Error); - {A1,Alen1,_Tlen1,_Ics1,L1,_S1} -> + {A1,Alen1,Tlen1,_Ics1,L1,_S1} -> Token = yyaction(A1, Alen1, Tcs, Tline), - skip_cont(yysuf(Tcs, Alen1), L1, Token, Error) + Tcs1 = yysuf(Tcs, Alen1), + L2 = adjust_line(Tlen1, Alen1, Tcs1, L1), + skip_cont(Tcs1, L2, Token, Error) end. %% skip_cont(RestChars, Line, Token, Error) @@ -269,6 +277,17 @@ yyrev(List, Tail) -> lists:reverse(List, Tail). yypre(List, N) -> lists:sublist(List, N). yysuf(List, N) -> lists:nthtail(N, List). +%% adjust_line(TokenLength, AcceptLength, Chars, Line) -> NewLine +%% Make sure that newlines in Chars are not counted twice. +%% Line has been updated with respect to newlines in the prefix of +%% Chars consisting of (TokenLength - AcceptLength) characters. + +adjust_line(N, N, _Cs, L) -> L; +adjust_line(T, A, [$\n|Cs], L) -> + adjust_line(T-1, A, Cs, L-1); +adjust_line(T, A, [_|Cs], L) -> + adjust_line(T-1, A, Cs, L). + %% yystate() -> InitialState. %% yystate(State, InChars, Line, CurrTokLen, AcceptAction, AcceptLen) -> %% {Action, AcceptLen, RestChars, Line} | -- cgit v1.2.3