Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ada.environment_variables [2012/01/14 20:44] (current)
thomaslocke created
Line 1: Line 1:
 +===== Introduction =====
 +
 +The [[http://​adaic.org/​standards/​05rm/​html/​RM-A-17.html|Ada.Environment_Variables]] package allows an Ada program to read, write and modify [[http://​en.wikipedia.org/​wiki/​Environment_variable|environment variables]]. Exactly what constitutes an environment variable is implementation defined. All the code in this article is compiled and executed on a Slackware Linux system. The compiler used is //GNATMAKE GPL 2008 (20080521)//​.
 +
 +===== Using Ada.Environment_Variables =====
 +
 +Environment variables are simple key/value pairs. Both the key and the value are strings. With the //​Environment_Variables//​ package we can check if a key exists, we can set new key/value pairs, we can delete keys, we can read values, and we can iterate through all the key/value pairs (as can be seen from the very straightforward specification of the package): ​
 +
 +<code ada>
 +package Ada.Environment_Variables is
 +   ​pragma Preelaborate (Environment_Variables);​
 +   ​function Value (Name : String) return String;
 +   ​function Exists (Name : String) return Boolean;
 +   ​procedure Set (Name : String; Value : String);
 +   ​procedure Clear (Name : String);
 +   ​procedure Clear;
 +   ​procedure Iterate (Process : not null access procedure (Name, Value : String));
 +end Ada.Environment_Variables;​
 +</​code>​
 +
 +All of the following examples will be built around this simple core program:
 +
 +<code ada>
 +with Ada.Text_IO;​
 +with Ada.Environment_Variables;​
 +
 +procedure Env is
 +   ​package IO renames Ada.Text_IO;​
 +   ​package EV renames Ada.Environment_Variables;​
 +begin
 +   ​IO.Put_Line (Item => "​Environment_Variables test"​);​
 +end Env;
 +</​code>​
 +
 +Simply insert the code from the following examples after the //​IO.Put_Line//​ line. So, let's move on and see how we can read an environment value using Ada.
 +
 +===== Ada.Environment_Variables.Value =====
 +
 +The specification for //Value// looks like this:
 +
 +<code ada>
 +function Value (Name : String) return String;
 +</​code>​
 +
 +Reading an environment variable is done using the //Value// function. It takes a string as its sole parameter and returns the value of a matching environment variable. Try adding this to the core program:
 +
 +<code ada>
 +   ​IO.Put_Line (Item => EV.Value (Name => "​VISUAL"​));​
 +   ​IO.Put_Line (Item => EV.Value (Name => "​NONEXISTENT"​));​
 +   
 +exception
 +   when Constraint_Error =>
 +      IO.Put_Line (Item => "No such environment variable."​);​
 +</​code>​
 +
 +When running this on my machine, I get the following output:
 +
 +  Environment_Variables test
 +  /​usr/​local/​bin:/​usr/​bin:/​bin:/​usr/​games:/​usr/​lib/​java/​bin:/​usr/​lib/​java/​jre/​bin:/​usr/​lib/​qt/​bin:​.:/​usr/​local/​texlive/​2008/​bin/​i386-linux/​
 +  No such environment variable.
 +
 +As you can see, a //​Constraint_Error//​ is raised if the given //Name// parameter does not match any existing environment variable. If the notion of environment variables isn't supported in the target operating system, a //​Program_Error//​ is raised instead.
 +
 +[[Ada.Environment_Variables.Value Example Source]]
 +
 +===== Ada.Environment_Variables.Exists =====
 +
 +The specification for //Exists// looks like this:
 +
 +<code ada>
 +function Exists (Name : String) return Boolean;
 +</​code>​
 +
 +The //Exists// function is used to check whether or not a given environment variable name is known to the operating system. If it is, the function will return boolean //True//, otherwise it returns boolean //​False//>​
 +
 +<code ada>
 +if EV.Exists (Name => "​PATH"​) then
 +   ​IO.Put_Line (Item => "​EXISTS!"​);​
 +else
 +   ​IO.Put_Line (Item => "DOES NOT EXIST!"​);​
 +end if;
 +   
 +if EV.Exists (Name => "​NONEXISTENT"​) then
 +   ​IO.Put_Line (Item => "​EXISTS!"​);​
 +else
 +   ​IO.Put_Line (Item => "DOES NOT EXIST!"​);​
 +end if;
 +</​code>​
 +
 +The resulting output on my computer is:
 +
 +  Environment_Variables test
 +  EXISTS!
 +  DOES NOT EXIST!
 +
 +The manual does not say anything about what happens if the execution environment lacks support for environment variables in this case, but I suspect a //​Program_Error//​ is raised, as with [[Ada.Environment_Variables#​Ada.Environment_Variables.Value | Value]].
 +
 +[[Ada.Environment_Variables.Exists Example Source]]
 +
 +===== Ada.Environment_Variables.Set =====
 +
 +The specification for //Set// looks like this:
 +
 +<code ada>
 +procedure Set (Name : String; Value : String);
 +</​code>​
 +
 +With //Set// we can define new and alter existing environment variables:
 +
 +<code ada>
 +if not EV.Exists (Name => "​NONEXISTENT"​) then
 +   ​IO.Put_Line (Item => "DOES NOT EXIST!"​);​
 +end if;
 +EV.Set (Name  => "​NONEXISTENT",​
 +        Value => "​FooBar"​);​
 +IO.Put_Line (Item => EV.Value (Name => "​NONEXISTENT"​));​
 +EV.Set (Name  => "​NONEXISTENT",​
 +        Value => "​FooBar again"​);​
 +IO.Put_Line (Item => EV.Value (Name => "​NONEXISTENT"​));​
 +</​code>​
 +
 +The output of this is:
 +
 +  Environment_Variables test
 +  DOES NOT EXIST!
 +  FooBar
 +  FooBar again
 +
 +If setting or altering a given environment variable is prohibited by the operating environment,​ a //​Constraint_Error//​ is raised. As with [[Ada.Environment_Variables#​Ada.Environment_Variables.Value | Value]], a //​Program_Error//​ is raised if the execution environment has no notion of environment variables.
 +
 +[[Ada.Environment_Variables.Set Example Source]]
 +
 +===== Ada.Environment_Variables.Clear =====
 +
 +The specification for //Clear// looks like this:
 +
 +<code ada>
 +procedure Clear (Name : String);
 +procedure Clear;
 +</​code>​
 +
 +Deleting environment variables is done using one of the //Clear// procedures. If a //Name// parameter is given, //Clear// will try to delete all environment variables with that name. If no //Name// parameter is given, //Clear// will try to delete all existing environment variables. ​
 +
 +First lets see how //Clear// works when given a //Name// parameter:
 +
 +<code ada>
 +   ​EV.Set (Name  => "​Foo",​
 +           Value => "This is Foo");
 +   ​IO.Put_Line (Item => EV.Value (Name => "​Foo"​));​
 +   ​EV.Clear (Name => "​Foo"​);​
 +   ​IO.Put_Line (Item => EV.Value (Name => "​Foo"​));​
 +   
 +exception
 +   when Constraint_Error =>
 +      IO.Put_Line (Item => "​Environment variable Foo does not exist"​);​
 +</​code>​
 +
 +And the output:
 +
 +  Environment_Variables test
 +  This is Foo
 +  Environment variable Foo does not exist
 +
 +Now lets see //Clear// in action with no //Name// parameter:
 +
 +<code ada>
 +EV.Set (Name  => "​Foo",​
 +        Value => "This is Foo");
 +IO.Put_Line (Item => EV.Value (Name => "​Foo"​));​
 +   
 +EV.Set (Name  => "​Bar",​
 +        Value => "This is Bar");
 +IO.Put_Line (Item => EV.Value (Name => "​Bar"​));​
 +  ​
 +EV.Clear;
 +   
 +if not EV.Exists (Name => "​Foo"​) and not EV.Exists (Name => "​Bar"​) then
 +   ​IO.Put_Line (Item => "Foo and Bar are both gone!"​);​
 +end if;
 +</​code>​
 +
 +And the output is:
 +
 +  Environment_Variables test
 +  This is Foo
 +  This is Bar
 +  Foo and Bar are both gone!
 +
 +Exactly as expected.
 +
 +[[Ada.Environment_Variables.Clear Example Source]]
 +
 +===== Ada.Environment_Variables.Iterate =====
 +
 +The specification for //Iterate// looks like this:
 +
 +<code ada>
 +procedure Iterate (Process : not null access procedure (Name, Value : String));
 +</​code>​
 +
 +//Iterate// enables us to serially act upon all the environment variables that are available to the program at the time of execution. We can do this by creating a procedure that takes two //String// parameters and then give //Iterate// access to this procedure. ​
 +
 +Such a program could look something like this:
 +
 +<code ada>
 +with Ada.Text_IO;​
 +with Ada.Environment_Variables;​
 +
 +procedure Env is
 +   ​package IO renames Ada.Text_IO;​
 +   ​package EV renames Ada.Environment_Variables;​
 +   
 +   ​procedure Print_EV (Name, Value : in String) is
 +   begin
 +      IO.Put_Line (Item => Name & "​="​ & Value);
 +   end Print_EV;
 +begin
 +   ​IO.Put_Line (Item => "​Environment_Variables test"​);​
 +   ​EV.Iterate (Process => Print_EV'​Access);​
 +end Env;
 +</​code>​
 +
 +Here's a small sample of the output generated by the above program on my system:
 +
 +  JAVA_HOME=/​usr/​lib/​java
 +  HOME=/​home/​thomas
 +  SHELL=/​bin/​bash
 +
 +There'​s a very important note about //Iterate// in the manual. It states:
 +
 +> Making calls to the procedures Set or Clear concurrently with calls to any subprogram of package Environment_Variables,​ or to any instantiation of Iterate, results in erroneous execution. Making calls to the procedures Set or Clear in the actual subprogram corresponding to the Process parameter of Iterate results in erroneous execution.
 +
 +So you cannot call either //Set// or //Clear// while using //​Iterate//,​ at least not without risking a certain amount of undefined behavior.
 +
 +[[Ada.Environment_Variables.Iterate Example Source]]
  

Navigation