1
0
Files
aarre
applications
bindings
components
ZVDateTimeCtrls
aboutcomponent
acs
beepfp
chelper
cconvconfig.pas
cconvert.lpi
cconvert.lpr
chelper.lpk
chelper.pas
codewriter.pas
converteridesettings.pas
cparsertypes.pas
cparserutils.pas
ctopasconvert.pas
ctopasexp.pas
extconvdialog.lfm
extconvdialog.pas
objcparsing.pas
textparsingutils.pas
tosourceeditor.pas
cmdline
cmdlinecfg
colorpalette
csvdocument
epiktimer
fpsound
fpspreadsheet
freetypepascal
geckoport
gradcontrols
iosdesigner
iphonelazext
jujiboutils
jvcllaz
kcontrols
lazbarcodes
manualdock
mplayer
multithreadprocs
nvidia-widgets
onguard
orpheus
poweredby
powerpdf
rgbgraphics
richmemo
richview
rtfview
rx
scrolltext
smnetgradient
spktoolbar
svn
tdi
thtmlport
tparadoxdataset
tvplanit
virtualtreeview
virtualtreeview-new
xdev_toolkit
zlibar
examples
lclbindings
wst
lazarus-ccr/components/chelper/textparsingutils.pas

235 lines
6.1 KiB
ObjectPascal
Raw Normal View History

{ The unit is part of Lazarus Chelper package
Copyright (C) 2010 Dmitry Boyarintsev skalogryz dot lists at gmail.com
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
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. See the GNU Library General Public License
for more details.
You should have received a copy of the GNU Library General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
}
unit TextParsingUtils;
{$ifdef fpc}{$mode delphi}{$h+}{$endif}
interface
uses
Types;
type
TCharSet = set of Char;
const
EoLnChars = [#10,#13];
SpaceChars = [#32,#9];
InvsChars = [#0..#32];
WhiteSpaceChars = SpaceChars;
SpaceEolnChars = EoLnChars+SpaceChars;
NumericChars = ['0'..'9'];
AlphabetChars = ['a'..'z','A'..'Z'];
AlphaNumChars = AlphabetChars+NumericChars;
function ScanWhile(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
function ScanTo(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
function SkipToEoln(const s: AnsiString; var index: Integer): AnsiString;
// returns #10, #13, #10#13 or #13#10, if s[index] is end-of-line sequence
// otherwise returns empty string
function EolnStr(const s: AnsiString; index: Integer): String;
function IsSubStr(const sbs, s: AnsiString; index: Integer): Boolean;
// todo: not used?
function SkipCommentBlock(const s: AnsiString; var index: Integer; const closecmt: AnsiString): AnsiString;
function SkipLine(const s: AnsiString; var index: Integer): AnsiString;
procedure OffsetToLinePos(const t: AnsiString; Offset: Integer; var P: TPoint);
type
TRange = record stofs, endofs : Integer; end;
{ TSubBuffer }
TSubBuffer = class(TObject)
Ranges : array of TRange;
RangesCount : Integer;
Name : string;
Tag : TObject;
constructor Create(const AName: string; ATag: TObject);
end;
{ TTextBuffer }
TTextBuffer = class(TObject)
private
function GetSubBuffer(i: Integer): TSubBuffer;
protected
function GetCount: Integer;
public
buffer: String;
constructor Create(const Abuffer: String=''; const aname: string = ''; aobj: TObject = nil);
procedure InsertSubBuffer(pos: Integer; const ABuffer: string; const AName: string = ''; ATag: TObject = '');
property SubBuffer[i: Integer]: TSubBuffer read GetSubBuffer;
property Count: Integer read GetCount;
end;
implementation
function ScanWhile(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
var
i : Integer;
begin
Result := '';
if (index <= 0) or (index > length(s)) then Exit;
for i := index to length(s) do
if not (s[i] in ch) then begin
if i = index then Result := ''
else Result := Copy(s, index, i - index);
index := i;
Exit;
end;
Result := Copy(s, index, length(s) - index + 1);
index := length(s) + 1;
end;
function ScanTo(const s: AnsiString; var index: Integer; const ch: TCharSet): AnsiString;
var
i : Integer;
begin
Result := '';
if (index <= 0) or (index > length(s)) then Exit;
for i := index to length(s) do
if (s[i] in ch) then begin
if i = index then Result := ''
else Result := Copy(s, index, i - index);
index := i;
Exit;
end;
Result := Copy(s, index, length(s) - index + 1);
index := length(s) + 1;
end;
function EolnStr(const s: AnsiString; index: Integer): String;
begin
if (index<=0) or (index>length(s)) or (not (s[index] in EoLnChars)) then
Result:=''
else begin
if (index<length(s)) and (s[index+1] in EolnChars) and (s[index]<>s[index+1]) then
Result:=Copy(s, index, 2)
else
Result:=s[index];
end;
end;
function SkipToEoln(const s: AnsiString; var index: Integer): AnsiString;
begin
Result := ScanTo(s, index, EoLnChars);
end;
function IsSubStr(const sbs, s: AnsiString; index: Integer): Boolean;
var
i : Integer;
j : Integer;
begin
Result := false;
if (sbs = '') or (length(sbs) > length(s) - index) then Exit;
j := index;
for i := 1 to length(sbs) do begin
if sbs[i] <> s[j] then Exit;
inc(j);
end;
Result := true;
end;
function SkipCommentBlock(const s: AnsiString; var index: Integer; const closecmt: AnsiString): AnsiString;
begin
Result := '';
if closecmt = '' then begin
index := length(s) + 1;
Exit;
end;
while index <= length(s) do begin
Result := Result + ScanTo(s, index, [closecmt[1]]+EoLnChars);
//if (index<=length(s)) and (s in EoLnChars(
if IsSubStr(closecmt, s, index) then begin
inc(index, length(closecmt));
Exit;
end else begin
Result := Result + s[index];
inc(index);
end;
end;
end;
function SkipLine(const s: AnsiString; var index: Integer): AnsiString;
begin
Result:=ScanTo(s, index, EoLnChars);
if (index<length(s)) and (s[index+1] in EoLnChars) and (s[index]<>s[index+1]) then
inc(index);
inc(index);
end;
procedure OffsetToLinePos(const t: AnsiString; Offset: Integer; var P: TPoint);
var
i, le : Integer;
begin
i := 1;
le := 0;
P.X := 0;
P.Y := 0;
while i < Offset do begin
Inc(P.Y);
le := i;
SkipLine(t, i);
end;
P.X := Offset - le + 1;
end;
{ TTextBuffer }
function TTextBuffer.GetSubBuffer(i: Integer): TSubBuffer;
begin
Result:=nil;
end;
function TTextBuffer.GetCount: Integer;
begin
Result:=0;
end;
constructor TTextBuffer.Create(const Abuffer: String; const aname: string;
aobj: TObject);
begin
if abuffer<>'' then
InsertSubBuffer(1, abuffer, aname, aobj);
end;
procedure TTextBuffer.InsertSubBuffer(pos: Integer; const ABuffer: string; const AName: string; ATag: TObject);
begin
end;
{ TSubBuffer }
constructor TSubBuffer.Create(const AName: string; ATag: TObject);
begin
inherited Create;
Name:=AName;
Tag:=ATag;
end;
end.