mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 19:08:15 +02:00
Merged revision 30573 from http://svn.freepascal.org/svn/fpc/trunk
------------------------------------------------------------------------ r30573 | pierre | 2015-04-13 18:40:27 +0200 (Mon, 13 Apr 2015) | 1 line Changed paths: M /trunk/ide/wini.pas Use pascal style doubling of quote char instead of C style escaping for ini file ------------------------------------------------------------------------ git-svn-id: branches/fixes_3_0@31754 -
This commit is contained in:
parent
88d00ef331
commit
81a6f3ea2a
@ -612,7 +612,7 @@ begin
|
||||
{ Files }
|
||||
{ avoid keeping old files }
|
||||
INIFile^.DeleteSection(secFiles);
|
||||
INIFile^.SetEntry(secFiles,ieOpenExts,'"'+OpenExts+'"');
|
||||
INIFile^.SetEntry(secFiles,ieOpenExts,EscapeIniText(OpenExts));
|
||||
for I:=1 to High(RecentFiles) do
|
||||
begin
|
||||
if I<=RecentFileCount then
|
||||
@ -678,17 +678,17 @@ begin
|
||||
{ Help }
|
||||
S:='';
|
||||
HelpFiles^.ForEach(@ConcatName);
|
||||
INIFile^.SetEntry(secHelp,ieHelpFiles,'"'+S+'"');
|
||||
INIFile^.SetEntry(secHelp,ieHelpFiles,EscapeIniText(S));
|
||||
{ Editor }
|
||||
INIFile^.SetIntEntry(secEditor,ieDefaultTabSize,DefaultTabSize);
|
||||
INIFile^.SetIntEntry(secEditor,ieDefaultIndentSize,DefaultIndentSize);
|
||||
INIFile^.SetIntEntry(secEditor,ieDefaultEditorFlags,DefaultCodeEditorFlags);
|
||||
INIFile^.SetEntry(secEditor,ieDefaultSaveExt,DefaultSaveExt);
|
||||
{ Highlight }
|
||||
INIFile^.SetEntry(secHighlight,ieHighlightExts,'"'+HighlightExts+'"');
|
||||
INIFile^.SetEntry(secHighlight,ieTabsPattern,'"'+TabsPattern+'"');
|
||||
INIFile^.SetEntry(secHighlight,ieHighlightExts,EscapeIniText(HighlightExts));
|
||||
INIFile^.SetEntry(secHighlight,ieTabsPattern,EscapeIniText(TabsPattern));
|
||||
{ SourcePath }
|
||||
INIFile^.SetEntry(secSourcePath,ieSourceList,'"'+SourceDirs+'"');
|
||||
INIFile^.SetEntry(secSourcePath,ieSourceList,EscapeIniText(SourceDirs));
|
||||
{ Mouse }
|
||||
INIFile^.SetIntEntry(secMouse,ieDoubleClickDelay,DoubleDelay);
|
||||
INIFile^.SetIntEntry(secMouse,ieReverseButtons,byte(MouseReverse));
|
||||
@ -718,9 +718,9 @@ begin
|
||||
begin
|
||||
S:=IntToStr(I);
|
||||
GetToolParams(I-1,S1,S2,S3,W);
|
||||
if S1<>'' then S1:='"'+S1+'"';
|
||||
if S2<>'' then S2:='"'+S2+'"';
|
||||
if S3<>'' then S3:='"'+S3+'"';
|
||||
if S1<>'' then S1:=EscapeIniText(S1);
|
||||
if S2<>'' then S2:=EscapeIniText(S2);
|
||||
if S3<>'' then S3:=EscapeIniText(S3);
|
||||
INIFile^.SetEntry(secTools,ieToolName+S,S1);
|
||||
INIFile^.SetEntry(secTools,ieToolProgram+S,S2);
|
||||
INIFile^.SetEntry(secTools,ieToolParams+S,S3);
|
||||
|
140
ide/wini.pas
140
ide/wini.pas
@ -23,11 +23,13 @@ type
|
||||
PINIEntry = ^TINIEntry;
|
||||
TINIEntry = object(TObject)
|
||||
constructor Init(const ALine: string);
|
||||
constructor Init(const ATag,AValue,AComment: string);
|
||||
function GetText: string;
|
||||
function GetTag: string;
|
||||
function GetComment: string;
|
||||
function GetValue: string;
|
||||
procedure SetValue(const S: string);
|
||||
procedure SetComment(const S: string);
|
||||
destructor Done; virtual;
|
||||
private
|
||||
TagHash : Cardinal;
|
||||
@ -44,6 +46,7 @@ type
|
||||
constructor Init(const AName: string);
|
||||
function GetName: string;
|
||||
function AddEntry(const S: string): PINIEntry;
|
||||
function AddEntry(const Tag,Value,Comment: string): PINIEntry;
|
||||
function SearchEntry(Tag: string): PINIEntry; virtual;
|
||||
procedure DeleteEntry(Tag: string);
|
||||
procedure ForEachEntry(EnumProc: pointer); virtual;
|
||||
@ -68,6 +71,7 @@ type
|
||||
procedure ForEachEntry(const Section: string; EnumProc: pointer); virtual;
|
||||
function GetEntry(const Section, Tag, Default: string): string; virtual;
|
||||
procedure SetEntry(const Section, Tag, Value: string); virtual;
|
||||
procedure SetEntry(const Section, Tag, Value,Comment: string); virtual;
|
||||
function GetIntEntry(const Section, Tag: string; Default: longint): longint; virtual;
|
||||
procedure SetIntEntry(const Section, Tag: string; Value: longint); virtual;
|
||||
procedure DeleteSection(const Section: string); virtual;
|
||||
@ -83,11 +87,38 @@ const MainSectionName : string[40] = 'MainSection';
|
||||
CommentChar : char = ';';
|
||||
ValidStrDelimiters: set of char = ['''','"'];
|
||||
|
||||
function EscapeIniText(S : string) : String;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
WUtils;
|
||||
|
||||
function EscapeIniText(S : string) : String;
|
||||
var
|
||||
delimiter : char;
|
||||
i: integer;
|
||||
begin
|
||||
delimiter:=#0;
|
||||
while delimiter < #255 do
|
||||
begin
|
||||
if (delimiter in ValidStrDelimiters) and
|
||||
(pos(delimiter,S)=0) then
|
||||
break;
|
||||
delimiter:=succ(delimiter);
|
||||
end;
|
||||
if delimiter=#255 then
|
||||
begin
|
||||
{ we use " delimiter, but the text also contains double quotes,
|
||||
which need to be escaped, by doubling it }
|
||||
delimiter:='"';
|
||||
for i:=length(s) downto 1 do
|
||||
if (s[i]=delimiter) then
|
||||
s:=copy(s,1,i-1)+delimiter+copy(s,i+1,length(s));
|
||||
end;
|
||||
EscapeIniText:=delimiter+s+delimiter;
|
||||
end;
|
||||
|
||||
{$IFOPT Q+}
|
||||
{$Q-}
|
||||
{$DEFINE REENABLE_Q}
|
||||
@ -120,11 +151,18 @@ begin
|
||||
Split;
|
||||
end;
|
||||
|
||||
constructor TINIEntry.Init(const ATag,AValue,AComment: string);
|
||||
begin
|
||||
inherited Init;
|
||||
Tag:=NewStr(ATag);
|
||||
Value:=NewStr(AValue);
|
||||
Comment:=NewStr(AComment);
|
||||
Text:=NewStr(GetText);
|
||||
end;
|
||||
|
||||
|
||||
function TINIEntry.GetText: string;
|
||||
var S,CoS: string;
|
||||
delimiter : char;
|
||||
i : longint;
|
||||
begin
|
||||
if Text=nil then
|
||||
begin
|
||||
@ -135,26 +173,7 @@ begin
|
||||
begin
|
||||
{ if Value contains CommentChar, we need to add delimiters }
|
||||
if pos(CommentChar,S)>0 then
|
||||
begin
|
||||
delimiter:=#0;
|
||||
while delimiter < #255 do
|
||||
begin
|
||||
if (delimiter in ValidStrDelimiters) and
|
||||
(pos(delimiter,S)=0) then
|
||||
break;
|
||||
delimiter:=succ(delimiter);
|
||||
end;
|
||||
if delimiter=#255 then
|
||||
delimiter:='"';
|
||||
{ we use \", but we also need to escape \ itself }
|
||||
for i:=length(s) downto 1 do
|
||||
if (s[i]=delimiter) then
|
||||
s:=copy(s,1,i-1)+'\'+delimiter+copy(s,i+1,length(s))
|
||||
else if (s[i]='\') then
|
||||
s:=copy(s,1,i-1)+'\\'+copy(s,i+1,length(s));
|
||||
|
||||
s:=delimiter+s+delimiter;
|
||||
end;
|
||||
S:=EscapeIniText(S);
|
||||
S:=S+' '+CommentChar+' '+CoS;
|
||||
end
|
||||
end
|
||||
@ -192,6 +211,17 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TINIEntry.SetComment(const S: string);
|
||||
begin
|
||||
if (GetComment<>S) then
|
||||
begin
|
||||
if Text<>nil then DisposeStr(Text); Text:=nil;
|
||||
if Comment<>nil then DisposeStr(Comment);
|
||||
Comment:=NewStr(S);
|
||||
Modified:=true;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TINIEntry.Split;
|
||||
var S,ValueS: string;
|
||||
@ -201,7 +231,8 @@ var S,ValueS: string;
|
||||
InString: boolean;
|
||||
Delimiter: char;
|
||||
begin
|
||||
S:=GetText; Delimiter:=#0;
|
||||
S:=GetText;
|
||||
Delimiter:=#0;
|
||||
P:=Pos('=',S); P2:=Pos(CommentChar,S);
|
||||
if (P2<>0) and (P2<P) then
|
||||
P:=0;
|
||||
@ -219,15 +250,14 @@ begin
|
||||
Delimiter:=C;
|
||||
InString:=true;
|
||||
end
|
||||
{ if Value is delimited with ' or ", handle escaping }
|
||||
else if (Delimiter<>#0) and (C='\') and (P2<length(S)) then
|
||||
else if (C=Delimiter) then
|
||||
begin
|
||||
inc(P2);
|
||||
C:=S[P2];
|
||||
ValueS:=ValueS+C;
|
||||
{ Delimiter inside escaped Value are simply doubled }
|
||||
if (P2+1<length(S)) and (S[P2+1]=Delimiter) then
|
||||
ValueS:=ValueS+Delimiter
|
||||
else
|
||||
InString:=not InString;
|
||||
end
|
||||
else if C=Delimiter then
|
||||
InString:=not InString
|
||||
else if (C=CommentChar) and (InString=false) then
|
||||
Break
|
||||
else
|
||||
@ -280,10 +310,47 @@ begin
|
||||
end;
|
||||
|
||||
function TINISection.AddEntry(const S: string): PINIEntry;
|
||||
var
|
||||
E: PINIEntry;
|
||||
Tag : String;
|
||||
begin
|
||||
if pos('=',S)>0 then
|
||||
begin
|
||||
Tag:=copy(S,1,pos('=',S)-1);
|
||||
E:=SearchEntry(Tag);
|
||||
end
|
||||
else
|
||||
E:=nil;
|
||||
if not assigned(E) then
|
||||
begin
|
||||
New(E, Init(S));
|
||||
Entries^.Insert(E);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if assigned(E^.Text) then
|
||||
DisposeStr(E^.Text);
|
||||
E^.Text:=NewStr(S);
|
||||
E^.Split;
|
||||
end;
|
||||
AddEntry:=E;
|
||||
end;
|
||||
|
||||
function TINISection.AddEntry(const Tag,Value,Comment: string): PINIEntry;
|
||||
var E: PINIEntry;
|
||||
begin
|
||||
New(E, Init(S));
|
||||
Entries^.Insert(E);
|
||||
E:=SearchEntry(Tag);
|
||||
if not assigned(E) then
|
||||
begin
|
||||
New(E, Init(Tag,Value,Comment));
|
||||
Entries^.Insert(E);
|
||||
end
|
||||
else
|
||||
begin
|
||||
E^.SetValue(Value);
|
||||
if Comment<>'' then
|
||||
E^.SetComment(Comment);
|
||||
end;
|
||||
AddEntry:=E;
|
||||
end;
|
||||
|
||||
@ -511,7 +578,7 @@ begin
|
||||
GetEntry:=S;
|
||||
end;
|
||||
|
||||
procedure TINIFile.SetEntry(const Section, Tag, Value: string);
|
||||
procedure TINIFile.SetEntry(const Section, Tag, Value,Comment: string);
|
||||
var E: PINIEntry;
|
||||
P: PINISection;
|
||||
begin
|
||||
@ -525,13 +592,18 @@ begin
|
||||
New(P, Init(Section));
|
||||
Sections^.Insert(P);
|
||||
end;
|
||||
E:=P^.AddEntry(Tag+'='+Value);
|
||||
E:=P^.AddEntry(Tag,Value,Comment);
|
||||
E^.Modified:=true;
|
||||
end;
|
||||
if E<>nil then
|
||||
E^.SetValue(Value);
|
||||
end;
|
||||
|
||||
procedure TINIFile.SetEntry(const Section, Tag, Value: string);
|
||||
begin
|
||||
SetEntry(Section,Tag,Value,'');
|
||||
end;
|
||||
|
||||
function TINIFile.GetIntEntry(const Section, Tag: string; Default: longint): longint;
|
||||
var L: longint;
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user