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 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
|
-------------------------------------------------------------------------------
--
-- <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>
-- Bash-style variable substitution.
-- </PURPOSE>
--
-- <NOT_TASK_SAFE>
--
-- <STORAGE>
-- No dynamic storage allocation. @Expand@ is recursive; the recursion
-- depth (and hence the stack consumption) is limited by the number of
-- variable references and escaped '@$@'-signs in the @Source@ string.
-- </STORAGE>
--
-- <HISTORY>
-- 03-MAY-2002 TW Initial version.
-- 14-MAY-2002 TW Added 'Set_Reference_Character'.
-- </HISTORY>
-------------------------------------------------------------------------------
pragma License (Modified_GPL);
package Util.Environment.Bash is
pragma Elaborate_Body;
type Bash_Expander is new String_Expander with private;
function Expand
(Self : access Bash_Expander;
Source : in String)
return String;
-- Replaces all references to environment variables in @Source@ by that
-- variable's definition (or the empty string, if an environment variable
-- is not defined) and returns the resulting string.
--
-- A @Bash_Expander@ uses a syntax very similar to that of the GNU
-- @bash@ shell. An environment variable has a name, which is an
-- identifier:
--
-- <PRE>
-- Ident = Alpha <B>{</B> Alpha <B>|</B> Digit <B>|</B> '_' <B>}</B>.
-- Alpha = 'A' .. 'Z' <B>|</B> 'a' ..'z'.
-- Digit = '0' .. '9'.
-- </PRE>
--
-- A simple reference to a variable has the form
--
-- <PRE>
-- $Identifier
-- </PRE>
--
-- and is replaced as a whole (including the '$' sign) by the variable's
-- value or by the empty string if no such variable is defined.
--
-- More interesting are the complex variable references, which have the
-- <A NAME="bash_syntax">syntax</A>
--
-- <PRE>
-- Value = <EM>any string, maybe containing environment
-- variable references</EM>.
-- Operator = :- <B>|</B> :+.
-- Reference = ${Var_Name<B>[</B>Operator<B>[</B>Value<B>]]</B>}.
-- Var_Name = Value <B>|</B> !Identifier.
-- </PRE>
--
-- In all forms, <CODE>Variable_Name</CODE> can have one of three formats:
--
-- <UL>
-- <LI>An identifier: expands to the empty string if no such variable
-- is defined, and to the variable's value otherwise.
-- <LI>A '!' and an identifier: expands the identifier as above, but
-- then takes the result of this expansion as the name of another
-- variable, which is then expanded. This is known as <EM>indirect
-- expansion</EM>, and is limited to one level of indirection only.
-- <LI>Some arbitrary string that may contain embedded references to
-- variables: environment variable substitution is performed on the
-- whole thing, and the resulting value is taken to be the name of
-- a variable, which is then expanded. This <EM>recursive
-- expansion</EM> is <EM>unknown</EM> in @bash@>, and it is done
-- for as many levels as specified.
-- </UL>
--
-- The semantics of these forms is as follows:
--
-- <DL><DT>@${Variable_Name}@
-- <DD>Is identical to the simple form of references @$Identifier@
-- except that it also allows indirect and recursive expansion.</DL>
--
-- <DL><DT>@${Variable_Name:-Value}@
-- <DD>Is replaced by the result of @${Variable_Name}@ unless that
-- result is empty, in which case it is replaced by the expansion
-- of @Value@.</DL>
--
-- <DL><DT>@${Variable_Name:+Value}@
-- <DD>Is replaced by the expansion of @Value@ if the result of
-- @${Variable_Name}@ is non-empty, or the empty string otherwise.
-- (@:+@ is the inverse of @:-@.)</DL>
--
-- Indirect expansion using the '@!@' character is supported only to keep
-- the syntax as close to the one used by @bash@ as possible. It is
-- actually superfluous and can be replaced by the more powerful (and, so
-- I think, simpler because more regular) recursive expansion:
-- "@${!Some_Name}@" is identical to "@${${Some_Name}}@" or
-- "@${$Some_Name}@".
--
-- In all operators, the '@:@' is actually optional. It appears that it
-- is optional in @bash@ (although the manual doesn't say so),
-- and I have therefore chosen to make it optional here, too.
--
-- To include a literal dollar sign '@$@' in the result of the expansion
-- of @Source@, escape it with a backslash and write "@\$@". If, for some
-- reason, you want to have a backslash immediately before a variable
-- reference without escaping the dollar sign, escape the backslash by
-- writing <EM>two</EM> backslashes before the dollar. The sequence
-- "@\\@" immediately followed by a variable reference is replaced by
-- a single backslash and the substitution of the reference.
--
-- Variable references that are not terminated properly are not replaced.
-- E.g. "<CODE>${Var</CODE>" is returned unchanged.
--
-- A @Bash_Expander@ implements only the two operators '@-@' and '@+@'.
-- Other operators may be added in derived types.
--
-- Also, a @Bash_Expander@ has <EM>no</EM> special variables. To add those,
-- override @Get@ and/or @Expand_Variable@ as needed. In general, special
-- variables with names that are not identifiers will require overriding
-- of @Expand_Variable@. Other special variables may be implemented by
-- overriding @Get@ only.
function Legal_Name
(Self : access Bash_Expander;
Source : in String)
return Natural;
function Indirection
(Self : access Bash_Expander;
Name : in String)
return String;
function Prefix
(Self : access Bash_Expander;
Source : in String;
Last : access Natural)
return String;
function Recurse
(Self : access Bash_Expander;
Source : in String)
return String;
-- Default does anything required for plain bash-style variable expansion.
-- In general, you'll only need to override this to add special handling
-- of isolated cases, and then invoke this default operation. @Last@ shall
-- be set to 0 in case of error (when no expansion shall occur), otherwise
-- to the index of the first character in @Name@ not processed anymore
-- (which may be <= @Name'Last@ only if @Prefix@ is @True@).
--
-- @Prefix@ is @True@ if @Expand_Variable@ shall use only the longest
-- possible legal prefix of @Name@ as the variable name.
--
-- @Indirect@ is @True@ if indirect expansion shall be performed.
function Is_Operator
(Self : access Bash_Expander;
Selector : in Character)
return Boolean;
-- Return @True@ if @Selector@ is a legal operator for your variation of
-- bash-style variable substitution, and @False@ otherwise. The default
-- returns @True@ only if @Selector@ is '@+@' or '@-@'.
function Execute_Operator
(Self : access Bash_Expander;
Operator : in Character;
Var_Name : in String;
Indirect : in Boolean;
Default_Part : in String)
return String;
-- Execute a variable substitition that uses an @Operator@. @Var_Name@ is
-- the @Var_Name@ part of the above <A HREF="#bash_syntax">syntax</A>, and
-- @Default_Part@ is the @Value@ from that syntax. if @Indirect@ is @True@,
-- @Var_Name@ is only the @Identifier@, it doesn't include the '@!@' sign.
--
-- Returns the expansion (which may be empty).
procedure Set_Reference_Character
(Self : access Bash_Expander;
Char : in Character);
-- By default, a @Bash_Expander@ uses the "@$@" sign to signal the start
-- of a variable reference. However, sometimes you might want to use some
-- other character. With this operation, you can redefine the character
-- used.
private
type Bash_Expander is new String_Expander with
record
Ref_Char : Character := '$';
end record;
end Util.Environment.Bash;
|