Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/program_options/src/parsers.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 6.2 KB
Line 
1// Copyright Vladimir Prus 2002-2004.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt
4// or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6
7#include <boost/config.hpp>
8
9#define BOOST_PROGRAM_OPTIONS_SOURCE
10#include <boost/program_options/config.hpp>
11#include <boost/program_options/parsers.hpp>
12#include <boost/program_options/options_description.hpp>
13#include <boost/program_options/positional_options.hpp>
14#include <boost/program_options/detail/cmdline.hpp>
15#include <boost/program_options/detail/config_file.hpp>
16#include <boost/program_options/environment_iterator.hpp>
17#include <boost/program_options/detail/convert.hpp>
18
19#include <boost/bind.hpp>
20#include <boost/throw_exception.hpp>
21
22#include <cctype>
23
24#if !defined(__GNUC__) || __GNUC__ < 3
25#include <iostream>
26#else
27#include <istream>
28#endif
29
30#ifdef _WIN32
31#include <stdlib.h>
32#else
33#include <unistd.h>
34#endif
35
36// The 'environ' should be declared in some cases. E.g. Linux man page says:
37// (This variable must be declared in the user program, but is declared in
38// the header file unistd.h in case the header files came from libc4 or libc5,
39// and in case they came from glibc and _GNU_SOURCE was defined.)
40// To be safe, declare it here.
41
42// It appears that on Mac OS X the 'environ' variable is not
43// available to dynamically linked libraries.
44// See: http://article.gmane.org/gmane.comp.lib.boost.devel/103843
45// See: http://lists.gnu.org/archive/html/bug-guile/2004-01/msg00013.html
46#if defined(__APPLE__) && defined(__DYNAMIC__)
47#include <crt_externs.h>
48#define environ (*_NSGetEnviron())
49#else
50#if defined(__MWERKS__)
51#include <crtl.h>
52#else
53#if !defined(_WIN32) || defined(__COMO_VERSION__)
54extern char** environ;
55#endif
56#endif
57#endif
58
59using namespace std;
60
61namespace boost { namespace program_options {
62
63#ifndef BOOST_NO_STD_WSTRING
64    namespace {
65        woption woption_from_option(const option& opt)
66        {
67            woption result;
68            result.string_key = opt.string_key;
69            result.position_key = opt.position_key;
70           
71            std::transform(opt.value.begin(), opt.value.end(),
72                           back_inserter(result.value),
73                           bind(from_utf8, _1));
74            return result;
75        }
76    }
77
78    basic_parsed_options<wchar_t>
79    ::basic_parsed_options(const parsed_options& po)
80    : description(po.description),
81      utf8_encoded_options(po)
82    {
83        for (unsigned i = 0; i < po.options.size(); ++i)
84            options.push_back(woption_from_option(po.options[i]));
85    }
86#endif
87
88    template<class charT>
89    basic_parsed_options<charT>
90    parse_config_file(std::basic_istream<charT>& is, 
91                      const options_description& desc)
92    {   
93        set<string> allowed_options;
94
95        const vector<shared_ptr<option_description> >& options = desc.options();
96        for (unsigned i = 0; i < options.size(); ++i)
97        {
98            const option_description& d = *options[i];
99
100            if (d.long_name().empty())
101                boost::throw_exception(
102                    error("long name required for config file"));
103
104            allowed_options.insert(d.long_name());
105        }
106
107        // Parser return char strings
108        parsed_options result(&desc);       
109        copy(detail::basic_config_file_iterator<charT>(is, allowed_options), 
110             detail::basic_config_file_iterator<charT>(), 
111             back_inserter(result.options));
112        // Convert char strings into desired type.
113        return basic_parsed_options<charT>(result);
114    }
115
116    template
117    BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options<char>
118    parse_config_file(std::basic_istream<char>& is, 
119                      const options_description& desc);
120
121#ifndef BOOST_NO_STD_WSTRING
122    template
123    BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options<wchar_t>
124    parse_config_file(std::basic_istream<wchar_t>& is, 
125                      const options_description& desc);
126#endif
127   
128// This versio, which accepts any options without validation, is disabled,
129// in the hope that nobody will need it and we cant drop it altogether.
130// Besides, probably the right way to handle all options is the '*' name.
131#if 0
132    BOOST_PROGRAM_OPTIONS_DECL parsed_options
133    parse_config_file(std::istream& is)
134    {
135        detail::config_file_iterator cf(is, false);
136        parsed_options result(0);
137        copy(cf, detail::config_file_iterator(),
138             back_inserter(result.options));
139        return result;
140    }
141#endif
142
143    BOOST_PROGRAM_OPTIONS_DECL parsed_options
144    parse_environment(const options_description& desc, 
145                      const function1<std::string, std::string>& name_mapper)
146    {
147        parsed_options result(&desc);
148       
149        for(environment_iterator i(environ), e; i != e; ++i) {
150            string option_name = name_mapper(i->first);
151
152            if (!option_name.empty()) {
153                option n;
154                n.string_key = option_name;
155                n.value.push_back(i->second);
156                result.options.push_back(n);
157            }               
158        }
159
160        return result;
161    }
162
163    namespace {
164        class prefix_name_mapper {
165        public:
166            prefix_name_mapper(const std::string& prefix)
167            : prefix(prefix)
168            {}
169
170            std::string operator()(const std::string& s)
171            {
172                string result;
173                if (s.find(prefix) == 0) {
174                    for(string::size_type n = prefix.size(); n < s.size(); ++n) 
175                    {   
176                        // Intel-Win-7.1 does not understand
177            // push_back on string.         
178                        result += tolower(s[n]);
179                    }
180                }
181                return result;
182            }
183        private:
184            std::string prefix;
185        };
186    }
187
188    BOOST_PROGRAM_OPTIONS_DECL parsed_options
189    parse_environment(const options_description& desc, 
190                      const std::string& prefix)
191    {
192        return parse_environment(desc, prefix_name_mapper(prefix));
193    }
194
195    BOOST_PROGRAM_OPTIONS_DECL parsed_options
196    parse_environment(const options_description& desc, const char* prefix)
197    {
198        return parse_environment(desc, string(prefix));
199    }
200
201
202
203
204}}
Note: See TracBrowser for help on using the repository browser.