mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2026-01-21 04:43:38 +01:00
svn+ssh://svn.freepascal.org/FPC/svn/fpc/branches/cleanroom ................ r9269 | michael | 2007-11-17 13:58:31 +0100 (Sat, 17 Nov 2007) | 1 line * Cleaned initial list of tained routines ................ r9270 | michael | 2007-11-17 14:00:25 +0100 (Sat, 17 Nov 2007) | 1 line * Test routines for cleanroom implementation ................ r9271 | michael | 2007-11-17 14:04:43 +0100 (Sat, 17 Nov 2007) | 1 line DoVarClearArray also tainted ................ r9272 | michael | 2007-11-17 15:25:04 +0100 (Sat, 17 Nov 2007) | 1 line * Removed possibly tainted code ................ r9276 | Almindor | 2007-11-17 21:29:16 +0100 (Sat, 17 Nov 2007) | 2 lines * initial cleanroom implementation of TStringList.Find ................ r9277 | Almindor | 2007-11-17 21:32:44 +0100 (Sat, 17 Nov 2007) | 2 lines * also commit forgotten part for "where would it instert" in case of sorted stringlist ................ r9295 | michael | 2007-11-19 21:07:10 +0100 (Mon, 19 Nov 2007) | 1 line * More tests ................ r9307 | michael | 2007-11-21 08:43:56 +0100 (Wed, 21 Nov 2007) | 1 line * More tests and reorganization per unit ................ r9308 | michael | 2007-11-21 08:47:58 +0100 (Wed, 21 Nov 2007) | 1 line * More reorganization of files ................ r9310 | michael | 2007-11-21 21:05:40 +0100 (Wed, 21 Nov 2007) | 1 line * Completed tccollection tests ................ r9322 | marco | 2007-11-24 15:40:18 +0100 (Sat, 24 Nov 2007) | 1 line * getnamepath first version. Tests not run yet (fpcunit) ................ r9337 | michael | 2007-11-27 09:21:31 +0100 (Tue, 27 Nov 2007) | 1 line * Removed TFPlist.Assign and TFPList.Extract ................ r9340 | michael | 2007-11-27 22:33:07 +0100 (Tue, 27 Nov 2007) | 1 line Removed HandleSafeCallException ................ r9343 | Almindor | 2007-11-28 11:23:00 +0100 (Wed, 28 Nov 2007) | 2 lines * add cleanroom quicksort implementation [tested very little] ................ r9344 | Almindor | 2007-11-28 11:25:54 +0100 (Wed, 28 Nov 2007) | 2 lines * update quicksort to use ExchangeItems instead of manual swap ................ r9359 | vincents | 2007-11-30 20:10:03 +0100 (Fri, 30 Nov 2007) | 1 line + clean room implementation of HandleSafeCallException; compiles, but not tested. ................ r9387 | michael | 2007-12-03 14:24:32 +0100 (Mon, 03 Dec 2007) | 1 line * Clean-room implementation of TParser by Giulio Bernardi ................ r9396 | michael | 2007-12-05 21:36:41 +0100 (Wed, 05 Dec 2007) | 5 lines * Patch from Giulio Bernardi: - Fixes token positioning after HexToBinary - Support for certain malformed negative integer values ................ r9399 | michael | 2007-12-06 16:53:41 +0100 (Thu, 06 Dec 2007) | 1 line * More tests for classes unit ................ r9401 | michael | 2007-12-06 21:58:16 +0100 (Thu, 06 Dec 2007) | 1 line * Added additional tests for collection streaming. Restructured ................ r9402 | michael | 2007-12-06 22:35:56 +0100 (Thu, 06 Dec 2007) | 1 line * All compiles again, resolving references not quite yet done ................ r9434 | michael | 2007-12-12 21:24:57 +0100 (Wed, 12 Dec 2007) | 1 line * New FindNestedComponent routine ................ r9466 | michael | 2007-12-15 23:44:41 +0100 (Sat, 15 Dec 2007) | 1 line * Fixed all tests ................ r9468 | michael | 2007-12-16 01:00:01 +0100 (Sun, 16 Dec 2007) | 1 line * Fixed reader fixup of references ................ r9491 | joost | 2007-12-18 21:46:54 +0100 (Tue, 18 Dec 2007) | 3 lines * Implemented TWriter.WriteComponent * Implemented TWriter.WriteComponentData * Implemented TWriter.WriteDescendent ................ r9492 | joost | 2007-12-18 21:56:32 +0100 (Tue, 18 Dec 2007) | 1 line * The BinaryObjectWriter of fpc stores TValueTypes as a byte, fixed the test for that ................ r9566 | michael | 2007-12-29 15:53:32 +0100 (Sat, 29 Dec 2007) | 1 line * Clean (and complete) implementation of T(FP)List.Assign ................ r9567 | michael | 2007-12-29 16:02:19 +0100 (Sat, 29 Dec 2007) | 1 line * Additional tests for reference resolving and TList.Assign ................ r9568 | michael | 2007-12-29 16:12:33 +0100 (Sat, 29 Dec 2007) | 1 line * Cleanroom implementation of extract ................ r9750 | yury | 2008-01-14 13:07:17 +0100 (Mon, 14 Jan 2008) | 1 line * My cleanroom implementation of DoVarClearArray. ................ r10271 | michael | 2008-02-10 15:52:37 +0100 (Sun, 10 Feb 2008) | 1 line * Correct implementation committed ................ r10273 | michael | 2008-02-10 17:08:59 +0100 (Sun, 10 Feb 2008) | 1 line * Added DecodeSoundexInt ................ r10352 | vincents | 2008-02-18 08:23:18 +0100 (Mon, 18 Feb 2008) | 1 line + TStringList.Grow, used algorithm from TFPList.Expand ................ r10353 | vincents | 2008-02-18 10:21:58 +0100 (Mon, 18 Feb 2008) | 1 line * use new TStringList.Grow implementation from trunk ................ r10354 | vincents | 2008-02-18 10:23:07 +0100 (Mon, 18 Feb 2008) | 1 line * fixed TList tests ................ r10355 | vincents | 2008-02-18 16:43:35 +0100 (Mon, 18 Feb 2008) | 1 line * fixed hint in test and removed session information from lpi ................ r10356 | vincents | 2008-02-18 21:58:29 +0100 (Mon, 18 Feb 2008) | 1 line + implemented TStringList.Find ................ r10358 | vincents | 2008-02-19 15:02:17 +0100 (Tue, 19 Feb 2008) | 1 line * fixed TTestTComponentNotifies test ................ r10359 | vincents | 2008-02-19 15:48:43 +0100 (Tue, 19 Feb 2008) | 1 line * fixed memleak in TWriter.WriteProperties ................ r10360 | vincents | 2008-02-19 15:49:20 +0100 (Tue, 19 Feb 2008) | 1 line + initial implementation of TReader.ReadCollection (needs further testing) ................ r10364 | vincents | 2008-02-19 23:05:49 +0100 (Tue, 19 Feb 2008) | 1 line + TDataset.SetFieldValues (untested) ................ r10365 | vincents | 2008-02-20 09:03:16 +0100 (Wed, 20 Feb 2008) | 1 line * initilize critical section used by resolving references ................ r10366 | vincents | 2008-02-20 09:38:03 +0100 (Wed, 20 Feb 2008) | 2 lines * fixed resolve references test * removed unused variable ................ r10369 | vincents | 2008-02-20 17:04:51 +0100 (Wed, 20 Feb 2008) | 1 line + initial version of TReader.FindComponentClass, works with a simple LCL application ................ r10370 | michael | 2008-02-20 20:48:36 +0100 (Wed, 20 Feb 2008) | 1 line * Added tcollection stream read tests ................ r10373 | vincents | 2008-02-21 00:33:10 +0100 (Thu, 21 Feb 2008) | 1 line * TReader.FindComponentClass: also search in FieldTables of parent classes. ................ r10374 | michael | 2008-02-21 11:00:04 +0100 (Thu, 21 Feb 2008) | 1 line * Fix voor ResolveReferences ................ r10376 | vincents | 2008-02-21 19:37:55 +0100 (Thu, 21 Feb 2008) | 1 line * reduced hints ................ r10377 | vincents | 2008-02-22 14:56:22 +0100 (Fri, 22 Feb 2008) | 1 line * add check for valid NewIndex in TFPList.Move, so that an invalid NewIndex doesn't lead to memleak ................ r10378 | vincents | 2008-02-22 15:16:56 +0100 (Fri, 22 Feb 2008) | 1 line * fixed TReader.ReadCollection in case more than one property was streamed ................ r10379 | vincents | 2008-02-22 15:35:44 +0100 (Fri, 22 Feb 2008) | 3 lines + added another test for writing collections (shows how it should be written and thus read + added a test for a writing an enum with default value ................ r10380 | vincents | 2008-02-22 15:36:14 +0100 (Fri, 22 Feb 2008) | 1 line * fixed memleak ................ r10381 | vincents | 2008-02-23 20:03:00 +0100 (Sat, 23 Feb 2008) | 1 line * fixed AV when streaming a component without published properties ................ r10390 | michael | 2008-02-25 21:34:10 +0100 (Mon, 25 Feb 2008) | 1 line * Clean version of searchbuf inserted ................ r10393 | vincents | 2008-02-26 23:06:14 +0100 (Tue, 26 Feb 2008) | 1 line * fixed TDataset.SetFieldValues ................ r10398 | michael | 2008-02-27 21:58:49 +0100 (Wed, 27 Feb 2008) | 1 line * Added test for streaming 2 components ................ r10400 | vincents | 2008-02-28 00:51:08 +0100 (Thu, 28 Feb 2008) | 1 line * improved tests for streaming components with owned subcomponents ................ r10403 | vincents | 2008-02-28 22:19:32 +0100 (Thu, 28 Feb 2008) | 1 line * fixed writing child components ................ r10441 | florian | 2008-03-04 20:11:46 +0100 (Tue, 04 Mar 2008) | 3 lines Initialized merge tracking via "svnmerge" with revisions "1-9261" from http://svn.freepascal.org/svn/fpc/trunk ................ r10444 | joost | 2008-03-05 11:31:07 +0100 (Wed, 05 Mar 2008) | 30 lines Merged revisions 9783,9786,9788,9814,9822,9825,9837-9850,9852,9854-9856,9863-9864,9867,9885,9895 via svnmerge from svn+ssh://joost@svn.freepascal.org/FPC/svn/fpc/trunk ........ r9783 | joost | 2008-01-18 23:52:13 +0100 (Fri, 18 Jan 2008) | 1 line * DigestTestREport makes it possible to write the unittest results to a testsuite-digest ........ r9786 | joost | 2008-01-19 00:40:44 +0100 (Sat, 19 Jan 2008) | 1 line * Added dependency on paszlib to fcl-fpcunit ........ r9788 | jonas | 2008-01-19 01:20:49 +0100 (Sat, 19 Jan 2008) | 2 lines + also add fpc-unit dependency on paszlib to build dependencies ........ r9854 | joost | 2008-01-21 17:26:20 +0100 (Mon, 21 Jan 2008) | 2 lines * Added Comment and Category properties to TDigestResultsWriter * Write Comment and Category to digest.cfg ........ r9885 | joost | 2008-01-23 22:56:34 +0100 (Wed, 23 Jan 2008) | 1 line * Write RelSrcDir to digest.cfg ........ r9895 | joost | 2008-01-24 18:02:47 +0100 (Thu, 24 Jan 2008) | 1 line * Add dash between hostname and date in digest-tarfile ........ ................ r10445 | joost | 2008-03-05 11:47:26 +0100 (Wed, 05 Mar 2008) | 9 lines Merged revisions 10431 via svnmerge from svn+ssh://joost@svn.freepascal.org/FPC/svn/fpc/trunk ........ r10431 | joost | 2008-03-02 18:08:16 +0100 (Sun, 02 Mar 2008) | 1 line * Set Modified to false when te state of a dataset changes ........ ................ r10446 | joost | 2008-03-05 15:34:38 +0100 (Wed, 05 Mar 2008) | 9 lines Merged revisions 10350 via svnmerge from svn+ssh://joost@svn.freepascal.org/FPC/svn/fpc/trunk ........ r10350 | joost | 2008-02-17 22:14:26 +0100 (Sun, 17 Feb 2008) | 1 line * Fixed bug #8464 ........ ................ r10490 | Almindor | 2008-03-15 11:18:42 +0100 (Sat, 15 Mar 2008) | 3 lines * add TDataLink.CalcFirstRecord cleanroom implementation (blind) * add TField.RefreshLookupList cleanroom implementation (blind) ................ r10491 | Almindor | 2008-03-15 11:29:54 +0100 (Sat, 15 Mar 2008) | 2 lines * fix compilation of the TField.RefreshLookuplist; ................ r10510 | Almindor | 2008-03-20 18:57:22 +0100 (Thu, 20 Mar 2008) | 2 lines * implement cleanroom TDataset.CalculateFields ................ r10511 | Almindor | 2008-03-20 19:16:55 +0100 (Thu, 20 Mar 2008) | 2 lines * add TDataSet.EnableControls cleanroom implementation ................ r10512 | Almindor | 2008-03-20 19:27:27 +0100 (Thu, 20 Mar 2008) | 2 lines * add TField.CalcLookupValue cleanroom implementation ................ r10513 | Almindor | 2008-03-20 19:30:23 +0100 (Thu, 20 Mar 2008) | 2 lines * fix potential bug in cleanroom TField.RefreshLookupList ................ r10514 | Almindor | 2008-03-20 19:33:13 +0100 (Thu, 20 Mar 2008) | 2 lines * add forgotten function call in TDataset.CalculateFields ................ r10515 | Almindor | 2008-03-20 19:37:19 +0100 (Thu, 20 Mar 2008) | 2 lines * fix potential bug in cleanroom TDataLink.CalcFirstRecord ................ r10531 | Almindor | 2008-03-22 10:57:40 +0100 (Sat, 22 Mar 2008) | 2 lines * implement cleanroom TDataSet.DataEvent ................ r10534 | Almindor | 2008-03-22 21:30:02 +0100 (Sat, 22 Mar 2008) | 2 lines * fix cleanroom TDataset.DataEvent, make it call all connected datasources ................ r10537 | michael | 2008-03-23 11:19:05 +0100 (Sun, 23 Mar 2008) | 6 lines * Fixed some issues: - Memleak in TReader.ReadPropValue. FFixups was re-allocated in beginreferences ! - FPC behaves different from Delphi if no Default value is declared, it assumes a default of ord(TEnum)=0, same for sets. - Fixed MemLeak when a reference was resolved, Removed item was not freed. ................ r10547 | Almindor | 2008-03-24 10:57:28 +0100 (Mon, 24 Mar 2008) | 2 lines * first fix to cleanroom TDataSet.DataEvent only 6 tests fail now :) ................ r10553 | joost | 2008-03-24 19:58:33 +0100 (Mon, 24 Mar 2008) | 9 lines Merged revisions 10470 via svnmerge from svn+ssh://joost@svn.freepascal.org/FPC/svn/fpc/trunk ........ r10470 | joost | 2008-03-09 21:11:17 +0100 (Sun, 09 Mar 2008) | 1 line * Set TDataSet.InternalCalcFields if there are InternalCalcFields ........ ................ r10555 | joost | 2008-03-25 12:06:12 +0100 (Tue, 25 Mar 2008) | 9 lines Merged revisions 10519 via svnmerge from svn+ssh://joost@svn.freepascal.org/FPC/svn/fpc/trunk ........ r10519 | joost | 2008-03-21 14:38:44 +0100 (Fri, 21 Mar 2008) | 1 line * Fix for ValueOfKey for multiple-fields keys ........ ................ r10565 | Almindor | 2008-03-25 18:28:58 +0100 (Tue, 25 Mar 2008) | 2 lines * fix cleanroom TDataLink.CalcFirstRecord (passes tests now) ................ git-svn-id: trunk@10572 -
458 lines
9.4 KiB
PHP
458 lines
9.4 KiB
PHP
{
|
|
This file is part of the Free Component Library (FCL)
|
|
Copyright (c) 1999-2007 by the Free Pascal development team
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
|
|
{****************************************************************************}
|
|
{* TParser *}
|
|
{****************************************************************************}
|
|
|
|
const
|
|
ParseBufSize = 4096;
|
|
LastSpecialToken = 5;
|
|
|
|
TokNames : array[0..LastSpecialToken] of string =
|
|
(
|
|
'EOF',
|
|
'Symbol',
|
|
'String',
|
|
'Integer',
|
|
'Float',
|
|
'WideString'
|
|
);
|
|
|
|
function TParser.GetTokenName(aTok: char): string;
|
|
begin
|
|
if ord(aTok) <= LastSpecialToken then
|
|
Result:=TokNames[ord(aTok)]
|
|
else Result:=aTok;
|
|
end;
|
|
|
|
procedure TParser.LoadBuffer;
|
|
var toread : integer;
|
|
begin
|
|
toread:=fStream.Size-fStream.Position;
|
|
if toread>ParseBufSize then toread:=ParseBufSize;
|
|
if toread=0 then
|
|
begin
|
|
fEofReached:=true;
|
|
exit;
|
|
end;
|
|
fStream.ReadBuffer(fBuf[0],toread);
|
|
fBuf[toread]:=#0;
|
|
inc(fDeltaPos,fPos);
|
|
fPos:=0;
|
|
fBufLen:=toread;
|
|
end;
|
|
|
|
procedure TParser.CheckLoadBuffer; inline;
|
|
begin
|
|
if fBuf[fPos]=#0 then LoadBuffer;
|
|
end;
|
|
|
|
procedure TParser.ProcessChar; inline;
|
|
begin
|
|
fLastTokenStr:=fLastTokenStr+fBuf[fPos];
|
|
inc(fPos);
|
|
CheckLoadBuffer;
|
|
end;
|
|
|
|
function TParser.IsNumber: boolean; inline;
|
|
begin
|
|
Result:=fBuf[fPos] in ['0'..'9'];
|
|
end;
|
|
|
|
function TParser.IsHexNum: boolean; inline;
|
|
begin
|
|
Result:=fBuf[fPos] in ['0'..'9','A'..'F','a'..'f'];
|
|
end;
|
|
|
|
function TParser.IsAlpha: boolean; inline;
|
|
begin
|
|
Result:=fBuf[fPos] in ['_','A'..'Z','a'..'z'];
|
|
end;
|
|
|
|
function TParser.IsAlphaNum: boolean; inline;
|
|
begin
|
|
Result:=IsAlpha or IsNumber;
|
|
end;
|
|
|
|
function TParser.GetHexValue(c: char): byte; inline;
|
|
begin
|
|
case c of
|
|
'0'..'9' : Result:=ord(c)-$30;
|
|
'A'..'F' : Result:=ord(c)-$37; //-$41+$0A
|
|
'a'..'f' : Result:=ord(c)-$57; //-$61+$0A
|
|
end;
|
|
end;
|
|
|
|
function TParser.GetAlphaNum: string;
|
|
begin
|
|
if not IsAlpha then
|
|
ErrorFmt(SParExpected,[GetTokenName(toSymbol)]);
|
|
Result:='';
|
|
while IsAlphaNum do
|
|
begin
|
|
Result:=Result+fBuf[fPos];
|
|
inc(fPos);
|
|
CheckLoadBuffer;
|
|
end;
|
|
end;
|
|
|
|
procedure TParser.HandleNewLine;
|
|
begin
|
|
if fBuf[fPos]=#13 then //CR
|
|
begin
|
|
inc(fPos);
|
|
CheckLoadBuffer;
|
|
if fBuf[fPos]=#10 then inc(fPos); //CR LF
|
|
end
|
|
else inc(fPos); //LF
|
|
inc(fSourceLine);
|
|
fDeltaPos:=-(fPos-1);
|
|
end;
|
|
|
|
procedure TParser.SkipSpaces;
|
|
begin
|
|
while fBuf[fPos] in [' ',#9] do
|
|
inc(fPos);
|
|
end;
|
|
|
|
procedure TParser.SkipWhitespace;
|
|
begin
|
|
while true do
|
|
begin
|
|
CheckLoadBuffer;
|
|
case fBuf[fPos] of
|
|
' ',#9 : SkipSpaces;
|
|
#10,#13 : HandleNewLine
|
|
else break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TParser.HandleEof;
|
|
begin
|
|
fToken:=toEOF;
|
|
fLastTokenStr:='';
|
|
end;
|
|
|
|
procedure TParser.HandleAlphaNum;
|
|
begin
|
|
fLastTokenStr:=GetAlphaNum;
|
|
fToken:=toSymbol;
|
|
end;
|
|
|
|
procedure TParser.HandleNumber;
|
|
type
|
|
floatPunct = (fpDot,fpE);
|
|
floatPuncts = set of floatPunct;
|
|
var
|
|
allowed : floatPuncts;
|
|
begin
|
|
fLastTokenStr:='';
|
|
while IsNumber do
|
|
ProcessChar;
|
|
fToken:=toInteger;
|
|
if (fBuf[fPos] in ['.','e','E']) then
|
|
begin
|
|
fToken:=toFloat;
|
|
allowed:=[fpDot,fpE];
|
|
while (fBuf[fPos] in ['.','e','E','0'..'9']) do
|
|
begin
|
|
case fBuf[fPos] of
|
|
'.' : if fpDot in allowed then Exclude(allowed,fpDot) else break;
|
|
'E','e' : if fpE in allowed then
|
|
begin
|
|
allowed:=[];
|
|
ProcessChar;
|
|
if (fBuf[fPos] in ['+','-']) then ProcessChar;
|
|
if not (fBuf[fPos] in ['0'..'9']) then
|
|
ErrorFmt(SParInvalidFloat,[fLastTokenStr+fBuf[fPos]]);
|
|
end
|
|
else break;
|
|
end;
|
|
ProcessChar;
|
|
end;
|
|
end;
|
|
if (fBuf[fPos] in ['s','S','d','D','c','C']) then //single, date, currency
|
|
begin
|
|
fFloatType:=fBuf[fPos];
|
|
inc(fPos);
|
|
fToken:=toFloat;
|
|
end
|
|
else fFloatType:=#0;
|
|
end;
|
|
|
|
procedure TParser.HandleHexNumber;
|
|
var valid : boolean;
|
|
begin
|
|
fLastTokenStr:='$';
|
|
inc(fPos);
|
|
CheckLoadBuffer;
|
|
valid:=false;
|
|
while IsHexNum do
|
|
begin
|
|
valid:=true;
|
|
ProcessChar;
|
|
end;
|
|
if not valid then
|
|
ErrorFmt(SParInvalidInteger,[fLastTokenStr]);
|
|
fToken:=toInteger;
|
|
end;
|
|
|
|
function TParser.HandleQuotedString: string;
|
|
begin
|
|
Result:='';
|
|
inc(fPos);
|
|
CheckLoadBuffer;
|
|
while true do
|
|
begin
|
|
case fBuf[fPos] of
|
|
#0 : ErrorStr(SParUnterminatedString);
|
|
#13,#10 : ErrorStr(SParUnterminatedString);
|
|
'''' : begin
|
|
inc(fPos);
|
|
CheckLoadBuffer;
|
|
if fBuf[fPos]<>'''' then exit;
|
|
end;
|
|
end;
|
|
Result:=Result+fBuf[fPos];
|
|
inc(fPos);
|
|
CheckLoadBuffer;
|
|
end;
|
|
end;
|
|
|
|
function TParser.HandleDecimalString(var ascii : boolean): widestring;
|
|
var i : integer;
|
|
begin
|
|
Result:='';
|
|
inc(fPos);
|
|
CheckLoadBuffer;
|
|
while IsNumber do
|
|
begin
|
|
Result:=Result+fBuf[fPos];
|
|
inc(fPos);
|
|
CheckLoadBuffer;
|
|
end;
|
|
if TryStrToInt(Result,i) and (i<256) then
|
|
begin
|
|
if i>127 then ascii:=false;
|
|
setlength(Result,1);
|
|
Result[1]:=widechar(word(i));
|
|
end
|
|
else
|
|
Result:='#'+Result;
|
|
end;
|
|
|
|
procedure TParser.HandleString;
|
|
var ascii : boolean;
|
|
begin
|
|
fLastTokenWStr:='';
|
|
ascii:=true;
|
|
while true do
|
|
case fBuf[fPos] of
|
|
'''' : fLastTokenWStr:=fLastTokenWStr+HandleQuotedString;
|
|
'#' : fLastTokenWStr:=fLastTokenWStr+HandleDecimalString(ascii)
|
|
else break;
|
|
end;
|
|
if ascii then
|
|
fToken:=toString
|
|
else
|
|
fToken:=toWString;
|
|
fLastTokenStr:=fLastTokenWStr;
|
|
end;
|
|
|
|
procedure TParser.HandleMinus;
|
|
begin
|
|
inc(fPos);
|
|
CheckLoadBuffer;
|
|
if IsNumber then
|
|
begin
|
|
HandleNumber;
|
|
fLastTokenStr:='-'+fLastTokenStr;
|
|
end
|
|
else
|
|
begin
|
|
fToken:='-';
|
|
fLastTokenStr:=fToken;
|
|
end;
|
|
end;
|
|
|
|
procedure TParser.HandleUnknown;
|
|
begin
|
|
fToken:=fBuf[fPos];
|
|
fLastTokenStr:=fToken;
|
|
inc(fPos);
|
|
end;
|
|
|
|
constructor TParser.Create(Stream: TStream);
|
|
begin
|
|
fStream:=Stream;
|
|
fBuf:=GetMem(ParseBufSize+1);
|
|
fBufLen:=0;
|
|
fPos:=0;
|
|
fDeltaPos:=1;
|
|
fSourceLine:=1;
|
|
fEofReached:=false;
|
|
fLastTokenStr:='';
|
|
fLastTokenWStr:='';
|
|
fFloatType:=#0;
|
|
fToken:=#0;
|
|
LoadBuffer;
|
|
NextToken;
|
|
end;
|
|
|
|
destructor TParser.Destroy;
|
|
begin
|
|
fStream.Position:=SourcePos;
|
|
FreeMem(fBuf);
|
|
end;
|
|
|
|
procedure TParser.CheckToken(T: Char);
|
|
begin
|
|
if fToken<>T then
|
|
ErrorFmt(SParWrongTokenType,[GetTokenName(T),GetTokenName(fToken)]);
|
|
end;
|
|
|
|
procedure TParser.CheckTokenSymbol(const S: string);
|
|
begin
|
|
CheckToken(toSymbol);
|
|
if CompareText(fLastTokenStr,S)<>0 then
|
|
ErrorFmt(SParWrongTokenSymbol,[s,fLastTokenStr]);
|
|
end;
|
|
|
|
procedure TParser.Error(const Ident: string);
|
|
begin
|
|
ErrorStr(Ident);
|
|
end;
|
|
|
|
procedure TParser.ErrorFmt(const Ident: string; const Args: array of const);
|
|
begin
|
|
ErrorStr(Format(Ident,Args));
|
|
end;
|
|
|
|
procedure TParser.ErrorStr(const Message: string);
|
|
begin
|
|
raise EParserError.CreateFmt(Message+SParLocInfo,[SourceLine,fPos+fDeltaPos,SourcePos]);
|
|
end;
|
|
|
|
procedure TParser.HexToBinary(Stream: TStream);
|
|
var outbuf : array[0..ParseBufSize-1] of byte;
|
|
b : byte;
|
|
i : integer;
|
|
begin
|
|
i:=0;
|
|
SkipWhitespace;
|
|
while IsHexNum do
|
|
begin
|
|
b:=(GetHexValue(fBuf[fPos]) shl 4);
|
|
inc(fPos);
|
|
CheckLoadBuffer;
|
|
if not IsHexNum then
|
|
Error(SParUnterminatedBinValue);
|
|
b:=b or GetHexValue(fBuf[fPos]);
|
|
inc(fPos);
|
|
outbuf[i]:=b;
|
|
inc(i);
|
|
if i>=ParseBufSize then
|
|
begin
|
|
Stream.WriteBuffer(outbuf[0],i);
|
|
i:=0;
|
|
end;
|
|
SkipWhitespace;
|
|
end;
|
|
if i>0 then
|
|
Stream.WriteBuffer(outbuf[0],i);
|
|
NextToken;
|
|
end;
|
|
|
|
function TParser.NextToken: Char;
|
|
|
|
begin
|
|
SkipWhiteSpace;
|
|
if fEofReached then
|
|
HandleEof
|
|
else
|
|
case fBuf[fPos] of
|
|
'_','A'..'Z','a'..'z' : HandleAlphaNum;
|
|
'$' : HandleHexNumber;
|
|
'-' : HandleMinus;
|
|
'0'..'9' : HandleNumber;
|
|
'''','#' : HandleString
|
|
else
|
|
HandleUnknown;
|
|
end;
|
|
Result:=fToken;
|
|
end;
|
|
|
|
function TParser.SourcePos: Longint;
|
|
begin
|
|
Result:=fStream.Position-fBufLen+fPos;
|
|
end;
|
|
|
|
function TParser.TokenComponentIdent: string;
|
|
begin
|
|
if fToken<>toSymbol then
|
|
ErrorFmt(SParExpected,[GetTokenName(toSymbol)]);
|
|
CheckLoadBuffer;
|
|
while fBuf[fPos]='.' do
|
|
begin
|
|
ProcessChar;
|
|
fLastTokenStr:=fLastTokenStr+GetAlphaNum;
|
|
end;
|
|
Result:=fLastTokenStr;
|
|
end;
|
|
|
|
{$ifndef FPUNONE}
|
|
Function TParser.TokenFloat: Extended;
|
|
|
|
var errcode : word;
|
|
|
|
begin
|
|
Val(fLastTokenStr,Result,errcode);
|
|
if errcode<>0 then
|
|
ErrorFmt(SParInvalidFloat,[fLastTokenStr]);
|
|
end;
|
|
{$endif}
|
|
|
|
Function TParser.TokenInt: Int64;
|
|
begin
|
|
if not TryStrToInt64(fLastTokenStr,Result) then
|
|
Result:=Int64(StrToQWord(fLastTokenStr)); //second chance for malformed files
|
|
end;
|
|
|
|
function TParser.TokenString: string;
|
|
begin
|
|
case fToken of
|
|
toWString : Result:=fLastTokenWStr;
|
|
toFloat : if fFloatType<>#0 then
|
|
Result:=fLastTokenStr+fFloatType
|
|
else Result:=fLastTokenStr
|
|
else
|
|
Result:=fLastTokenStr;
|
|
end;
|
|
end;
|
|
|
|
function TParser.TokenWideString: WideString;
|
|
begin
|
|
if fToken=toWString then
|
|
Result:=fLastTokenWStr
|
|
else
|
|
Result:=fLastTokenStr;
|
|
end;
|
|
|
|
function TParser.TokenSymbolIs(const S: string): Boolean;
|
|
begin
|
|
Result:=(fToken=toSymbol) and (CompareText(fLastTokenStr,S)=0);
|
|
end;
|
|
|