mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 08:00:34 +02:00
LazUtils: Move string manipulation functions from LazUtilities to LazStringUtils.
git-svn-id: trunk@58634 -
This commit is contained in:
parent
9b85717453
commit
41dc46374f
@ -35,7 +35,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, zstream, Laz2_XMLCfg, LazUTF8, LConvEncoding,
|
Classes, SysUtils, zstream, Laz2_XMLCfg, LazUTF8, LConvEncoding,
|
||||||
LazFileUtils, LazUtilities;
|
LazFileUtils, LazStringUtils, LazUtilities;
|
||||||
|
|
||||||
type
|
type
|
||||||
TAPackageType = (
|
TAPackageType = (
|
||||||
|
@ -43,7 +43,7 @@ uses
|
|||||||
Classes, SysUtils, contnrs, TypInfo, types, Laz_AVL_Tree,
|
Classes, SysUtils, contnrs, TypInfo, types, Laz_AVL_Tree,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazFileUtils, LazFileCache, LazMethodList, LazDbgLog, AvgLvlTree,
|
LazFileUtils, LazFileCache, LazMethodList, LazDbgLog, AvgLvlTree,
|
||||||
LazUtilities,
|
LazStringUtils,
|
||||||
// Codetools
|
// Codetools
|
||||||
FileProcs, BasicCodeTools, CodeToolsStrConsts,
|
FileProcs, BasicCodeTools, CodeToolsStrConsts,
|
||||||
EventCodeTool, CodeTree, CodeAtom, SourceChanger, DefineTemplates, CodeCache,
|
EventCodeTool, CodeTree, CodeAtom, SourceChanger, DefineTemplates, CodeCache,
|
||||||
|
@ -32,7 +32,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, Laz_AVL_Tree,
|
Classes, SysUtils, Laz_AVL_Tree,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazFileUtils, LazUtilities,
|
LazFileUtils, LazStringUtils,
|
||||||
// Codetools
|
// Codetools
|
||||||
FileProcs, FindDeclarationTool, CodeBeautifier, CodeCache, StdCodeTools,
|
FileProcs, FindDeclarationTool, CodeBeautifier, CodeCache, StdCodeTools,
|
||||||
DirectoryCacher, LinkScanner, CustomCodeTool, CodeTree, CodeToolsStructs;
|
DirectoryCacher, LinkScanner, CustomCodeTool, CodeTree, CodeToolsStructs;
|
||||||
|
@ -59,8 +59,8 @@ uses
|
|||||||
CodeToolsStrConsts, ExprEval, DirectoryCacher, BasicCodeTools,
|
CodeToolsStrConsts, ExprEval, DirectoryCacher, BasicCodeTools,
|
||||||
CodeToolsStructs, KeywordFuncLists, LinkScanner, FileProcs,
|
CodeToolsStructs, KeywordFuncLists, LinkScanner, FileProcs,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazUtilities, LazUTF8, LazUTF8Classes, LazFileUtils, UTF8Process,
|
LazStringUtils, LazFileUtils, LazFileCache,
|
||||||
LazFileCache, LazDbgLog, AvgLvlTree, Laz2_XMLCfg;
|
LazUTF8, LazUTF8Classes, UTF8Process, LazDbgLog, AvgLvlTree, Laz2_XMLCfg;
|
||||||
|
|
||||||
const
|
const
|
||||||
ExternalMacroStart = ExprEval.ExternalMacroStart;
|
ExternalMacroStart = ExprEval.ExternalMacroStart;
|
||||||
|
@ -40,7 +40,8 @@ uses
|
|||||||
// CodeTools
|
// CodeTools
|
||||||
FileProcs,
|
FileProcs,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazUTF8, LazFileCache, LazFileUtils, LazUtilities, AvgLvlTree, LazDbgLog;
|
LazUTF8, LazFileCache, LazFileUtils, LazUtilities, LazStringUtils, LazDbgLog,
|
||||||
|
AvgLvlTree;
|
||||||
|
|
||||||
// verbosity
|
// verbosity
|
||||||
{ $DEFINE CTDEBUG}
|
{ $DEFINE CTDEBUG}
|
||||||
|
@ -16,9 +16,9 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils,
|
||||||
// LCL
|
// LCL
|
||||||
LCLProc, LCLType, Forms, Controls, Graphics,
|
LCLType, Forms, Controls, Graphics,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
FileUtil, Laz2_XMLCfg,
|
FileUtil, Laz2_XMLCfg, LazStringUtils,
|
||||||
// IdeIntf
|
// IdeIntf
|
||||||
ProjectIntf, IDECommands;
|
ProjectIntf, IDECommands;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, types, math,
|
Classes, SysUtils, types, math,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazLoggerBase, LazClasses, LazFileUtils, LazUtilities, LazUTF8;
|
LazLoggerBase, LazClasses, LazFileUtils, LazStringUtils, LazUTF8;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
|
@ -37,8 +37,14 @@ type
|
|||||||
const
|
const
|
||||||
EndOfLine: shortstring = LineEnding;
|
EndOfLine: shortstring = LineEnding;
|
||||||
|
|
||||||
|
// Functions for line endings
|
||||||
function LineEndingCount(const Txt: string; var LengthOfLastLine: integer): integer;
|
function LineEndingCount(const Txt: string; var LengthOfLastLine: integer): integer;
|
||||||
function ChangeLineEndings(const s, NewLineEnding: string): string;
|
function ChangeLineEndings(const s, NewLineEnding: string): string;
|
||||||
|
function LineBreaksToSystemLineBreaks(const s: string): string;
|
||||||
|
function LineBreaksToDelimiter(const s: string; Delimiter: char): string;
|
||||||
|
function ConvertLineEndings(const s: string): string;
|
||||||
|
|
||||||
|
// Conversions
|
||||||
function TabsToSpaces(const s: string; TabWidth: integer; UseUTF8: boolean): string;
|
function TabsToSpaces(const s: string; TabWidth: integer; UseUTF8: boolean): string;
|
||||||
//function CommentLines(const s: string): string;
|
//function CommentLines(const s: string): string;
|
||||||
function CommentText(const s: string; CommentType: TCommentType): string;
|
function CommentText(const s: string; CommentType: TCommentType): string;
|
||||||
@ -47,13 +53,14 @@ function CommentText(const s: string; CommentType: TCommentType): string;
|
|||||||
// const SpecialChars: string): string;
|
// const SpecialChars: string): string;
|
||||||
function SimpleSyntaxToRegExpr(const Src: string): string;
|
function SimpleSyntaxToRegExpr(const Src: string): string;
|
||||||
function BinaryStrToText(const s: string): string;
|
function BinaryStrToText(const s: string): string;
|
||||||
|
function SpecialCharsToSpaces(const s: string; FixUTF8: boolean): string;
|
||||||
|
function SpecialCharsToHex(const s: string): string;
|
||||||
|
function BreakString(const s: string; MaxLineLength, Indent: integer): string;
|
||||||
|
|
||||||
|
// Conversions to and from a StringList
|
||||||
function SplitString(const s: string; Delimiter: char): TStrings;
|
function SplitString(const s: string; Delimiter: char): TStrings;
|
||||||
procedure SplitString(const s: string; Delimiter: char; AddTo: TStrings;
|
procedure SplitString(const s: string; Delimiter: char; AddTo: TStrings;
|
||||||
ClearList: boolean = true);
|
ClearList: boolean = true);
|
||||||
function SpecialCharsToSpaces(const s: string; FixUTF8: boolean): string;
|
|
||||||
function SpecialCharsToHex(const s: string): string;
|
|
||||||
function LineBreaksToSystemLineBreaks(const s: string): string;
|
|
||||||
function LineBreaksToDelimiter(const s: string; Delimiter: char): string;
|
|
||||||
function StringListToText(List: TStrings; const Delimiter: string;
|
function StringListToText(List: TStrings; const Delimiter: string;
|
||||||
IgnoreEmptyLines: boolean = false): string;
|
IgnoreEmptyLines: boolean = false): string;
|
||||||
function StringListPartToText(List: TStrings; FromIndex, ToIndex: integer;
|
function StringListPartToText(List: TStrings; FromIndex, ToIndex: integer;
|
||||||
@ -63,6 +70,15 @@ function StringListToString(List: TStrings; FromIndex, ToIndex: integer;
|
|||||||
IgnoreEmptyLines: boolean = false): string;
|
IgnoreEmptyLines: boolean = false): string;
|
||||||
procedure StringToStringList(const s: string; List: TStrings);
|
procedure StringToStringList(const s: string; List: TStrings);
|
||||||
|
|
||||||
|
// Text with delimiters
|
||||||
|
function GetNextDelimitedItem(const List: string; Delimiter: char;
|
||||||
|
var Position: integer): string;
|
||||||
|
function HasDelimitedItem(const List: string; Delimiter: char; FindItem: string
|
||||||
|
): boolean;
|
||||||
|
function FindNextDelimitedItem(const List: string; Delimiter: char;
|
||||||
|
var Position: integer; FindItem: string): string;
|
||||||
|
function MergeWithDelimiter(const a, b: string; Delimiter: char): string;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -143,6 +159,59 @@ begin
|
|||||||
//if Src-1<>@s[length(s)] then RaiseGDBException('');
|
//if Src-1<>@s[length(s)] then RaiseGDBException('');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function LineBreaksToSystemLineBreaks(const s: string): string;
|
||||||
|
begin
|
||||||
|
Result:=ChangeLineEndings(s,LineEnding);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function LineBreaksToDelimiter(const s: string; Delimiter: char): string;
|
||||||
|
var
|
||||||
|
p: Integer;
|
||||||
|
StartPos: LongInt;
|
||||||
|
begin
|
||||||
|
Result:=s;
|
||||||
|
p:=1;
|
||||||
|
while (p<=length(Result)) do begin
|
||||||
|
if Result[p] in [#10,#13] then begin
|
||||||
|
StartPos:=p;
|
||||||
|
repeat
|
||||||
|
inc(p);
|
||||||
|
until (p>length(Result)) or (not (Result[p] in [#10,#13]));
|
||||||
|
if p<=length(Result) then
|
||||||
|
Result:=copy(Result,1,StartPos-1)+Delimiter+copy(Result,p,length(Result))
|
||||||
|
else
|
||||||
|
Result:=copy(Result,1,StartPos-1);
|
||||||
|
end else begin
|
||||||
|
inc(p);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ConvertLineEndings(const s: string): string;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
EndingStart: LongInt;
|
||||||
|
begin
|
||||||
|
Result:=s;
|
||||||
|
i:=1;
|
||||||
|
while (i<=length(Result)) do begin
|
||||||
|
if Result[i] in [#10,#13] then begin
|
||||||
|
EndingStart:=i;
|
||||||
|
inc(i);
|
||||||
|
if (i<=length(Result)) and (Result[i] in [#10,#13])
|
||||||
|
and (Result[i]<>Result[i-1]) then
|
||||||
|
inc(i);
|
||||||
|
if (length(LineEnding)<>i-EndingStart)
|
||||||
|
or (LineEnding<>copy(Result,EndingStart,length(LineEnding))) then begin
|
||||||
|
// line end differs => replace with current LineEnding
|
||||||
|
Result:=copy(Result,1,EndingStart-1)+LineEnding+copy(Result,i,length(Result));
|
||||||
|
i:=EndingStart+length(LineEnding);
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TabsToSpaces(const s: string; TabWidth: integer; UseUTF8: boolean): string;
|
function TabsToSpaces(const s: string; TabWidth: integer; UseUTF8: boolean): string;
|
||||||
// Convert all tabs to TabWidth number of spaces.
|
// Convert all tabs to TabWidth number of spaces.
|
||||||
|
|
||||||
@ -602,37 +671,6 @@ begin
|
|||||||
RaiseGDBException('ERROR: BinaryStrToText: '+IntToStr(NewLen)+'<>'+IntToStr(NewPos-1));
|
RaiseGDBException('ERROR: BinaryStrToText: '+IntToStr(NewLen)+'<>'+IntToStr(NewPos-1));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function SplitString(const s: string; Delimiter: char): TStrings;
|
|
||||||
begin
|
|
||||||
Result:=TStringList.Create;
|
|
||||||
SplitString(s,Delimiter,Result,false);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure SplitString(const s: string; Delimiter: char; AddTo: TStrings;
|
|
||||||
ClearList: boolean);
|
|
||||||
var
|
|
||||||
SLen: Integer;
|
|
||||||
StartPos: Integer;
|
|
||||||
EndPos: Integer;
|
|
||||||
begin
|
|
||||||
if ClearList then
|
|
||||||
AddTo.Clear;
|
|
||||||
SLen:=length(s);
|
|
||||||
StartPos:=1;
|
|
||||||
EndPos:=1;
|
|
||||||
repeat
|
|
||||||
if (EndPos<=sLen) and (s[EndPos]<>Delimiter) then
|
|
||||||
inc(EndPos)
|
|
||||||
else begin
|
|
||||||
if EndPos>StartPos then
|
|
||||||
AddTo.Add(copy(s,StartPos,EndPos-StartPos));
|
|
||||||
StartPos:=EndPos+1;
|
|
||||||
if StartPos>sLen then exit;
|
|
||||||
inc(EndPos);
|
|
||||||
end;
|
|
||||||
until false;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function SpecialCharsToSpaces(const s: string; FixUTF8: boolean): string;
|
function SpecialCharsToSpaces(const s: string; FixUTF8: boolean): string;
|
||||||
// Converts illegal characters to spaces. Trim leading and trailing spaces.
|
// Converts illegal characters to spaces. Trim leading and trailing spaces.
|
||||||
var
|
var
|
||||||
@ -676,32 +714,116 @@ begin
|
|||||||
+copy(Result,i+1,length(Result));
|
+copy(Result,i+1,length(Result));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function LineBreaksToSystemLineBreaks(const s: string): string;
|
function BreakString(const s: string; MaxLineLength, Indent: integer): string;
|
||||||
|
var
|
||||||
|
SrcLen: Integer;
|
||||||
|
APos: Integer;
|
||||||
|
Src: String;
|
||||||
|
SplitPos: Integer;
|
||||||
|
CurMaxLineLength: Integer;
|
||||||
begin
|
begin
|
||||||
Result:=ChangeLineEndings(s,LineEnding);
|
Result:='';
|
||||||
|
Src:=s;
|
||||||
|
CurMaxLineLength:=MaxLineLength;
|
||||||
|
if Indent>MaxLineLength-2 then
|
||||||
|
Indent:=MaxLineLength-2;
|
||||||
|
if Indent<0 then
|
||||||
|
MaxLineLength:=0;
|
||||||
|
repeat
|
||||||
|
SrcLen:=length(Src);
|
||||||
|
if SrcLen<=CurMaxLineLength then begin
|
||||||
|
Result:=Result+Src;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
// split line
|
||||||
|
SplitPos:=0;
|
||||||
|
// search new line chars
|
||||||
|
APos:=1;
|
||||||
|
while (APos<=CurMaxLineLength) do begin
|
||||||
|
if Src[APos] in [#13,#10] then begin
|
||||||
|
SplitPos:=APos;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
inc(APos);
|
||||||
|
end;
|
||||||
|
// search a space boundary
|
||||||
|
if SplitPos=0 then begin
|
||||||
|
APos:=CurMaxLineLength;
|
||||||
|
while APos>1 do begin
|
||||||
|
if (Src[APos-1] in [' ',#9])
|
||||||
|
and (not (Src[APos] in [' ',#9])) then begin
|
||||||
|
SplitPos:=APos;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
dec(APos);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
// search a word boundary
|
||||||
|
if SplitPos=0 then begin
|
||||||
|
APos:=CurMaxLineLength;
|
||||||
|
while APos>1 do begin
|
||||||
|
if (Src[APos] in ['A'..'Z','a'..'z'])
|
||||||
|
and (not (Src[APos-1] in ['A'..'Z','a'..'z'])) then begin
|
||||||
|
SplitPos:=APos;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
dec(APos);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if SplitPos=0 then begin
|
||||||
|
// no word boundary found -> split chars
|
||||||
|
SplitPos:=CurMaxLineLength;
|
||||||
|
end;
|
||||||
|
// append part and newline
|
||||||
|
if (SplitPos<=SrcLen) and (Src[SplitPos] in [#10,#13]) then begin
|
||||||
|
// there is already a new line char at position
|
||||||
|
inc(SplitPos);
|
||||||
|
if (SplitPos<=SrcLen) and (Src[SplitPos] in [#10,#13])
|
||||||
|
and (Src[SplitPos]<>Src[SplitPos-1]) then
|
||||||
|
inc(SplitPos);
|
||||||
|
Result:=Result+copy(Src,1,SplitPos-1);
|
||||||
|
end else begin
|
||||||
|
Result:=Result+copy(Src,1,SplitPos-1)+LineEnding;
|
||||||
|
end;
|
||||||
|
// append indent
|
||||||
|
if Indent>0 then
|
||||||
|
Result:=Result+StringOfChar(' ',Indent);
|
||||||
|
// calculate new LineLength
|
||||||
|
CurMaxLineLength:=MaxLineLength-Indent;
|
||||||
|
// cut string
|
||||||
|
Src:=copy(Src,SplitPos,length(Src)-SplitPos+1);
|
||||||
|
until false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function LineBreaksToDelimiter(const s: string; Delimiter: char): string;
|
function SplitString(const s: string; Delimiter: char): TStrings;
|
||||||
var
|
|
||||||
p: Integer;
|
|
||||||
StartPos: LongInt;
|
|
||||||
begin
|
begin
|
||||||
Result:=s;
|
Result:=TStringList.Create;
|
||||||
p:=1;
|
SplitString(s,Delimiter,Result,false);
|
||||||
while (p<=length(Result)) do begin
|
end;
|
||||||
if Result[p] in [#10,#13] then begin
|
|
||||||
StartPos:=p;
|
procedure SplitString(const s: string; Delimiter: char; AddTo: TStrings;
|
||||||
repeat
|
ClearList: boolean);
|
||||||
inc(p);
|
var
|
||||||
until (p>length(Result)) or (not (Result[p] in [#10,#13]));
|
SLen: Integer;
|
||||||
if p<=length(Result) then
|
StartPos: Integer;
|
||||||
Result:=copy(Result,1,StartPos-1)+Delimiter+copy(Result,p,length(Result))
|
EndPos: Integer;
|
||||||
else
|
begin
|
||||||
Result:=copy(Result,1,StartPos-1);
|
if ClearList then
|
||||||
end else begin
|
AddTo.Clear;
|
||||||
inc(p);
|
SLen:=length(s);
|
||||||
|
StartPos:=1;
|
||||||
|
EndPos:=1;
|
||||||
|
repeat
|
||||||
|
if (EndPos<=sLen) and (s[EndPos]<>Delimiter) then
|
||||||
|
inc(EndPos)
|
||||||
|
else begin
|
||||||
|
if EndPos>StartPos then
|
||||||
|
AddTo.Add(copy(s,StartPos,EndPos-StartPos));
|
||||||
|
StartPos:=EndPos+1;
|
||||||
|
if StartPos>sLen then exit;
|
||||||
|
inc(EndPos);
|
||||||
end;
|
end;
|
||||||
end;
|
until false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function StringListToText(List: TStrings; const Delimiter: string;
|
function StringListToText(List: TStrings; const Delimiter: string;
|
||||||
@ -880,5 +1002,47 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function GetNextDelimitedItem(const List: string; Delimiter: char;
|
||||||
|
var Position: integer): string;
|
||||||
|
var
|
||||||
|
StartPos: LongInt;
|
||||||
|
begin
|
||||||
|
StartPos:=Position;
|
||||||
|
while (Position<=length(List)) and (List[Position]<>Delimiter) do
|
||||||
|
inc(Position);
|
||||||
|
Result:=copy(List,StartPos,Position-StartPos);
|
||||||
|
if Position<=length(List) then inc(Position); // skip Delimiter
|
||||||
|
end;
|
||||||
|
|
||||||
|
function HasDelimitedItem(const List: string; Delimiter: char; FindItem: string
|
||||||
|
): boolean;
|
||||||
|
var
|
||||||
|
p: Integer;
|
||||||
|
begin
|
||||||
|
p:=1;
|
||||||
|
Result:=FindNextDelimitedItem(List,Delimiter,p,FindItem)<>'';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function FindNextDelimitedItem(const List: string; Delimiter: char;
|
||||||
|
var Position: integer; FindItem: string): string;
|
||||||
|
begin
|
||||||
|
while Position<=length(List) do begin
|
||||||
|
Result:=GetNextDelimitedItem(List,Delimiter,Position);
|
||||||
|
if Result=FindItem then exit;
|
||||||
|
end;
|
||||||
|
Result:='';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function MergeWithDelimiter(const a, b: string; Delimiter: char): string;
|
||||||
|
begin
|
||||||
|
if a<>'' then begin
|
||||||
|
if b<>'' then
|
||||||
|
Result:=a+Delimiter+b
|
||||||
|
else
|
||||||
|
Result:=a;
|
||||||
|
end else
|
||||||
|
Result:=b;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -25,16 +25,6 @@ function CompareBoolean(b1, b2: boolean): integer;
|
|||||||
procedure MergeSortWithLen(List: PPointer; ListLength: PtrInt;
|
procedure MergeSortWithLen(List: PPointer; ListLength: PtrInt;
|
||||||
const Compare: TListSortCompare);
|
const Compare: TListSortCompare);
|
||||||
|
|
||||||
function GetNextDelimitedItem(const List: string; Delimiter: char;
|
|
||||||
var Position: integer): string;
|
|
||||||
function HasDelimitedItem(const List: string; Delimiter: char; FindItem: string
|
|
||||||
): boolean;
|
|
||||||
function FindNextDelimitedItem(const List: string; Delimiter: char;
|
|
||||||
var Position: integer; FindItem: string): string;
|
|
||||||
function MergeWithDelimiter(const a, b: string; Delimiter: char): string;
|
|
||||||
function BreakString(const s: string; MaxLineLength, Indent: integer): string;
|
|
||||||
function ConvertLineEndings(const s: string): string;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
ConsoleVerbosity: integer = 0; // 0=normal, -1=quiet, 1=verbose, 2=very verbose
|
ConsoleVerbosity: integer = 0; // 0=normal, -1=quiet, 1=verbose, 2=very verbose
|
||||||
|
|
||||||
@ -141,153 +131,5 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetNextDelimitedItem(const List: string; Delimiter: char;
|
|
||||||
var Position: integer): string;
|
|
||||||
var
|
|
||||||
StartPos: LongInt;
|
|
||||||
begin
|
|
||||||
StartPos:=Position;
|
|
||||||
while (Position<=length(List)) and (List[Position]<>Delimiter) do
|
|
||||||
inc(Position);
|
|
||||||
Result:=copy(List,StartPos,Position-StartPos);
|
|
||||||
if Position<=length(List) then inc(Position); // skip Delimiter
|
|
||||||
end;
|
|
||||||
|
|
||||||
function HasDelimitedItem(const List: string; Delimiter: char; FindItem: string
|
|
||||||
): boolean;
|
|
||||||
var
|
|
||||||
p: Integer;
|
|
||||||
begin
|
|
||||||
p:=1;
|
|
||||||
Result:=FindNextDelimitedItem(List,Delimiter,p,FindItem)<>'';
|
|
||||||
end;
|
|
||||||
|
|
||||||
function FindNextDelimitedItem(const List: string; Delimiter: char;
|
|
||||||
var Position: integer; FindItem: string): string;
|
|
||||||
begin
|
|
||||||
while Position<=length(List) do begin
|
|
||||||
Result:=GetNextDelimitedItem(List,Delimiter,Position);
|
|
||||||
if Result=FindItem then exit;
|
|
||||||
end;
|
|
||||||
Result:='';
|
|
||||||
end;
|
|
||||||
|
|
||||||
function MergeWithDelimiter(const a, b: string; Delimiter: char): string;
|
|
||||||
begin
|
|
||||||
if a<>'' then begin
|
|
||||||
if b<>'' then
|
|
||||||
Result:=a+Delimiter+b
|
|
||||||
else
|
|
||||||
Result:=a;
|
|
||||||
end else
|
|
||||||
Result:=b;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function BreakString(const s: string; MaxLineLength, Indent: integer): string;
|
|
||||||
var
|
|
||||||
SrcLen: Integer;
|
|
||||||
APos: Integer;
|
|
||||||
Src: String;
|
|
||||||
SplitPos: Integer;
|
|
||||||
CurMaxLineLength: Integer;
|
|
||||||
begin
|
|
||||||
Result:='';
|
|
||||||
Src:=s;
|
|
||||||
CurMaxLineLength:=MaxLineLength;
|
|
||||||
if Indent>MaxLineLength-2 then
|
|
||||||
Indent:=MaxLineLength-2;
|
|
||||||
if Indent<0 then
|
|
||||||
MaxLineLength:=0;
|
|
||||||
repeat
|
|
||||||
SrcLen:=length(Src);
|
|
||||||
if SrcLen<=CurMaxLineLength then begin
|
|
||||||
Result:=Result+Src;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
// split line
|
|
||||||
SplitPos:=0;
|
|
||||||
// search new line chars
|
|
||||||
APos:=1;
|
|
||||||
while (APos<=CurMaxLineLength) do begin
|
|
||||||
if Src[APos] in [#13,#10] then begin
|
|
||||||
SplitPos:=APos;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
inc(APos);
|
|
||||||
end;
|
|
||||||
// search a space boundary
|
|
||||||
if SplitPos=0 then begin
|
|
||||||
APos:=CurMaxLineLength;
|
|
||||||
while APos>1 do begin
|
|
||||||
if (Src[APos-1] in [' ',#9])
|
|
||||||
and (not (Src[APos] in [' ',#9])) then begin
|
|
||||||
SplitPos:=APos;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
dec(APos);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
// search a word boundary
|
|
||||||
if SplitPos=0 then begin
|
|
||||||
APos:=CurMaxLineLength;
|
|
||||||
while APos>1 do begin
|
|
||||||
if (Src[APos] in ['A'..'Z','a'..'z'])
|
|
||||||
and (not (Src[APos-1] in ['A'..'Z','a'..'z'])) then begin
|
|
||||||
SplitPos:=APos;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
dec(APos);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
if SplitPos=0 then begin
|
|
||||||
// no word boundary found -> split chars
|
|
||||||
SplitPos:=CurMaxLineLength;
|
|
||||||
end;
|
|
||||||
// append part and newline
|
|
||||||
if (SplitPos<=SrcLen) and (Src[SplitPos] in [#10,#13]) then begin
|
|
||||||
// there is already a new line char at position
|
|
||||||
inc(SplitPos);
|
|
||||||
if (SplitPos<=SrcLen) and (Src[SplitPos] in [#10,#13])
|
|
||||||
and (Src[SplitPos]<>Src[SplitPos-1]) then
|
|
||||||
inc(SplitPos);
|
|
||||||
Result:=Result+copy(Src,1,SplitPos-1);
|
|
||||||
end else begin
|
|
||||||
Result:=Result+copy(Src,1,SplitPos-1)+LineEnding;
|
|
||||||
end;
|
|
||||||
// append indent
|
|
||||||
if Indent>0 then
|
|
||||||
Result:=Result+StringOfChar(' ',Indent);
|
|
||||||
// calculate new LineLength
|
|
||||||
CurMaxLineLength:=MaxLineLength-Indent;
|
|
||||||
// cut string
|
|
||||||
Src:=copy(Src,SplitPos,length(Src)-SplitPos+1);
|
|
||||||
until false;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function ConvertLineEndings(const s: string): string;
|
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
EndingStart: LongInt;
|
|
||||||
begin
|
|
||||||
Result:=s;
|
|
||||||
i:=1;
|
|
||||||
while (i<=length(Result)) do begin
|
|
||||||
if Result[i] in [#10,#13] then begin
|
|
||||||
EndingStart:=i;
|
|
||||||
inc(i);
|
|
||||||
if (i<=length(Result)) and (Result[i] in [#10,#13])
|
|
||||||
and (Result[i]<>Result[i-1]) then
|
|
||||||
inc(i);
|
|
||||||
if (length(LineEnding)<>i-EndingStart)
|
|
||||||
or (LineEnding<>copy(Result,EndingStart,length(LineEnding))) then begin
|
|
||||||
// line end differs => replace with current LineEnding
|
|
||||||
Result:=copy(Result,1,EndingStart-1)+LineEnding+copy(Result,i,length(Result));
|
|
||||||
i:=EndingStart+length(LineEnding);
|
|
||||||
end;
|
|
||||||
end else
|
|
||||||
inc(i);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ uses
|
|||||||
FileProcs, CodeToolsCfgScript, LinkScanner,
|
FileProcs, CodeToolsCfgScript, LinkScanner,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LConvEncoding, FileUtil, LazFileUtils, LazFileCache, LazUTF8, Laz2_XMLCfg,
|
LConvEncoding, FileUtil, LazFileUtils, LazFileCache, LazUTF8, Laz2_XMLCfg,
|
||||||
LazUtilities, LazMethodList,
|
LazUtilities, LazStringUtils, LazMethodList,
|
||||||
// IDEIntf
|
// IDEIntf
|
||||||
BaseIDEIntf, IDEOptionsIntf, ProjectIntf, MacroIntf, IDEDialogs, IDEExternToolIntf,
|
BaseIDEIntf, IDEOptionsIntf, ProjectIntf, MacroIntf, IDEDialogs, IDEExternToolIntf,
|
||||||
CompOptsIntf, LazIDEIntf, MacroDefIntf, IDEMsgIntf, PackageDependencyIntf,
|
CompOptsIntf, LazIDEIntf, MacroDefIntf, IDEMsgIntf, PackageDependencyIntf,
|
||||||
|
@ -32,7 +32,7 @@ uses
|
|||||||
// LCL
|
// LCL
|
||||||
Forms, Controls, Dialogs, ButtonPanel, StdCtrls, ComCtrls, Masks, LCLIntf,
|
Forms, Controls, Dialogs, ButtonPanel, StdCtrls, ComCtrls, Masks, LCLIntf,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazFileUtils, LazFileCache, LazUtilities, AvgLvlTree,
|
LazFileUtils, LazFileCache, LazStringUtils, AvgLvlTree,
|
||||||
// codetools
|
// codetools
|
||||||
FileProcs, CodeToolManager, DirectoryCacher,
|
FileProcs, CodeToolManager, DirectoryCacher,
|
||||||
// IDEIntf
|
// IDEIntf
|
||||||
|
@ -54,7 +54,7 @@ uses
|
|||||||
BasicCodeTools, DefineTemplates, CodeTree, CodeCache, CodeToolManager,
|
BasicCodeTools, DefineTemplates, CodeTree, CodeCache, CodeToolManager,
|
||||||
PascalParserTool, LinkScanner, FileProcs, CodeIndex, StdCodeTools, SourceLog,
|
PascalParserTool, LinkScanner, FileProcs, CodeIndex, StdCodeTools, SourceLog,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazFileUtils, LazUtilities, AvgLvlTree,
|
LazFileUtils, LazStringUtils, AvgLvlTree,
|
||||||
// IDEIntf
|
// IDEIntf
|
||||||
IDEWindowIntf, SrcEditorIntf, IDEMsgIntf, IDEDialogs, LazConfigStorage,
|
IDEWindowIntf, SrcEditorIntf, IDEMsgIntf, IDEDialogs, LazConfigStorage,
|
||||||
IDEHelpIntf, PackageIntf, IDECommands, LazIDEIntf, IDEExternToolIntf,
|
IDEHelpIntf, PackageIntf, IDECommands, LazIDEIntf, IDEExternToolIntf,
|
||||||
|
@ -44,14 +44,12 @@ unit CodeToolsDefines;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
//Classes, SysUtils, Math, LCLIntf, Forms, Controls, Buttons, StdCtrls,
|
|
||||||
//ComCtrls, LCLType, ExtCtrls, Menus, LCLProc, Graphics, Dialogs, ButtonPanel,
|
|
||||||
Classes, SysUtils, Math,
|
Classes, SysUtils, Math,
|
||||||
// LCL
|
// LCL
|
||||||
LCLType, LCLIntf, Forms, Controls, Buttons, StdCtrls,
|
LCLType, LCLIntf, Forms, Controls, Buttons, StdCtrls,
|
||||||
ComCtrls, ExtCtrls, Menus, Graphics, Dialogs, ButtonPanel,
|
ComCtrls, ExtCtrls, Menus, Graphics, Dialogs, ButtonPanel,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazFileUtils, LazLogger, LazUtilities,
|
LazFileUtils, LazLogger, LazStringUtils,
|
||||||
// SynEdit
|
// SynEdit
|
||||||
SynEdit,
|
SynEdit,
|
||||||
// Codetools
|
// Codetools
|
||||||
|
@ -33,7 +33,7 @@ uses
|
|||||||
// FCL
|
// FCL
|
||||||
Classes, SysUtils,
|
Classes, SysUtils,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
Laz2_DOM, Laz2_XMLRead, LazUtilities, LazTracer,
|
Laz2_DOM, Laz2_XMLRead, LazStringUtils, LazTracer,
|
||||||
// LCL
|
// LCL
|
||||||
LResources, StdCtrls, Buttons, ComCtrls, Controls, Dialogs,
|
LResources, StdCtrls, Buttons, ComCtrls, Controls, Dialogs,
|
||||||
ExtCtrls, Forms, Graphics, LCLType, LCLProc,
|
ExtCtrls, Forms, Graphics, LCLType, LCLProc,
|
||||||
|
@ -32,7 +32,7 @@ uses
|
|||||||
// LCL
|
// LCL
|
||||||
Controls, Dialogs, Graphics, StdCtrls,
|
Controls, Dialogs, Graphics, StdCtrls,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazFileUtils, LazUtilities,
|
LazFileUtils, LazStringUtils,
|
||||||
// CodeTools
|
// CodeTools
|
||||||
DefineTemplates,
|
DefineTemplates,
|
||||||
// IdeIntf
|
// IdeIntf
|
||||||
|
@ -40,7 +40,7 @@ uses
|
|||||||
// CodeTools
|
// CodeTools
|
||||||
BasicCodeTools, FileProcs, CodeToolManager, CodeToolsConfig, CodeCache,
|
BasicCodeTools, FileProcs, CodeToolManager, CodeToolsConfig, CodeCache,
|
||||||
// IDE
|
// IDE
|
||||||
IDECmdLine, LazConf;
|
LazConf;
|
||||||
|
|
||||||
type
|
type
|
||||||
// copy
|
// copy
|
||||||
|
@ -32,14 +32,14 @@ uses
|
|||||||
Interfaces, // this includes the NoGUI widgetset
|
Interfaces, // this includes the NoGUI widgetset
|
||||||
// LazUtils
|
// LazUtils
|
||||||
Masks, LConvEncoding, FileUtil, LazFileUtils, LazLoggerBase, LazUtilities,
|
Masks, LConvEncoding, FileUtil, LazFileUtils, LazLoggerBase, LazUtilities,
|
||||||
LazUTF8, Laz2_XMLCfg, UITypes,
|
LazUTF8, Laz2_XMLCfg, UITypes, LazStringUtils,
|
||||||
// LCL
|
// LCL
|
||||||
LCLPlatformDef, Forms,
|
LCLPlatformDef, Forms,
|
||||||
// Codetools
|
// Codetools
|
||||||
CodeCache, CodeToolManager, DefineTemplates, FileProcs,
|
CodeCache, CodeToolManager, DefineTemplates, FileProcs,
|
||||||
// IDEIntf
|
// IDEIntf
|
||||||
BaseIDEIntf, MacroIntf, PackageIntf, LazMsgDialogs, ProjectIntf, IDEExternToolIntf,
|
BaseIDEIntf, MacroIntf, PackageIntf, LazMsgDialogs, ProjectIntf, IDEExternToolIntf,
|
||||||
CompOptsIntf, IDEOptionsIntf, LazIDEIntf, PackageDependencyIntf,
|
CompOptsIntf, IDEOptionsIntf, PackageDependencyIntf,
|
||||||
// IDE
|
// IDE
|
||||||
IDEProcs, InitialSetupProc, ExtTools, CompilerOptions,
|
IDEProcs, InitialSetupProc, ExtTools, CompilerOptions,
|
||||||
ApplicationBundle, TransferMacros, EnvironmentOpts, IDETranslations,
|
ApplicationBundle, TransferMacros, EnvironmentOpts, IDETranslations,
|
||||||
|
@ -40,7 +40,7 @@ uses
|
|||||||
// LCL
|
// LCL
|
||||||
LCLType, Graphics, Controls,
|
LCLType, Graphics, Controls,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazFileUtils, LazUtilities,
|
LazFileUtils, LazStringUtils,
|
||||||
// SynEdit
|
// SynEdit
|
||||||
SynCompletion,
|
SynCompletion,
|
||||||
// CodeTools
|
// CodeTools
|
||||||
|
@ -43,7 +43,7 @@ uses
|
|||||||
CodeToolManager, DefineTemplates, CTUnitGraph, CTUnitGroupGraph,
|
CodeToolManager, DefineTemplates, CTUnitGraph, CTUnitGroupGraph,
|
||||||
FileProcs, CodeCache, AvgLvlTree,
|
FileProcs, CodeCache, AvgLvlTree,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazLoggerBase, LazFileUtils, LazFileCache, LazUtilities, LazUTF8, LvlGraphCtrl,
|
LazLoggerBase, LazFileUtils, LazFileCache, LazStringUtils, LazUTF8, LvlGraphCtrl,
|
||||||
// IDE interface
|
// IDE interface
|
||||||
LazIDEIntf, ProjectIntf, IDEWindowIntf, PackageIntf, SrcEditorIntf, IDEImagesIntf,
|
LazIDEIntf, ProjectIntf, IDEWindowIntf, PackageIntf, SrcEditorIntf, IDEImagesIntf,
|
||||||
IDEMsgIntf, IDEExternToolIntf, IDECommands, IDEDialogs,
|
IDEMsgIntf, IDEExternToolIntf, IDECommands, IDEDialogs,
|
||||||
|
@ -24,11 +24,11 @@ uses
|
|||||||
// RTL + FCL
|
// RTL + FCL
|
||||||
Types, typinfo, Classes, SysUtils,
|
Types, typinfo, Classes, SysUtils,
|
||||||
// LCL
|
// LCL
|
||||||
LMessages, LResources, LCLIntf, InterfaceBase, LCLStrConsts, LCLType, LCLProc,
|
LMessages, LResources, LCLIntf, InterfaceBase, LCLStrConsts, LCLType,
|
||||||
Forms, Controls, Themes, GraphType, Graphics, Buttons, ButtonPanel, StdCtrls,
|
Forms, Controls, Themes, GraphType, Graphics, Buttons, ButtonPanel, StdCtrls,
|
||||||
ExtCtrls, LCLClasses, ClipBrd, Menus, LCLTaskDialog,
|
ExtCtrls, LCLClasses, ClipBrd, Menus, LCLTaskDialog,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
UITypes, FileUtil, LazFileUtils;
|
UITypes, FileUtil, LazFileUtils, LazStringUtils, LazLoggerBase;
|
||||||
|
|
||||||
type
|
type
|
||||||
// Aliases for types in UITypes.
|
// Aliases for types in UITypes.
|
||||||
|
@ -28,7 +28,7 @@ uses
|
|||||||
// LCL
|
// LCL
|
||||||
LCLProc, LCLType, Graphics, Controls, StdCtrls,
|
LCLProc, LCLType, Graphics, Controls, StdCtrls,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazUtf8Classes, TextStrings,
|
LazUtf8Classes, TextStrings, LazStringUtils,
|
||||||
// LCL Carbon
|
// LCL Carbon
|
||||||
CarbonEdits, CarbonListViews;
|
CarbonEdits, CarbonListViews;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ uses
|
|||||||
{$EndIf}
|
{$EndIf}
|
||||||
gdk2pixbuf, gtk2, gdk2, glib2, Pango,
|
gdk2pixbuf, gtk2, gdk2, glib2, Pango,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazFileUtils, LazUTF8, DynHashArray, Maps, IntegerList, LazLoggerBase, LazUtilities,
|
LazFileUtils, LazUTF8, DynHashArray, Maps, IntegerList, LazLoggerBase, LazStringUtils,
|
||||||
// LCL
|
// LCL
|
||||||
Dialogs, Controls, Forms, LCLStrConsts,
|
Dialogs, Controls, Forms, LCLStrConsts,
|
||||||
LMessages, LCLProc, LCLIntf, LCLType, GraphType, GraphMath,
|
LMessages, LCLProc, LCLIntf, LCLType, GraphType, GraphMath,
|
||||||
|
@ -38,7 +38,7 @@ uses
|
|||||||
// FPC
|
// FPC
|
||||||
Classes, SysUtils, Math, Types,
|
Classes, SysUtils, Math, Types,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazUTF8, Maps, LazUtilities,
|
LazUTF8, Maps, LazStringUtils,
|
||||||
// LCL
|
// LCL
|
||||||
LCLPlatformDef, InterfaceBase, LCLProc, LCLType, LCLIntf,
|
LCLPlatformDef, InterfaceBase, LCLProc, LCLType, LCLIntf,
|
||||||
LMessages, LCLMessageGlue, LCLStrConsts,
|
LMessages, LCLMessageGlue, LCLStrConsts,
|
||||||
|
@ -37,7 +37,7 @@ uses
|
|||||||
// FPC
|
// FPC
|
||||||
Classes, SysUtils, Math, Types, maps,
|
Classes, SysUtils, Math, Types, maps,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazUtilities,
|
LazStringUtils,
|
||||||
// LCL
|
// LCL
|
||||||
InterfaceBase, LCLPlatformDef, LCLProc, LazUTF8, LCLType, LMessages, LCLMessageGlue, LCLStrConsts,
|
InterfaceBase, LCLPlatformDef, LCLProc, LazUTF8, LCLType, LMessages, LCLMessageGlue, LCLStrConsts,
|
||||||
Controls, ExtCtrls, Forms,
|
Controls, ExtCtrls, Forms,
|
||||||
|
@ -244,7 +244,6 @@ procedure DbgOut(const s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12: string); overload
|
|||||||
procedure CloseDebugOutput;
|
procedure CloseDebugOutput;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
function ConvertLineEndings(const s: string): string; inline;
|
|
||||||
function DbgS(const c: cardinal): string; overload; inline;
|
function DbgS(const c: cardinal): string; overload; inline;
|
||||||
function DbgS(const i: longint): string; overload; inline;
|
function DbgS(const i: longint): string; overload; inline;
|
||||||
function DbgS(const i: int64): string; overload; inline;
|
function DbgS(const i: int64): string; overload; inline;
|
||||||
@ -1838,11 +1837,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
function ConvertLineEndings(const s: string): string;
|
|
||||||
begin
|
|
||||||
Result:=LazUtilities.ConvertLineEndings(s);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function DbgS(const c: cardinal): string;
|
function DbgS(const c: cardinal): string;
|
||||||
begin
|
begin
|
||||||
Result:=LazLoggerBase.DbgS(c);
|
Result:=LazLoggerBase.DbgS(c);
|
||||||
|
@ -35,7 +35,7 @@ uses
|
|||||||
// LCL
|
// LCL
|
||||||
Forms, Controls, ComCtrls, StdCtrls, ExtCtrls, LCLType, ButtonPanel,
|
Forms, Controls, ComCtrls, StdCtrls, ExtCtrls, LCLType, ButtonPanel,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazUtilities,
|
LazStringUtils,
|
||||||
// LazControls
|
// LazControls
|
||||||
ListViewFilterEdit,
|
ListViewFilterEdit,
|
||||||
// IdeIntf
|
// IdeIntf
|
||||||
|
@ -42,7 +42,7 @@ uses
|
|||||||
LCLType, LCLIntf, Forms, Controls, ComCtrls, StdCtrls, ExtCtrls,
|
LCLType, LCLIntf, Forms, Controls, ComCtrls, StdCtrls, ExtCtrls,
|
||||||
Menus, ButtonPanel,
|
Menus, ButtonPanel,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
LazLoggerBase, LazUtilities, LazTracer,
|
LazLoggerBase, LazTracer, LazStringUtils,
|
||||||
// LazControls
|
// LazControls
|
||||||
LvlGraphCtrl,
|
LvlGraphCtrl,
|
||||||
// IdeIntf
|
// IdeIntf
|
||||||
|
Loading…
Reference in New Issue
Block a user