mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 06:49:12 +02:00
codetools+tests: function to fix xml attribute values
git-svn-id: trunk@32634 -
This commit is contained in:
parent
b758561187
commit
10329ea87b
@ -33,12 +33,16 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, FileProcs, contnrs, BasicCodeTools;
|
Classes, SysUtils, FileProcs, contnrs, BasicCodeTools;
|
||||||
|
|
||||||
|
type
|
||||||
|
PObjectList = ^TObjectList;
|
||||||
|
|
||||||
procedure FixFPDocFragment(var Fragment: string;
|
procedure FixFPDocFragment(var Fragment: string;
|
||||||
AllowTags, // for attribute values set this to false, so that all < are converted
|
AllowTags, // for attribute values set this to false, so that all < are converted
|
||||||
Fix: boolean; // fix errors using heuristics creating valid xml
|
Fix: boolean; // fix errors using heuristics creating valid xml
|
||||||
out ErrorList: TObjectList;
|
ErrorList: PObjectList = nil;
|
||||||
Verbose: boolean = false // write debugln to stdout
|
Verbose: boolean = false // write debugln to stdout
|
||||||
);
|
);
|
||||||
|
procedure FixFPDocAttributeValue(var Value: string);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -51,7 +55,7 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure FixFPDocFragment(var Fragment: string; AllowTags, Fix: boolean;
|
procedure FixFPDocFragment(var Fragment: string; AllowTags, Fix: boolean;
|
||||||
out ErrorList: TObjectList; Verbose: boolean);
|
ErrorList: PObjectList; Verbose: boolean);
|
||||||
{ - Fix all tags to lowercase to reduce svn commits
|
{ - Fix all tags to lowercase to reduce svn commits
|
||||||
- auto close comments
|
- auto close comments
|
||||||
- remove #0 from comments
|
- remove #0 from comments
|
||||||
@ -105,12 +109,13 @@ var
|
|||||||
copy(Fragment,Rel(ErrorPos),LineEnd-Rel(ErrorPos)+1)]);
|
copy(Fragment,Rel(ErrorPos),LineEnd-Rel(ErrorPos)+1)]);
|
||||||
end;
|
end;
|
||||||
if not Fix then exit;
|
if not Fix then exit;
|
||||||
if ErrorList=nil then
|
if ErrorList=nil then exit;
|
||||||
ErrorList:=TObjectList.Create(true);
|
if ErrorList^=nil then
|
||||||
|
ErrorList^:=TObjectList.Create(true);
|
||||||
NewError:=TFPDocFragmentError.Create;
|
NewError:=TFPDocFragmentError.Create;
|
||||||
NewError.ErrorPos:=Rel(ErrorPos);
|
NewError.ErrorPos:=Rel(ErrorPos);
|
||||||
NewError.Msg:=ErrorMsg;
|
NewError.Msg:=ErrorMsg;
|
||||||
ErrorList.Add(NewError);
|
ErrorList^.Add(NewError);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure Replace(StartPos, Len: integer; const NewTxt: string);
|
procedure Replace(StartPos, Len: integer; const NewTxt: string);
|
||||||
@ -486,7 +491,6 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
ErrorList:=nil;
|
|
||||||
if Fragment='' then exit;
|
if Fragment='' then exit;
|
||||||
Top:=-1;
|
Top:=-1;
|
||||||
TopItem:=nil;
|
TopItem:=nil;
|
||||||
@ -514,6 +518,9 @@ begin
|
|||||||
HandleSpecialChar;
|
HandleSpecialChar;
|
||||||
'&':
|
'&':
|
||||||
ParseAmpersand;
|
ParseAmpersand;
|
||||||
|
'"','''':
|
||||||
|
if not AllowTags then
|
||||||
|
HandleSpecialChar;
|
||||||
else
|
else
|
||||||
inc(p);
|
inc(p);
|
||||||
end;
|
end;
|
||||||
@ -530,5 +537,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure FixFPDocAttributeValue(var Value: string);
|
||||||
|
begin
|
||||||
|
FixFPDocFragment(Value,false,true);
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ uses
|
|||||||
// codetools
|
// codetools
|
||||||
CodeAtom, CodeTree, CodeToolManager, FindDeclarationTool, BasicCodeTools,
|
CodeAtom, CodeTree, CodeToolManager, FindDeclarationTool, BasicCodeTools,
|
||||||
KeywordFuncLists, PascalParserTool, CodeCache, CacheCodeTools, CustomCodeTool,
|
KeywordFuncLists, PascalParserTool, CodeCache, CacheCodeTools, CustomCodeTool,
|
||||||
FileProcs,
|
FileProcs, CTXMLFixFragment,
|
||||||
{$IFNDEF OldXMLCfg}
|
{$IFNDEF OldXMLCfg}
|
||||||
Laz2_DOM, Laz2_XMLRead, Laz2_XMLWrite,
|
Laz2_DOM, Laz2_XMLRead, Laz2_XMLWrite,
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
@ -1889,6 +1889,7 @@ begin
|
|||||||
CodeNode:=CodeNode.Parent;
|
CodeNode:=CodeNode.Parent;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
//FixFPDocAttributeValue(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCodeHelpManager.GetFPDocNode(Tool: TCodeTool; CodeNode: TCodeTreeNode;
|
function TCodeHelpManager.GetFPDocNode(Tool: TCodeTool; CodeNode: TCodeTreeNode;
|
||||||
|
@ -1270,29 +1270,23 @@ var
|
|||||||
function SetValue(Item: TFPDocItem): boolean;
|
function SetValue(Item: TFPDocItem): boolean;
|
||||||
var
|
var
|
||||||
NewValue: String;
|
NewValue: String;
|
||||||
ErrorList: TObjectList;
|
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
NewValue:=Values[Item];
|
NewValue:=Values[Item];
|
||||||
ErrorList:=nil;
|
|
||||||
try
|
try
|
||||||
try
|
FixFPDocFragment(NewValue,
|
||||||
FixFPDocFragment(NewValue,
|
Item in [fpdiShort,fpdiDescription,fpdiErrors,fpdiSeeAlso],
|
||||||
Item in [fpdiShort,fpdiDescription,fpdiErrors,fpdiSeeAlso],
|
true);
|
||||||
true,ErrorList);
|
CurDocFile.SetChildValue(TopNode,FPDocItemNames[Item],NewValue);
|
||||||
CurDocFile.SetChildValue(TopNode,FPDocItemNames[Item],NewValue);
|
Result:=true;
|
||||||
Result:=true;
|
except
|
||||||
except
|
on E: EXMLReadError do begin
|
||||||
on E: EXMLReadError do begin
|
DebugLn(['SetValue ',dbgs(E.LineCol),' Name=',FPDocItemNames[Item]]);
|
||||||
DebugLn(['SetValue ',dbgs(E.LineCol),' Name=',FPDocItemNames[Item]]);
|
JumpToError(Item,E.LineCol);
|
||||||
JumpToError(Item,E.LineCol);
|
MessageDlg(lisFPDocFPDocSyntaxError,
|
||||||
MessageDlg(lisFPDocFPDocSyntaxError,
|
Format(lisFPDocThereIsASyntaxErrorInTheFpdocElement, [FPDocItemNames
|
||||||
Format(lisFPDocThereIsASyntaxErrorInTheFpdocElement, [FPDocItemNames
|
[Item], #13#13, E.Message]), mtError, [mbOk], '');
|
||||||
[Item], #13#13, E.Message]), mtError, [mbOk], '');
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
finally
|
|
||||||
FreeAndNil(ErrorList);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
Test individually:
|
Test individually:
|
||||||
./runtests --format=plain --suite=TestFixXMLFragmentComment
|
./runtests --format=plain --suite=TestFixXMLFragmentComment
|
||||||
|
./runtests --format=plain --suite=TestFixXMLValue
|
||||||
}
|
}
|
||||||
unit TestCTXMLFixFragments;
|
unit TestCTXMLFixFragments;
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ unit TestCTXMLFixFragments;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
fpcunit, Classes, SysUtils, FileProcs, contnrs, testglobals, CTXMLFixFragment;
|
fpcunit, Classes, SysUtils, FileProcs, testglobals, CTXMLFixFragment;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -20,7 +21,8 @@ type
|
|||||||
|
|
||||||
TTestCTXMLFixFragment = class(TTestCase)
|
TTestCTXMLFixFragment = class(TTestCase)
|
||||||
protected
|
protected
|
||||||
function Test(Title, Fragment, FixedFragment: string): boolean;
|
function TestFrag(Title, Fragment, FixedFragment: string): boolean;
|
||||||
|
function TestAttr(Title, Value, FixedValue: string): boolean;
|
||||||
published
|
published
|
||||||
procedure TestFixXMLFragmentComment;
|
procedure TestFixXMLFragmentComment;
|
||||||
procedure TestFixXMLFragmentInvalidCharacters;
|
procedure TestFixXMLFragmentInvalidCharacters;
|
||||||
@ -28,76 +30,95 @@ type
|
|||||||
procedure TestFixXMLFragmentAttribute;
|
procedure TestFixXMLFragmentAttribute;
|
||||||
procedure TestFixXMLFragmentCloseTag;
|
procedure TestFixXMLFragmentCloseTag;
|
||||||
procedure TestFixXMLFragmentBugReports;
|
procedure TestFixXMLFragmentBugReports;
|
||||||
|
// attribute value
|
||||||
|
procedure TestFixXMLValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
{ TTestCTXMLFixFragment }
|
{ TTestCTXMLFixFragment }
|
||||||
|
|
||||||
function TTestCTXMLFixFragment.Test(Title, Fragment, FixedFragment: string
|
function TTestCTXMLFixFragment.TestFrag(Title, Fragment, FixedFragment: string
|
||||||
): boolean;
|
): boolean;
|
||||||
var
|
var
|
||||||
s: String;
|
s: String;
|
||||||
ErrorList: TObjectList;
|
|
||||||
begin
|
begin
|
||||||
Result:=true;
|
Result:=true;
|
||||||
try
|
s:=Fragment;
|
||||||
s:=Fragment;
|
FixFPDocFragment(s,true,true,nil,false);
|
||||||
FixFPDocFragment(s,true,true,ErrorList,false);
|
AssertEquals(Title+' fragment: '+DbgStr(Fragment),dbgstr(FixedFragment),dbgstr(s));
|
||||||
AssertEquals(Title+' fragment: '+DbgStr(Fragment),dbgstr(FixedFragment),dbgstr(s));
|
end;
|
||||||
finally
|
|
||||||
ErrorList.Free;
|
function TTestCTXMLFixFragment.TestAttr(Title, Value, FixedValue: string
|
||||||
end;
|
): boolean;
|
||||||
|
var
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
Result:=true;
|
||||||
|
s:=Value;
|
||||||
|
FixFPDocAttributeValue(s);
|
||||||
|
AssertEquals(Title+' value: '+DbgStr(Value),dbgstr(FixedValue),dbgstr(s));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestCTXMLFixFragment.TestFixXMLFragmentComment;
|
procedure TTestCTXMLFixFragment.TestFixXMLFragmentComment;
|
||||||
begin
|
begin
|
||||||
Test('close comment','<!--','<!---->');
|
TestFrag('close comment','<!--','<!---->');
|
||||||
Test('close comment and delete invalid char','<!--null'#0#1#2'comment','<!--nullcomment-->');
|
TestFrag('close comment and delete invalid char','<!--null'#0#1#2'comment','<!--nullcomment-->');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestCTXMLFixFragment.TestFixXMLFragmentInvalidCharacters;
|
procedure TTestCTXMLFixFragment.TestFixXMLFragmentInvalidCharacters;
|
||||||
begin
|
begin
|
||||||
Test('delete special characters','A'#0'B'#1#127,'AB');
|
TestFrag('delete special characters','A'#0'B'#1#127,'AB');
|
||||||
Test('replace tag characters','LT< GT>AMP&','LT< GT>AMP&');
|
TestFrag('replace tag characters','LT< GT>AMP&','LT< GT>AMP&');
|
||||||
Test('lower case special characters','<','<');
|
TestFrag('lower case special characters','<','<');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestCTXMLFixFragment.TestFixXMLFragmentOpenTag;
|
procedure TTestCTXMLFixFragment.TestFixXMLFragmentOpenTag;
|
||||||
begin
|
begin
|
||||||
Test('valid short tag','<link/>','<link/>');
|
TestFrag('valid short tag','<link/>','<link/>');
|
||||||
Test('valid short with empty attribute tag','<link id=""/>','<link id=""/>');
|
TestFrag('valid short with empty attribute tag','<link id=""/>','<link id=""/>');
|
||||||
Test('missing tag name','<>','<>');
|
TestFrag('missing tag name','<>','<>');
|
||||||
Test('lower case tag name','<A></a>','<a></a>');
|
TestFrag('lower case tag name','<A></a>','<a></a>');
|
||||||
Test('invalid character in tag','<a "></a>','<a >"></a>');
|
TestFrag('invalid character in tag','<a "></a>','<a >"></a>');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestCTXMLFixFragment.TestFixXMLFragmentAttribute;
|
procedure TTestCTXMLFixFragment.TestFixXMLFragmentAttribute;
|
||||||
begin
|
begin
|
||||||
Test('lower case attribute name','<a Name=""></a>','<a name=""></a>');
|
TestFrag('lower case attribute name','<a Name=""></a>','<a name=""></a>');
|
||||||
Test('missing attribute equal','<a name ""></a>','<a name =""></a>');
|
TestFrag('missing attribute equal','<a name ""></a>','<a name =""></a>');
|
||||||
Test('missing attribute value','<a name=></a>','<a name=""></a>');
|
TestFrag('missing attribute value','<a name=></a>','<a name=""></a>');
|
||||||
Test('missing attribute quotes','<a name=1></a>','<a name="1"></a>');
|
TestFrag('missing attribute quotes','<a name=1></a>','<a name="1"></a>');
|
||||||
Test('missing attribute ending quote','<a name="1></a>','<a name="1"></a>');
|
TestFrag('missing attribute ending quote','<a name="1></a>','<a name="1"></a>');
|
||||||
Test('invalid character in attribute value','<a name="&"></a>','<a name="&"></a>');
|
TestFrag('invalid character in xml fragment attribute value','<a name="&"></a>','<a name="&"></a>');
|
||||||
Test('amp attribute value','<a name="&"></a>','<a name="&"></a>');
|
TestFrag('amp attribute value','<a name="&"></a>','<a name="&"></a>');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestCTXMLFixFragment.TestFixXMLFragmentCloseTag;
|
procedure TTestCTXMLFixFragment.TestFixXMLFragmentCloseTag;
|
||||||
begin
|
begin
|
||||||
Test('lower case close tag name','<a></A>','<a></a>');
|
TestFrag('lower case close tag name','<a></A>','<a></a>');
|
||||||
Test('close open tag','<a>','<a/>');
|
TestFrag('close open tag','<a>','<a/>');
|
||||||
Test('close open sub tag','<p><a></p>','<p><a/></p>');
|
TestFrag('close open sub tag','<p><a></p>','<p><a/></p>');
|
||||||
Test('disable invalid close tag','</p>','</p>');
|
TestFrag('disable invalid close tag','</p>','</p>');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestCTXMLFixFragment.TestFixXMLFragmentBugReports;
|
procedure TTestCTXMLFixFragment.TestFixXMLFragmentBugReports;
|
||||||
begin
|
begin
|
||||||
Test('15120','operator <(TPoint, TPoint): Boolean',
|
TestFrag('15120','operator <(TPoint, TPoint): Boolean',
|
||||||
'operator <(TPoint, TPoint): Boolean');
|
'operator <(TPoint, TPoint): Boolean');
|
||||||
Test('16671','<br>',
|
TestFrag('16671','<br>',
|
||||||
'<br/>');
|
'<br/>');
|
||||||
Test('18800','<link id="foo"/>','<link id="foo"/>');
|
TestFrag('18800','<link id="foo"/>','<link id="foo"/>');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestCTXMLFixFragment.TestFixXMLValue;
|
||||||
|
begin
|
||||||
|
TestAttr('invalid character in xml attribute value','operator<','operator<');
|
||||||
|
TestAttr('correct character in xml attribute value','&','&');
|
||||||
|
TestAttr('lower case character name in attribute value','&','&');
|
||||||
|
TestAttr('" in attribute value','"','"');
|
||||||
|
TestAttr(''' in attribute value','''',''');
|
||||||
|
TestAttr('< in attribute value','<','<');
|
||||||
|
TestAttr('> in attribute value','>','>');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
@ -129,6 +129,12 @@
|
|||||||
<StackChecks Value="True"/>
|
<StackChecks Value="True"/>
|
||||||
</Checks>
|
</Checks>
|
||||||
</CodeGeneration>
|
</CodeGeneration>
|
||||||
|
<Linking>
|
||||||
|
<Debugging>
|
||||||
|
<GenerateDebugInfo Value="True"/>
|
||||||
|
<DebugInfoType Value="dsAuto"/>
|
||||||
|
</Debugging>
|
||||||
|
</Linking>
|
||||||
<Other>
|
<Other>
|
||||||
<CompilerMessages>
|
<CompilerMessages>
|
||||||
<UseMsgFile Value="True"/>
|
<UseMsgFile Value="True"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user