You've already forked lazarus-ccr
chelper: further changes to match c-preprocess text processing. added precompiler evaluation
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3990 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -30,6 +30,9 @@ const
|
|||||||
|
|
||||||
function ParseCExprEx(p: TTextParser): TExp;
|
function ParseCExprEx(p: TTextParser): TExp;
|
||||||
|
|
||||||
|
function ValuateIntExp(exp: TExp; macros: TCMacroHandler): Integer; overload;
|
||||||
|
function ValuateIntExp(const exp: string; macros: TCMacroHandler): Integer; overload;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function Rotate(core: TExp): TExp;
|
function Rotate(core: TExp): TExp;
|
||||||
@ -410,5 +413,60 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function IntVal(exp: TExp): Integer;
|
||||||
|
var
|
||||||
|
code : Integer;
|
||||||
|
l, r : Integer;
|
||||||
|
const
|
||||||
|
IntRes : array [boolean] of integer = (0,1);
|
||||||
|
begin
|
||||||
|
Result:=0;
|
||||||
|
if exp.dir = edInfix then begin
|
||||||
|
l:=IntVal(exp.left);
|
||||||
|
r:=IntVal(exp.right);
|
||||||
|
if exp.op = '+' then Result:=l+r
|
||||||
|
else if exp.op = '-' then Result:=l-r
|
||||||
|
else if exp.op = '/' then Result:=l div r
|
||||||
|
else if exp.op = '%' then Result:=l mod r
|
||||||
|
else if exp.op = '*' then Result:=l * r
|
||||||
|
else if exp.op = '&' then Result:=l and r
|
||||||
|
else if exp.op = '|' then Result:=l or r
|
||||||
|
else if exp.op = '<<' then Result:=l shr r
|
||||||
|
else if exp.op = '>>' then Result:=l shl r
|
||||||
|
else if exp.op = '==' then Result:=IntRes[l = r]
|
||||||
|
else if exp.op = '!=' then Result:=IntRes[l <> r]
|
||||||
|
else if exp.op = '>=' then Result:=IntRes[l >= r]
|
||||||
|
else if exp.op = '<=' then Result:=IntRes[l <= r]
|
||||||
|
else if exp.op = '>' then Result:=IntRes[l > r]
|
||||||
|
else if exp.op = '<' then Result:=IntRes[l < r];
|
||||||
|
end else begin
|
||||||
|
Val(exp.val, Result, code);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ValuateIntExp(exp: TExp; macros: TCMacroHandler): Integer;
|
||||||
|
begin
|
||||||
|
Result:=IntVal(Exp);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ValuateIntExp(const exp: string; macros: TCMacroHandler): Integer;
|
||||||
|
var
|
||||||
|
prs : TTextParser;
|
||||||
|
expObj : TExp;
|
||||||
|
begin
|
||||||
|
prs := CreateCParser(exp, false);
|
||||||
|
try
|
||||||
|
prs.MacroHandler:=macros;
|
||||||
|
if prs.NextToken then begin
|
||||||
|
expObj:=ParseCExprEx(prs);
|
||||||
|
if Assigned(expObj)
|
||||||
|
then Result:=ValuateIntExp(expObj, macros)
|
||||||
|
else Result:=0;
|
||||||
|
end else
|
||||||
|
Result:=0;
|
||||||
|
finally
|
||||||
|
prs.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -161,7 +161,11 @@ type
|
|||||||
end;
|
end;
|
||||||
TEntityClass = class of TEntity;
|
TEntityClass = class of TEntity;
|
||||||
|
|
||||||
TCPrepocessor = class(TEntity);
|
TCPrepocessor = class(TEntity)
|
||||||
|
public
|
||||||
|
_Directive : string;
|
||||||
|
_Value : string;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TCPrepDefine }
|
{ TCPrepDefine }
|
||||||
|
|
||||||
@ -182,9 +186,9 @@ type
|
|||||||
protected
|
protected
|
||||||
function DoParse(AParser: TTextParser): Boolean; override;
|
function DoParse(AParser: TTextParser): Boolean; override;
|
||||||
public
|
public
|
||||||
Params : TStringList;
|
|
||||||
Included : AnsiString;
|
Included : AnsiString;
|
||||||
destructor Destroy; override;
|
isSysFile : Boolean;
|
||||||
|
isImport : Boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TCPrepElse = class(TCPrepocessor)
|
TCPrepElse = class(TCPrepocessor)
|
||||||
@ -197,6 +201,7 @@ type
|
|||||||
|
|
||||||
TCPrepIf = class(TCPrepocessor)
|
TCPrepIf = class(TCPrepocessor)
|
||||||
_Cond : AnsiString;
|
_Cond : AnsiString;
|
||||||
|
Exp : TObject; // expression object
|
||||||
IfOp : AnsiString;
|
IfOp : AnsiString;
|
||||||
function DoParse(AParser: TTextParser): Boolean; override;
|
function DoParse(AParser: TTextParser): Boolean; override;
|
||||||
end;
|
end;
|
||||||
@ -219,16 +224,6 @@ type
|
|||||||
_Comment : AnsiString; // in case sources are UTF8 or Unicode
|
_Comment : AnsiString; // in case sources are UTF8 or Unicode
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TPrecompiler }
|
|
||||||
|
|
||||||
TPrecompiler = class(TEntity)
|
|
||||||
protected
|
|
||||||
function DoParse(AParser: TTextParser): Boolean; override;
|
|
||||||
public
|
|
||||||
_Directive : AnsiString;
|
|
||||||
_Params : AnsiString;
|
|
||||||
end;
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
{ TSimpleType }
|
{ TSimpleType }
|
||||||
@ -415,9 +410,77 @@ function ParseTypeDef(AParser: TTextParser): TTypeDef;
|
|||||||
function ParseEnum(AParser: TTextParser): TEnumType;
|
function ParseEnum(AParser: TTextParser): TEnumType;
|
||||||
|
|
||||||
function PreprocGlobal(const buf: string; fs: TFileOffsets; ent: TList): string;
|
function PreprocGlobal(const buf: string; fs: TFileOffsets; ent: TList): string;
|
||||||
|
procedure ParseDirectives(const s: string; entList: TList);
|
||||||
|
function PreprocessHeader(const s: string; entList: TList; macros: TCMacroHandler; fs: TFileOffsets): string;
|
||||||
|
procedure CPrepDefineToMacrosHandler(def: TCPrepDefine; mh: TCMacroHandler);
|
||||||
|
|
||||||
|
procedure DebugEnList(entlist: TList);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
cparserexp; // todo: expression parsing should in the same unit!
|
||||||
|
|
||||||
|
procedure ParseDirectives(const s: string; entList: TList);
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
j : integer;
|
||||||
|
nm : string;
|
||||||
|
vl : string;
|
||||||
|
ent : TCPrepocessor;
|
||||||
|
t : integer;
|
||||||
|
begin
|
||||||
|
i:=1;
|
||||||
|
while (i<=length(s)) do begin
|
||||||
|
SkipWhile(s, i, WhiteSpaceChars);
|
||||||
|
if (i<=length(s)) then begin
|
||||||
|
if (s[i]='#') then begin
|
||||||
|
j:=i;
|
||||||
|
inc(i);
|
||||||
|
SkipWhile(s, i, WhiteSpaceChars);
|
||||||
|
nm:=ScanTo(s, i, SpaceEolnChars);
|
||||||
|
SkipWhile(s, i, WhiteSpaceChars);
|
||||||
|
vl:=trim(ScanTo(s, i, EolnChars));
|
||||||
|
if (nm='if') or (nm='elif') then begin
|
||||||
|
ent:=TCPrepIf.Create(j);
|
||||||
|
TCPrepIf(ent).IfOp:=nm;
|
||||||
|
TCPrepIf(ent)._Cond:=vl;
|
||||||
|
end else if (nm='ifdef') or (nm='ifndef') then begin
|
||||||
|
ent:=TCPrepIf.Create(j);
|
||||||
|
TCPrepIf(ent)._Cond:=vl;
|
||||||
|
TCPrepIf(ent).IfOp:=nm;
|
||||||
|
end else if (nm='include') or (nm='import') then begin
|
||||||
|
ent:=TCPrepInclude.Create(j);
|
||||||
|
if (length(vl)>0) and (vl[1] in ['<','"'])then begin
|
||||||
|
t:=length(vl)-1;
|
||||||
|
if (vl[length(vl)] in ['>','"']) then dec(t);
|
||||||
|
TCPrepInclude(ent).Included:=Copy(vl, 2, t);
|
||||||
|
TCPrepInclude(ent).isSysFile:=vl[1]='<';
|
||||||
|
end;
|
||||||
|
end else if (nm='endif') then begin
|
||||||
|
ent:=TCPrepEndif.Create(j);
|
||||||
|
end else
|
||||||
|
ent:=TCPrepocessor.Create(j);
|
||||||
|
ent._Directive:=nm;
|
||||||
|
ent._Value:=vl;
|
||||||
|
ent.EndOffset:=i;
|
||||||
|
// consume 1 eoln
|
||||||
|
if (i<=length(s)) and (s[i] in [#10,#13]) then begin
|
||||||
|
inc(i);
|
||||||
|
inc(ent.EndOffset);
|
||||||
|
if (i<=length(s)) and (s[i] in [#10,#13]) and (s[i]<>s[i-1]) then begin
|
||||||
|
inc(i);
|
||||||
|
inc(ent.EndOffset);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
entList.Add(ent);
|
||||||
|
end else
|
||||||
|
SkipToEoln(s, i);
|
||||||
|
end;
|
||||||
|
SkipWhile(s, i, SpaceEolnChars);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{function FindNextPreproc(const s: string; var i: integer;
|
{function FindNextPreproc(const s: string; var i: integer;
|
||||||
var PreType: TPreprocType; var Name, Content: string): Boolean;
|
var PreType: TPreprocType; var Name, Content: string): Boolean;
|
||||||
var
|
var
|
||||||
@ -458,7 +521,7 @@ var
|
|||||||
begin
|
begin
|
||||||
if (ToIdx>=k) then begin
|
if (ToIdx>=k) then begin
|
||||||
Result:=Result+Copy(buf, k, toIdx-k);
|
Result:=Result+Copy(buf, k, toIdx-k);
|
||||||
ToIdx:=k+1;
|
k:=ToIdx+1;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -565,6 +628,8 @@ begin
|
|||||||
Result.AddSymbol('--');
|
Result.AddSymbol('--');
|
||||||
Result.AddSymbol('||');
|
Result.AddSymbol('||');
|
||||||
Result.AddSymbol('&&');
|
Result.AddSymbol('&&');
|
||||||
|
Result.AddSymbol('>=');
|
||||||
|
Result.AddSymbol('<=');
|
||||||
|
|
||||||
Result.SpaceChars := EoLnChars + InvsChars;
|
Result.SpaceChars := EoLnChars + InvsChars;
|
||||||
Result.Precompile := '#';
|
Result.Precompile := '#';
|
||||||
@ -1172,27 +1237,6 @@ begin
|
|||||||
AParser.EndParse;
|
AParser.EndParse;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TPrecompiler }
|
|
||||||
|
|
||||||
function TPrecompiler.DoParse(AParser: TTextParser): Boolean;
|
|
||||||
var
|
|
||||||
tt : TTokenType;
|
|
||||||
begin
|
|
||||||
Result := false;
|
|
||||||
if not AParser.FindNextToken(_Directive, tt) then begin
|
|
||||||
AParser.SetError('precompiler directive not found');
|
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
if (_Directive = '') or (_Directive[1] <> '#') then begin
|
|
||||||
AParser.Index := AParser.TokenPos;
|
|
||||||
AParser.SetError('identifier is not precompiler directive');
|
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
_Params := SkipLine(AParser.Buf, AParser.Index);
|
|
||||||
Result := true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TComment }
|
{ TComment }
|
||||||
|
|
||||||
function TComment.DoParse(AParser: TTextParser): Boolean;
|
function TComment.DoParse(AParser: TTextParser): Boolean;
|
||||||
@ -1284,7 +1328,7 @@ function TCPrepInclude.DoParse(AParser: TTextParser): Boolean;
|
|||||||
var
|
var
|
||||||
s : AnsiString;
|
s : AnsiString;
|
||||||
tt : TTokenType;
|
tt : TTokenType;
|
||||||
exp : AnsiString;
|
exp : AnsiChar;
|
||||||
chars : TCharSet;
|
chars : TCharSet;
|
||||||
begin
|
begin
|
||||||
chars := AParser.TokenTable.Symbols;
|
chars := AParser.TokenTable.Symbols;
|
||||||
@ -1302,8 +1346,9 @@ begin
|
|||||||
AParser.SetError('" is expected');
|
AParser.SetError('" is expected');
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
isSysFile:=exp='>';
|
||||||
|
|
||||||
Included:=ScanTo(AParser.Buf, AParser.Index, [exp[1]]+ EoLnChars);
|
Included:=ScanTo(AParser.Buf, AParser.Index, [exp]+ EoLnChars);
|
||||||
if (AParser.Index<=length(AParser.Buf)) and (AParser.Buf[AParser.Index] in EoLnChars) then begin
|
if (AParser.Index<=length(AParser.Buf)) and (AParser.Buf[AParser.Index] in EoLnChars) then begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
AParser.SetError(exp+' is expected');
|
AParser.SetError(exp+' is expected');
|
||||||
@ -1327,11 +1372,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TCPrepInclude.Destroy;
|
|
||||||
begin
|
|
||||||
Params.Free;
|
|
||||||
inherited Destroy;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TCPrepElse }
|
{ TCPrepElse }
|
||||||
|
|
||||||
@ -2315,6 +2355,102 @@ begin
|
|||||||
if Assigned(Result) then Result.EndOffset:=AParser.Index;
|
if Assigned(Result) then Result.EndOffset:=AParser.Index;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure ParseIfDef(const s: string; var idx: integer; ifdef: TCPrepIf);
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure DebugEnList(entlist: TList);
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
ent : TEntity;
|
||||||
|
begin
|
||||||
|
for i:=0 to entList.Count-1 do begin
|
||||||
|
ent := TEntity(entList[i]);
|
||||||
|
writeln(ent.Offset,'-',ent.EndOffset,' ',ent.ClassName);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function PreprocessHeader(const s: string; entList: TList; macros: TCMacroHandler; fs: TFileOffsets): string;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
ent : TEntity;
|
||||||
|
df : TCPrepDefine;
|
||||||
|
dif : TCPrepIf;
|
||||||
|
isCondMet : Boolean;
|
||||||
|
lvl : Integer;
|
||||||
|
|
||||||
|
k : Integer;
|
||||||
|
|
||||||
|
procedure Feed(ToIdx: Integer);
|
||||||
|
begin
|
||||||
|
if (ToIdx>=k) then begin
|
||||||
|
Result:=Result+Copy(s, k, toIdx-k);
|
||||||
|
k:=ToIdx+1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SetFeedOfs(ToIdx: integer);
|
||||||
|
begin
|
||||||
|
k:=ToIdx;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
begin
|
||||||
|
i:=0;
|
||||||
|
k:=1;
|
||||||
|
Result:='';
|
||||||
|
|
||||||
|
while (i<entList.Count) do begin
|
||||||
|
ent:=TEntity(entList[i]);
|
||||||
|
if (ent is TCPrepDefine) then begin
|
||||||
|
Feed( ent.Offset );
|
||||||
|
SetFeedOfs( ent.EndOffset );
|
||||||
|
CPrepDefineToMacrosHandler( TCPrepDefine(ent), macros );
|
||||||
|
inc(i);
|
||||||
|
end else if ent is TCPrepIf then begin
|
||||||
|
Feed( ent.Offset );
|
||||||
|
dif := TCPrepIf(ent);
|
||||||
|
if (dif.IfOp='ifdef') or (dif.IfOp='ifndef') then begin
|
||||||
|
isCondMet:=macros.isMacroDefined(dif._Cond);
|
||||||
|
if (dif.IfOp='ifndef') then isCondMet:=not isCondMet;
|
||||||
|
end else if (dif.IfOp='if') or (dif.IfOp='elif') then begin
|
||||||
|
isCondMet:=ValuateIntExp(dif._Cond, macros)<>0;
|
||||||
|
end else
|
||||||
|
isCondMet:=false;
|
||||||
|
inc(i);
|
||||||
|
|
||||||
|
if not isCondMet then begin
|
||||||
|
lvl:=1;
|
||||||
|
while (i<entList.Count) and (lvl>0) do begin
|
||||||
|
ent:=TEntity(entList[i]);
|
||||||
|
if ent is TCPrepEndif then dec(lvl)
|
||||||
|
else if ent is TCPrepIf then inc(lvl);
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
SetFeedOfs( ent.EndOffset );
|
||||||
|
end else
|
||||||
|
SetFeedOfs( ent.EndOffset );
|
||||||
|
end else begin
|
||||||
|
Feed( ent.Offset );
|
||||||
|
SetFeedOfs( ent.EndOffset );
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Feed( length(s)+1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CPrepDefineToMacrosHandler(def: TCPrepDefine; mh: TCMacroHandler);
|
||||||
|
begin
|
||||||
|
if not Assigned(def) or not Assigned(mh) then Exit;
|
||||||
|
|
||||||
|
if not Assigned(def.Params) or (def.Params.Count=0) then
|
||||||
|
mh.AddSimpleMacro(def._Name, def.SubsText)
|
||||||
|
else
|
||||||
|
mh.AddParamMacro(def._Name, def.SubsText, def.Params);
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
_ParseNextEntity:=@ParseNextCEntity;
|
_ParseNextEntity:=@ParseNextCEntity;
|
||||||
ParseNamePart:=@ParseCNamePart;
|
ParseNamePart:=@ParseCNamePart;
|
||||||
|
@ -162,7 +162,6 @@ function CEntitiesToPas(const originText: string; entList: TList; cfg: TConvertS
|
|||||||
procedure ReleaseList(enlist: TList);
|
procedure ReleaseList(enlist: TList);
|
||||||
|
|
||||||
procedure AssignIntComments(SortedEnlist: TList);
|
procedure AssignIntComments(SortedEnlist: TList);
|
||||||
procedure DebugEnList(entlist: TList);
|
|
||||||
procedure DebugHeaders(files: TStrings);
|
procedure DebugHeaders(files: TStrings);
|
||||||
|
|
||||||
function PreprocDirectives(const buf: string; macro: TMacrosMaker; fs: TFileOffsets; ent: TList): string;
|
function PreprocDirectives(const buf: string; macro: TMacrosMaker; fs: TFileOffsets; ent: TList): string;
|
||||||
@ -460,11 +459,7 @@ begin
|
|||||||
|
|
||||||
if hnd.isMacroDefined(d._Name) and not allowRedfine then Exit;
|
if hnd.isMacroDefined(d._Name) and not allowRedfine then Exit;
|
||||||
|
|
||||||
if not Assigned(d.Params) or (d.Params.Count=0) then begin
|
CPrepDefineToMacrosHandler(d, hnd);
|
||||||
hnd.AddSimpleMacro(d._Name, d.SubsText);
|
|
||||||
end else begin
|
|
||||||
hnd.AddParamMacro(d._Name, d.SubsText, d.Params);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure SkipPreproc(AParser: TTextParser);
|
procedure SkipPreproc(AParser: TTextParser);
|
||||||
@ -655,17 +650,6 @@ begin
|
|||||||
SortedEnList.Pack;
|
SortedEnList.Pack;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure DebugEnList(entlist: TList);
|
|
||||||
var
|
|
||||||
i : Integer;
|
|
||||||
ent : TEntity;
|
|
||||||
begin
|
|
||||||
for i:=0 to entList.Count-1 do begin
|
|
||||||
ent := TEntity(entList[i]);
|
|
||||||
writeln(ent.Offset,'-',ent.EndOffset,' ',ent.ClassName);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure DebugHeaders(files: TStrings);
|
procedure DebugHeaders(files: TStrings);
|
||||||
var
|
var
|
||||||
hdr : THeaderFile;
|
hdr : THeaderFile;
|
||||||
|
@ -38,11 +38,13 @@ const
|
|||||||
AlphabetChars = ['a'..'z','A'..'Z'];
|
AlphabetChars = ['a'..'z','A'..'Z'];
|
||||||
AlphaNumChars = AlphabetChars+NumericChars;
|
AlphaNumChars = AlphabetChars+NumericChars;
|
||||||
|
|
||||||
function ScanWhile(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
function ScanWhile(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString; overload;
|
||||||
function ScanBackWhile(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
function ScanBackWhile(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
||||||
function ScanTo(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
function ScanTo(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
||||||
function ScanBackTo(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
function ScanBackTo(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
||||||
function SkipToEoln(const s: AnsiString; var index: Integer): AnsiString;
|
procedure SkipTo(const s: AnsiString; var index: Integer; const ch: TCharSet);
|
||||||
|
procedure SkipWhile(const s: AnsiString; var index: Integer; const ch: TCharSet);
|
||||||
|
procedure SkipToEoln(const s: AnsiString; var index: Integer);
|
||||||
|
|
||||||
// returns #10, #13, #10#13 or #13#10, if s[index] is end-of-line sequence
|
// returns #10, #13, #10#13 or #13#10, if s[index] is end-of-line sequence
|
||||||
// otherwise returns empty string
|
// otherwise returns empty string
|
||||||
@ -104,7 +106,8 @@ type
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function ScanWhile(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
function ScanWhile(const s: AnsiString; var index: Integer; const ch: TCharSet
|
||||||
|
): string;
|
||||||
var
|
var
|
||||||
i : Integer;
|
i : Integer;
|
||||||
begin
|
begin
|
||||||
@ -132,9 +135,21 @@ begin
|
|||||||
Result:=Copy(s, index+1, j-index);
|
Result:=Copy(s, index+1, j-index);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure SkipTo(const s: AnsiString; var index: Integer; const ch: TCharSet);
|
||||||
|
begin
|
||||||
|
if (index <= 0) or (index > length(s)) then Exit;
|
||||||
|
while (index<=length(s)) and not (s[index] in ch) do inc(index);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SkipWhile(const s: AnsiString; var index: Integer; const ch: TCharSet);
|
||||||
|
begin
|
||||||
|
if (index <= 0) or (index > length(s)) then Exit;
|
||||||
|
while (index<=length(s)) and (s[index] in ch) do inc(index);
|
||||||
|
end;
|
||||||
|
|
||||||
function ScanBackTo(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
function ScanBackTo(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
|
||||||
var
|
var
|
||||||
j : integer;
|
j : integer;
|
||||||
begin
|
begin
|
||||||
Result:='';
|
Result:='';
|
||||||
if (index <= 0) or (index > length(s)) then Exit;
|
if (index <= 0) or (index > length(s)) then Exit;
|
||||||
@ -172,9 +187,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function SkipToEoln(const s: AnsiString; var index: Integer): AnsiString;
|
procedure SkipToEoln(const s: AnsiString; var index: Integer);
|
||||||
begin
|
begin
|
||||||
Result := ScanTo(s, index, EoLnChars);
|
SkipTo(s, index, EoLnChars);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function IsSubStr(const sbs, s: AnsiString; index: Integer): Boolean;
|
function IsSubStr(const sbs, s: AnsiString; index: Integer): Boolean;
|
||||||
|
Reference in New Issue
Block a user