mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-20 14:19:17 +02:00
codetools: parse multiline string constant
This commit is contained in:
parent
89a9d84d34
commit
e2ad6b3d8d
5
components/anchordocking/Makefile.compiled
Normal file
5
components/anchordocking/Makefile.compiled
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CONFIG>
|
||||||
|
<Makefile Value="2"/>
|
||||||
|
<Params Value=" -Fu../../packager/units/$(CPU_TARGET)-$(OS_TARGET);../lazutils/lib/$(CPU_TARGET)-$(OS_TARGET);../freetype/lib/$(CPU_TARGET)-$(OS_TARGET);../../lcl/units/$(CPU_TARGET)-$(OS_TARGET);../../lcl/units/$(CPU_TARGET)-$(OS_TARGET)/$(LCL_PLATFORM);. -MObjFPC -Scghi -O1 -g -gl -l -vewnhibq -dLCL -dLCL$(LCL_PLATFORM) anchordockpkg.pas"/>
|
||||||
|
</CONFIG>
|
5
components/anchordocking/design/Makefile.compiled
Normal file
5
components/anchordocking/design/Makefile.compiled
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CONFIG>
|
||||||
|
<Makefile Value="2"/>
|
||||||
|
<Params Value=" -Fu../../../packager/units/$(CPU_TARGET)-$(OS_TARGET);../../lazutils/lib/$(CPU_TARGET)-$(OS_TARGET);../../buildintf/units/$(CPU_TARGET)-$(OS_TARGET);../../freetype/lib/$(CPU_TARGET)-$(OS_TARGET);../../../lcl/units/$(CPU_TARGET)-$(OS_TARGET);../../../lcl/units/$(CPU_TARGET)-$(OS_TARGET)/$(LCL_PLATFORM);../units/$(CPU_TARGET)-$(OS_TARGET)/$(LCL_PLATFORM);../../lazcontrols/lib/$(CPU_TARGET)-$(OS_TARGET)/$(LCL_PLATFORM);../../ideintf/units/$(CPU_TARGET)-$(OS_TARGET)/$(LCL_PLATFORM);. -MObjFPC -Scghi -O1 -g -gl -l -vewnhibq -dLCL -dLCL$(LCL_PLATFORM) anchordockingdsgn.pas"/>
|
||||||
|
</CONFIG>
|
@ -1409,7 +1409,17 @@ begin
|
|||||||
begin
|
begin
|
||||||
inc(Result);
|
inc(Result);
|
||||||
while (Result<=MaxPos) do begin
|
while (Result<=MaxPos) do begin
|
||||||
if (ASource[Result] in ['''',#10,#13]) then
|
if (ASource[Result] in ['''',#0,#10,#13]) then
|
||||||
|
break;
|
||||||
|
inc(Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
inc(Result);
|
||||||
|
while (Result<=MaxPos) do begin
|
||||||
|
if (ASource[Result] in ['`',#0]) then
|
||||||
break;
|
break;
|
||||||
inc(Result);
|
inc(Result);
|
||||||
end;
|
end;
|
||||||
@ -1493,11 +1503,16 @@ begin
|
|||||||
begin
|
begin
|
||||||
inc(Result);
|
inc(Result);
|
||||||
while (Result<=MaxPos) do begin
|
while (Result<=MaxPos) do begin
|
||||||
if (ASource[Result]<>'''') then
|
case ASource[Result] of
|
||||||
inc(Result)
|
'''':
|
||||||
else begin
|
begin
|
||||||
inc(Result);
|
inc(Result);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
#0,#10,#13:
|
||||||
break;
|
break;
|
||||||
|
else
|
||||||
|
inc(Result);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2106,7 +2121,7 @@ begin
|
|||||||
inc(Src);
|
inc(Src);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
'''','#': // string constant
|
'''','#','`': // string constant
|
||||||
begin
|
begin
|
||||||
while true do begin
|
while true do begin
|
||||||
case Src^ of
|
case Src^ of
|
||||||
@ -2124,11 +2139,19 @@ begin
|
|||||||
'''':
|
'''':
|
||||||
begin
|
begin
|
||||||
inc(Src);
|
inc(Src);
|
||||||
while not (Src^ in ['''',#0]) do
|
while not (Src^ in ['''',#0,#10,#13]) do
|
||||||
inc(Src);
|
inc(Src);
|
||||||
if Src^='''' then
|
if Src^='''' then
|
||||||
inc(Src);
|
inc(Src);
|
||||||
end;
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
inc(Src);
|
||||||
|
while not (Src^ in ['`',#0]) do
|
||||||
|
inc(Src);
|
||||||
|
if Src^='`' then
|
||||||
|
inc(Src);
|
||||||
|
end;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
@ -2245,6 +2268,13 @@ var
|
|||||||
dec(Position);
|
dec(Position);
|
||||||
until (Position<1) or (Source[Position] in [#0,#10,#13,'''']);
|
until (Position<1) or (Source[Position] in [#0,#10,#13,'''']);
|
||||||
end;
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
dec(Position);
|
||||||
|
repeat
|
||||||
|
dec(Position);
|
||||||
|
until (Position<1) or (Source[Position] in [#0,'`']);
|
||||||
|
end;
|
||||||
'0'..'9','A'..'Z','a'..'z':
|
'0'..'9','A'..'Z','a'..'z':
|
||||||
begin
|
begin
|
||||||
// test if char constant
|
// test if char constant
|
||||||
@ -2356,6 +2386,18 @@ var
|
|||||||
if IsStringConstant then break;
|
if IsStringConstant then break;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
// a multiline string constant -> skip it
|
||||||
|
OldPrePos:=PrePos;
|
||||||
|
while (PrePos<Position) do begin
|
||||||
|
inc(PrePos);
|
||||||
|
if Source[PrePos]='`' then
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
if IsStringConstant then break;
|
||||||
|
end;
|
||||||
|
|
||||||
#10,#13:
|
#10,#13:
|
||||||
// no comment and no string constant found
|
// no comment and no string constant found
|
||||||
break;
|
break;
|
||||||
@ -2445,7 +2487,7 @@ begin
|
|||||||
// read atom
|
// read atom
|
||||||
if IsStringConstant then begin
|
if IsStringConstant then begin
|
||||||
Position:=OldPrePos;
|
Position:=OldPrePos;
|
||||||
if (Position>1) and (Source[Position-1]='''') then begin
|
if (Position>1) and (Source[Position-1] in ['''','`']) then begin
|
||||||
ReadStringConstantBackward;
|
ReadStringConstantBackward;
|
||||||
end;
|
end;
|
||||||
exit;
|
exit;
|
||||||
@ -2473,7 +2515,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
'''':
|
'''','`':
|
||||||
begin
|
begin
|
||||||
inc(Position);
|
inc(Position);
|
||||||
ReadStringConstantBackward;
|
ReadStringConstantBackward;
|
||||||
@ -2683,7 +2725,7 @@ begin
|
|||||||
inc(p);
|
inc(p);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
'''','#': // string constant
|
'''','#','`': // string constant
|
||||||
begin
|
begin
|
||||||
while true do begin
|
while true do begin
|
||||||
case p^ of
|
case p^ of
|
||||||
@ -2696,7 +2738,14 @@ begin
|
|||||||
'''':
|
'''':
|
||||||
begin
|
begin
|
||||||
inc(p);
|
inc(p);
|
||||||
while not (p^ in ['''',#10,#13]) do
|
while not (p^ in ['''',#0,#10,#13]) do
|
||||||
|
inc(p);
|
||||||
|
inc(p);
|
||||||
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
inc(p);
|
||||||
|
while not (p^ in ['`',#0]) do
|
||||||
inc(p);
|
inc(p);
|
||||||
inc(p);
|
inc(p);
|
||||||
end;
|
end;
|
||||||
@ -2819,6 +2868,20 @@ function FindStartOfAtom(const Source: string; Position: integer): integer;
|
|||||||
until (Source[PrePos]='''');
|
until (Source[PrePos]='''');
|
||||||
p:=PrePos;
|
p:=PrePos;
|
||||||
end;
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
PrePos:=p;
|
||||||
|
dec(PrePos);
|
||||||
|
repeat
|
||||||
|
dec(PrePos);
|
||||||
|
if (PrePos<1) then begin
|
||||||
|
// the StartPos was the start of a string constant
|
||||||
|
p:=StartPos-1;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
until (Source[PrePos]='`');
|
||||||
|
p:=PrePos;
|
||||||
|
end;
|
||||||
'0'..'9','A'..'Z','a'..'z':
|
'0'..'9','A'..'Z','a'..'z':
|
||||||
begin
|
begin
|
||||||
// test if char constant
|
// test if char constant
|
||||||
@ -2887,7 +2950,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
'''':
|
'''','`':
|
||||||
begin
|
begin
|
||||||
// could be start or end
|
// could be start or end
|
||||||
inc(Result);
|
inc(Result);
|
||||||
@ -4078,6 +4141,19 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
inc(Result);
|
||||||
|
while (Result<=MaxPos) do begin
|
||||||
|
if (ASource[Result]<>'`') then
|
||||||
|
inc(Result)
|
||||||
|
else begin
|
||||||
|
inc(Result);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
'/':
|
'/':
|
||||||
begin
|
begin
|
||||||
inc(Result);
|
inc(Result);
|
||||||
@ -4123,7 +4199,7 @@ var
|
|||||||
l: Integer;
|
l: Integer;
|
||||||
p: PChar;
|
p: PChar;
|
||||||
begin
|
begin
|
||||||
SetLength(Result,length(Src));
|
SetLength(Result{%H-},length(Src));
|
||||||
SrcPos:=1;
|
SrcPos:=1;
|
||||||
ResultPos:=1;
|
ResultPos:=1;
|
||||||
while SrcPos<=length(Src) do begin
|
while SrcPos<=length(Src) do begin
|
||||||
@ -4453,7 +4529,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
case p1^ of
|
case p1^ of
|
||||||
'''':
|
'''','`':
|
||||||
// compare string constants case sensitive
|
// compare string constants case sensitive
|
||||||
exit(CompareStringConstants(p1,p2));
|
exit(CompareStringConstants(p1,p2));
|
||||||
'{':
|
'{':
|
||||||
@ -4495,9 +4571,13 @@ end;
|
|||||||
function CompareStringConstants(p1, p2: PChar): integer;
|
function CompareStringConstants(p1, p2: PChar): integer;
|
||||||
// 1: 'aa' 'ab' because bigger
|
// 1: 'aa' 'ab' because bigger
|
||||||
// 1: 'aa' 'a' because longer
|
// 1: 'aa' 'a' because longer
|
||||||
|
var
|
||||||
|
s1, s2: Char;
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := 0;
|
||||||
if (p1^='''') and (p2^='''') then begin
|
s1:=p1^;
|
||||||
|
s2:=p2^;
|
||||||
|
if (s1 in ['''','`']) and (s2 in ['''','`']) then begin
|
||||||
inc(p1);
|
inc(p1);
|
||||||
inc(p2);
|
inc(p2);
|
||||||
repeat
|
repeat
|
||||||
@ -4507,19 +4587,19 @@ begin
|
|||||||
exit(-1); // p2 bigger
|
exit(-1); // p2 bigger
|
||||||
inc(p1);
|
inc(p1);
|
||||||
inc(p2);
|
inc(p2);
|
||||||
if p1^='''' then begin
|
if p1^=s1 then begin
|
||||||
// maybe ''
|
// maybe '' or ``
|
||||||
inc(p1);
|
inc(p1);
|
||||||
inc(p2);
|
inc(p2);
|
||||||
if p1^='''' then begin
|
if p1^=s1 then begin
|
||||||
if p2^='''' then begin
|
if p2^=s2 then begin
|
||||||
inc(p1);
|
inc(p1);
|
||||||
inc(p2);
|
inc(p2);
|
||||||
end else begin
|
end else begin
|
||||||
// p1 is longer (e.g.: 'a''b' 'a')
|
// p1 is longer (e.g.: 'a''b' 'a')
|
||||||
exit(1);
|
exit(1);
|
||||||
end;
|
end;
|
||||||
end else if p2^='''' then begin
|
end else if p2^=s2 then begin
|
||||||
// p2 is longer (e.g. 'a' 'a''b')
|
// p2 is longer (e.g. 'a' 'a''b')
|
||||||
exit(-1);
|
exit(-1);
|
||||||
end else begin
|
end else begin
|
||||||
@ -4527,25 +4607,28 @@ begin
|
|||||||
exit(0);
|
exit(0);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if p1^ in [#0,#10,#13] then begin
|
if ((s1='''') and (p1^ in [#0,#10,#13]))
|
||||||
|
or ((s1='`') and (p1^=#0)) then begin
|
||||||
// end of p1 found
|
// end of p1 found
|
||||||
if p2^ in [#0,#10,#13] then begin
|
if ((s2='''') and (p2^ in [#0,#10,#13]))
|
||||||
|
or ((s2='`') and (p2^=#0)) then begin
|
||||||
// same
|
// same
|
||||||
exit(0);
|
exit(0);
|
||||||
end else begin
|
end else begin
|
||||||
// p2 is longer
|
// p2 is longer
|
||||||
exit(-1);
|
exit(-1);
|
||||||
end;
|
end;
|
||||||
end else if p2^ in [#0,#10,#13] then begin
|
end else if ((s2='''') and (p2^ in [#0,#10,#13]))
|
||||||
|
or ((s2='`') and (p2^=#0)) then begin
|
||||||
// p1 is longer
|
// p1 is longer
|
||||||
exit(1);
|
exit(1);
|
||||||
end;
|
end;
|
||||||
until false;
|
until false;
|
||||||
end else begin
|
end else begin
|
||||||
if p1^='''' then
|
if p1^=s1 then
|
||||||
// p1 longer
|
// p1 longer
|
||||||
exit(1)
|
exit(1)
|
||||||
else if p2^='''' then
|
else if p2^=s2 then
|
||||||
// p2 longer
|
// p2 longer
|
||||||
exit(-1)
|
exit(-1)
|
||||||
else
|
else
|
||||||
@ -4748,11 +4831,21 @@ begin
|
|||||||
while (Result<=MaxPos) do begin
|
while (Result<=MaxPos) do begin
|
||||||
c:=Source[Result];
|
c:=Source[Result];
|
||||||
if IsIdentStartChar[c] then exit;
|
if IsIdentStartChar[c] then exit;
|
||||||
if c='''' then begin
|
case c of
|
||||||
// skip string constant
|
'''':
|
||||||
inc(Result);
|
begin
|
||||||
while (Result<=MaxPos) and (not (Source[Result] in ['''',#10,#13])) do
|
// skip string constant
|
||||||
inc(Result);
|
inc(Result);
|
||||||
|
while (Result<=MaxPos) and (not (Source[Result] in ['''',#10,#13])) do
|
||||||
|
inc(Result);
|
||||||
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
// skip multiline string constant
|
||||||
|
inc(Result);
|
||||||
|
while (Result<=MaxPos) and (Source[Result]<>'`') do
|
||||||
|
inc(Result);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
inc(Result);
|
inc(Result);
|
||||||
end;
|
end;
|
||||||
@ -4917,7 +5010,7 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
if TabWidth<=0 then begin
|
if TabWidth<=0 then begin
|
||||||
SetLength(Result,Indent);
|
SetLength(Result{%H-},Indent);
|
||||||
if Indent>0 then
|
if Indent>0 then
|
||||||
FillChar(Result[1],length(Result),' ');
|
FillChar(Result[1],length(Result),' ');
|
||||||
end else begin
|
end else begin
|
||||||
@ -5101,7 +5194,7 @@ var
|
|||||||
l: Integer;
|
l: Integer;
|
||||||
begin
|
begin
|
||||||
l:=DottedIdentifierLength(Identifier);
|
l:=DottedIdentifierLength(Identifier);
|
||||||
SetLength(Result,l);
|
SetLength(Result{%H-},l);
|
||||||
if l>0 then
|
if l>0 then
|
||||||
System.Move(Identifier^,Result[1],l);
|
System.Move(Identifier^,Result[1],l);
|
||||||
end;
|
end;
|
||||||
@ -5182,7 +5275,7 @@ var CodePos, ResultPos, CodeLen, SpaceEndPos: integer;
|
|||||||
c1, c2: char;
|
c1, c2: char;
|
||||||
begin
|
begin
|
||||||
CodeLen:=length(ACode);
|
CodeLen:=length(ACode);
|
||||||
SetLength(Result,CodeLen);
|
SetLength(Result{%H-},CodeLen);
|
||||||
CodePos:=1;
|
CodePos:=1;
|
||||||
ResultPos:=1;
|
ResultPos:=1;
|
||||||
while CodePos<=CodeLen do begin
|
while CodePos<=CodeLen do begin
|
||||||
|
@ -2044,7 +2044,7 @@ begin
|
|||||||
// first read and compute needed length
|
// first read and compute needed length
|
||||||
ReadIt;
|
ReadIt;
|
||||||
// allocate space and copy tokens
|
// allocate space and copy tokens
|
||||||
SetLength(s,p-1);
|
SetLength(s{%H-},p-1);
|
||||||
ReadIt;
|
ReadIt;
|
||||||
Result:=s;
|
Result:=s;
|
||||||
end;
|
end;
|
||||||
|
@ -881,7 +881,7 @@ var
|
|||||||
begin
|
begin
|
||||||
if (CurPos.StartPos<1) or (CurPos.StartPos>SrcLen) then exit(false);
|
if (CurPos.StartPos<1) or (CurPos.StartPos>SrcLen) then exit(false);
|
||||||
p:=@Src[CurPos.StartPos];
|
p:=@Src[CurPos.StartPos];
|
||||||
Result:=(p^ in ['''','#']) or ((p^='^') and (p[1] in ['A'..'Z']));
|
Result:=(p^ in ['''','#','`']) or ((p^='^') and (p[1] in ['A'..'Z']));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomCodeTool.AtomIsCharConstant: boolean;
|
function TCustomCodeTool.AtomIsCharConstant: boolean;
|
||||||
@ -922,6 +922,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
inc(p);
|
||||||
|
if p^='`' then begin
|
||||||
|
// could be ````
|
||||||
|
if (p[1]<>'`') or (p[2]<>'`') then exit;
|
||||||
|
inc(p,3);
|
||||||
|
end else begin
|
||||||
|
// could be `a`
|
||||||
|
if p[1]<>'`' then exit;
|
||||||
|
inc(p,2);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
'^':
|
'^':
|
||||||
begin
|
begin
|
||||||
if not (p[1] in ['A'..'Z']) then exit;
|
if not (p[1] in ['A'..'Z']) then exit;
|
||||||
@ -930,18 +944,25 @@ begin
|
|||||||
|
|
||||||
end;
|
end;
|
||||||
// check that no second character is following
|
// check that no second character is following
|
||||||
Result:=not (p^ in ['''','#','^']);
|
Result:=not (p^ in ['''','`','#','^']);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomCodeTool.AtomIsEmptyStringConstant: boolean;
|
function TCustomCodeTool.AtomIsEmptyStringConstant: boolean;
|
||||||
var
|
var
|
||||||
p: LongInt;
|
p: LongInt;
|
||||||
|
c: Char;
|
||||||
begin
|
begin
|
||||||
p:=CurPos.StartPos;
|
p:=CurPos.StartPos;
|
||||||
while (p<=SrcLen) and (Src[p]='''') do inc(p);
|
if (p>SrcLen) then exit(false);
|
||||||
dec(p,CurPos.StartPos);
|
c:=Src[p];
|
||||||
Result:=(p>0) and ((p and 1)=0);
|
if not (c in ['''','`']) then exit(false);
|
||||||
|
inc(p);
|
||||||
|
if (p>SrcLen) then exit(true);
|
||||||
|
if Src[p]<>c then exit(false);
|
||||||
|
inc(p);
|
||||||
|
if (p>SrcLen) then exit(true);
|
||||||
|
if Src[p] in ['''','`','#'] then exit(false);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomCodeTool.LastAtomIs(BackIndex: integer;
|
function TCustomCodeTool.LastAtomIs(BackIndex: integer;
|
||||||
@ -1181,7 +1202,7 @@ begin
|
|||||||
CurPos.Flag:=cafEnd;
|
CurPos.Flag:=cafEnd;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
'''','#':
|
'''','#','`':
|
||||||
begin
|
begin
|
||||||
// string constant
|
// string constant
|
||||||
while true do begin
|
while true do begin
|
||||||
@ -1218,6 +1239,23 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
inc(p);
|
||||||
|
while true do begin
|
||||||
|
case p^ of
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
inc(p);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
#0:
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
inc(p);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
'^':
|
'^':
|
||||||
begin
|
begin
|
||||||
inc(p);
|
inc(p);
|
||||||
@ -1404,6 +1442,13 @@ var
|
|||||||
dec(CurPos.StartPos);
|
dec(CurPos.StartPos);
|
||||||
until (CurPos.StartPos<1) or (Src[CurPos.StartPos] in [#0,#10,#13,'''']);
|
until (CurPos.StartPos<1) or (Src[CurPos.StartPos] in [#0,#10,#13,'''']);
|
||||||
end;
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
dec(CurPos.StartPos);
|
||||||
|
repeat
|
||||||
|
dec(CurPos.StartPos);
|
||||||
|
until (CurPos.StartPos<1) or (Src[CurPos.StartPos] in [#0,'`']);
|
||||||
|
end;
|
||||||
'0'..'9','A'..'Z','a'..'z':
|
'0'..'9','A'..'Z','a'..'z':
|
||||||
begin
|
begin
|
||||||
// test if char constant
|
// test if char constant
|
||||||
@ -1515,6 +1560,29 @@ var
|
|||||||
if IsStringConstant then break;
|
if IsStringConstant then break;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
// a multiline string constant -> skip it
|
||||||
|
OldPrePos:=PrePos;
|
||||||
|
while (PrePos<CurPos.StartPos) do begin
|
||||||
|
inc(PrePos);
|
||||||
|
case Src[PrePos] of
|
||||||
|
'`':
|
||||||
|
break;
|
||||||
|
|
||||||
|
#0:
|
||||||
|
begin
|
||||||
|
// string constant right border is the line end
|
||||||
|
// -> last atom of line found
|
||||||
|
IsStringConstant:=true;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if IsStringConstant then break;
|
||||||
|
end;
|
||||||
|
|
||||||
#10,#13:
|
#10,#13:
|
||||||
// no comment and no string constant found
|
// no comment and no string constant found
|
||||||
break;
|
break;
|
||||||
@ -1610,7 +1678,7 @@ begin
|
|||||||
// read atom
|
// read atom
|
||||||
if IsStringConstant then begin
|
if IsStringConstant then begin
|
||||||
CurPos.StartPos:=OldPrePos;
|
CurPos.StartPos:=OldPrePos;
|
||||||
if (CurPos.StartPos>1) and (Src[CurPos.StartPos-1]='''') then begin
|
if (CurPos.StartPos>1) and (Src[CurPos.StartPos-1] in ['''','`']) then begin
|
||||||
ReadStringConstantBackward;
|
ReadStringConstantBackward;
|
||||||
end;
|
end;
|
||||||
LastAtoms.AddReverse(CurPos);
|
LastAtoms.AddReverse(CurPos);
|
||||||
@ -1649,7 +1717,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
'''':
|
'''','`':
|
||||||
begin
|
begin
|
||||||
inc(CurPos.StartPos);
|
inc(CurPos.StartPos);
|
||||||
ReadStringConstantBackward;
|
ReadStringConstantBackward;
|
||||||
@ -1886,6 +1954,25 @@ begin
|
|||||||
#0,#10,#13:
|
#0,#10,#13:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
else
|
||||||
|
inc(p);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
inc(p);
|
||||||
|
while true do begin
|
||||||
|
case p^ of
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
inc(p);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
#0:
|
||||||
|
break;
|
||||||
|
|
||||||
else
|
else
|
||||||
inc(p);
|
inc(p);
|
||||||
end;
|
end;
|
||||||
@ -3099,7 +3186,7 @@ begin
|
|||||||
while (CleanStartPos<=SrcLen)
|
while (CleanStartPos<=SrcLen)
|
||||||
and (IsIdentChar[Src[CleanStartPos+len]]) do
|
and (IsIdentChar[Src[CleanStartPos+len]]) do
|
||||||
inc(len);
|
inc(len);
|
||||||
SetLength(Result,len);
|
SetLength(Result{%H-},len);
|
||||||
if len>0 then
|
if len>0 then
|
||||||
Move(Src[CleanStartPos],Result[1],len);
|
Move(Src[CleanStartPos],Result[1],len);
|
||||||
end else
|
end else
|
||||||
|
@ -2347,7 +2347,7 @@ begin
|
|||||||
try
|
try
|
||||||
WritePascalToStream(ms);
|
WritePascalToStream(ms);
|
||||||
|
|
||||||
SetLength(NewSrc,ms.Size);
|
SetLength(NewSrc{%H-},ms.Size);
|
||||||
if NewSrc<>'' then begin
|
if NewSrc<>'' then begin
|
||||||
ms.Position:=0;
|
ms.Position:=0;
|
||||||
ms.Read(NewSrc[1],length(NewSrc));
|
ms.Read(NewSrc[1],length(NewSrc));
|
||||||
|
@ -227,7 +227,8 @@ type
|
|||||||
cmsExternalClass, { pas2js: allow class external [pkgname] name [symbol] }
|
cmsExternalClass, { pas2js: allow class external [pkgname] name [symbol] }
|
||||||
cmsIgnoreAttributes, { pas2js: ignore attributes }
|
cmsIgnoreAttributes, { pas2js: ignore attributes }
|
||||||
cmsOmitRTTI, { pas2js: treat class section 'published' as 'public' and typeinfo does not work on symbols declared with this switch }
|
cmsOmitRTTI, { pas2js: treat class section 'published' as 'public' and typeinfo does not work on symbols declared with this switch }
|
||||||
cmsImplicitFunctionSpecialization { infer types on calls of generic functions }
|
cmsImplicitFunctionSpecialization, { infer types on calls of generic functions }
|
||||||
|
cmsMultiLineStrings { pas2js: Multiline strings }
|
||||||
);
|
);
|
||||||
TCompilerModeSwitches = set of TCompilerModeSwitch;
|
TCompilerModeSwitches = set of TCompilerModeSwitch;
|
||||||
const
|
const
|
||||||
@ -318,7 +319,8 @@ const
|
|||||||
'EXTERNALCLASS',
|
'EXTERNALCLASS',
|
||||||
'IGNOREATTRIBUTES',
|
'IGNOREATTRIBUTES',
|
||||||
'OMITRTTI',
|
'OMITRTTI',
|
||||||
'IMPLICITFUNCTIONSPECIALIZATION'
|
'IMPLICITFUNCTIONSPECIALIZATION',
|
||||||
|
'MULTILINESTRINGS'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -1922,7 +1924,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
SrcPos:=p-PChar(Src)+1;
|
SrcPos:=p-PChar(Src)+1;
|
||||||
end;
|
end;
|
||||||
'''','#':
|
'''','#','`':
|
||||||
begin
|
begin
|
||||||
TokenType:=lsttStringConstant;
|
TokenType:=lsttStringConstant;
|
||||||
while true do begin
|
while true do begin
|
||||||
@ -1962,6 +1964,27 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
inc(p);
|
||||||
|
while true do begin
|
||||||
|
case p^ of
|
||||||
|
#0:
|
||||||
|
begin
|
||||||
|
SrcPos:=p-PChar(Src)+1;
|
||||||
|
if SrcPos>SrcLen then break;
|
||||||
|
inc(p);
|
||||||
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
inc(p);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
inc(p);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
@ -4590,6 +4613,14 @@ begin
|
|||||||
if p^='''' then
|
if p^='''' then
|
||||||
inc(p);
|
inc(p);
|
||||||
end;
|
end;
|
||||||
|
'`':
|
||||||
|
begin
|
||||||
|
// skip multiline string constant
|
||||||
|
inc(p);
|
||||||
|
while not (p^ in ['`',#0]) do inc(p);
|
||||||
|
if p^='`' then
|
||||||
|
inc(p);
|
||||||
|
end;
|
||||||
#0:
|
#0:
|
||||||
begin
|
begin
|
||||||
// FPC allows that corresponding IFDEF and ENDIF are in different files
|
// FPC allows that corresponding IFDEF and ENDIF are in different files
|
||||||
|
@ -56,6 +56,7 @@ type
|
|||||||
procedure TestParseProcAnoArg;
|
procedure TestParseProcAnoArg;
|
||||||
procedure TestParseProcAnoArgSubFunc;
|
procedure TestParseProcAnoArgSubFunc;
|
||||||
procedure TestParseThreadVar;
|
procedure TestParseThreadVar;
|
||||||
|
procedure TestParseMultilineString;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -614,6 +615,25 @@ begin
|
|||||||
ParseModule;
|
ParseModule;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestPascalParser.TestParseMultilineString;
|
||||||
|
begin
|
||||||
|
Add([
|
||||||
|
'program test1;',
|
||||||
|
'{$modeswitch multilinestrings}',
|
||||||
|
'const',
|
||||||
|
' s = `First',
|
||||||
|
'Second',
|
||||||
|
'Third`;',
|
||||||
|
' a = ``;',
|
||||||
|
' b = `',
|
||||||
|
'`#10`',
|
||||||
|
'line`;',
|
||||||
|
' c = ''''``;',
|
||||||
|
'begin',
|
||||||
|
'']);
|
||||||
|
ParseModule;
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
RegisterTest(TTestPascalParser);
|
RegisterTest(TTestPascalParser);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user