summaryrefslogtreecommitdiff
path: root/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLineParser.cpp
blob: 5f7d1d603bdf82d362d09d93c65ed109a9199d6f (plain)
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
// file      : CCF/CodeGenerationKit/CommandLineParser.cpp
// author    : Boris Kolpackov <boris@dre.vanderbilt.edu>
// cvs-id    : $Id$

#include "CCF/CodeGenerationKit/CommandLineParser.hpp"

#include <string>
#include <iostream>

using std::cerr;
using std::endl;

bool
parse (int argc, char* argv[], CL::Description const& cld, CommandLine& cl)
{
  cl.command = argv[0];

  bool seen_double_dash (false);

  for (int i (1); i < argc; ++i)
  {
    std::string arg (argv[i]);

    if (seen_double_dash)
    {
      cl.arguments.push_back (arg);
      continue;
    }

    if (arg == "--")
    {
      seen_double_dash = true;
      continue;
    }

    if (arg.length () > 0 && arg[0] == '-')
    {
      if (arg.length () > 1 && arg[1] == '-')
      {
        // Double-dash (long) option.
        //

        std::string op (arg, 2);

        if (CL::OptionDescription const* d = cld.find_option (op))
        {
          if (d->type () == CL::OptionType::value)
          {
            if (++i >= argc)
            {
              cerr << argv[0] << ": argument expected for option '--"
                   << op << "'" << endl;
              return false;
            }

            // cerr << "--" << op << ": " << argv[i] << endl;

            cl.options.push_back (CommandLine::Option (op, argv[i]));
          }
          else
            cl.options.push_back (CommandLine::Option (op));

          continue;
        }
      }
      else
      {
        // Single-dash (short) option. We support two formats: '-D foo' and
        // -Dfoo.
        //
        std::string op (arg, 1, 1);

        if (CL::OptionDescription const* d = cld.find_option (op))
        {
          if (d->type () == CL::OptionType::value)
          {
            std::string value;

            if (arg.length () > 2)
            {
              value.assign (arg, 2, arg.size () - 2);
            }
            else
            {
              if (++i >= argc)
              {
                cerr << argv[0] << ": argument expected for option '-"
                     << op << "'" << endl;
                return false;
              }

              value = argv[i];
            }

            // cerr << "-" << op << ": " << value << endl;

            cl.options.push_back (CommandLine::Option (op, value));
          }
          else
          {
            if (arg.length () > 2)
            {
              cerr << argv[0] << ": argument not expected for option '-"
                   << op << "' in '" << arg << "'" << endl;
              return false;
            }

            cl.options.push_back (CommandLine::Option (op));
          }

          continue;
        }
      }
    }

    cl.arguments.push_back (arg);
  }

  return true;
}