mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-06 00:53:54 +02:00
243 lines
5.7 KiB
ObjectPascal
243 lines
5.7 KiB
ObjectPascal
{(*}
|
|
(*------------------------------------------------------------------------------
|
|
Delphi Code formatter source code
|
|
|
|
The Original Code is CodeReader.pas, released April 2000.
|
|
The Initial Developer of the Original Code is Anthony Steele.
|
|
Portions created by Anthony Steele are Copyright (C) 1999-2000 Anthony Steele.
|
|
All Rights Reserved.
|
|
Contributor(s): Anthony Steele.
|
|
|
|
The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
(the "License"). you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at http://www.mozilla.org/NPL/
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing rights and limitations
|
|
under the License.
|
|
|
|
Alternatively, the contents of this file may be used under the terms of
|
|
the GNU General Public License Version 2 or later (the "GPL")
|
|
See http://www.gnu.org/licenses/gpl.html
|
|
------------------------------------------------------------------------------*)
|
|
{*)}
|
|
|
|
unit CodeReader;
|
|
|
|
{
|
|
{ Created AFS 27 November 1999
|
|
abstract base class reader for both IDE and file
|
|
defines the itnerface to get the code text
|
|
|
|
The method is to first read the entire file into a string
|
|
This is a textbook optimization - 1 read for the whole file
|
|
instead of 1 per char. The file may be large
|
|
(the largest file that ships with Delphi5, excel2000.pas, is 4Mb!!!!)
|
|
but even this should fit into memory
|
|
This technique is not optimised for files of that size,
|
|
but hey, that code has got to be machine-generated anyway.
|
|
Why would it need machine-reformatting?
|
|
|
|
8 Jan 2K - the original code is now split into
|
|
TCodeReader (base class) and TFileReader (read from file
|
|
so that another subclass (TEditorReader) can be made for the IDE pluggin
|
|
with the same interface
|
|
|
|
Now called TCodeReader not TReader to avoid a name clash with Classes.Reader
|
|
|
|
}
|
|
|
|
{$I JcfGlobal.inc}
|
|
|
|
interface
|
|
|
|
type
|
|
TCodeReader = class(TObject)
|
|
private
|
|
function GetBuffer: string;
|
|
procedure SetBufferLength(const piValue: integer);
|
|
|
|
protected
|
|
{ working vars }
|
|
fsSource: string;
|
|
fiSourceLength: integer;
|
|
fiReadIndex, fiBufferLength: integer;
|
|
|
|
fbHasRead: boolean;
|
|
|
|
procedure ReadFromSource; virtual;
|
|
|
|
public
|
|
constructor Create; virtual;
|
|
|
|
procedure Clear; virtual;
|
|
|
|
procedure Consume; overload;
|
|
procedure Consume(piChars: integer); overload;
|
|
function ConsumeBuffer: string;
|
|
|
|
function Current: char;
|
|
function Last: char;
|
|
|
|
procedure IncBuffer;
|
|
procedure DecBuffer;
|
|
|
|
function BufferChar(const piIndex: integer): char;
|
|
function BufferCharsLeft(const piLength: integer): string;
|
|
function BufferCharsRight(const piLength: integer): string;
|
|
|
|
|
|
function EndOfFile: boolean;
|
|
function BufferEndOfFile: boolean;
|
|
|
|
property Buffer: string Read GetBuffer;
|
|
property BufferLength: integer Read fiBufferLength Write SetBufferLength;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TCodeReader }
|
|
|
|
constructor TCodeReader.Create;
|
|
begin
|
|
inherited;
|
|
Clear;
|
|
end;
|
|
|
|
procedure TCodeReader.Clear;
|
|
begin
|
|
fsSource := '';
|
|
fiSourceLength := 0;
|
|
|
|
fiReadIndex := -1;
|
|
fiBufferLength := 1;
|
|
fbHasRead := False;
|
|
end;
|
|
|
|
|
|
function TCodeReader.EndOfFile: boolean;
|
|
begin
|
|
Result := (fiReadIndex > fiSourceLength);
|
|
end;
|
|
|
|
function TCodeReader.BufferEndOfFile: boolean;
|
|
begin
|
|
Result := ((fiReadIndex + BufferLength - 1) >= fiSourceLength);
|
|
end;
|
|
|
|
{ make sure that the buffer is at least this length }
|
|
procedure TCodeReader.SetBufferLength(const piValue: integer);
|
|
begin
|
|
if not fbHasRead then
|
|
ReadFromSource;
|
|
|
|
Assert(piValue >= 1);
|
|
fiBufferLength := piValue;
|
|
end;
|
|
|
|
procedure TCodeReader.IncBuffer;
|
|
begin
|
|
Inc(fiBufferLength);
|
|
|
|
{ chop to the remaining length }
|
|
if (fiReadIndex + fiBufferLength - 1) > fiSourceLength then
|
|
fiBufferLength := fiSourceLength - fiReadIndex + 1;
|
|
end;
|
|
|
|
procedure TCodeReader.DecBuffer;
|
|
begin
|
|
Dec(fiBufferLength);
|
|
if fiBufferLength < 1 then
|
|
fiBufferLength := 1;
|
|
end;
|
|
|
|
|
|
procedure TCodeReader.Consume;
|
|
begin
|
|
Inc(fiReadIndex);
|
|
end;
|
|
|
|
procedure TCodeReader.Consume(piChars: integer);
|
|
begin
|
|
Assert(piChars > 0);
|
|
Inc(fiReadIndex, piChars);
|
|
Dec(fiBufferLength, piChars);
|
|
if fiBufferLength < 1 then
|
|
fiBufferLength := 1;
|
|
end;
|
|
|
|
function TCodeReader.ConsumeBuffer: string;
|
|
begin
|
|
Result := Buffer;
|
|
Consume(BufferLength);
|
|
BufferLength := 1;
|
|
end;
|
|
|
|
function TCodeReader.GetBuffer: string;
|
|
begin
|
|
Result := Copy(fsSource, fiReadIndex, BufferLength);
|
|
end;
|
|
|
|
function TCodeReader.BufferChar(const piIndex: integer): char;
|
|
begin
|
|
Result := fsSource[fiReadIndex + piIndex];
|
|
end;
|
|
|
|
function TCodeReader.BufferCharsLeft(const piLength: integer): string;
|
|
begin
|
|
Result := '';
|
|
if fsSource = '' then
|
|
exit;
|
|
|
|
Result := Copy(fsSource, fiReadIndex, piLength);
|
|
end;
|
|
|
|
function TCodeReader.BufferCharsRight(const piLength: integer): string;
|
|
var
|
|
liStart: integer;
|
|
begin
|
|
Result := '';
|
|
if fsSource = '' then
|
|
exit;
|
|
Assert(piLength <= BufferLength);
|
|
|
|
liStart := (fiReadIndex + BufferLength - piLength);
|
|
if liStart > fiSourceLength then
|
|
Result := #0
|
|
else
|
|
Result := Copy(fsSource, liStart, piLength);
|
|
end;
|
|
|
|
function TCodeReader.Current: char;
|
|
begin
|
|
if not fbHasRead then
|
|
ReadFromSource;
|
|
|
|
if (fiReadIndex > fiSourceLength) then
|
|
Result := #0
|
|
else
|
|
Result := fsSource[fiReadIndex];
|
|
end;
|
|
|
|
function TCodeReader.Last: char;
|
|
var
|
|
liIndex: integer;
|
|
begin
|
|
liIndex := fiReadIndex + BufferLength - 1;
|
|
|
|
if BufferLength < 0 then
|
|
Result := #0
|
|
else if (liIndex > fiSourceLength) or (liIndex < 1) then
|
|
Result := #0
|
|
else
|
|
Result := fsSource[liIndex];
|
|
end;
|
|
|
|
procedure TCodeReader.ReadFromSource;
|
|
begin
|
|
Assert(False, ClassName + ' must override TCodeReader.ReadFromSource');
|
|
end;
|
|
|
|
end.
|