1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
-------------------------------------------------------------------------------
--
-- <STRONG>Copyright © 2001, 2002 by Thomas Wolf.</STRONG>
-- <BLOCKQUOTE>
-- This piece of software is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as published
-- by the Free Software Foundation; either version 2, or (at your option)
-- any later version. This software is distributed in the hope that it will
-- be useful, but <EM>without any warranty</EM>; without even the implied
-- warranty of <EM>merchantability or fitness for a particular purpose.</EM>
-- See the GNU General Public License for more details. You should have
-- received a copy of the GNU General Public License with this distribution,
-- see file "<A HREF="GPL.txt">GPL.txt</A>". If not, write to the Free
-- Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-- USA.
-- </BLOCKQUOTE>
-- <BLOCKQUOTE>
-- As a special exception from the GPL, if other files instantiate generics
-- from this unit, or you link this unit with other files to produce an
-- executable, this unit does not by itself cause the resulting executable
-- to be covered by the GPL. This exception does not however invalidate any
-- other reasons why the executable file might be covered by the GPL.
-- </BLOCKQUOTE>
--
-- <AUTHOR>
-- Thomas Wolf (TW) <E_MAIL>
-- </AUTHOR>
--
-- <PURPOSE>
-- Simple configuration reader/writer. A configuration file consists of
-- lines of the format key [= value].
--
-- The file format allows for line comments (starting with '#' and
-- extending up to the end of the line) and line continuations using
-- the backslash notation.
-- </PURPOSE>
--
-- <NOT_TASK_SAFE>
--
-- <STORAGE>
-- Dynamic storage allocation in the default pool. @Configuration@s are
-- controlled types.
-- </STORAGE>
--
-- <HISTORY>
-- 19-JUN-2002 TW Initial version.
-- 08-JUN-2003 TW Added 'Full_Name' to 'Set_File_Name'.
-- </HISTORY>
-------------------------------------------------------------------------------
pragma License (Modified_GPL);
with Ada.Finalization;
with Ada.Strings.Maps;
package Util.Files.Config is
type Reader is abstract
new Ada.Finalization.Limited_Controlled with private;
procedure Set_File_Name
(Self : in out Reader;
Name : in String;
Full_Name : in String);
-- Called when a file has been opened. Default does nothing.
function Parse_Key
(Self : in Reader;
Line : in String)
return Natural;
-- Assuming that @Line@ starts with a valid key, parse a key and
-- return the index of its last character. Return zero if no
-- legal key is found.
--
-- Default recognizes <CODE>Identifier {"." Identifier}</CODE>
procedure Parse_Operator
(Self : in Reader;
Line : in String;
From, To : out Natural);
-- If an operator is found, return in @From@ and @To@ the starting
-- and ending index, otherwise set @To@ to zero and -- if white space
-- was skipped -- @From@ to the index one beyond the last skipped
-- character.
--
-- Default skips white space and then recognizes a '='.
function Delimiters
(Self : in Reader)
return Ada.Strings.Maps.Character_Set;
-- Return a set containing all legal string delimiter characters.
-- Default returns @Util.Strings.String_Quotes@.
function Skip_String
(Self : in Reader;
Line : in String;
Delim : in Character)
return Natural;
-- Called by @Read_From_File@ if Line (Line'First) in Delimiters (Self).
-- Shall return the index of the string closing character or
-- @Line'First@ if strings are not to be recognized.
--
-- The default uses
-- <CODE>Util.Strings.Skip_String (Line, Delim,Delim)</CODE>, i.e. handles
-- enclosed delimiters as in Ada (must be doubled).
procedure New_Key
(Self : in out Reader;
Key : in String;
Operator : in String;
Value : in String)
is abstract;
-- Called after a successful parse of a line. Note that @Operator@ and
-- @Value@ may both be empty. If @New_Key@ wants to signal an error, it
-- should <EM>not</EM> use @Invalid_Configuration@ but some other
-- exception. (@Read@ passes on @Invalid_Configuration@ unchanged, but
-- adds the file name and the offending line to the message of any
-- other exception.)
Invalid_Configuration : exception;
procedure Read
(File_Name : in String;
R : in out Reader'Class);
-- Read lines from the file (handling line continuations and comments)
-- and parse the lines using the @Reader@. Raises @Invalid_Configuration@
-- with a descriptive message if a parse error occurs.
--
-- The @Reader@ may rely on the particular sequence of parsing operations
-- use by @Read@: for each line, it first calls @Parse_Key@, then
-- @Parse_Operator@, and finally @New_Key@. The value of a key is the
-- rest of the line beyond the operator, with leading and trailing white
-- space trimmed.
--
-- This routine is smart enough to handle recursive calls, where the
-- @Reader@'s @New_Key@ operation calls @Read_From_File@ again. If
-- a recursive inclusion of an already included file is detected,
-- @Invalid_Configuration@ is raised.
--
-- Warning: this recursion detection can be subverted if an original
-- @Reader@'s @New_Key@ operation calls @Read_From_File@ passing another
-- @Reader@!
private
type String_Ptr is access all String;
type Files is array (Positive range <>) of String_Ptr;
type Stack_Ptr is access all Files;
type Reader is abstract new Ada.Finalization.Limited_Controlled with
record
Stack : Stack_Ptr;
end record;
procedure Finalize
(Self : in out Reader);
end Util.Files.Config;
|