mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 13:19:35 +02:00
1451 lines
35 KiB
ObjectPascal
1451 lines
35 KiB
ObjectPascal
{
|
|
$Id$
|
|
This file is part of the Free Pascal Integrated Development Environment
|
|
Copyright (c) 1998 by Berczi Gabor
|
|
|
|
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.
|
|
|
|
**********************************************************************}
|
|
unit WUtils;
|
|
|
|
interface
|
|
|
|
{$ifndef FPC}
|
|
{$define TPUNIXLF}
|
|
{$endif}
|
|
|
|
|
|
uses
|
|
{$ifdef win32}
|
|
windows,
|
|
{$endif win32}
|
|
{$ifdef Unix}
|
|
{$ifdef VER1_0}
|
|
linux,
|
|
{$else}
|
|
unix,
|
|
{$endif}
|
|
{$endif Unix}
|
|
Dos,Objects;
|
|
|
|
const
|
|
kbCtrlGrayPlus = $9000;
|
|
kbCtrlGrayMinus = $8e00;
|
|
kbCtrlGrayMul = $9600;
|
|
|
|
TempFirstChar = {$ifndef Unix}'~'{$else}'_'{$endif};
|
|
TempExt = '.tmp';
|
|
TempNameLen = 8;
|
|
EOL : String[2] = {$ifdef Unix}#10;{$else}#13#10;{$endif}
|
|
|
|
type
|
|
PByteArray = ^TByteArray;
|
|
TByteArray = array[0..MaxBytes] of byte;
|
|
|
|
PNoDisposeCollection = ^TNoDisposeCollection;
|
|
TNoDisposeCollection = object(TCollection)
|
|
procedure FreeItem(Item: Pointer); virtual;
|
|
end;
|
|
|
|
PUnsortedStringCollection = ^TUnsortedStringCollection;
|
|
TUnsortedStringCollection = object(TCollection)
|
|
constructor CreateFrom(ALines: PUnsortedStringCollection);
|
|
procedure Assign(ALines: PUnsortedStringCollection);
|
|
function At(Index: Sw_Integer): PString;
|
|
procedure FreeItem(Item: Pointer); virtual;
|
|
function GetItem(var S: TStream): Pointer; virtual;
|
|
procedure PutItem(var S: TStream; Item: Pointer); virtual;
|
|
procedure InsertStr(const S: string);
|
|
end;
|
|
|
|
PNulStream = ^TNulStream;
|
|
TNulStream = object(TStream)
|
|
constructor Init;
|
|
function GetPos: Longint; virtual;
|
|
function GetSize: Longint; virtual;
|
|
procedure Read(var Buf; Count: Word); virtual;
|
|
procedure Seek(Pos: Longint); virtual;
|
|
procedure Write(var Buf; Count: Word); virtual;
|
|
end;
|
|
|
|
PSubStream = ^TSubStream;
|
|
TSubStream = object(TStream)
|
|
constructor Init(AStream: PStream; AStartPos, ASize: longint);
|
|
function GetPos: Longint; virtual;
|
|
function GetSize: Longint; virtual;
|
|
procedure Read(var Buf; Count: Word); virtual;
|
|
procedure Seek(Pos: Longint); virtual;
|
|
procedure Write(var Buf; Count: Word); virtual;
|
|
private
|
|
StartPos: longint;
|
|
S : PStream;
|
|
end;
|
|
|
|
PFastBufStream = ^TFastBufStream;
|
|
TFastBufStream = object(TBufStream)
|
|
procedure Seek(Pos: Longint); virtual;
|
|
private
|
|
BasePos: longint;
|
|
end;
|
|
|
|
PTextCollection = ^TTextCollection;
|
|
TTextCollection = object(TStringCollection)
|
|
function LookUp(const S: string; var Idx: sw_integer): string;
|
|
function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
|
|
end;
|
|
|
|
PIntCollection = ^TIntCollection;
|
|
TIntCollection = object(TSortedCollection)
|
|
function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
|
|
procedure FreeItem(Item: Pointer); virtual;
|
|
procedure Add(Item: longint);
|
|
function Contains(Item: longint): boolean;
|
|
function AtInt(Index: sw_integer): longint;
|
|
end;
|
|
|
|
{$ifdef TPUNIXLF}
|
|
procedure readln(var t:text;var s:string);
|
|
{$endif}
|
|
|
|
procedure ReadlnFromStream(Stream: PStream; var s:string;var linecomplete,hasCR : boolean);
|
|
function eofstream(s: pstream): boolean;
|
|
|
|
function Min(A,B: longint): longint;
|
|
function Max(A,B: longint): longint;
|
|
|
|
function CharStr(C: char; Count: integer): string;
|
|
function UpcaseStr(const S: string): string;
|
|
function LowCase(C: char): char;
|
|
function LowcaseStr(S: string): string;
|
|
function RExpand(const S: string; MinLen: byte): string;
|
|
function LExpand(const S: string; MinLen: byte): string;
|
|
function LTrim(const S: string): string;
|
|
function RTrim(const S: string): string;
|
|
function Trim(const S: string): string;
|
|
function IntToStr(L: longint): string;
|
|
function IntToStrL(L: longint; MinLen: sw_integer): string;
|
|
function IntToStrZ(L: longint; MinLen: sw_integer): string;
|
|
function StrToInt(const S: string): longint;
|
|
function StrToCard(const S: string): cardinal;
|
|
function FloatToStr(D: Double; Decimals: byte): string;
|
|
function FloatToStrL(D: Double; Decimals: byte; MinLen: byte): string;
|
|
function HexToInt(S: string): longint;
|
|
function HexToCard(S: string): cardinal;
|
|
function IntToHex(L: longint; MinLen: integer): string;
|
|
function GetStr(P: PString): string;
|
|
function GetPChar(P: PChar): string;
|
|
function BoolToStr(B: boolean; const TrueS, FalseS: string): string;
|
|
function LExtendString(S: string; MinLen: byte): string;
|
|
|
|
function DirOf(const S: string): string;
|
|
function ExtOf(const S: string): string;
|
|
function NameOf(const S: string): string;
|
|
function NameAndExtOf(const S: string): string;
|
|
function DirAndNameOf(const S: string): string;
|
|
{ return Dos GetFTime value or -1 if the file does not exist }
|
|
function GetFileTime(const FileName: string): longint;
|
|
{ copied from compiler global unit }
|
|
function GetShortName(const n:string):string;
|
|
function GetLongName(const n:string):string;
|
|
function TrimEndSlash(const Path: string): string;
|
|
function CompleteDir(const Path: string): string;
|
|
function GetCurDir: string;
|
|
function OptimizePath(Path: string; MaxLen: integer): string;
|
|
function CompareText(S1, S2: string): integer;
|
|
function ExistsDir(const DirName: string): boolean;
|
|
function ExistsFile(const FileName: string): boolean;
|
|
function DeleteFile(const FileName: string): integer;
|
|
function CopyFile(const SrcFileName, DestFileName: string): boolean;
|
|
function GenTempFileName: string;
|
|
|
|
function FormatPath(Path: string): string;
|
|
function CompletePath(const Base, InComplete: string): string;
|
|
function CompleteURL(const Base, URLRef: string): string;
|
|
|
|
function EatIO: integer;
|
|
|
|
function Now: longint;
|
|
|
|
function FormatDateTimeL(L: longint; const Format: string): string;
|
|
function FormatDateTime(const D: DateTime; const Format: string): string;
|
|
|
|
{$ifdef TP}
|
|
function StrPas(C: PChar): string;
|
|
{$endif}
|
|
function MemToStr(var B; Count: byte): string;
|
|
procedure StrToMem(S: string; var B);
|
|
|
|
procedure GiveUpTimeSlice;
|
|
|
|
const LastStrToIntResult : integer = 0;
|
|
LastHexToIntResult : integer = 0;
|
|
LastStrToCardResult : integer = 0;
|
|
LastHexToCardResult : integer = 0;
|
|
DirSep : char = {$ifdef Unix}'/'{$else}'\'{$endif};
|
|
|
|
procedure RegisterWUtils;
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFDEF OS2}
|
|
DosCalls,
|
|
{$ENDIF OS2}
|
|
Strings;
|
|
|
|
{$ifndef NOOBJREG}
|
|
const
|
|
SpaceStr = ' '+
|
|
' '+
|
|
' '+
|
|
' ' ;
|
|
|
|
|
|
RUnsortedStringCollection: TStreamRec = (
|
|
ObjType: 22500;
|
|
VmtLink: Ofs(TypeOf(TUnsortedStringCollection)^);
|
|
Load: @TUnsortedStringCollection.Load;
|
|
Store: @TUnsortedStringCollection.Store
|
|
);
|
|
{$endif}
|
|
|
|
{$ifdef TPUNIXLF}
|
|
procedure readln(var t:text;var s:string);
|
|
var
|
|
c : char;
|
|
i : longint;
|
|
begin
|
|
if TextRec(t).UserData[1]=2 then
|
|
system.readln(t,s)
|
|
else
|
|
begin
|
|
c:=#0;
|
|
i:=0;
|
|
while (not eof(t)) and (c<>#10) and (i<High(S)) do
|
|
begin
|
|
read(t,c);
|
|
if c<>#10 then
|
|
begin
|
|
inc(i);
|
|
s[i]:=c;
|
|
end;
|
|
end;
|
|
if (i>0) and (s[i]=#13) then
|
|
begin
|
|
dec(i);
|
|
TextRec(t).UserData[1]:=2;
|
|
end;
|
|
s[0]:=chr(i);
|
|
end;
|
|
end;
|
|
{$endif}
|
|
|
|
function eofstream(s: pstream): boolean;
|
|
begin
|
|
eofstream:=(s^.getpos>=s^.getsize);
|
|
end;
|
|
|
|
procedure ReadlnFromStream(Stream: PStream; var S:string;var linecomplete,hasCR : boolean);
|
|
var
|
|
c : char;
|
|
i,pos : longint;
|
|
begin
|
|
linecomplete:=false;
|
|
c:=#0;
|
|
i:=0;
|
|
{ this created problems for lines longer than 255 characters
|
|
now those lines are cutted into pieces without warning PM }
|
|
{ changed implicit 255 to High(S), so it will be automatically extended
|
|
when longstrings eventually become default - Gabor }
|
|
while (not eofstream(stream)) and (c<>#10) and (i<High(S)) do
|
|
begin
|
|
stream^.read(c,sizeof(c));
|
|
if c<>#10 then
|
|
begin
|
|
inc(i);
|
|
s[i]:=c;
|
|
end;
|
|
end;
|
|
{ if there was a CR LF then remove the CR Dos newline style }
|
|
if (i>0) and (s[i]=#13) then
|
|
begin
|
|
dec(i);
|
|
end;
|
|
if (c=#13) and (not eofstream(stream)) then
|
|
stream^.read(c,sizeof(c));
|
|
if (i=High(S)) and not eofstream(stream) then
|
|
begin
|
|
pos:=stream^.getpos;
|
|
stream^.read(c,sizeof(c));
|
|
if (c=#13) and not eofstream(stream) then
|
|
stream^.read(c,sizeof(c));
|
|
if c<>#10 then
|
|
stream^.seek(pos);
|
|
end;
|
|
if (c=#10) or eofstream(stream) then
|
|
linecomplete:=true;
|
|
if (c=#10) then
|
|
hasCR:=true;
|
|
s[0]:=chr(i);
|
|
end;
|
|
|
|
{$ifdef TP}
|
|
{ TP's own StrPas() is buggy, because it causes GPF with strings longer than
|
|
255 chars }
|
|
function StrPas(C: PChar): string;
|
|
var S: string;
|
|
I: longint;
|
|
begin
|
|
if Assigned(C)=false then
|
|
S:=''
|
|
else
|
|
begin
|
|
I:=StrLen(C); if I>High(S) then I:=High(S);
|
|
S[0]:=chr(I); Move(C^,S[1],I);
|
|
end;
|
|
StrPas:=S;
|
|
end;
|
|
{$endif}
|
|
|
|
function MemToStr(var B; Count: byte): string;
|
|
var S: string;
|
|
begin
|
|
S[0]:=chr(Count);
|
|
if Count>0 then Move(B,S[1],Count);
|
|
MemToStr:=S;
|
|
end;
|
|
|
|
procedure StrToMem(S: string; var B);
|
|
begin
|
|
if length(S)>0 then Move(S[1],B,length(S));
|
|
end;
|
|
|
|
function Max(A,B: longint): longint;
|
|
begin
|
|
if A>B then Max:=A else Max:=B;
|
|
end;
|
|
|
|
function Min(A,B: longint): longint;
|
|
begin
|
|
if A<B then Min:=A else Min:=B;
|
|
end;
|
|
|
|
function CharStr(C: char; Count: integer): string;
|
|
{$ifndef FPC}
|
|
var S: string;
|
|
{$endif}
|
|
begin
|
|
if Count<=0 then
|
|
begin
|
|
CharStr:='';
|
|
exit;
|
|
end
|
|
else if Count>255 then
|
|
Count:=255;
|
|
{$ifdef FPC}
|
|
CharStr[0]:=chr(Count);
|
|
FillChar(CharStr[1],Count,C);
|
|
{$else}
|
|
S[0]:=chr(Count);
|
|
FillChar(S[1],Count,C);
|
|
CharStr:=S;
|
|
{$endif}
|
|
end;
|
|
|
|
function UpcaseStr(const S: string): string;
|
|
var
|
|
I: Longint;
|
|
begin
|
|
for I:=1 to length(S) do
|
|
if S[I] in ['a'..'z'] then
|
|
UpCaseStr[I]:=chr(ord(S[I])-32)
|
|
else
|
|
UpCaseStr[I]:=S[I];
|
|
UpcaseStr[0]:=S[0];
|
|
end;
|
|
|
|
function RExpand(const S: string; MinLen: byte): string;
|
|
begin
|
|
if length(S)<MinLen then
|
|
RExpand:=S+CharStr(' ',MinLen-length(S))
|
|
else
|
|
RExpand:=S;
|
|
end;
|
|
|
|
function LExpand(const S: string; MinLen: byte): string;
|
|
begin
|
|
if length(S)<MinLen then
|
|
LExpand:=CharStr(' ',MinLen-length(S))+S
|
|
else
|
|
LExpand:=S;
|
|
end;
|
|
|
|
function LTrim(const S: string): string;
|
|
var
|
|
i : longint;
|
|
begin
|
|
i:=1;
|
|
while (i<length(s)) and (s[i]=' ') do
|
|
inc(i);
|
|
LTrim:=Copy(s,i,High(S));
|
|
end;
|
|
|
|
function RTrim(const S: string): string;
|
|
var
|
|
i : longint;
|
|
begin
|
|
i:=length(s);
|
|
while (i>0) and (s[i]=' ') do
|
|
dec(i);
|
|
RTrim:=Copy(s,1,i);
|
|
end;
|
|
|
|
function Trim(const S: string): string;
|
|
var
|
|
i,j : longint;
|
|
begin
|
|
i:=1;
|
|
while (i<length(s)) and (s[i]=' ') do
|
|
inc(i);
|
|
j:=length(s);
|
|
while (j>0) and (s[j]=' ') do
|
|
dec(j);
|
|
Trim:=Copy(S,i,j-i+1);
|
|
end;
|
|
|
|
function IntToStr(L: longint): string;
|
|
var S: string;
|
|
begin
|
|
Str(L,S);
|
|
IntToStr:=S;
|
|
end;
|
|
|
|
function IntToStrL(L: longint; MinLen: sw_integer): string;
|
|
begin
|
|
IntToStrL:=LExpand(IntToStr(L),MinLen);
|
|
end;
|
|
|
|
function IntToStrZ(L: longint; MinLen: sw_integer): string;
|
|
var S: string;
|
|
begin
|
|
S:=IntToStr(L);
|
|
if length(S)<MinLen then
|
|
S:=CharStr('0',MinLen-length(S))+S;
|
|
IntToStrZ:=S;
|
|
end;
|
|
|
|
function StrToInt(const S: string): longint;
|
|
var L: longint;
|
|
C: integer;
|
|
begin
|
|
Val(S,L,C); if C<>0 then L:=-1;
|
|
LastStrToIntResult:=C;
|
|
StrToInt:=L;
|
|
end;
|
|
|
|
function StrToCard(const S: string): cardinal;
|
|
var L: cardinal;
|
|
C: integer;
|
|
begin
|
|
Val(S,L,C); if C<>0 then L:=$ffffffff;
|
|
LastStrToCardResult:=C;
|
|
StrToCard:=L;
|
|
end;
|
|
|
|
function HexToInt(S: string): longint;
|
|
var L,I: longint;
|
|
C: char;
|
|
const HexNums: string[16] = '0123456789ABCDEF';
|
|
begin
|
|
S:=Trim(S); L:=0; I:=1; LastHexToIntResult:=0;
|
|
while (I<=length(S)) and (LastHexToIntResult=0) do
|
|
begin
|
|
C:=Upcase(S[I]);
|
|
if C in['0'..'9','A'..'F'] then
|
|
begin
|
|
L:=L*16+(Pos(C,HexNums)-1);
|
|
end else LastHexToIntResult:=I;
|
|
Inc(I);
|
|
end;
|
|
HexToInt:=L;
|
|
end;
|
|
|
|
function HexToCard(S: string): cardinal;
|
|
var L,I: cardinal;
|
|
C: char;
|
|
const HexNums: string[16] = '0123456789ABCDEF';
|
|
begin
|
|
S:=Trim(S); L:=0; I:=1; LastHexToCardResult:=0;
|
|
while (I<=length(S)) and (LastHexToCardResult=0) do
|
|
begin
|
|
C:=Upcase(S[I]);
|
|
if C in['0'..'9','A'..'F'] then
|
|
begin
|
|
L:=L*16+(Pos(C,HexNums)-1);
|
|
end else LastHexToCardResult:=I;
|
|
Inc(I);
|
|
end;
|
|
HexToCard:=L;
|
|
end;
|
|
|
|
function IntToHex(L: longint; MinLen: integer): string;
|
|
const HexNums : string[16] = '0123456789ABCDEF';
|
|
var S: string;
|
|
R: real;
|
|
function DivF(Mit,Mivel: real): longint;
|
|
begin
|
|
DivF:=trunc(Mit/Mivel);
|
|
end;
|
|
function ModF(Mit,Mivel: real): longint;
|
|
begin
|
|
ModF:=trunc(Mit-DivF(Mit,Mivel)*Mivel);
|
|
end;
|
|
begin
|
|
S:='';
|
|
R:=L; if R<0 then begin R:=R+2147483647+2147483647+2; end;
|
|
repeat
|
|
Insert(HexNums[ModF(R,16)+1],S,1);
|
|
R:=DivF(R,16);
|
|
until R=0;
|
|
while length(S)<MinLen do
|
|
Insert('0',S,1);
|
|
IntToHex:=S;
|
|
end;
|
|
|
|
function FloatToStr(D: Double; Decimals: byte): string;
|
|
var S: string;
|
|
L: byte;
|
|
begin
|
|
Str(D:0:Decimals,S);
|
|
if length(S)>0 then
|
|
while (S[1]=' ') do Delete(S,1,1);
|
|
FloatToStr:=S;
|
|
end;
|
|
|
|
function FloatToStrL(D: Double; Decimals: byte; MinLen: byte): string;
|
|
begin
|
|
FloatToStrL:=LExtendString(FloatToStr(D,Decimals),MinLen);
|
|
end;
|
|
|
|
function LExtendString(S: string; MinLen: byte): string;
|
|
begin
|
|
LExtendString:=copy(SpaceStr,1,MinLen-length(S))+S;
|
|
end;
|
|
|
|
function GetStr(P: PString): string;
|
|
begin
|
|
if P=nil then GetStr:='' else GetStr:=P^;
|
|
end;
|
|
|
|
function GetPChar(P: PChar): string;
|
|
begin
|
|
if P=nil then GetPChar:='' else GetPChar:=StrPas(P);
|
|
end;
|
|
|
|
function DirOf(const S: string): string;
|
|
var D: DirStr; E: ExtStr; N: NameStr;
|
|
begin
|
|
FSplit(S,D,N,E);
|
|
if (D<>'') and (D[Length(D)]<>DirSep) then
|
|
DirOf:=D+DirSep
|
|
else
|
|
DirOf:=D;
|
|
end;
|
|
|
|
|
|
function ExtOf(const S: string): string;
|
|
var D: DirStr; E: ExtStr; N: NameStr;
|
|
begin
|
|
FSplit(S,D,N,E);
|
|
ExtOf:=E;
|
|
end;
|
|
|
|
|
|
function NameOf(const S: string): string;
|
|
var D: DirStr; E: ExtStr; N: NameStr;
|
|
begin
|
|
FSplit(S,D,N,E);
|
|
NameOf:=N;
|
|
end;
|
|
|
|
function NameAndExtOf(const S: string): string;
|
|
var D: DirStr; E: ExtStr; N: NameStr;
|
|
begin
|
|
FSplit(S,D,N,E);
|
|
NameAndExtOf:=N+E;
|
|
end;
|
|
|
|
function DirAndNameOf(const S: string): string;
|
|
var D: DirStr; E: ExtStr; N: NameStr;
|
|
begin
|
|
FSplit(S,D,N,E);
|
|
DirAndNameOf:=D+N;
|
|
end;
|
|
|
|
{ return Dos GetFTime value or -1 if the file does not exist }
|
|
function GetFileTime(const FileName: string): longint;
|
|
var T: longint;
|
|
f: file;
|
|
FM: integer;
|
|
begin
|
|
if FileName='' then
|
|
T:=-1
|
|
else
|
|
begin
|
|
FM:=FileMode; FileMode:=0;
|
|
EatIO; Dos.DosError:=0;
|
|
Assign(f,FileName);
|
|
{$I-}
|
|
Reset(f);
|
|
if InOutRes=0 then
|
|
begin
|
|
GetFTime(f,T);
|
|
Close(f);
|
|
end;
|
|
{$I+}
|
|
if (EatIO<>0) or (Dos.DosError<>0) then T:=-1;
|
|
FileMode:=FM;
|
|
end;
|
|
GetFileTime:=T;
|
|
end;
|
|
|
|
function GetShortName(const n:string):string;
|
|
{$ifdef win32}
|
|
var
|
|
hs,hs2 : string;
|
|
i : longint;
|
|
{$endif}
|
|
{$ifdef go32v2}
|
|
var
|
|
hs : string;
|
|
{$endif}
|
|
begin
|
|
GetShortName:=n;
|
|
{$ifdef win32}
|
|
hs:=n+#0;
|
|
i:=Windows.GetShortPathName(@hs[1],@hs2[1],high(hs2));
|
|
if (i>0) and (i<=high(hs2)) then
|
|
begin
|
|
hs2[0]:=chr(strlen(@hs2[1]));
|
|
GetShortName:=hs2;
|
|
end;
|
|
{$endif}
|
|
{$ifdef go32v2}
|
|
hs:=n;
|
|
if Dos.GetShortName(hs) then
|
|
GetShortName:=hs;
|
|
{$endif}
|
|
end;
|
|
|
|
function GetLongName(const n:string):string;
|
|
{$ifdef win32}
|
|
var
|
|
hs : string;
|
|
hs2 : Array [0..255] of char;
|
|
i : longint;
|
|
j : pchar;
|
|
{$endif}
|
|
{$ifdef go32v2}
|
|
var
|
|
hs : string;
|
|
{$endif}
|
|
begin
|
|
GetLongName:=n;
|
|
{$ifdef win32}
|
|
hs:=n+#0;
|
|
i:=Windows.GetFullPathName(@hs[1],256,hs2,j);
|
|
if (i>0) and (i<=high(hs)) then
|
|
begin
|
|
hs:=strpas(hs2);
|
|
GetLongName:=hs;
|
|
end;
|
|
{$endif}
|
|
{$ifdef go32v2}
|
|
hs:=n;
|
|
if Dos.GetLongName(hs) then
|
|
GetLongName:=hs;
|
|
{$endif}
|
|
end;
|
|
|
|
|
|
function EatIO: integer;
|
|
begin
|
|
EatIO:=IOResult;
|
|
end;
|
|
|
|
|
|
function LowCase(C: char): char;
|
|
begin
|
|
if ('A'<=C) and (C<='Z') then C:=chr(ord(C)+32);
|
|
LowCase:=C;
|
|
end;
|
|
|
|
|
|
function LowcaseStr(S: string): string;
|
|
var I: Longint;
|
|
begin
|
|
for I:=1 to length(S) do
|
|
S[I]:=Lowcase(S[I]);
|
|
LowcaseStr:=S;
|
|
end;
|
|
|
|
|
|
function BoolToStr(B: boolean; const TrueS, FalseS: string): string;
|
|
begin
|
|
if B then BoolToStr:=TrueS else BoolToStr:=FalseS;
|
|
end;
|
|
|
|
procedure TNoDisposeCollection.FreeItem(Item: Pointer);
|
|
begin
|
|
{ don't do anything here }
|
|
end;
|
|
|
|
constructor TUnsortedStringCollection.CreateFrom(ALines: PUnsortedStringCollection);
|
|
begin
|
|
if Assigned(ALines)=false then Fail;
|
|
inherited Init(ALines^.Count,ALines^.Count div 10);
|
|
Assign(ALines);
|
|
end;
|
|
|
|
procedure TUnsortedStringCollection.Assign(ALines: PUnsortedStringCollection);
|
|
procedure AddIt(P: PString); {$ifndef FPC}far;{$endif}
|
|
begin
|
|
Insert(NewStr(GetStr(P)));
|
|
end;
|
|
begin
|
|
FreeAll;
|
|
if Assigned(ALines) then
|
|
ALines^.ForEach(@AddIt);
|
|
end;
|
|
|
|
procedure TUnsortedStringCollection.InsertStr(const S: string);
|
|
begin
|
|
Insert(NewStr(S));
|
|
end;
|
|
|
|
function TUnsortedStringCollection.At(Index: Sw_Integer): PString;
|
|
begin
|
|
At:=inherited At(Index);
|
|
end;
|
|
|
|
procedure TUnsortedStringCollection.FreeItem(Item: Pointer);
|
|
begin
|
|
if Item<>nil then DisposeStr(Item);
|
|
end;
|
|
|
|
function TUnsortedStringCollection.GetItem(var S: TStream): Pointer;
|
|
begin
|
|
GetItem:=S.ReadStr;
|
|
end;
|
|
|
|
procedure TUnsortedStringCollection.PutItem(var S: TStream; Item: Pointer);
|
|
begin
|
|
S.WriteStr(Item);
|
|
end;
|
|
|
|
function TIntCollection.Contains(Item: longint): boolean;
|
|
var Index: sw_integer;
|
|
begin
|
|
Contains:=Search(pointer(Item),Index);
|
|
end;
|
|
|
|
function TIntCollection.AtInt(Index: sw_integer): longint;
|
|
begin
|
|
AtInt:=longint(At(Index));
|
|
end;
|
|
|
|
procedure TIntCollection.Add(Item: longint);
|
|
begin
|
|
Insert(pointer(Item));
|
|
end;
|
|
|
|
function TIntCollection.Compare(Key1, Key2: Pointer): sw_Integer;
|
|
var K1: longint absolute Key1;
|
|
K2: longint absolute Key2;
|
|
R: integer;
|
|
begin
|
|
if K1<K2 then R:=-1 else
|
|
if K1>K2 then R:= 1 else
|
|
R:=0;
|
|
Compare:=R;
|
|
end;
|
|
|
|
procedure TIntCollection.FreeItem(Item: Pointer);
|
|
begin
|
|
{ do nothing here }
|
|
end;
|
|
|
|
constructor TNulStream.Init;
|
|
begin
|
|
inherited Init;
|
|
Position:=0;
|
|
end;
|
|
|
|
function TNulStream.GetPos: Longint;
|
|
begin
|
|
GetPos:=Position;
|
|
end;
|
|
|
|
function TNulStream.GetSize: Longint;
|
|
begin
|
|
GetSize:=Position;
|
|
end;
|
|
|
|
procedure TNulStream.Read(var Buf; Count: Word);
|
|
begin
|
|
Error(stReadError,0);
|
|
end;
|
|
|
|
procedure TNulStream.Seek(Pos: Longint);
|
|
begin
|
|
if Pos<=Position then
|
|
Position:=Pos;
|
|
end;
|
|
|
|
procedure TNulStream.Write(var Buf; Count: Word);
|
|
begin
|
|
Inc(Position,Count);
|
|
end;
|
|
|
|
constructor TSubStream.Init(AStream: PStream; AStartPos, ASize: longint);
|
|
begin
|
|
inherited Init;
|
|
if Assigned(AStream)=false then Fail;
|
|
S:=AStream; StartPos:=AStartPos; StreamSize:=ASize;
|
|
Seek(0);
|
|
end;
|
|
|
|
function TSubStream.GetPos: Longint;
|
|
var Pos: longint;
|
|
begin
|
|
Pos:=S^.GetPos; Dec(Pos,StartPos);
|
|
GetPos:=Pos;
|
|
end;
|
|
|
|
function TSubStream.GetSize: Longint;
|
|
begin
|
|
GetSize:=StreamSize;
|
|
end;
|
|
|
|
procedure TSubStream.Read(var Buf; Count: Word);
|
|
var Pos: longint;
|
|
RCount: word;
|
|
begin
|
|
Pos:=GetPos;
|
|
if Pos+Count>StreamSize then RCount:=StreamSize-Pos else RCount:=Count;
|
|
S^.Read(Buf,RCount);
|
|
if RCount<Count then
|
|
Error(stReadError,0);
|
|
end;
|
|
|
|
procedure TSubStream.Seek(Pos: Longint);
|
|
var RPos: longint;
|
|
begin
|
|
if (Pos<=StreamSize) then RPos:=Pos else RPos:=StreamSize;
|
|
S^.Seek(StartPos+RPos);
|
|
end;
|
|
|
|
procedure TSubStream.Write(var Buf; Count: Word);
|
|
begin
|
|
S^.Write(Buf,Count);
|
|
end;
|
|
|
|
procedure TFastBufStream.Seek(Pos: Longint);
|
|
function BufStartPos: longint;
|
|
begin
|
|
BufStartPos:=Position-BufPtr;
|
|
end;
|
|
var RelOfs: longint;
|
|
begin
|
|
RelOfs:=Pos-{BufStartPos}BasePos;
|
|
if (RelOfs<0) or (RelOfs>=BufEnd) or (BufEnd=0) then
|
|
begin
|
|
inherited Seek(Pos);
|
|
BasePos:=Pos-BufPtr;
|
|
end
|
|
else
|
|
begin
|
|
BufPtr:=RelOfs;
|
|
Position:=Pos;
|
|
end;
|
|
end;
|
|
|
|
function TTextCollection.Compare(Key1, Key2: Pointer): Sw_Integer;
|
|
var K1: PString absolute Key1;
|
|
K2: PString absolute Key2;
|
|
R: Sw_integer;
|
|
S1,S2: string;
|
|
begin
|
|
S1:=UpCaseStr(K1^);
|
|
S2:=UpCaseStr(K2^);
|
|
if S1<S2 then R:=-1 else
|
|
if S1>S2 then R:=1 else
|
|
R:=0;
|
|
Compare:=R;
|
|
end;
|
|
|
|
function TTextCollection.LookUp(const S: string; var Idx: sw_integer): string;
|
|
var OLI,ORI,Left,Right,Mid: integer;
|
|
{LeftP,RightP,}MidP: PString;
|
|
{LeftS,}MidS{,RightS}: string;
|
|
FoundS: string;
|
|
UpS : string;
|
|
begin
|
|
Idx:=-1; FoundS:='';
|
|
Left:=0; Right:=Count-1;
|
|
UpS:=UpCaseStr(S);
|
|
while Left<=Right do
|
|
begin
|
|
OLI:=Left; ORI:=Right;
|
|
Mid:=Left+(Right-Left) div 2;
|
|
MidP:=At(Mid);
|
|
MidS:=UpCaseStr(MidP^);
|
|
if copy(MidS,1,length(UpS))=UpS then
|
|
begin
|
|
Idx:=Mid; FoundS:=GetStr(MidP);
|
|
{ exit immediately if exact match PM }
|
|
If Length(MidS)=Length(UpS) then
|
|
break;
|
|
end;
|
|
if UpS<MidS then
|
|
Right:=Mid
|
|
else
|
|
Left:=Mid;
|
|
if (OLI=Left) and (ORI=Right) then
|
|
begin
|
|
if (Left<Right) then
|
|
Left:=Right
|
|
else
|
|
Break;
|
|
end;
|
|
end;
|
|
LookUp:=FoundS;
|
|
end;
|
|
|
|
function TrimEndSlash(const Path: string): string;
|
|
var S: string;
|
|
begin
|
|
S:=Path;
|
|
if (length(S)>0) and (S<>DirSep) and (copy(S,length(S),1)=DirSep) and
|
|
(S[length(S)-1]<>':') then
|
|
S:=copy(S,1,length(S)-1);
|
|
TrimEndSlash:=S;
|
|
end;
|
|
|
|
function CompareText(S1, S2: string): integer;
|
|
var R: integer;
|
|
begin
|
|
S1:=UpcaseStr(S1); S2:=UpcaseStr(S2);
|
|
if S1<S2 then R:=-1 else
|
|
if S1>S2 then R:= 1 else
|
|
R:=0;
|
|
CompareText:=R;
|
|
end;
|
|
|
|
function FormatPath(Path: string): string;
|
|
var P: sw_integer;
|
|
SC: char;
|
|
begin
|
|
if ord(DirSep)=ord('/') then
|
|
SC:='\'
|
|
else
|
|
SC:='/';
|
|
|
|
repeat
|
|
P:=Pos(SC,Path);
|
|
if P>0 then Path[P]:=DirSep;
|
|
until P=0;
|
|
FormatPath:=Path;
|
|
end;
|
|
|
|
function CompletePath(const Base, InComplete: string): string;
|
|
var Drv,BDrv: string[40]; D,BD: DirStr; N,BN: NameStr; E,BE: ExtStr;
|
|
P: sw_integer;
|
|
Complete: string;
|
|
begin
|
|
Complete:=FormatPath(InComplete);
|
|
FSplit(FormatPath(InComplete),D,N,E);
|
|
P:=Pos(':',D); if P=0 then Drv:='' else begin Drv:=copy(D,1,P); Delete(D,1,P); end;
|
|
FSplit(FormatPath(Base),BD,BN,BE);
|
|
P:=Pos(':',BD); if P=0 then BDrv:='' else begin BDrv:=copy(BD,1,P); Delete(BD,1,P); end;
|
|
if copy(D,1,1)<>DirSep then
|
|
Complete:=BD+D+N+E;
|
|
if Drv='' then
|
|
Complete:=BDrv+Complete;
|
|
Complete:=FExpand(Complete);
|
|
CompletePath:=Complete;
|
|
end;
|
|
|
|
function CompleteURL(const Base, URLRef: string): string;
|
|
var P: integer;
|
|
Drive: string[20];
|
|
IsComplete: boolean;
|
|
S: string;
|
|
Ref: string;
|
|
Bookmark: string;
|
|
begin
|
|
IsComplete:=false; Ref:=URLRef;
|
|
P:=Pos(':',Ref);
|
|
if P=0 then Drive:='' else Drive:=UpcaseStr(copy(Ref,1,P-1));
|
|
if Drive<>'' then
|
|
if (Drive='MAILTO') or (Drive='FTP') or (Drive='HTTP') or
|
|
(Drive='GOPHER') or (Drive='FILE') then
|
|
IsComplete:=true;
|
|
if IsComplete then S:=Ref else
|
|
begin
|
|
P:=Pos('#',Ref);
|
|
if P=0 then
|
|
Bookmark:=''
|
|
else
|
|
begin
|
|
Bookmark:=copy(Ref,P+1,length(Ref));
|
|
Ref:=copy(Ref,1,P-1);
|
|
end;
|
|
S:=CompletePath(Base,Ref);
|
|
if Bookmark<>'' then
|
|
S:=S+'#'+Bookmark;
|
|
end;
|
|
CompleteURL:=S;
|
|
end;
|
|
|
|
function OptimizePath(Path: string; MaxLen: integer): string;
|
|
var i : integer;
|
|
BackSlashs : array[1..20] of integer;
|
|
BSCount : integer;
|
|
Jobbra : boolean;
|
|
Jobb, Bal : byte;
|
|
Hiba : boolean;
|
|
begin
|
|
if length(Path)>MaxLen then
|
|
begin
|
|
BSCount:=0; Jobbra:=true;
|
|
for i:=1 to length(Path) do if Path[i]=DirSep then
|
|
begin
|
|
Inc(BSCount);
|
|
BackSlashs[BSCount]:=i;
|
|
end;
|
|
i:=BSCount div 2;
|
|
Hiba:=false;
|
|
Bal:=i; Jobb:=i+1;
|
|
case i of 0 : ;
|
|
1 : Path:=copy(Path, 1, BackSlashs[1])+'..'+
|
|
copy(Path, BackSlashs[2], length(Path));
|
|
else begin
|
|
while (BackSlashs[Bal]+(length(Path)-BackSlashs[Jobb]) >=
|
|
MaxLen) and not Hiba do
|
|
begin
|
|
if Jobbra then begin
|
|
if Jobb<BSCount then inc(Jobb)
|
|
else Hiba:=true;
|
|
Jobbra:=false;
|
|
end
|
|
else begin
|
|
if Bal>1 then dec(Bal)
|
|
else Hiba:=true;
|
|
Jobbra:=true;
|
|
end;
|
|
end;
|
|
Path:=copy(Path, 1, BackSlashs[Bal])+'..'+
|
|
copy(Path, BackSlashs[Jobb], length(Path));
|
|
end;
|
|
end;
|
|
end;
|
|
if length(Path)>MaxLen then
|
|
begin
|
|
i:=Pos('\..\',Path);
|
|
if i>0 then Path:=copy(Path,1,i-1)+'..'+copy(Path,i+length('\..\'),length(Path));
|
|
end;
|
|
OptimizePath:=Path;
|
|
end;
|
|
|
|
function Now: longint;
|
|
var D: DateTime;
|
|
W: word;
|
|
L: longint;
|
|
begin
|
|
FillChar(D,sizeof(D),0);
|
|
GetDate(D.Year,D.Month,D.Day,W);
|
|
GetTime(D.Hour,D.Min,D.Sec,W);
|
|
PackTime(D,L);
|
|
Now:=L;
|
|
end;
|
|
|
|
function FormatDateTimeL(L: longint; const Format: string): string;
|
|
var D: DateTime;
|
|
begin
|
|
UnpackTime(L,D);
|
|
FormatDateTimeL:=FormatDateTime(D,Format);
|
|
end;
|
|
|
|
function FormatDateTime(const D: DateTime; const Format: string): string;
|
|
var I: sw_integer;
|
|
CurCharStart: sw_integer;
|
|
CurChar: char;
|
|
CurCharCount: integer;
|
|
DateS: string;
|
|
C: char;
|
|
procedure FlushChars;
|
|
var S: string;
|
|
I: sw_integer;
|
|
begin
|
|
S:='';
|
|
for I:=1 to CurCharCount do
|
|
S:=S+CurChar;
|
|
case CurChar of
|
|
'y' : S:=IntToStrL(D.Year,length(S));
|
|
'm' : S:=IntToStrZ(D.Month,length(S));
|
|
'd' : S:=IntToStrZ(D.Day,length(S));
|
|
'h' : S:=IntToStrZ(D.Hour,length(S));
|
|
'n' : S:=IntToStrZ(D.Min,length(S));
|
|
's' : S:=IntToStrZ(D.Sec,length(S));
|
|
end;
|
|
DateS:=DateS+S;
|
|
end;
|
|
begin
|
|
DateS:='';
|
|
CurCharStart:=-1; CurCharCount:=0; CurChar:=#0;
|
|
for I:=1 to length(Format) do
|
|
begin
|
|
C:=Format[I];
|
|
if (C<>CurChar) or (CurCharStart=-1) then
|
|
begin
|
|
if CurCharStart<>-1 then FlushChars;
|
|
CurCharCount:=1; CurCharStart:=I;
|
|
end
|
|
else
|
|
Inc(CurCharCount);
|
|
CurChar:=C;
|
|
end;
|
|
FlushChars;
|
|
FormatDateTime:=DateS;
|
|
end;
|
|
|
|
function DeleteFile(const FileName: string): integer;
|
|
var f: file;
|
|
begin
|
|
{$I-}
|
|
Assign(f,FileName);
|
|
Erase(f);
|
|
DeleteFile:=EatIO;
|
|
{$I+}
|
|
end;
|
|
|
|
function ExistsFile(const FileName: string): boolean;
|
|
var
|
|
Dir : SearchRec;
|
|
begin
|
|
Dos.FindFirst(FileName,Archive+ReadOnly,Dir);
|
|
ExistsFile:=(Dos.DosError=0);
|
|
{$ifdef FPC}
|
|
Dos.FindClose(Dir);
|
|
{$endif def FPC}
|
|
end;
|
|
|
|
function ExistsDir(const DirName: string): boolean;
|
|
var
|
|
Dir : SearchRec;
|
|
begin
|
|
Dos.FindFirst(TrimEndSlash(DirName),Directory,Dir);
|
|
{ if a file is found it is also reported
|
|
at least for some Dos version
|
|
so we need to check the attributes PM }
|
|
ExistsDir:=(Dos.DosError=0) and ((Dir.attr and Directory) <> 0);
|
|
{$ifdef FPC}
|
|
Dos.FindClose(Dir);
|
|
{$endif def FPC}
|
|
end;
|
|
|
|
function CompleteDir(const Path: string): string;
|
|
begin
|
|
{ keep c: untouched PM }
|
|
if (Path<>'') and (Path[Length(Path)]<>DirSep) and
|
|
(Path[Length(Path)]<>':') then
|
|
CompleteDir:=Path+DirSep
|
|
else
|
|
CompleteDir:=Path;
|
|
end;
|
|
|
|
function GetCurDir: string;
|
|
var S: string;
|
|
begin
|
|
GetDir(0,S);
|
|
if copy(S,length(S),1)<>DirSep then S:=S+DirSep;
|
|
GetCurDir:=S;
|
|
end;
|
|
|
|
function GenTempFileName: string;
|
|
var Dir: string;
|
|
Name: string;
|
|
I: integer;
|
|
OK: boolean;
|
|
Path: string;
|
|
begin
|
|
Dir:=GetEnv('TEMP');
|
|
if Dir='' then Dir:=GetEnv('TMP');
|
|
if (Dir<>'') then if not ExistsDir(Dir) then Dir:='';
|
|
if Dir='' then Dir:=GetCurDir;
|
|
repeat
|
|
Name:=TempFirstChar;
|
|
for I:=2 to TempNameLen do
|
|
Name:=Name+chr(ord('a')+random(ord('z')-ord('a')+1));
|
|
Name:=Name+TempExt;
|
|
Path:=CompleteDir(Dir)+Name;
|
|
OK:=not ExistsFile(Path);
|
|
until OK;
|
|
GenTempFileName:=Path;
|
|
end;
|
|
|
|
function CopyFile(const SrcFileName, DestFileName: string): boolean;
|
|
var SrcF,DestF: PBufStream;
|
|
OK: boolean;
|
|
begin
|
|
SrcF:=nil; DestF:=nil;
|
|
New(SrcF, Init(SrcFileName,stOpenRead,4096));
|
|
OK:=Assigned(SrcF) and (SrcF^.Status=stOK);
|
|
if OK then
|
|
begin
|
|
New(DestF, Init(DestFileName,stCreate,1024));
|
|
OK:=Assigned(DestF) and (DestF^.Status=stOK);
|
|
end;
|
|
if OK then DestF^.CopyFrom(SrcF^,SrcF^.GetSize);
|
|
if Assigned(DestF) then Dispose(DestF, Done);
|
|
if Assigned(SrcF) then Dispose(SrcF, Done);
|
|
CopyFile:=OK;
|
|
end;
|
|
|
|
procedure GiveUpTimeSlice;
|
|
{$ifdef GO32V2}{$define DOS}{$endif}
|
|
{$ifdef TP}{$define DOS}{$endif}
|
|
{$ifdef DOS}
|
|
var r: registers;
|
|
begin
|
|
r.ax:=$1680;
|
|
intr($2f,r);
|
|
end;
|
|
{$endif}
|
|
{$ifdef Unix}
|
|
var
|
|
req,rem : timespec;
|
|
begin
|
|
req.tv_sec:=0;
|
|
req.tv_nsec:=10000000;{ 10 ms }
|
|
nanosleep(req,rem);
|
|
end;
|
|
{$endif}
|
|
{$IFDEF OS2}
|
|
begin
|
|
DosSleep (5);
|
|
end;
|
|
{$ENDIF}
|
|
{$ifdef Win32}
|
|
begin
|
|
{ if the return value of this call is non zero then
|
|
it means that a ReadFileEx or WriteFileEx have completed
|
|
unused for now ! }
|
|
{ wait for 10 ms }
|
|
if SleepEx(10,true)=WAIT_IO_COMPLETION then
|
|
begin
|
|
{ here we should handle the completion of the routines
|
|
if we use them }
|
|
end;
|
|
end;
|
|
{$endif}
|
|
{$undef DOS}
|
|
|
|
procedure RegisterWUtils;
|
|
begin
|
|
{$ifndef NOOBJREG}
|
|
RegisterType(RUnsortedStringCollection);
|
|
{$endif}
|
|
end;
|
|
|
|
BEGIN
|
|
Randomize;
|
|
END.
|
|
{
|
|
$Log$
|
|
Revision 1.9 2002-05-13 13:44:33 peter
|
|
* fixed range error
|
|
|
|
Revision 1.8 2002/04/02 13:23:02 pierre
|
|
+ HextToCard StrToCard new functions
|
|
|
|
Revision 1.7 2002/03/22 16:43:27 pierre
|
|
* avoid that constructor is proposed for code complete if const is given
|
|
|
|
Revision 1.6 2002/03/20 13:48:31 pierre
|
|
* avoid stack corruption in CharStr if count > 255
|
|
|
|
Revision 1.5 2001/11/18 20:18:54 peter
|
|
* use cp_value_equal_const instead of cp_all
|
|
|
|
Revision 1.4 2001/09/18 15:36:58 pierre
|
|
* avoid bug 1610
|
|
|
|
Revision 1.3 2001/08/12 00:04:50 pierre
|
|
* some speed improvements for string operations
|
|
|
|
Revision 1.2 2001/08/05 02:01:49 peter
|
|
* FVISION define to compile with fvision units
|
|
|
|
Revision 1.1 2001/08/04 11:30:26 peter
|
|
* ide works now with both compiler versions
|
|
|
|
Revision 1.1.2.14 2001/06/20 22:56:31 pierre
|
|
* check that the Dir in ExistsDir is really a directory and not a file
|
|
|
|
Revision 1.1.2.13 2001/02/05 14:45:42 pierre
|
|
* fix for bug 1370
|
|
|
|
Revision 1.1.2.12 2000/11/29 18:28:54 pierre
|
|
+ add save to file capability for list boxes
|
|
|
|
Revision 1.1.2.11 2000/11/27 12:06:52 pierre
|
|
New bunch of Gabor fixes
|
|
|
|
Revision 1.1.2.10 2000/11/14 09:08:51 marco
|
|
* First batch IDE renamefest
|
|
|
|
Revision 1.1.2.9 2000/11/13 16:59:10 pierre
|
|
* some function in double removed from fputils unit
|
|
|
|
Revision 1.1.2.8 2000/11/12 19:50:36 hajny
|
|
* OS/2 changes from the main branch merged
|
|
|
|
Revision 1.1.2.7 2000/11/06 17:19:58 pierre
|
|
* avoid eating of last carriage return
|
|
|
|
Revision 1.1.2.6 2000/10/24 12:31:40 pierre
|
|
* fix the last commit for linux
|
|
|
|
Revision 1.1.2.5 2000/10/24 12:24:03 pierre
|
|
+ GiveUpTimeSlice for linux and win32
|
|
|
|
Revision 1.1.2.4 2000/09/18 13:20:56 pierre
|
|
New bunch of Gabor changes
|
|
|
|
Revision 1.2 2000/08/22 09:41:42 pierre
|
|
* first big merge from fixes branch
|
|
|
|
Revision 1.1.2.3 2000/08/20 15:00:23 peter
|
|
* windows fix
|
|
|
|
Revision 1.1.2.2 2000/08/16 18:46:15 peter
|
|
[*] double clicking on a droplistbox caused GPF (due to invalid recurson)
|
|
[*] Make, Build now possible even in Compiler Messages Window
|
|
[+] when started in a new dir the IDE now ask whether to create a local
|
|
config, or to use the one located in the IDE dir
|
|
|
|
Revision 1.1.2.1 2000/07/20 11:02:16 michael
|
|
+ Fixes from gabor. See fixes.txt
|
|
|
|
Revision 1.1 2000/07/13 09:48:37 michael
|
|
+ Initial import
|
|
|
|
Revision 1.27 2000/07/03 08:54:54 pierre
|
|
* Some enhancements for WinHelp support by G abor
|
|
|
|
Revision 1.26 2000/06/26 07:29:23 pierre
|
|
* new bunch of Gabor's changes
|
|
|
|
Revision 1.25 2000/06/22 09:07:15 pierre
|
|
* Gabor changes: see fixes.txt
|
|
|
|
Revision 1.24 2000/06/16 21:16:41 pierre
|
|
* allow to read until 255 chars per line
|
|
|
|
Revision 1.23 2000/06/16 08:50:45 pierre
|
|
+ new bunch of Gabor's changes
|
|
|
|
Revision 1.22 2000/05/29 11:09:14 pierre
|
|
+ New bunch of Gabor's changes: see fixes.txt
|
|
|
|
Revision 1.21 2000/05/02 08:42:29 pierre
|
|
* new set of Gabor changes: see fixes.txt
|
|
|
|
Revision 1.20 2000/04/25 08:42:36 pierre
|
|
* New Gabor changes : see fixes.txt
|
|
|
|
Revision 1.19 2000/04/18 11:42:39 pierre
|
|
lot of Gabor changes : see fixes.txt
|
|
|
|
Revision 1.18 2000/03/21 23:19:13 pierre
|
|
+ TrimEndSlash and CompareText by Gabor
|
|
|
|
Revision 1.17 2000/03/20 19:19:45 pierre
|
|
* LFN support in streams
|
|
|
|
Revision 1.16 2000/03/14 13:36:12 pierre
|
|
* error for unexistant file in GetFileTime fixed
|
|
|
|
Revision 1.15 2000/02/07 11:45:11 pierre
|
|
+ TUnsortedStringCollection CreateFrom/Assign/GetItem/PutItem from Gabor
|
|
|
|
Revision 1.14 2000/01/20 00:30:32 pierre
|
|
* Result of GetShortPathName is checked
|
|
|
|
Revision 1.13 2000/01/17 12:20:03 pierre
|
|
* uses windows needed for GetShortName
|
|
|
|
Revision 1.12 2000/01/14 15:36:43 pierre
|
|
+ GetShortFileName used for tcodeeditor file opening
|
|
|
|
Revision 1.11 2000/01/05 17:27:20 pierre
|
|
+ linecomplete arg for ReadlnFromStream
|
|
|
|
Revision 1.10 2000/01/03 11:38:35 michael
|
|
Changes from Gabor
|
|
|
|
Revision 1.9 1999/12/01 16:19:46 pierre
|
|
+ GetFileTime moved here
|
|
|
|
Revision 1.8 1999/10/25 16:39:03 pierre
|
|
+ GetPChar to avoid nil pointer problems
|
|
|
|
Revision 1.7 1999/09/13 11:44:00 peter
|
|
* fixes from gabor, idle event, html fix
|
|
|
|
Revision 1.6 1999/08/24 22:01:48 pierre
|
|
* readlnfromstream length check added
|
|
|
|
Revision 1.5 1999/08/03 20:22:45 peter
|
|
+ TTab acts now on Ctrl+Tab and Ctrl+Shift+Tab...
|
|
+ Desktop saving should work now
|
|
- History saved
|
|
- Clipboard content saved
|
|
- Desktop saved
|
|
- Symbol info saved
|
|
* syntax-highlight bug fixed, which compared special keywords case sensitive
|
|
(for ex. 'asm' caused asm-highlighting, while 'ASM' didn't)
|
|
* with 'whole words only' set, the editor didn't found occourences of the
|
|
searched text, if the text appeared previously in the same line, but didn't
|
|
satisfied the 'whole-word' condition
|
|
* ^QB jumped to (SelStart.X,SelEnd.X) instead of (SelStart.X,SelStart.Y)
|
|
(ie. the beginning of the selection)
|
|
* when started typing in a new line, but not at the start (X=0) of it,
|
|
the editor inserted the text one character more to left as it should...
|
|
* TCodeEditor.HideSelection (Ctrl-K+H) didn't update the screen
|
|
* Shift shouldn't cause so much trouble in TCodeEditor now...
|
|
* Syntax highlight had problems recognizing a special symbol if it was
|
|
prefixed by another symbol character in the source text
|
|
* Auto-save also occours at Dos shell, Tool execution, etc. now...
|
|
|
|
Revision 1.4 1999/04/07 21:56:06 peter
|
|
+ object support for browser
|
|
* html help fixes
|
|
* more desktop saving things
|
|
* NODEBUG directive to exclude debugger
|
|
|
|
Revision 1.2 1999/03/08 14:58:22 peter
|
|
+ prompt with dialogs for tools
|
|
|
|
Revision 1.1 1999/03/01 15:51:43 peter
|
|
+ Log
|
|
|
|
}
|