package GNATCOLL.Config is
--------------------------
-- Parsing config files --
--------------------------
type Config_Parser is abstract tagged private;
-- Abstract type for all config streams (files, in-memory,...), with any
-- format. Concrete types below will provide the actual implementation.
-- Typical usage looks like:
-- declare
-- C : File_Config_Parser;
-- begin
-- Open (C, "filename.txt");
-- while not C.At_End loop
-- Put_Line (C.Key & " = " & C.Value);
-- C.Next;
-- end loop;
-- end;
function At_End (Self : Config_Parser) return Boolean is abstract;
-- Whether the config parsing is at the end
procedure Next (Self : in out Config_Parser) is abstract;
-- Move to the next (key, value) in the configuration. Before that call,
-- the parser is left on the first value in the configuration.
function Section (Self : Config_Parser) return String is abstract;
function Key (Self : Config_Parser) return String is abstract;
function Value (Self : Config_Parser) return String is abstract;
-- Return the current (section, key, value);
procedure Set_System_Id (Self : in out Config_Parser; System_ID : String);
-- Sets the system ID for the config.
-- If the config is found in a file, this should be the absolute path name
-- to that file. This will generally be called automatically when opening
-- the file.
-- This system id is used to resolve absolute file names.
function As_Integer (Self : Config_Parser) return Integer;
function As_Boolean (Self : Config_Parser) return Boolean;
function As_Absolute_File (Self : Config_Parser) return String;
function As_Absolute_Dir (Self : Config_Parser) return String;
-- Assuming the current value is a file or directory, converts it to an
-- absolute name, where relative paths are resolved relative to the
-- config's system_id.
-- These will raise Constraint_Error if used on non-matching values.
-----------------
-- File config --
-----------------
type File_Config_Parser is abstract new Config_Parser with private;
-- A special implementation for config streams based on actual files
procedure Open (Self : in out File_Config_Parser; Filename : String);
-- Open a file
overriding function At_End (Self : File_Config_Parser) return Boolean;
---------------
-- INI files --
---------------
type INI_Parser is new File_Config_Parser with private;
-- a special parser for Windows' .ini files
procedure Configure
(Self : in out INI_Parser;
Comment_Start : String := "#";
Handles_Sections : Boolean := True;
Home : String := "");
-- "Home" is the substitution pattern for "HOME" in the values. If
-- unspecified, it is computed automatically.
overriding procedure Open (Self : in out INI_Parser; Filename : String);
overriding procedure Next (Self : in out INI_Parser);
overriding function Section (Self : INI_Parser) return String;
overriding function Key (Self : INI_Parser) return String;
overriding function Value (Self : INI_Parser) return String;
-------------------
-- Resource pool --
-------------------
type Config_Pool is tagged private;
-- This type provides storage for a config file
procedure Set_System_Id (Self : in out Config_Pool; System_ID : String);
-- Set the absolute name used to resolve file names in Get_File
procedure Fill
(Self : in out Config_Pool;
Config : in out Config_Parser'Class);
-- Load all keys from Config, and store the (key, value) pairs in Self.
-- Multiple files can be merged into the same pool.
-- Set_System_Id is automatically called, thus file names will be resolved
-- relative to the last Config loaded in the pool.
Section_From_Key : constant String;
-- Indicates that the section should in fact be read from the key (as
-- opposed to being specified separately). In this case, the key is split
-- at the first "." (if there is none, the section name is empty).
-- For instance: "section1.key1" or "section1.key2".
--
-- It is often more convenient to specify the section that way, in exchange
-- for a small performance penalty and a possible ambiguity if the key
-- itself contains a ".", which is not recommended.
Whole_Value : constant Natural := 0;
function Get (Self : Config_Pool;
Key : String;
Section : String := Section_From_Key;
Index : Natural := Whole_Value) return String;
-- Return the value associated with Key.
-- Index is used for comma-separated lists of values, and will retrieve
-- one of the specific elements of the list. The whole value (no splitting)
-- is returned if Index is Whole_Value. The empty string is returned if
-- there is no such item in the list
function Get_Integer
(Self : Config_Pool;
Key : String;
Section : String := Section_From_Key;
Index : Natural := Whole_Value) return Integer;
function Get_Boolean
(Self : Config_Pool;
Key : String;
Section : String := Section_From_Key;
Index : Natural := Whole_Value) return Boolean;
function Get_File
(Self : Config_Pool;
Key : String;
Section : String := Section_From_Key;
Index : Natural := Whole_Value) return String;
-- Same as above, but returns an absolute filename. Relative paths are
-- resolved relative to the config location where Key was declared.
function To_File
(Self : Config_Pool;
Key : String;
Section : String := Section_From_Key;
Value : String) return GNATCOLL.VFS.Virtual_File;
-- Converts value to a file. It is relative to the location of the config
-- file that provided Key. This is similar to calling Get_File directly,
-- but is useful in contexts where you need to first manipulate the value
-- read from the config and then interpret it as a file.
procedure Set (Self : in out Config_Pool; Section, Key, Value : String);
-- Override a specific key
--------------------------------
-- Resource pool, static keys --
--------------------------------
type Config_Key is tagged private;
function Create (Key : String; Section : String := "") return Config_Key;
-- Create a new config key
function Get
(Self : Config_Key;
Conf : Config_Pool'Class;
Index : Natural := Whole_Value) return String;
function Get_Integer
(Self : Config_Key;
Conf : Config_Pool'Class;
Index : Natural := Whole_Value) return Integer;
function Get_Boolean
(Self : Config_Key;
Conf : Config_Pool'Class;
Index : Natural := Whole_Value) return Boolean;
function Get_File
(Self : Config_Key;
Conf : Config_Pool'Class;
Index : Natural := Whole_Value) return String;
function To_File
(Self : Config_Key;
Conf : Config_Pool'Class;
Value : String) return GNATCOLL.VFS.Virtual_File;
-- Read the key from the configuration.
-- Using this API might help ensure that you are always accessing existing
-- keys. In this case, you would have a global package that defines all
-- valid keys:
--
-- Key1 : constant Config_Key := Create ("...");
-- Key2 : constant Config_Key := Create ("...");
--
-- Then your coding standard should specify that you can only access the
-- configuration via those keys:
--
-- Put_Line (Key1.Get);
--
-- There is therefore no possible typo in the name of the key, and if you
-- rename the key in the configuration file, you have a single place to
-- change.
end GNATCOLL.Config;