CACAO
Option.cpp
Go to the documentation of this file.
1 /* src/toolbox/Option.cpp - Command line option parsing library
2 
3  Copyright (C) 1996-2014
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 #include "toolbox/Option.hpp"
26 #include "toolbox/Debug.hpp"
27 #include "toolbox/logging.hpp"
28 #include "toolbox/OStream.hpp"
29 
30 namespace cacao {
31 
32 namespace option {
33 
35  static OptionPrefix prefix("-");
36  return prefix;
37 }
38 
40  static OptionPrefix prefix("-XX:");
41  return prefix;
42 }
43 
44 } // end namespace option
45 
46 OptionPrefix::OptionPrefix(const char* name) : name(name), s(std::strlen(name)) {
47 }
49  children.insert(oe);
50 }
51 
53  static const char* blank29 = " "; // 29 spaces
54  static const char* blank25 = blank29 + 4; // 25 spaces
55  OStream OS(fp);
56 
57  std::set<OptionEntry*> sorted(root.begin(),root.end());
58 
59  for(std::set<OptionEntry*>::iterator i = sorted.begin(), e = sorted.end();
60  i != e; ++i) {
61  OptionEntry& oe = **i;
62  OS << " " << root.get_name();
63  std::size_t name_len = root.size() + oe.print(OS);
64  if (name_len < (25-1)) {
65  OS << (blank25 + name_len);
66  } else {
67  OS << nl << blank29;
68  }
69 
70  const char* c = oe.get_desc();
71  for (std::size_t i = 29; *c != 0; c++, i++) {
72  /* If we are at the end of the line, break it. */
73  if (i == 80) {
74  OS << nl << blank29;
75  i = 29;
76  }
77  OS << *c;
78  }
79  OS << nl;
80  }
81 
82 }
83 
84 std::size_t option_print(OptionEntry& option, OStream& OS) {
85  OS << option.get_name() << "=<value>";
86  return option.size() + 8;
87 }
88 
89 std::size_t option_print(OptionBase<bool>& option, OStream& OS) {
90  OS << '+' << option.get_name();
91  return option.size() + 1;
92 }
93 
94 
95 namespace {
96 
97 bool option_matcher(const char* a, std::size_t a_len,
98  const char* b, std::size_t b_len) {
99  return (a_len == b_len) && std::strncmp(a, b, a_len) == 0;
100 }
101 
102 } // end anonymous namespace
103 
104 bool OptionParser::parse_option(OptionPrefix& root, const char* name, size_t name_len,
105  const char* value, size_t value_len) {
106  assert(std::strncmp(root.get_name(), name, std::strlen(root.get_name())) == 0);
107  name += root.size();
108  name_len -= root.size();
109  assert(name_len > 0);
110  if (name[0] == '-' || name[0] == '+') {
111  assert(value_len == 0);
112  assert(value == 0);
113  value = name;
114  value_len = 1;
115  ++name;
116  --name_len;
117  }
118  for(OptionPrefix::iterator i = root.begin(), e = root.end();
119  i != e; ++i) {
120  OptionEntry& oe = **i;
121  if (option_matcher(oe.get_name(), oe.size(), name, name_len)) {
122  if (oe.parse(value,value_len))
123  return true;
124  return false;
125  }
126  }
127  return false;
128 }
129 
130 template<>
131 bool Option<const char*>::parse(const char* value, std::size_t value_len) {
132  set_value(value);
133  return true;
134 }
135 
136 template<>
137 bool Option<bool>::parse(const char* value, std::size_t value_len) {
138  assert(value_len == 1);
139  char first = value[0];
140  if (first == '-') {
141  set_value(false);
142  return true;
143  }
144  if (first == '+') {
145  set_value(true);
146  return true;
147  }
148  ABORT_MSG("ERROR", "boolean option not valid: " << value);
149  return false;
150 }
151 
152 template<>
153 bool Option<unsigned int>::parse(const char* value, std::size_t value_len) {
154  int verb = os::atoi(value);
155  set_value(verb >= 0 ? verb : 0);
156  return true;
157 }
158 
159 } // end namespace cacao
160 
161 /*
162  * These are local overrides for various environment variables in Emacs.
163  * Please do not remove this and leave it at the end of the file, where
164  * Emacs will automagically detect them.
165  * ---------------------------------------------------------------------
166  * Local variables:
167  * mode: c++
168  * indent-tabs-mode: t
169  * c-basic-offset: 4
170  * tab-width: 4
171  * End:
172  * vim:noexpandtab:sw=4:ts=4:
173  */
const char * get_name() const
Definition: Option.hpp:101
iterator end()
Definition: Option.hpp:75
static void print_usage(OptionPrefix &root, FILE *fp=stdout)
Definition: Option.cpp:52
ChildSetTy::iterator iterator
Definition: Option.hpp:64
const char * get_name() const
Definition: Option.hpp:68
void insert(OptionEntry *oe)
Definition: Option.cpp:48
ChildSetTy children
Definition: Option.hpp:85
JNIEnv jclass jobject const char * name
Definition: jvmti.h:312
std::size_t option_print(OptionEntry &option, OStream &OS)
Definition: Option.cpp:84
iterator begin()
Definition: Option.hpp:74
static int atoi(const char *nptr)
Definition: os.hpp:223
OptionPrefix & root()
Definition: Option.cpp:34
Simple stream class for formatted output.
Definition: OStream.hpp:141
virtual bool parse(const char *value, std::size_t value_len)=0
std::size_t size() const
Definition: Option.hpp:104
MIIterator i
virtual std::size_t print(OStream &OS)=0
std::size_t size() const
Definition: Option.hpp:71
OStream & OS
MIIterator e
virtual bool parse(const char *value, std::size_t value_len)
This file contains the command line option parsing library.
bool parse(jitdata *jd)
Definition: parse.cpp:604
OptionPrefix & xx_root()
Definition: Option.cpp:39
const char * get_desc() const
Definition: Option.hpp:107
OptionPrefix(const char *name)
Definition: Option.cpp:46
#define ABORT_MSG(EXPR_SHORT, EXPR_LONG)
Definition: logging.hpp:133
Nl nl
Definition: OStream.cpp:56
#define fp
Definition: md-asm.hpp:79
static bool parse_option(OptionPrefix &root, const char *name, size_t name_len, const char *value, size_t value_len)
Definition: Option.cpp:104