[Back to TEXTFILE SWAG index]  [Back to Main SWAG index]  [Original]

{
This unit allows your programs to have professional .INI file entries
that determine its behaviour.  I use this unit in 4 programs so far,
and I plan to keep using it.  It is *very* simple, but nonetheless
rather useful.  An INI file has the following structure:

; Comments are lines that start with a semicolon.  They are ignored.

; Blank lines are also ignored

SECTION = <name>
; SECTION specifies the current INI section.  This allows you to use one
; INI file for several programs, as in WIN.INI. The default SECTION is
; GLOBAL.
<item> = <value>
; <item> is a name (other than section) for an INI entry.  <value> is
; a value for <item>.
; eg: Author=Byron Ellacott
; All spaces before and after the equal sign are ignored.

An INI file can have an unlimited number of sections and items.

SWAG people: Feel free to include this in your next packet
}

unit INI;

interface

type
  TINIOption = record
    ioType: string[20]; { Type of INI option }
    ioSection: string[20]; { Current section }
    ioValue: string[40]; { Value of option }
  end;

{All INI options are returned in a TINIOption record.  It is up to your
 program to then take a course of action or to set a variable accordingly}

function OpenINI(s: string): boolean;
{OpenINI attempts to open the filename S.  If it succeeds, it returns
 true and all further options work on that file.  If it cant find the
 file or cant open it, it returns False}

procedure CloseINI;
{This procedure closes an INI file if one is open.  It checks if one is
 opened before attempting to close it also..}

function GetINIOption(var INIOption: TINIOption): boolean;
{This function gets the next option in the INI file.  Once you have read
 an INI option, you cannot go back through the file.  You will have to
 reopen the file.. If there are no more options, it returns false.  The
 current section will be updated if it is changed (and reflected in
 the global variable CurrentSection)}

function FindSection(section: string): boolean;
{This function seeks through the file until it finds the section passed
 to it.  If it doesnt find it, a return value of False is given}

function UpStr(s: string): string;
{A utility procedure to convert a string to uppercase.  Not particularly
 thrilling..}

var
  CurrentSection: string[20];
{The current section}

implementation

var
  INIOpen: boolean;
  INIFile: text;

function UpStr(s: string): string;
var
  b:byte;
begin
  for b := 1 to length(s) do s[b] := upcase(s[b]);
  UpStr := s;
end;

function OpenINI;
begin
  if INIOpen then close(INIFile);
  assign(INIFile,s);
  {$I-} reset(INIFile); {$I+}
  CurrentSection := 'GLOBAL';
  INIOpen := (ioresult = 0);
  OpenINI := INIOpen;
end;

procedure CloseINI;
begin
  if INIOpen then close(INIFile);
  INIOpen := false;
end;

function ReadLine(var s: string): boolean;
begin
  repeat
    if eof(INIFile) then begin
      ReadLine := false;
      exit;
    end;
    readln(INIFile,s);
  until (length(s) > 0) and (s[1] <> ';');
  if UpStr(copy(s,1,7)) = 'SECTION' then begin
    delete(s,1,7);
    if length(s) > 0 then begin
      while (s[1] = ' ') and (length(s) > 0) do delete(s,1,1);
      if (length(s) > 0) and (s[1] = '=') then begin
        while (s[1] = ' ') and (length(s) > 0) do delete(s,1,1);
        if length(s) > 0 then CurrentSection := s;
      end;
    end;
    ReadLine := ReadLine(s);
  end;
end;

function GetINIOption;
var
  s: string;
  b: byte;
begin
  if not ReadLine(s) then begin
    GetINIOption := false;
    exit;
  end;
  b := pos('=',s);
  if b = 0 then begin
    GetINIOption := GetINIOption(INIOption); { Recurse to find '=' }
    exit;
  end;
  dec(b);
  while s[b] = ' ' do dec(b);
  INIOption.ioType := copy(s,1,b);
  inc(b);
  while s[b] <> '=' do inc(b);
  inc(b);
  while (b < length(s)) and (s[b] = ' ') do inc(b);
  while (length(s) >= b) and (s[length(s)] = ' ') do delete(s,length(s),1);
  INIOption.ioValue := copy(s,b,40);
  INIOption.ioSection := CurrentSection;
  GetINIOption := true;
end;

function FindSection;
var
  s: string;
begin
  reset(INIFile);
  CurrentSection := 'GLOBAL';
  while CurrentSection <> section do begin
    repeat
      if eof(INIFile) then begin
        FindSection := false;
        exit;
      end;
      readln(INIFile,s);
    until (length(s) > 0) and (s[1] <> ';');
    if UpStr(copy(s,1,7)) = 'SECTION' then begin
      delete(s,1,7);
      if length(s) > 0 then begin
        while (s[1] = ' ') and (length(s) > 0) do delete(s,1,1);
        if (length(s) > 0) and (s[1] = '=') then begin
          while (s[1] = ' ') and (length(s) > 0) do delete(s,1,1);
          if length(s) > 0 then CurrentSection := s;
        end;
      end;
    end;
  end;
  FindSection := true;
end;

begin
  CurrentSection := 'GLOBAL';
  INIOpen := false;
end.

[Back to TEXTFILE SWAG index]  [Back to Main SWAG index]  [Original]