codetools: reading operand: old tp style character constants, bug #19260

git-svn-id: trunk@30600 -
This commit is contained in:
mattias 2011-05-07 16:19:57 +00:00
parent da938a240f
commit e39bb2d05b
4 changed files with 140 additions and 54 deletions

View File

@ -185,6 +185,7 @@ function SplitStringConstant(const StringConstant: string;
const aLineBreak: string): string;
procedure ImproveStringConstantStart(const ACode: string; var StartPos: integer);
procedure ImproveStringConstantEnd(const ACode: string; var EndPos: integer);
function HexStrToIntDef(p: PChar; Def: integer): integer;
// search
function SearchNextInText(Search: PChar; SearchLen: PtrInt;
@ -4752,6 +4753,28 @@ begin
until AtomEndPos>=EndPos;
end;
function HexStrToIntDef(p: PChar; Def: integer): integer;
var
OldP: PChar;
i: Integer;
begin
Result:=0;
OldP:=p;
while true do begin
case p^ of
'0'..'9': i:=ord(p^)-ord('0');
'A'..'Z': i:=ord(p^)-ord('A')+10;
'a'..'z': i:=ord(p^)-ord('a')+10;
else
exit;
end;
if Result>(High(Result) shr 4) then exit(Def);
Result:=(Result shl 4)+i;
inc(p);
end;
if OldP=p then exit(Def);
end;
function SearchNextInText(Search: PChar; SearchLen: PtrInt; Src: PChar;
SrcLen: PtrInt; StartPos: PtrInt; out MatchStart, MatchEnd: PtrInt;
WholeWords: boolean; MultiLine: boolean): boolean;

View File

@ -261,6 +261,7 @@ type
procedure ReadNextAtom;
procedure UndoReadNextAtom;
procedure ReadPriorAtom;
procedure ReadAsStringConstant; // start at CurPos.StartPos
// read blocks
function ReadTilBracketClose(ExceptionOnNotFound: boolean): boolean;
@ -1105,11 +1106,6 @@ begin
// string constant
while true do begin
case p^ of
#0:
begin
CurPos.EndPos:=p-PChar(Src)+1;
if CurPos.EndPos>SrcLen then break;
end;
'#':
begin
inc(p);
@ -1130,20 +1126,13 @@ begin
inc(p);
while true do begin
case p^ of
#0:
begin
CurPos.EndPos:=p-PChar(Src)+1;
if CurPos.EndPos>SrcLen then break;
end;
'''':
begin
inc(p);
break;
end;
#10,#13:
#0,#10,#13:
break;
else
inc(p);
end;
@ -1310,7 +1299,6 @@ begin
end else begin
CurPos:=NextPos;
NextPos.StartPos:=-1;
exit;
end;
{$IFDEF RangeChecking}{$R+}{$UNDEF RangeChecking}{$ENDIF}
end;
@ -1693,6 +1681,67 @@ begin
end;
end;
procedure TCustomCodeTool.ReadAsStringConstant;
var
p: PChar;
begin
CurPos.Flag:=cafNone;
NextPos.StartPos:=-1;
if CurPos.StartPos>SrcLen then begin
CurPos.EndPos:=CurPos.StartPos;
exit;
end;
p:=@Src[CurPos.StartPos];
// string constant
while true do begin
case p^ of
'#':
begin
inc(p);
if IsNumberChar[p^] then begin
// decimal
repeat
inc(p);
until not IsNumberChar[p^];
end else if p^='$' then begin
// hexadecimal
repeat
inc(p);
until not IsHexNumberChar[p^];
end;
end;
'''':
begin
inc(p);
while true do begin
case p^ of
'''':
begin
inc(p);
break;
end;
#0,#10,#13:
break;
else
inc(p);
end;
end;
end;
'^':
begin
inc(p);
if not (p^ in ['A'..'Z']) then break;
inc(p);
end;
else
break;
end;
end;
CurPos.EndPos:=p-PChar(Src)+1;
end;
procedure TCustomCodeTool.UndoReadNextAtom;
begin
if LastAtoms.Count>0 then begin

View File

@ -7377,10 +7377,8 @@ begin
Result.Desc:=xtChar
else
Result.Desc:=xtConstString;
if Src[CurPos.StartPos]='^' then
MoveCursorToCleanPos(CurPos.StartPos+2) // e.g. ^M
else
MoveCursorToCleanPos(CurPos.EndPos);
MoveCursorToCleanPos(CurPos.StartPos);
ReadAsStringConstant;
end
else if AtomIsNumber then begin
// ordinal or real constant

View File

@ -1291,55 +1291,60 @@ end;
function TPascalReaderTool.ReadStringConstantValue(StartPos: integer): string;
// reads a string constant and returns the resulting string
var
APos: Integer;
Run: Integer;
NumberStart: Integer;
NumberStart: PChar;
ResultLen: Integer;
Number: Integer;
p: PChar;
begin
Result:='';
if StartPos>SrcLen then exit;
// first read and calculate the resulting length, then copy the chars
for Run:=1 to 2 do begin
APos:=StartPos;
ResultLen:=0;
while APos<=SrcLen do begin
if Src[APos]='''' then begin
// read string
inc(APos);
while APos<=SrcLen do begin
if (Src[APos]='''') then begin
if (APos<SrcLen) and (Src[APos+1]='''') then begin
// a double ' means a single '
inc(ResultLen);
if Run=2 then Result[ResultLen]:='''';
inc(APos,2);
p:=@Src[StartPos];
while true do begin
case p^ of
'''':
begin
// read string
inc(p);
while true do begin
if p^='''' then begin
if p[1]='''' then begin
// a double ' means a single '
inc(ResultLen);
if Run=2 then Result[ResultLen]:='''';
inc(p,2);
end else begin
// a single ' means end of string constant
inc(p);
break;
end;
end else begin
// a single ' means end of string constant
inc(APos);
break;
// normal char
inc(ResultLen);
if Run=2 then Result[ResultLen]:=p^;
inc(p);
end;
end else begin
// normal char
inc(ResultLen);
if Run=2 then Result[ResultLen]:=Src[APos];
inc(APos);
end;
end;
end else if Src[APos]='#' then begin
// read char constant
inc(APos);
NumberStart:=APos;
if APos<=SrcLen then begin
if IsNumberChar[Src[APos]] then begin
'#':
begin
// read char constant
inc(p);
NumberStart:=p;
if IsNumberChar[p^] then begin
// read decimal number
while (APos<=SrcLen) and IsNumberChar[Src[APos]] do
inc(APos);
Number:=StrToIntDef(copy(Src,NumberStart,APos-NumberStart),-1);
end else if Src[APos]='$' then begin
while IsNumberChar[p^] do
inc(p);
Number:=StrToIntDef(copy(Src,NumberStart-PChar(Src)+1,p-NumberStart),-1);
end else if p^='$' then begin
// read hexnumber
while (APos<=SrcLen) and IsHexNumberChar[Src[APos]] do
inc(APos);
Number:=StrToIntDef(copy(Src,NumberStart,APos-NumberStart),-1);
inc(p);
while IsHexNumberChar[p^] do
inc(p);
Number:=HexStrToIntDef(NumberStart,-1);
end else
Number:=-1;
// add special character
@ -1347,8 +1352,19 @@ begin
inc(ResultLen);
if Run=2 then Result[ResultLen]:=chr(Number);
end;
end else
'^':
begin
inc(p);
if p^ in ['A'..'Z'] then begin
inc(ResultLen);
if Run=2 then Result[ResultLen]:=chr(ord(p^)-ord('A'));
end else begin
break;
end;
end;
else
break;
end;
end;
if Run=1 then SetLength(Result,ResultLen);
end;