From 8c63be40f9b8def7547e158d0905e742bfc87131 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 11 Sep 2016 08:04:36 +0000 Subject: [PATCH] * Fix bug ID #24983: additional possibilities for boolean reading/writing git-svn-id: trunk@34506 - --- .gitattributes | 1 + packages/fcl-base/src/inifiles.pp | 72 +++++++++++++- packages/fcl-base/tests/fclbase-unittests.lpi | 6 +- packages/fcl-base/tests/fclbase-unittests.pp | 2 +- packages/fcl-base/tests/tcinifile.pp | 98 +++++++++++++++++++ 5 files changed, 173 insertions(+), 6 deletions(-) create mode 100644 packages/fcl-base/tests/tcinifile.pp diff --git a/.gitattributes b/.gitattributes index c04a07bc71..8032119a56 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2076,6 +2076,7 @@ packages/fcl-base/src/wtex.pp svneol=native#text/plain packages/fcl-base/tests/fclbase-unittests.lpi svneol=native#text/plain packages/fcl-base/tests/fclbase-unittests.pp svneol=native#text/plain packages/fcl-base/tests/tchashlist.pp svneol=native#text/plain +packages/fcl-base/tests/tcinifile.pp svneol=native#text/plain packages/fcl-base/tests/tcmaskutils.pp svneol=native#text/plain packages/fcl-base/tests/testexprpars.pp svneol=native#text/plain packages/fcl-base/tests/tests_fptemplate.pp svneol=native#text/plain diff --git a/packages/fcl-base/src/inifiles.pp b/packages/fcl-base/src/inifiles.pp index 6ecd2be960..1587f98254 100644 --- a/packages/fcl-base/src/inifiles.pp +++ b/packages/fcl-base/src/inifiles.pp @@ -139,7 +139,9 @@ type ifoEscapeLineFeeds, // Escape linefeeds when reading file. ifoCaseSensitive, // Use Case sensitive section/key names ifoStripQuotes, // Strip quotes when reading string values. - ifoFormatSettingsActive); // Use format settings when writing date/float etc. + ifoFormatSettingsActive, // Use format settings when writing date/float etc. + ifoWriteStringBoolean // Write booleans as string + ); TIniFileOptions = Set of TIniFileOption; TSectionValuesOption = (svoIncludeComments,svoIncludeInvalid, svoIncludeQuotes); @@ -149,6 +151,8 @@ type TCustomIniFile = class Private + FBoolFalseStrings: TStringArray; + FBoolTrueStrings: TStringArray; FFileName: string; FOptions: TIniFileOptions; FSectionList: TIniFileSectionList; @@ -160,6 +164,7 @@ type constructor Create(const AFileName: string; AOptions : TIniFileOptions = []); virtual; constructor Create(const AFileName: string; AEscapeLineFeeds : Boolean); virtual; destructor Destroy; override; + Procedure SetBoolStringValues(ABoolValue : Boolean; Values : Array of string); function SectionExists(const Section: string): Boolean; virtual; function ReadString(const Section, Ident, Default: string): string; virtual; abstract; procedure WriteString(const Section, Ident, Value: String); virtual; abstract; @@ -193,6 +198,8 @@ type Property CaseSensitive : Boolean index ifoCaseSensitive Read GetOption Write SetOption; deprecated 'Use options instead'; Property StripQuotes : Boolean index ifoStripQuotes Read GetOption Write SetOption; deprecated 'Use options instead'; Property FormatSettingsActive : Boolean index ifoFormatSettingsActive Read GetOption Write SetOption;deprecated 'Use options instead'; + Property BoolTrueStrings : TStringArray Read FBoolTrueStrings Write FBoolTrueStrings; + Property BoolFalseStrings : TStringArray Read FBoolFalseStrings Write FBoolFalseStrings; end; { TIniFile } @@ -598,6 +605,23 @@ begin inherited Destroy; end; +procedure TCustomIniFile.SetBoolStringValues(ABoolValue: Boolean; + Values: array of string); + +Var + A : TstringArray; + I : Integer; + +begin + SetLength(A,Length(Values)); + For I:=0 to length(Values)-1 do + A[i]:=Values[i]; + If AboolValue then + FBoolTrueStrings:=A + else + FBoolFalseStrings:=A; +end; + function TCustomIniFile.SectionExists(const Section: string): Boolean; Var @@ -630,19 +654,59 @@ begin WriteString(Section, Ident, IntToStr(Value)); end; +function IndexOfString(A : TStringArray; S : String) : integer; + +begin + Result:=Length(A)-1; + While (Result>=0) and (CompareText(A[Result],S)<>0) do + Dec(Result); +end; + function TCustomIniFile.ReadBool(const Section, Ident: string; Default: Boolean): Boolean; + var s: string; begin Result := Default; - s := ReadString(Section, Ident, ''); + s:=ReadString(Section, Ident, ''); if s > '' then - Result := CharToBool(s[1]); + if (Length(FBoolTrueStrings)>0) or (Length(FBoolFalseStrings)>0) then + begin + if IndexOfString(FBoolTrueStrings,S)>=0 then + Result:=True + else if IndexOfString(FBoolFalseStrings,S)>=0 then + Result:=False + end + else + Result := CharToBool(s[1]); end; procedure TCustomIniFile.WriteBool(const Section, Ident: string; Value: Boolean); + +Var + S : String; + begin - WriteString(Section, Ident, BoolToChar(Value)); + if (ifoWriteStringBoolean in options) then + begin + if Value then + begin + if Length(BoolTrueStrings)>0 then + S:=BoolTrueStrings[0] + else + S:='true'; + end + else + begin + if Length(BoolFalseStrings)>0 then + S:=BoolFalseStrings[0] + else + S:='false'; + end; + end + else + S:=BoolToChar(Value); + WriteString(Section, Ident, S); end; function TCustomIniFile.ReadDate(const Section, Ident: string; Default: TDateTime): TDateTime; diff --git a/packages/fcl-base/tests/fclbase-unittests.lpi b/packages/fcl-base/tests/fclbase-unittests.lpi index 435bfa30a0..c6beac3fa6 100644 --- a/packages/fcl-base/tests/fclbase-unittests.lpi +++ b/packages/fcl-base/tests/fclbase-unittests.lpi @@ -33,7 +33,7 @@ - + @@ -51,6 +51,10 @@ + + + + diff --git a/packages/fcl-base/tests/fclbase-unittests.pp b/packages/fcl-base/tests/fclbase-unittests.pp index 9ae760417b..479c2ed93b 100644 --- a/packages/fcl-base/tests/fclbase-unittests.pp +++ b/packages/fcl-base/tests/fclbase-unittests.pp @@ -4,7 +4,7 @@ program fclbase_unittests; uses Classes, consoletestrunner, tests_fptemplate, tchashlist, - testexprpars, tcmaskutils; + testexprpars, tcmaskutils, tcinifile; var Application: TTestRunner; diff --git a/packages/fcl-base/tests/tcinifile.pp b/packages/fcl-base/tests/tcinifile.pp new file mode 100644 index 0000000000..7fa12dcf46 --- /dev/null +++ b/packages/fcl-base/tests/tcinifile.pp @@ -0,0 +1,98 @@ +unit tcinifile; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, fpcunit, testutils, inifiles, testregistry; + +type + + { TTestIniFile } + + TTestIniFile= class(TTestCase) + private + Fini: TCustomIniFile; + protected + Procedure CreateIni; + procedure SetUp; override; + procedure TearDown; override; + Property Ini : TCustomIniFile Read Fini; + published + procedure TestWriteBoolean; + procedure TestReadBoolean; + end; + +implementation + +procedure TTestIniFile.CreateIni; + +begin + Fini:=TMemIniFIle.Create('tmp.ini'); +end; + +procedure TTestIniFile.TestWriteBoolean; + +begin + CreateIni; + Ini.WriteBool('a','b',true); + AssertEquals('Default true','1',Ini.ReadString('a','b','')); + Ini.WriteBool('a','b',False); + AssertEquals('Default false','0',Ini.ReadString('a','b','')); + Ini.Options:=Ini.Options+[ifoWriteStringBoolean]; + Ini.WriteBool('a','b',true); + AssertEquals('Default string true','true',Ini.ReadString('a','b','')); + Ini.WriteBool('a','b',false); + AssertEquals('Default string false','false',Ini.ReadString('a','b','')); + Ini.SetBoolStringValues(true,['t','true']); + Ini.WriteBool('a','b',true); + AssertEquals('True from string array','t',Ini.ReadString('a','b','')); + Ini.SetBoolStringValues(false,['f','false']); + Ini.WriteBool('a','b',false); + AssertEquals('True from string array','f',Ini.ReadString('a','b','')); +end; + +procedure TTestIniFile.TestReadBoolean; +begin + CreateIni; + Ini.WriteString('a','b','1'); + AssertEquals('Default true',true,Ini.ReadBool('a','b',False)); + Ini.WriteString('a','b','0'); + AssertEquals('Default false',false,Ini.ReadBool('a','b',True)); + Ini.WriteString('a','b',''); + AssertEquals('Empty returns Default ',true,Ini.ReadBool('a','b',true)); + Ini.SetBoolStringValues(true,['t','true']); + Ini.WriteString('a','b','t'); + AssertEquals('First string match',true,Ini.ReadBool('a','b',false)); + Ini.WriteString('a','b','true'); + AssertEquals('Second string match',true,Ini.ReadBool('a','b',false)); + Ini.WriteString('a','b','d'); + AssertEquals('No string match, default',true,Ini.ReadBool('a','b',true)); + Ini.SetBoolStringValues(true,[]); + Ini.SetBoolStringValues(false,['f','false']); + Ini.WriteString('a','b','f'); + AssertEquals('First string match',false,Ini.ReadBool('a','b',true)); + Ini.WriteString('a','b','false'); + AssertEquals('Second string match',false,Ini.ReadBool('a','b',true)); + Ini.WriteString('a','b','d'); + AssertEquals('No string match, default',false,Ini.ReadBool('a','b',false)); + Ini.SetBoolStringValues(true,['t','true']); + AssertEquals('No string match, default',false,Ini.ReadBool('a','b',false)); +end; + +procedure TTestIniFile.SetUp; +begin + DeleteFile('tmp.ini'); +end; + +procedure TTestIniFile.TearDown; +begin + DeleteFile('tmp.ini'); +end; + +initialization + + RegisterTest(TTestIniFile); +end. +