mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-13 04:49:29 +02:00
lazutils: moved ReplaceSubString to LazUTF8, added UTF8QuotedStr
git-svn-id: trunk@47748 -
This commit is contained in:
parent
a8a5b670ea
commit
69edc4d8c0
@ -39,8 +39,8 @@ uses
|
|||||||
{$IFDEF Windows}
|
{$IFDEF Windows}
|
||||||
Windows,
|
Windows,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Classes, SysUtils, LazUtilities, LazUTF8, LazDbgLog, LazFileCache,
|
Classes, SysUtils, LazUtilities, LazDbgLog, LazLogger, LazUTF8, LazFileCache,
|
||||||
LazFileUtils, LazUTF8Classes, LazLogger, AVL_Tree, CodeToolsStrConsts;
|
LazFileUtils, LazUTF8Classes, AVL_Tree, CodeToolsStrConsts;
|
||||||
|
|
||||||
type
|
type
|
||||||
TFPCStreamSeekType = int64;
|
TFPCStreamSeekType = int64;
|
||||||
|
@ -4,7 +4,7 @@ unit LazLogger;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, types, math, LazLoggerBase, LazClasses, FileUtil;
|
Classes, SysUtils, types, math, LazUTF8, LazLoggerBase, LazClasses, FileUtil;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ function DbgWideStr(const StringWithSpecialChars: widestring): string; overload;
|
|||||||
|
|
||||||
function ConvertLineEndings(const s: string): string;
|
function ConvertLineEndings(const s: string): string;
|
||||||
procedure ReplaceSubstring(var s: string; StartPos, Count: SizeInt;
|
procedure ReplaceSubstring(var s: string; StartPos, Count: SizeInt;
|
||||||
const Insertion: string);
|
const Insertion: string); inline; deprecated;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -785,52 +785,8 @@ end;
|
|||||||
|
|
||||||
procedure ReplaceSubstring(var s: string; StartPos, Count: SizeInt;
|
procedure ReplaceSubstring(var s: string; StartPos, Count: SizeInt;
|
||||||
const Insertion: string);
|
const Insertion: string);
|
||||||
var
|
|
||||||
MaxCount: SizeInt;
|
|
||||||
InsertionLen: SizeInt;
|
|
||||||
SLen: SizeInt;
|
|
||||||
RestLen: SizeInt;
|
|
||||||
p: PByte;
|
|
||||||
begin
|
begin
|
||||||
SLen:=length(s);
|
LazUTF8.ReplaceSubstring(s,StartPos,Count,Insertion);
|
||||||
if StartPos>SLen then begin
|
|
||||||
s:=s+Insertion;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
if StartPos<1 then StartPos:=1;
|
|
||||||
if Count<0 then Count:=0;
|
|
||||||
MaxCount:=SLen-StartPos+1;
|
|
||||||
if Count>MaxCount then
|
|
||||||
Count:=MaxCount;
|
|
||||||
InsertionLen:=length(Insertion);
|
|
||||||
if (Count=0) and (InsertionLen=0) then
|
|
||||||
exit; // nothing to do
|
|
||||||
if (Count=InsertionLen) then begin
|
|
||||||
if CompareMem(PByte(s)+StartPos-1,Pointer(Insertion),Count) then
|
|
||||||
// already the same content
|
|
||||||
exit;
|
|
||||||
UniqueString(s);
|
|
||||||
end else begin
|
|
||||||
RestLen:=SLen-StartPos-Count+1;
|
|
||||||
if InsertionLen<Count then begin
|
|
||||||
// shorten
|
|
||||||
if RestLen>0 then begin
|
|
||||||
UniqueString(s);
|
|
||||||
p:=PByte(s)+StartPos-1;
|
|
||||||
System.Move((p+Count)^,(p+InsertionLen)^,RestLen);
|
|
||||||
end;
|
|
||||||
Setlength(s,SLen-Count+InsertionLen);
|
|
||||||
end else begin
|
|
||||||
// longen
|
|
||||||
Setlength(s,SLen-Count+InsertionLen);
|
|
||||||
if RestLen>0 then begin
|
|
||||||
p:=PByte(s)+StartPos-1;
|
|
||||||
System.Move((p+Count)^,(p+InsertionLen)^,RestLen);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
if InsertionLen>0 then
|
|
||||||
System.Move(PByte(Insertion)^,(PByte(s)+StartPos-1)^,InsertionLen);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
@ -95,16 +95,17 @@ function UTF8LowerString(const s: string): string;
|
|||||||
function UTF8UpperCase(const AInStr: string; ALanguage: string=''): string;
|
function UTF8UpperCase(const AInStr: string; ALanguage: string=''): string;
|
||||||
function UTF8UpperString(const s: string): string;
|
function UTF8UpperString(const s: string): string;
|
||||||
function FindInvalidUTF8Character(p: PChar; Count: PtrInt;
|
function FindInvalidUTF8Character(p: PChar; Count: PtrInt;
|
||||||
StopOnNonASCII: Boolean = true): PtrInt;
|
StopOnNonUTF8: Boolean = true): PtrInt;
|
||||||
function ValidUTF8String(const s: String): String;
|
function ValidUTF8String(const s: String): String;
|
||||||
function Utf8StringOfChar(AUtf8Char: String; N: Integer): String;
|
function UTF8StringOfChar(AUtf8Char: String; N: Integer): String;
|
||||||
function Utf8AddChar(AUtf8Char: String; const S: String; N: Integer): String;
|
function UTF8AddChar(AUtf8Char: String; const S: String; N: Integer): String;
|
||||||
function Utf8AddCharR(AUtf8Char: String; const S: String; N: Integer): String;
|
function UTF8AddCharR(AUtf8Char: String; const S: String; N: Integer): String;
|
||||||
function UTF8PadLeft(const S: String; const N: Integer; const AUtf8Char: String = #32): String;
|
function UTF8PadLeft(const S: String; const N: Integer; const AUtf8Char: String = #32): String;
|
||||||
function UTF8PadRight(const S: String; const N: Integer; const AUtf8Char: String = #32): String;
|
function UTF8PadRight(const S: String; const N: Integer; const AUtf8Char: String = #32): String;
|
||||||
function UTF8PadCenter(const S: String; const N: Integer; const AUtf8Char: String = #32): String;
|
function UTF8PadCenter(const S: String; const N: Integer; const AUtf8Char: String = #32): String;
|
||||||
function Utf8LeftStr(const AText: String; const ACount: Integer): String;
|
function UTF8LeftStr(const AText: String; const ACount: Integer): String;
|
||||||
function Utf8RightStr(const AText: String; const ACount: Integer): String;
|
function UTF8RightStr(const AText: String; const ACount: Integer): String;
|
||||||
|
function UTF8QuotedStr(const S, Quote: string): string;
|
||||||
//Utf8 version of MidStr is just Utf8Copy with same parameters, so it is not implemented here
|
//Utf8 version of MidStr is just Utf8Copy with same parameters, so it is not implemented here
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -158,6 +159,9 @@ procedure LazGetShortLanguageID(var Lang: String);
|
|||||||
var
|
var
|
||||||
FPUpChars: array[char] of char;
|
FPUpChars: array[char] of char;
|
||||||
|
|
||||||
|
procedure ReplaceSubstring(var s: string; StartPos, Count: SizeInt;
|
||||||
|
const Insertion: string);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -2482,7 +2486,7 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
function FindInvalidUTF8Character(p: PChar; Count: PtrInt;
|
function FindInvalidUTF8Character(p: PChar; Count: PtrInt;
|
||||||
StopOnNonASCII: Boolean): PtrInt;
|
StopOnNonUTF8: Boolean): PtrInt;
|
||||||
// return -1 if ok
|
// return -1 if ok
|
||||||
var
|
var
|
||||||
CharLen: Integer;
|
CharLen: Integer;
|
||||||
@ -2493,12 +2497,12 @@ begin
|
|||||||
while Result<Count do begin
|
while Result<Count do begin
|
||||||
c:=p^;
|
c:=p^;
|
||||||
if ord(c)<%10000000 then begin
|
if ord(c)<%10000000 then begin
|
||||||
// regular single byte ASCII character (#0 is a character, this is pascal ;)
|
// regular single byte ASCII character (#0 is a character, this is Pascal ;)
|
||||||
CharLen:=1;
|
CharLen:=1;
|
||||||
end else if ord(c)<=%11000001 then begin
|
end else if ord(c)<=%11000001 then begin
|
||||||
// single byte character, between valid UTF-8 encodings
|
// single byte character, between valid UTF-8 encodings
|
||||||
// %11000000 and %11000001 map 2 byte to #0..#128, which is invalid and used for XSS attacks
|
// %11000000 and %11000001 map 2 byte to #0..#128, which is invalid and used for XSS attacks
|
||||||
if StopOnNonASCII or (ord(c)>=192) then
|
if StopOnNonUTF8 or (ord(c)>=192) then
|
||||||
exit;
|
exit;
|
||||||
CharLen:=1;
|
CharLen:=1;
|
||||||
end else if ord(c)<=%11011111 then begin
|
end else if ord(c)<=%11011111 then begin
|
||||||
@ -2533,7 +2537,7 @@ begin
|
|||||||
exit; // missing following bytes
|
exit; // missing following bytes
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if StopOnNonASCII then
|
if StopOnNonUTF8 then
|
||||||
exit;
|
exit;
|
||||||
CharLen:=1;
|
CharLen:=1;
|
||||||
end;
|
end;
|
||||||
@ -2698,8 +2702,31 @@ begin
|
|||||||
Result := Utf8Copy(AText,l-j+1,j);
|
Result := Utf8Copy(AText,l-j+1,j);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function UTF8QuotedStr(const S, Quote: string): string;
|
||||||
|
// replace all Quote in S with double Quote and enclose the result in Quote.
|
||||||
|
var
|
||||||
|
QuoteC: Char;
|
||||||
|
p, QuoteP, CopyPos: PChar;
|
||||||
|
QuoteLen: SizeInt;
|
||||||
|
begin
|
||||||
|
Result:=Quote;
|
||||||
|
p:=PChar(S);
|
||||||
|
CopyPos:=p;
|
||||||
|
QuoteC:=Quote[1];
|
||||||
|
QuoteP:=PChar(Quote);
|
||||||
|
QuoteLen:=length(Quote);
|
||||||
|
repeat
|
||||||
|
if (p^=#0) and (p-PChar(S)=length(S)) then
|
||||||
|
break;
|
||||||
|
if (p^=QuoteC) and CompareMem(p,QuoteP,QuoteLen) then begin
|
||||||
|
inc(p,QuoteLen);
|
||||||
|
Result+=copy(S,CopyPos-PChar(S)+1,p-CopyPos)+Quote;
|
||||||
|
CopyPos:=p;
|
||||||
|
end else
|
||||||
|
inc(p);
|
||||||
|
until false;
|
||||||
|
Result+=copy(S,CopyPos-PChar(S)+1,p-CopyPos)+Quote;
|
||||||
|
end;
|
||||||
|
|
||||||
function UTF8Trim(const s: string; Flags: TUTF8TrimFlags): string;
|
function UTF8Trim(const s: string; Flags: TUTF8TrimFlags): string;
|
||||||
var
|
var
|
||||||
@ -3380,6 +3407,56 @@ begin
|
|||||||
if Length(Lang) > 2 then Lang := Lang[1] + Lang[2];
|
if Length(Lang) > 2 then Lang := Lang[1] + Lang[2];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure ReplaceSubstring(var s: string; StartPos, Count: SizeInt;
|
||||||
|
const Insertion: string);
|
||||||
|
var
|
||||||
|
MaxCount: SizeInt;
|
||||||
|
InsertionLen: SizeInt;
|
||||||
|
SLen: SizeInt;
|
||||||
|
RestLen: SizeInt;
|
||||||
|
p: PByte;
|
||||||
|
begin
|
||||||
|
SLen:=length(s);
|
||||||
|
if StartPos>SLen then begin
|
||||||
|
s:=s+Insertion;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if StartPos<1 then StartPos:=1;
|
||||||
|
if Count<0 then Count:=0;
|
||||||
|
MaxCount:=SLen-StartPos+1;
|
||||||
|
if Count>MaxCount then
|
||||||
|
Count:=MaxCount;
|
||||||
|
InsertionLen:=length(Insertion);
|
||||||
|
if (Count=0) and (InsertionLen=0) then
|
||||||
|
exit; // nothing to do
|
||||||
|
if (Count=InsertionLen) then begin
|
||||||
|
if CompareMem(PByte(s)+StartPos-1,Pointer(Insertion),Count) then
|
||||||
|
// already the same content
|
||||||
|
exit;
|
||||||
|
UniqueString(s);
|
||||||
|
end else begin
|
||||||
|
RestLen:=SLen-StartPos-Count+1;
|
||||||
|
if InsertionLen<Count then begin
|
||||||
|
// shorten
|
||||||
|
if RestLen>0 then begin
|
||||||
|
UniqueString(s);
|
||||||
|
p:=PByte(s)+StartPos-1;
|
||||||
|
System.Move((p+Count)^,(p+InsertionLen)^,RestLen);
|
||||||
|
end;
|
||||||
|
Setlength(s,SLen-Count+InsertionLen);
|
||||||
|
end else begin
|
||||||
|
// longen
|
||||||
|
Setlength(s,SLen-Count+InsertionLen);
|
||||||
|
if RestLen>0 then begin
|
||||||
|
p:=PByte(s)+StartPos-1;
|
||||||
|
System.Move((p+Count)^,(p+InsertionLen)^,RestLen);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if InsertionLen>0 then
|
||||||
|
System.Move(PByte(Insertion)^,(PByte(s)+StartPos-1)^,InsertionLen);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure InitFPUpchars;
|
procedure InitFPUpchars;
|
||||||
var
|
var
|
||||||
c: Char;
|
c: Char;
|
||||||
|
@ -34,7 +34,7 @@ unit WikiParser;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, laz2_XMLRead, laz2_DOM, LazUTF8, LazLogger,
|
Classes, SysUtils, laz2_XMLRead, laz2_DOM, LazLogger, LazUTF8,
|
||||||
BasicCodeTools, KeywordFuncLists;
|
BasicCodeTools, KeywordFuncLists;
|
||||||
|
|
||||||
const
|
const
|
||||||
|
@ -30,7 +30,7 @@ uses
|
|||||||
cthreads,
|
cthreads,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Classes, SysUtils, LazFileUtils, laz2_XMLRead, laz2_DOM, laz2_XMLWrite,
|
Classes, SysUtils, LazFileUtils, laz2_XMLRead, laz2_DOM, laz2_XMLWrite,
|
||||||
LazUTF8, LazLogger, CodeToolsStructs, CustApp, AVL_Tree,
|
LazLogger, LazUTF8, CodeToolsStructs, CustApp, AVL_Tree,
|
||||||
{$IF FPC_FULLVERSION<20701}
|
{$IF FPC_FULLVERSION<20701}
|
||||||
myfphttpclient,
|
myfphttpclient,
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
|
@ -1,125 +1,7 @@
|
|||||||
Extending the IDE (Overview)
|
Extending the IDE (Overview)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
The online pages are more up to date and have more examples:
|
See the online pages:
|
||||||
http://wiki.lazarus.freepascal.org/Extending_the_IDE
|
http://wiki.lazarus.freepascal.org/Extending_the_IDE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The IDE supports several types of plugins:
|
|
||||||
|
|
||||||
Components
|
|
||||||
These are the items in the component palette. For a example TButton can be
|
|
||||||
used to create Buttons.
|
|
||||||
|
|
||||||
Component Editors
|
|
||||||
Component editors are used when you double click on a component in the
|
|
||||||
designer or to add some extra items to the popup menu of the designer, when
|
|
||||||
you right click on a component.
|
|
||||||
|
|
||||||
Property Editors
|
|
||||||
These are used by the rows in the object inspector.
|
|
||||||
|
|
||||||
Experts
|
|
||||||
These are all other types.
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
There are two possibilities to add your own plugins to Lazarus:
|
|
||||||
|
|
||||||
1. Write a package, install it and register your plugins in the 'Register'
|
|
||||||
procedure of a unit.
|
|
||||||
2. Extend the lazarus code, and send your cvs diff to the lazarus mailing list.
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Writing components:
|
|
||||||
|
|
||||||
ToDo
|
|
||||||
Hint: Create a new component via the package editor.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Writing component editors:
|
|
||||||
|
|
||||||
ToDo
|
|
||||||
Hint: see componenteditors.pas for examples
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Writing property editors
|
|
||||||
|
|
||||||
ToDo
|
|
||||||
Hint: see propedits.pp for examples
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Register event handlers
|
|
||||||
|
|
||||||
There are several events in the IDE, for which plugins can add their own
|
|
||||||
handlers.
|
|
||||||
In propedits.pp there is a GlobalDesignHook object, which maintains several
|
|
||||||
events for designing. Each event calls a list of handlers. The default handlers
|
|
||||||
are added by the IDE. You can add your own handlers with the AddHandlerXXX and
|
|
||||||
RemoveHandlerXXX methods. They will be called before the default handlers.
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
Adding your handler (this is normally done in the constructor of your object):
|
|
||||||
GlobalDesignHook.AddHandlerComponentAdded(@YourOnComponentAdded);
|
|
||||||
|
|
||||||
Removing your handler:
|
|
||||||
GlobalDesignHook.RemoveHandlerComponentAdded(@YourOnComponentAdded);
|
|
||||||
|
|
||||||
You can remove all handlers at once. For example, it is a good idea to add
|
|
||||||
this line in the destructor of object:
|
|
||||||
GlobalDesignHook.RemoveAllHandlersForObject(Self);
|
|
||||||
|
|
||||||
|
|
||||||
The handlers of GlobalDesignHook:
|
|
||||||
|
|
||||||
// lookup root
|
|
||||||
ChangeLookupRoot
|
|
||||||
Called when the LookupRoot changed.
|
|
||||||
The LookupRoot is the owner object of the currently selected components.
|
|
||||||
Normally this is a TForm.
|
|
||||||
|
|
||||||
// methods
|
|
||||||
CreateMethod
|
|
||||||
GetMethodName
|
|
||||||
GetMethods
|
|
||||||
MethodExists
|
|
||||||
RenameMethod
|
|
||||||
ShowMethod
|
|
||||||
Called
|
|
||||||
MethodFromAncestor
|
|
||||||
ChainCall
|
|
||||||
|
|
||||||
// components
|
|
||||||
GetComponent
|
|
||||||
GetComponentName
|
|
||||||
GetComponentNames
|
|
||||||
GetRootClassName
|
|
||||||
ComponentRenamed
|
|
||||||
Called when a component was renamed
|
|
||||||
ComponentAdded
|
|
||||||
Called when a new component was added to the LookupRoot
|
|
||||||
ComponentDeleting
|
|
||||||
Called before a component is freed.
|
|
||||||
DeleteComponent
|
|
||||||
Called by the IDE to delete a component.
|
|
||||||
GetSelectedComponents
|
|
||||||
Get the current selection of components.
|
|
||||||
|
|
||||||
// persistent objects
|
|
||||||
GetObject
|
|
||||||
GetObjectName
|
|
||||||
GetObjectNames
|
|
||||||
|
|
||||||
// modifing
|
|
||||||
Modified
|
|
||||||
Revert
|
|
||||||
RefreshPropertyValues
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -444,8 +444,10 @@ Returns 0 if not found.
|
|||||||
</element>
|
</element>
|
||||||
<!-- function Visibility: default -->
|
<!-- function Visibility: default -->
|
||||||
<element name="FindInvalidUTF8Character">
|
<element name="FindInvalidUTF8Character">
|
||||||
<short/>
|
<short>Returns -1 if ok, otherwise byte index of invalid UTF8 codepoint</short>
|
||||||
<descr/>
|
<descr>It always stops on irregular codepoints. For example Codepoint 0 is normally encoded as #0, but it can also be encoded as #192#0. Because most software does not check this, it can be exploited and is a security risk.
|
||||||
|
|
||||||
|
If StopOnNonUTF8 is false it will ignore undefined codes. For example #128. By default it stops on such codes.</descr>
|
||||||
<errors/>
|
<errors/>
|
||||||
<seealso/>
|
<seealso/>
|
||||||
</element>
|
</element>
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
Standard Quick Fixes - tools to help fixing (compiler) messages.
|
Standard Quick Fixes - tools to help fixing (compiler) messages.
|
||||||
|
|
||||||
ToDo:
|
ToDo:
|
||||||
|
- cant find unit: duplicate include file, e.g. control.inc
|
||||||
- TQuickFixIdentifierNotFoundAddLocal: extend with add private/public
|
- TQuickFixIdentifierNotFoundAddLocal: extend with add private/public
|
||||||
- local var not used: remove declaration and all assignments
|
- local var not used: remove declaration and all assignments
|
||||||
- There is no method in an ancestor class to be overriden:
|
- There is no method in an ancestor class to be overriden:
|
||||||
@ -53,7 +54,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils,
|
||||||
LazLogger, AvgLvlTree, LazFileUtils,
|
LazLogger, AvgLvlTree, LazFileUtils, LazUTF8,
|
||||||
Menus, Dialogs, Controls,
|
Menus, Dialogs, Controls,
|
||||||
CodeToolManager, CodeCache, CodeTree, CodeAtom, BasicCodeTools,
|
CodeToolManager, CodeCache, CodeTree, CodeAtom, BasicCodeTools,
|
||||||
KeywordFuncLists,
|
KeywordFuncLists,
|
||||||
|
@ -26,7 +26,7 @@ unit ModeMatrixOpts;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, contnrs, LazConfigStorage, Laz2_XMLCfg, LazLogger,
|
Classes, SysUtils, contnrs, LazConfigStorage, Laz2_XMLCfg, LazLogger, LazUTF8,
|
||||||
FileProcs, KeywordFuncLists, CodeToolsCfgScript, LazarusIDEStrConsts;
|
FileProcs, KeywordFuncLists, CodeToolsCfgScript, LazarusIDEStrConsts;
|
||||||
|
|
||||||
const
|
const
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
./runtests --format=plain --suite=TestUTF8Trim
|
./runtests --format=plain --suite=TestUTF8Trim
|
||||||
./runtests --format=plain --suite=TestUTF8Pos
|
./runtests --format=plain --suite=TestUTF8Pos
|
||||||
./runtests --format=plain --suite=TestFindInvalidUTF8
|
./runtests --format=plain --suite=TestFindInvalidUTF8
|
||||||
|
./runtests --format=plain --suite=TestUTF8QuotedStr
|
||||||
}
|
}
|
||||||
unit TestLazUTF8;
|
unit TestLazUTF8;
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ type
|
|||||||
procedure TestUTF8Trim;
|
procedure TestUTF8Trim;
|
||||||
procedure TestUTF8Pos;
|
procedure TestUTF8Pos;
|
||||||
procedure TestFindInvalidUTF8;
|
procedure TestFindInvalidUTF8;
|
||||||
|
procedure TestUTF8QuotedStr;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -103,6 +105,24 @@ begin
|
|||||||
t(#$f0#$8f#$bf#$bf,0,'invalid: $ffff encoded as 4 byte');
|
t(#$f0#$8f#$bf#$bf,0,'invalid: $ffff encoded as 4 byte');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestLazUTF8.TestUTF8QuotedStr;
|
||||||
|
|
||||||
|
procedure t(const S, Quote, Expected: string);
|
||||||
|
var
|
||||||
|
Actual: String;
|
||||||
|
begin
|
||||||
|
Actual:=UTF8QuotedStr(S,Quote);
|
||||||
|
AssertEquals('S="'+S+'" Quote="'+Quote+'"',Expected,Actual);
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
t('','=','==');
|
||||||
|
t('','AB','ABAB');
|
||||||
|
t('A','A','AAAA');
|
||||||
|
t('bAb','A','AbAAbA');
|
||||||
|
t('cABc','AB','ABcABABcAB');
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
AddToLazUtilsTestSuite(TTestLazUTF8);
|
AddToLazUtilsTestSuite(TTestLazUTF8);
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ unit TestLazUtils;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, fpcunit, testglobals, LazLogger, LazFileUtils;
|
Classes, SysUtils, fpcunit, testglobals, LazLogger, LazUTF8, LazFileUtils;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user