~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/program_options/config_file.h

  • Committer: Lee Bieber
  • Date: 2010-11-14 23:15:42 UTC
  • mfrom: (1929.1.42 warning-stack-frame)
  • Revision ID: kalebral@gmail.com-20101114231542-fnnu6ydd2p17n582
Merge Monty - fix bug 672372: some functions use > 32k stack

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2002-2004 Vladimir Prus.
3
 
 * Copyright (C) 2010 Monty Taylor
 
2
 * Copyright (c) 2002-2004 Vladimir Prus.
4
3
 *
5
4
 * Distributed under the Boost Software License, Version 1.0.
6
5
 * (See accompanying file LICENSE_1_0.txt or copy at
29
28
namespace program_options
30
29
{
31
30
 
32
 
typedef std::pair<std::string, std::string> option_result_pair;
33
 
std::string parse_suffix(const std::string& arg_val);
34
 
option_result_pair parse_size_suffixes(std::string s);
35
 
option_result_pair parse_size_arg(std::string s);
36
 
 
37
 
std::string parse_suffix(const std::string& arg_val)
38
 
{
39
 
  try
40
 
  {
41
 
    size_t size_suffix_pos= arg_val.find_last_of("kmgKMG");
42
 
    if (size_suffix_pos == arg_val.size()-1)
43
 
    {
44
 
      char suffix= arg_val[size_suffix_pos];
45
 
      std::string size_val(arg_val.substr(0, size_suffix_pos));
46
 
 
47
 
      uint64_t base_size= boost::lexical_cast<uint64_t>(size_val);
48
 
      uint64_t new_size= 0;
49
 
 
50
 
      switch (suffix)
51
 
      {
52
 
      case 'K':
53
 
      case 'k':
54
 
        new_size= base_size * 1024;
55
 
        break;
56
 
      case 'M':
57
 
      case 'm':
58
 
        new_size= base_size * 1024 * 1024;
59
 
        break;
60
 
      case 'G':
61
 
      case 'g':
62
 
        new_size= base_size * 1024 * 1024 * 1024;
63
 
        break;
64
 
      }
65
 
      return boost::lexical_cast<std::string>(new_size);
66
 
    }
67
 
  }
68
 
  catch (std::exception&)
69
 
  { }
70
 
 
71
 
  return arg_val;
72
 
}
73
 
 
74
 
option_result_pair parse_size_suffixes(std::string s)
75
 
{
76
 
  size_t equal_pos= s.find("=");
77
 
  if (equal_pos != std::string::npos)
78
 
  {
79
 
    std::string arg_key(s.substr(0, equal_pos));
80
 
    std::string arg_val(parse_suffix(s.substr(equal_pos+1)));
81
 
 
82
 
    if (arg_val != s.substr(equal_pos+1))
83
 
    {
84
 
      return std::make_pair(arg_key, arg_val);
85
 
    }
86
 
  }
87
 
 
88
 
  return std::make_pair(std::string(""), std::string(""));
89
 
}
90
 
 
91
 
option_result_pair parse_size_arg(std::string s)
92
 
{
93
 
  if (s.find("--") == 0)
94
 
  {
95
 
    return parse_size_suffixes(s.substr(2));
96
 
  }
97
 
  return make_pair(std::string(""), std::string(""));
98
 
}
99
 
 
100
31
class invalid_syntax :
101
32
  public boost::program_options::error
102
33
{
103
34
public:
104
 
  enum kind_t
105
 
  {
 
35
  enum kind_t {
106
36
    long_not_allowed = 30,
107
37
    long_adjacent_not_allowed,
108
38
    short_adjacent_not_allowed,
176
106
 
177
107
invalid_syntax::invalid_syntax(const std::string& in_tokens,
178
108
                               invalid_syntax::kind_t in_kind) :
179
 
  boost::program_options::error(error_message(in_kind).append(" in '").append(in_tokens).append("'")),
180
 
  m_tokens(in_tokens),
181
 
  m_kind(in_kind)
182
 
{ }
 
109
 boost::program_options::error(error_message(in_kind).append(" in '").append(in_tokens).append("'"))
 
110
, m_tokens(in_tokens)
 
111
  , m_kind(in_kind)
 
112
{}
183
113
 
184
114
namespace detail
185
115
{
255
185
 
256
186
      if (!s.empty()) {
257
187
        // Handle section name
258
 
        if (*s.begin() == '[' && *s.rbegin() == ']')
259
 
        {
 
188
        if (*s.begin() == '[' && *s.rbegin() == ']') {
260
189
          m_prefix = s.substr(1, s.size()-2);
261
190
          if (*m_prefix.rbegin() != '.')
262
191
            m_prefix += '.';
263
192
        }
264
 
        else
265
 
        {
266
 
          
267
 
          std::string name;
268
 
          std::string option_value("true");
269
 
 
270
 
          if ((n = s.find('=')) != std::string::npos)
271
 
          {
272
 
 
273
 
            name = m_prefix + boost::trim_copy(s.substr(0, n));
274
 
            option_value = boost::trim_copy(parse_suffix(s.substr(n+1)));
275
 
 
276
 
          }
277
 
          else
278
 
          {
279
 
            name = m_prefix + boost::trim_copy(s);
280
 
          }
 
193
        else if ((n = s.find('=')) != std::string::npos) {
 
194
 
 
195
          std::string name = m_prefix + boost::trim_copy(s.substr(0, n));
 
196
          std::string option_value = boost::trim_copy(s.substr(n+1));
281
197
 
282
198
          bool registered = allowed_option(name);
283
199
          if (!registered && !m_allow_unregistered)
293
209
          this->value().original_tokens.push_back(option_value);
294
210
          break;
295
211
 
 
212
        } else {
 
213
          boost::throw_exception(invalid_syntax(s, invalid_syntax::unrecognized_line));
296
214
        }
297
215
      }
298
216
    }
318
236
  {
319
237
    std::string s(name);
320
238
    assert(!s.empty());
321
 
    if (*s.rbegin() == '*')
322
 
    {
 
239
    if (*s.rbegin() == '*') {
323
240
      s.resize(s.size()-1);
324
241
      bool bad_prefixes(false);
325
242
      // If 's' is a prefix of one of allowed suffix, then
327
244
      // If some element is prefix of 's', then lower_bound will
328
245
      // return the next element.
329
246
      std::set<std::string>::iterator i = allowed_prefixes.lower_bound(s);
330
 
      if (i != allowed_prefixes.end())
331
 
      {
 
247
      if (i != allowed_prefixes.end()) {
332
248
        if (i->find(s) == 0)
333
249
          bad_prefixes = true;                    
334
250
      }
335
 
      if (i != allowed_prefixes.begin())
336
 
      {
 
251
      if (i != allowed_prefixes.begin()) {
337
252
        --i;
338
253
        if (s.find(*i) == 0)
339
254
          bad_prefixes = true;
423
338
bool
424
339
basic_config_file_iterator<charT>::getline(std::string& s)
425
340
{
426
 
  if (std::getline(*is, s))
427
 
  {
 
341
  if (std::getline(*is, s)) {
428
342
    return true;
429
 
  }
430
 
  else
431
 
  {
 
343
  } else {
432
344
    return false;
433
345
  }
434
346
}
453
365
    const boost::program_options::option_description& d= *options[i];
454
366
 
455
367
    if (d.long_name().empty())
456
 
      boost::throw_exception(boost::program_options::error("long name required for config file"));
 
368
      boost::throw_exception(
 
369
                             boost::program_options::error("long name required for config file"));
457
370
 
458
371
    allowed_options.insert(d.long_name());
459
372
  }
460
373
 
461
374
  // Parser return char strings
462
375
  boost::program_options::parsed_options result(&desc);        
463
 
  std::copy(detail::basic_config_file_iterator<charT>(is,
464
 
                                                      allowed_options,
465
 
                                                      allow_unregistered), 
 
376
  std::copy(detail::basic_config_file_iterator<charT>(
 
377
                                                      is, allowed_options, allow_unregistered), 
466
378
       detail::basic_config_file_iterator<charT>(), 
467
379
       std::back_inserter(result.options));
468
380
  // Convert char strings into desired type.