|
@@ -0,0 +1,490 @@
|
|
|
+{
|
|
|
+ $Id$
|
|
|
+ This file is part of the Free Component Library (FCL)
|
|
|
+ Copyright (c) 1999-2000 by Michael A. Hess
|
|
|
+
|
|
|
+ Old inifiles unit adapted for fpcmake
|
|
|
+
|
|
|
+ This program is distributed in the hope that it will be useful,
|
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
+
|
|
|
+ **********************************************************************}
|
|
|
+
|
|
|
+unit MakeIni;
|
|
|
+
|
|
|
+{$mode objfpc}
|
|
|
+{$H+}
|
|
|
+
|
|
|
+interface
|
|
|
+
|
|
|
+uses Classes;
|
|
|
+
|
|
|
+type
|
|
|
+
|
|
|
+{ TIniFile class }
|
|
|
+
|
|
|
+ TIniFile = class(TObject)
|
|
|
+ private
|
|
|
+ FEscapeLineFeeds : Boolean;
|
|
|
+ FFileName : string;
|
|
|
+ FStream : TStream;
|
|
|
+ FFileBuffer : TStringList;
|
|
|
+ function GetName(const line : string) : string;
|
|
|
+ function GetValue(const line, name : string) : string;
|
|
|
+ function IsComment(const line : string) : boolean;
|
|
|
+ function IsSection(const line : string) : boolean;
|
|
|
+ function GetSectionIndex(const section : string) : integer;
|
|
|
+ protected
|
|
|
+ procedure SetFileName(const fn:string);
|
|
|
+ procedure SetStream(s:TStream);
|
|
|
+ procedure LoadFromFile;
|
|
|
+ procedure SaveToFile;
|
|
|
+ procedure LoadFromStream;
|
|
|
+ procedure SaveToStream;
|
|
|
+ public
|
|
|
+ constructor Create(const theFileName : string);
|
|
|
+ constructor Create(s:TStream);
|
|
|
+ destructor Destroy; override;
|
|
|
+ procedure DeleteKey(const section, ident : string);
|
|
|
+ procedure EraseSection(const section : string);
|
|
|
+ function ReadBool(const section, ident : string; defaultValue : boolean) : boolean;
|
|
|
+ function ReadInteger(const section, ident : string; defaultValue : longint) : longint;
|
|
|
+ procedure ReadSection(const section : string; strings : TStrings);
|
|
|
+ procedure ReadSections(strings : TStrings);
|
|
|
+ procedure ReadSectionValues(const section : string; strings : TStrings);
|
|
|
+ procedure ReadSectionRaw(const section : string; strings : TStrings);
|
|
|
+ function ReadString(const section, ident, defaultValue : string) : string;
|
|
|
+ procedure WriteBool(const section, ident : string; value : boolean);
|
|
|
+ procedure WriteInteger(const section, ident : string; value : longint);
|
|
|
+ procedure WriteString(const section, ident, value : string);
|
|
|
+ property FileName : String read FFileName;
|
|
|
+ property EscapeLineFeeds : Boolean Read FEscapeLineFeeds Write FEscapeLineFeeds default false;
|
|
|
+ end;
|
|
|
+
|
|
|
+implementation
|
|
|
+
|
|
|
+uses SysUtils;
|
|
|
+
|
|
|
+const
|
|
|
+ brackets : array[0..1] of Char = ('[', ']');
|
|
|
+ separator : Char = '=';
|
|
|
+ comment : Char = ';';
|
|
|
+
|
|
|
+
|
|
|
+{ TIniFile }
|
|
|
+
|
|
|
+constructor TIniFile.Create(const theFileName : string);
|
|
|
+begin
|
|
|
+ FFileName := theFileName;
|
|
|
+ FStream:=nil;
|
|
|
+ FEscapeLineFeeds:=False;
|
|
|
+ FFileBuffer := TStringList.Create;
|
|
|
+
|
|
|
+ if FileExists(fileName) then
|
|
|
+ LoadFromFile;
|
|
|
+end;
|
|
|
+
|
|
|
+constructor TIniFile.Create(s:TStream);
|
|
|
+begin
|
|
|
+ FFileName := '';
|
|
|
+ FStream:=s;
|
|
|
+ FEscapeLineFeeds:=False;
|
|
|
+ FFileBuffer := TStringList.Create;
|
|
|
+ LoadFromStream;
|
|
|
+end;
|
|
|
+
|
|
|
+destructor TIniFile.Destroy;
|
|
|
+begin
|
|
|
+ FFileBuffer.Free;
|
|
|
+end;
|
|
|
+
|
|
|
+function TIniFile.GetName(const line : string) : string;
|
|
|
+var
|
|
|
+ index,index2 : integer;
|
|
|
+begin
|
|
|
+ Result := '';
|
|
|
+ index := Pos(separator, line);
|
|
|
+ if index <> 0 then
|
|
|
+ begin
|
|
|
+ index2:=Pos(comment, line);
|
|
|
+ if (index2=0) or (index2>index) then
|
|
|
+ result := Trim(Copy(line, 1, index - 1));
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TIniFile.GetValue(const line, name : string) : string;
|
|
|
+var
|
|
|
+ index1,index2,index3 : integer;
|
|
|
+begin
|
|
|
+ result := '';
|
|
|
+ if (line <> '') and (name <> '') then
|
|
|
+ begin
|
|
|
+ index1 := Pos(name, line);
|
|
|
+ index2 := Pos(separator, line);
|
|
|
+ index3 := Pos(comment, line);
|
|
|
+ if index3=0 then
|
|
|
+ index3:=MaxInt;
|
|
|
+ if (index1 <> 0) and (index2 <> 0) and (index2 > index1) then
|
|
|
+ result := Trim(Copy(line, index2 + 1, index3));
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TIniFile.IsSection(const line : string) : boolean;
|
|
|
+var
|
|
|
+ str : string;
|
|
|
+begin
|
|
|
+ result := False;
|
|
|
+ if line <> '' then
|
|
|
+ begin
|
|
|
+ str := Trim(line);
|
|
|
+ if (str[1] = brackets[0]) and (str[Length(str)] = brackets[1]) then
|
|
|
+ result := True;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TIniFile.IsComment(const line : string) : boolean;
|
|
|
+var
|
|
|
+ str : string;
|
|
|
+begin
|
|
|
+ result := False;
|
|
|
+ if line <> '' then
|
|
|
+ begin
|
|
|
+ str := Trim(line);
|
|
|
+ result := (str[1]=comment);
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TIniFile.GetSectionIndex(const section : string) : integer;
|
|
|
+begin
|
|
|
+ result := FFileBuffer.IndexOf(brackets[0] + section + brackets[1]);
|
|
|
+end;
|
|
|
+
|
|
|
+{ Load/Save }
|
|
|
+
|
|
|
+procedure TIniFile.SetFileName(const fn:string);
|
|
|
+begin
|
|
|
+ FFileName:=fn;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TIniFile.SetStream(s:TStream);
|
|
|
+begin
|
|
|
+ FStream:=s;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TIniFile.LoadFromFile;
|
|
|
+begin
|
|
|
+ if FFileName<>'' then
|
|
|
+ FFileBuffer.LoadFromFile(FFileName);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TIniFile.SaveToFile;
|
|
|
+begin
|
|
|
+ if FFileName<>'' then
|
|
|
+ FFileBuffer.SaveToFile(FFileName);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TIniFile.LoadFromStream;
|
|
|
+begin
|
|
|
+ if assigned(FStream) then
|
|
|
+ FFileBuffer.LoadFromStream(FStream);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TIniFile.SaveToStream;
|
|
|
+begin
|
|
|
+ if assigned(FStream) then
|
|
|
+ FFileBuffer.SaveToStream(FStream);
|
|
|
+end;
|
|
|
+
|
|
|
+{ Read all Names of one Section }
|
|
|
+
|
|
|
+procedure TIniFile.ReadSection(const section : string; strings : TStrings);
|
|
|
+var
|
|
|
+ index : integer;
|
|
|
+ name : string;
|
|
|
+begin
|
|
|
+ strings.BeginUpdate;
|
|
|
+ try
|
|
|
+ strings.Clear;
|
|
|
+ if FFileBuffer.Count > 0 then
|
|
|
+ begin
|
|
|
+ index := GetSectionIndex(section);
|
|
|
+ if index <> -1 then
|
|
|
+ begin
|
|
|
+ Inc(index);
|
|
|
+ while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) do
|
|
|
+ begin
|
|
|
+ name := GetName(FFileBuffer[index]);
|
|
|
+ if name <> '' then
|
|
|
+ strings.Add(name);
|
|
|
+ Inc(index);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ finally
|
|
|
+ strings.EndUpdate;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+{ Read all Sections of the Ini-File }
|
|
|
+
|
|
|
+procedure TIniFile.ReadSections(strings : TStrings);
|
|
|
+var
|
|
|
+ index : integer;
|
|
|
+ section : string;
|
|
|
+begin
|
|
|
+ strings.BeginUpdate;
|
|
|
+ try
|
|
|
+ strings.Clear;
|
|
|
+ if FFileBuffer.Count > 0 then
|
|
|
+ begin
|
|
|
+ index := 0;
|
|
|
+ while (index < FFileBuffer.Count) do
|
|
|
+ begin
|
|
|
+ if IsSection(FFileBuffer[index]) then
|
|
|
+ begin
|
|
|
+ section := Trim(FFileBuffer[index]);
|
|
|
+ Delete(section, 1, 1);
|
|
|
+ Delete(section, Length(section), 1);
|
|
|
+ strings.Add(Trim(section));
|
|
|
+ end;
|
|
|
+ Inc(index);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ finally
|
|
|
+ strings.EndUpdate;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+{ Reads a String-Value of "ident" in one "section".
|
|
|
+ The result is "defaultValue" if
|
|
|
+ o section doesn't exists
|
|
|
+ o ident doesn't exists
|
|
|
+ o ident doesn't have any assigned value }
|
|
|
+
|
|
|
+function TIniFile.ReadString(const section, ident, defaultValue : string) : string;
|
|
|
+var
|
|
|
+ index : integer;
|
|
|
+ value : string;
|
|
|
+begin
|
|
|
+ result := defaultValue;
|
|
|
+ if FFileBuffer.Count > 0 then
|
|
|
+ begin
|
|
|
+ index := GetSectionIndex(section);
|
|
|
+ if index <> -1 then
|
|
|
+ begin
|
|
|
+ Inc(index);
|
|
|
+ while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) do
|
|
|
+ begin
|
|
|
+ if CompareText(GetName(FFileBuffer[index]),ident)=0 then
|
|
|
+ begin
|
|
|
+ value := GetValue(FFileBuffer[index], ident);
|
|
|
+ if value <> '' then
|
|
|
+ begin
|
|
|
+ result := value;
|
|
|
+ if EscapeLineFeeds and (result[length(result)]='\') then
|
|
|
+ begin
|
|
|
+ inc(index);
|
|
|
+ while (index < FFileBuffer.Count) and (result[length(result)]='\') do
|
|
|
+ begin
|
|
|
+ result:=Copy(result,1,length(result)-1)+Trim(FFileBuffer[index]);
|
|
|
+ inc(index);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ break;
|
|
|
+ end;
|
|
|
+ Inc(index);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+{ Reads an Integer-Value of Ident in one Section }
|
|
|
+
|
|
|
+function TIniFile.ReadInteger(const section, ident : string; defaultValue : longint) : longint;
|
|
|
+var
|
|
|
+ intStr : string;
|
|
|
+begin
|
|
|
+ intStr := ReadString(section, ident, '');
|
|
|
+ { convert a Hex-Value }
|
|
|
+ if (Length(intStr) > 2) and (intStr[1] = '0') and ((intStr[2] = 'X') or (intStr[2] = 'x')) then
|
|
|
+ intStr := '$' + Copy(intStr, 3, Maxint);
|
|
|
+ result := StrToIntDef(intStr, defaultValue);
|
|
|
+end;
|
|
|
+
|
|
|
+{ Reads a Bool-Value of Ident in one Section }
|
|
|
+
|
|
|
+function TIniFile.ReadBool(const section, ident : string; defaultValue : boolean) : boolean;
|
|
|
+begin
|
|
|
+ result := ReadInteger(section, ident, Ord(defaultValue)) <> 0;
|
|
|
+end;
|
|
|
+
|
|
|
+{ Reads all Names + Values of one Section }
|
|
|
+
|
|
|
+procedure TIniFile.ReadSectionValues(const section : string; strings : TStrings);
|
|
|
+var
|
|
|
+ name : string;
|
|
|
+ value : string;
|
|
|
+ index : integer;
|
|
|
+begin
|
|
|
+ strings.BeginUpdate;
|
|
|
+ try
|
|
|
+ strings.Clear;
|
|
|
+ if FFileBuffer.Count > 0 then
|
|
|
+ begin
|
|
|
+ index := GetSectionIndex(section);
|
|
|
+ if index <> -1 then
|
|
|
+ begin
|
|
|
+ Inc(index);
|
|
|
+ while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) do
|
|
|
+ begin
|
|
|
+ name := GetName(FFileBuffer[index]);
|
|
|
+ if name <> '' then
|
|
|
+ begin
|
|
|
+ value := GetValue(FFileBuffer[index], name);
|
|
|
+ strings.Add(name + separator + value);
|
|
|
+ end;
|
|
|
+ Inc(index);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ finally
|
|
|
+ strings.EndUpdate;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TIniFile.ReadSectionRaw(const section : string; strings : TStrings);
|
|
|
+var
|
|
|
+ eols,index : integer;
|
|
|
+begin
|
|
|
+ strings.BeginUpdate;
|
|
|
+ try
|
|
|
+ eols:=0;
|
|
|
+ strings.Clear;
|
|
|
+ if FFileBuffer.Count > 0 then
|
|
|
+ begin
|
|
|
+ index := GetSectionIndex(section);
|
|
|
+ if index <> -1 then
|
|
|
+ begin
|
|
|
+ Inc(index);
|
|
|
+ while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) do
|
|
|
+ begin
|
|
|
+ { Skip empty lines at the end of the section }
|
|
|
+ if FFileBuffer[index]='' then
|
|
|
+ inc(eols)
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ while eols>0 do
|
|
|
+ begin
|
|
|
+ Strings.Add('');
|
|
|
+ dec(eols);
|
|
|
+ end;
|
|
|
+ if not IsComment(FFileBuffer[index]) then
|
|
|
+ strings.Add(FFileBuffer[index]);
|
|
|
+ end;
|
|
|
+ Inc(index);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ finally
|
|
|
+ strings.EndUpdate;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+{ Writes a String-Value for Ident in one Section.
|
|
|
+ Note: If Section and/or Ident don't exist, they will be placed in the Ini-File }
|
|
|
+
|
|
|
+procedure TIniFile.WriteString(const section, ident, value : string);
|
|
|
+var
|
|
|
+ index : integer;
|
|
|
+begin
|
|
|
+ index := GetSectionIndex(section);
|
|
|
+ { Section exists }
|
|
|
+ if index <> -1 then
|
|
|
+ begin
|
|
|
+ Inc(index);
|
|
|
+ while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) and
|
|
|
+ (GetName(FFileBuffer[index]) <> ident) do
|
|
|
+ Inc(index);
|
|
|
+ if (index >= FFileBuffer.Count) or IsSection(FFileBuffer[index]) then
|
|
|
+ begin { End of File or ident doesn't exists in the section }
|
|
|
+ if ident <> '' then
|
|
|
+ FFileBuffer.Insert(index, ident + separator + value);
|
|
|
+ end
|
|
|
+ else if ident <> '' then { Ident does exists in the section }
|
|
|
+ FFileBuffer[index] := ident + separator + value;
|
|
|
+ end
|
|
|
+ else { section doesn't exists, so add new [section] with ident=value }
|
|
|
+ begin
|
|
|
+ FFileBuffer.Add('');
|
|
|
+ FFileBuffer.Add(brackets[0] + section + brackets[1]);
|
|
|
+ if ident <> '' then
|
|
|
+ FFileBuffer.Add(ident + separator + value);
|
|
|
+ end;
|
|
|
+ SaveToFile;
|
|
|
+end;
|
|
|
+
|
|
|
+{ Writes an Integer-Value for Ident in one Section }
|
|
|
+
|
|
|
+procedure TIniFile.WriteInteger(const section, ident : string; value : longint);
|
|
|
+begin
|
|
|
+ WriteString(section, ident, IntToStr(value));
|
|
|
+end;
|
|
|
+
|
|
|
+{ Writes a Bool-Value for Ident in one Section }
|
|
|
+
|
|
|
+procedure TIniFile.WriteBool(const section, ident : string; value : boolean);
|
|
|
+const
|
|
|
+ values: array[boolean] of string = ('0', '1');
|
|
|
+begin
|
|
|
+ WriteString(section, ident, values[Value]);
|
|
|
+end;
|
|
|
+
|
|
|
+{ Deletes the value of ident in one section.
|
|
|
+ Note: Only if section and ident exist, the value of ident will be set to NULL }
|
|
|
+
|
|
|
+procedure TIniFile.DeleteKey(const section, ident : string);
|
|
|
+var
|
|
|
+ index : integer;
|
|
|
+begin
|
|
|
+ index := GetSectionIndex(section);
|
|
|
+ if index <> -1 then
|
|
|
+ begin
|
|
|
+ Inc(index);
|
|
|
+ while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) and
|
|
|
+ (GetName(FFileBuffer[index]) <> ident) do
|
|
|
+ Inc(index);
|
|
|
+ if not (index >= FFileBuffer.Count) and not IsSection(FFileBuffer[index]) then
|
|
|
+ begin { Ident does exists }
|
|
|
+ FFileBuffer.Delete(index);
|
|
|
+ SaveToFile;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+{ Erases the whole Section from an Ini-File }
|
|
|
+
|
|
|
+procedure TIniFile.EraseSection(const section : string);
|
|
|
+var
|
|
|
+ index : integer;
|
|
|
+begin
|
|
|
+ index := GetSectionIndex(section);
|
|
|
+ if index <> -1 then
|
|
|
+ begin
|
|
|
+ FFileBuffer.Delete(index); { Delete Section-Header }
|
|
|
+ while (index < FFileBuffer.Count) and not IsSection(FFileBuffer[index]) do
|
|
|
+ FFileBuffer.Delete(index); { Delete Section-Items }
|
|
|
+ if index > 0 then FFileBuffer.Insert(index, '');
|
|
|
+ SaveToFile;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+end.
|
|
|
+
|
|
|
+{
|
|
|
+ $Log$
|
|
|
+ Revision 1.1 2000-05-11 17:59:12 peter
|
|
|
+ * makeini unit added as replacement for old inifiles unit
|
|
|
+
|
|
|
+}
|