1 //  (C) Copyright Gennadiy Rozental 2005-2008.
2 //  Distributed under the Boost Software License, Version 1.0.
3 //  (See accompanying file LICENSE_1_0.txt or copy at
4 //  http://www.boost.org/LICENSE_1_0.txt)
5 
6 //  See http://www.boost.org/libs/test for the library home page.
7 //
8 //  File        : $RCSfile$
9 //
10 //  Version     : $Revision: 54633 $
11 //
12 //  Description : defines and implements inline model of program environment
13 // ***************************************************************************
14 
15 #ifndef BOOST_RT_ENV_ENVIRONMENT_HPP_062604GER
16 #define BOOST_RT_ENV_ENVIRONMENT_HPP_062604GER
17 
18 #ifdef UNDER_CE
19 #error Windows CE does not support environment variables.
20 #endif
21 
22 // Boost.Runtime.Parameter
23 #include <boost/test/utils/runtime/config.hpp>
24 #include <boost/test/utils/runtime/fwd.hpp>
25 #include <boost/test/utils/runtime/argument.hpp>
26 #include <boost/test/utils/runtime/interpret_argument_value.hpp>
27 
28 #include <boost/test/utils/runtime/env/fwd.hpp>
29 #include <boost/test/utils/runtime/env/modifier.hpp>
30 #include <boost/test/utils/runtime/env/variable.hpp>
31 
32 // Boost.Test
33 #include <boost/test/utils/callback.hpp>
34 
35 // Boost
36 #include <boost/optional.hpp>
37 
38 namespace boost {
39 
40 namespace BOOST_RT_PARAM_NAMESPACE {
41 
42 // ************************************************************************** //
43 // **************      runtime::environment implementation     ************** //
44 // ************************************************************************** //
45 
46 namespace environment {
47 
48 namespace rt_env_detail {
49 
50 template<typename T, typename Modifiers>
51 variable_data&
init_new_var(cstring var_name,Modifiers m=nfp::no_params)52 init_new_var( cstring var_name, Modifiers m = nfp::no_params )
53 {
54     rt_env_detail::variable_data& new_vd = new_var_record( var_name );
55 
56     cstring str_value = sys_read_var( new_vd.m_var_name );
57 
58     if( !str_value.is_empty() ) {
59         try {
60             boost::optional<T> value;
61 
62             if( m.has( interpreter ) )
63                 m[interpreter]( str_value, value );
64             else
65                 interpret_argument_value( str_value, value, 0 );
66 
67             if( !!value ) {
68                 new_vd.m_value.reset( new typed_argument<T>( new_vd ) );
69 
70                 arg_value<T>( *new_vd.m_value ) = *value;
71             }
72         }
73         catch( ... ) { // !! could we do that
74             // !! should we report an error?
75         }
76     }
77 
78     if( !new_vd.m_value && m.has( default_value ) ) {
79         new_vd.m_value.reset( new typed_argument<T>( new_vd ) );
80 
81         nfp::optionally_assign( arg_value<T>( *new_vd.m_value ), m[default_value] );
82     }
83 
84     nfp::optionally_assign( new_vd.m_global_id, m, global_id );
85 
86     return new_vd;
87 }
88 
89 //____________________________________________________________________________//
90 
91 } // namespace rt_env_detail
92 
93 } // namespace environment
94 
95 // ************************************************************************** //
96 // **************             runtime::environment             ************** //
97 // ************************************************************************** //
98 
99 namespace environment {
100 
101     // variable access
102     variable_base
103     var( cstring var_name );
104 
105     //________________________________________________________________________//
106 
107     template<typename T>
108     inline variable<T>
var(cstring var_name)109     var( cstring var_name )
110     {
111         rt_env_detail::variable_data* vd = rt_env_detail::find_var_record( var_name );
112 
113         return environment::variable<T>( !vd ? rt_env_detail::init_new_var<T>( var_name, nfp::no_params ) : *vd );
114     }
115 
116     //________________________________________________________________________//
117 
118     template<typename T, typename Modifiers>
119     inline variable<T>
var(cstring var_name,Modifiers const & m)120     var( cstring var_name, Modifiers const& m )
121     {
122         rt_env_detail::variable_data* vd = rt_env_detail::find_var_record( var_name );
123 
124         return environment::variable<T>( !vd ? rt_env_detail::init_new_var<T>( var_name, m ) : *vd );
125     }
126 
127     //________________________________________________________________________//
128 
129     // direct variable value access
130     inline cstring
get(cstring var_name)131     get( cstring var_name )
132     {
133         return environment::var<cstring>( var_name ).value();
134     }
135 
136     //________________________________________________________________________//
137 
138     template<typename T>
139     inline T const&
get(cstring var_name)140     get( cstring var_name )
141     {
142         return environment::var<T>( var_name ).value();
143     }
144 
145     //________________________________________________________________________//
146 
147     template<typename T>
148     inline void
get(cstring var_name,boost::optional<T> & res)149     get( cstring var_name, boost::optional<T>& res )
150     {
151         variable<T> const& v = environment::var<T>( var_name );
152         v.value( res );
153     }
154 
155     //________________________________________________________________________//
156 
157 } // namespace environment
158 
159 namespace env = environment;
160 
161 } // namespace BOOST_RT_PARAM_NAMESPACE
162 
163 } // namespace boost
164 
165 #ifndef BOOST_RT_PARAM_OFFLINE
166 
167 #define BOOST_RT_PARAM_INLINE inline
168 #include <boost/test/utils/runtime/env/environment.ipp>
169 
170 #endif
171 
172 #endif // BOOST_RT_ENV_ENVIRONMENT_HPP_062604GER
173