Skip to content

Commit f93e0e6

Browse files
Add cmdline_definitiont
A structured way of defining command line options.
1 parent 0db1830 commit f93e0e6

File tree

3 files changed

+229
-0
lines changed

3 files changed

+229
-0
lines changed

src/util/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ SRC = allocate_objects.cpp \
66
byte_operators.cpp \
77
c_types.cpp \
88
cmdline.cpp \
9+
cmdline_definition.cpp \
910
config.cpp \
1011
cout_message.cpp \
1112
decision_procedure.cpp \

src/util/cmdline_definition.cpp

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*******************************************************************\
2+
3+
Module: Command line parsing
4+
5+
Author: Peter Schrammel
6+
7+
\*******************************************************************/
8+
9+
// \file Command line options definition
10+
11+
#include "cmdline_definition.h"
12+
13+
#include <sstream>
14+
15+
#include <util/invariant.h>
16+
#include <util/json.h>
17+
#include <util/xml.h>
18+
19+
cmdline_optiont::cmdline_optiont(
20+
std::string name,
21+
optionalt<argumentt> argument,
22+
std::string help_text,
23+
std::string option_group,
24+
optionalt<std::string> deprecated)
25+
: name(name),
26+
argument(argument),
27+
help_text(help_text),
28+
option_group(option_group),
29+
deprecated(deprecated)
30+
{
31+
}
32+
33+
cmdline_optiont::argumentt::argumentt(std::string name, std::string type)
34+
: name(name), type(type)
35+
{
36+
}
37+
38+
cmdline_definitiont::cmdline_definitiont(
39+
std::initializer_list<cmdline_optiont> &&initializer_list)
40+
: cmdline_options(initializer_list)
41+
{
42+
}
43+
44+
void cmdline_definitiont::concat(const cmdline_definitiont &other)
45+
{
46+
cmdline_options.insert(
47+
cmdline_options.end(),
48+
other.cmdline_options.begin(),
49+
other.cmdline_options.end());
50+
}
51+
52+
std::string cmdline_definitiont::to_help_text(
53+
std::size_t option_width,
54+
std::size_t total_width) const
55+
{
56+
std::ostringstream os;
57+
std::string option_group;
58+
for(const auto &option : cmdline_options)
59+
{
60+
// do not print deprecated options
61+
if(option.deprecated.has_value())
62+
continue;
63+
64+
// print option group at the start of a new grouop
65+
if(option.option_group != option_group)
66+
{
67+
option_group = option.option_group;
68+
os << '\n' << option_group << ":\n";
69+
}
70+
71+
// print option with optional argument and auto-wrap help text
72+
std::string option_text = option.name;
73+
if(option.name.size() == 1)
74+
option_text = " -" + option_text;
75+
else
76+
option_text = " --" + option_text;
77+
if(option.argument.has_value())
78+
option_text += " " + option.argument->name;
79+
os << option_text;
80+
std::size_t padding = option_width;
81+
if(option_text.size() < option_width)
82+
padding = option_width - (option_text.size());
83+
else
84+
os << '\n';
85+
std::size_t index = 0;
86+
do
87+
{
88+
os << std::string(padding, ' ')
89+
<< option.help_text.substr(index, total_width - option_width)
90+
<< '\n';
91+
padding = option_width;
92+
index += total_width - option_width;
93+
} while(index < option.help_text.size() - 1);
94+
}
95+
return os.str();
96+
}
97+
98+
std::string cmdline_definitiont::to_option_string() const
99+
{
100+
std::ostringstream os;
101+
for(const auto &option : cmdline_options)
102+
os << "(" + option.name + ")" + (option.argument.has_value() ? ":" : "");
103+
return os.str();
104+
}
105+
106+
json_arrayt cmdline_definitiont::to_json() const
107+
{
108+
json_arrayt json_array;
109+
for(const auto &option : cmdline_options)
110+
{
111+
json_objectt json_option;
112+
json_option["name"] = json_stringt(option.name);
113+
json_option["helpText"] = json_stringt(option.help_text);
114+
json_option["optionGroup"] = json_stringt(option.option_group);
115+
if(option.argument.has_value())
116+
{
117+
json_objectt &json_argument = json_option["argument"].make_object();
118+
json_argument["name"] = json_stringt(option.argument->name);
119+
json_argument["type"] = json_stringt(option.argument->type);
120+
}
121+
if(option.deprecated.has_value())
122+
{
123+
json_option["deprecated"] = json_stringt(*option.deprecated);
124+
}
125+
json_array.push_back(std::move(json_option));
126+
}
127+
return json_array;
128+
}
129+
130+
xmlt cmdline_definitiont::to_xml() const
131+
{
132+
xmlt xml_cmdline("commandline");
133+
for(const auto &option : cmdline_options)
134+
{
135+
xmlt &xml_option = xml_cmdline.new_element("option");
136+
xml_option.set_attribute("name", option.name);
137+
xml_option.new_element("help_text").data = option.help_text;
138+
xml_option.new_element("option_group").data = option.option_group;
139+
if(option.argument.has_value())
140+
{
141+
xmlt &xml_argument = xml_option.new_element("argument");
142+
xml_argument.set_attribute("name", option.argument->name);
143+
xml_argument.set_attribute("type", option.argument->type);
144+
}
145+
if(option.deprecated.has_value())
146+
{
147+
xml_option.new_element("deprecated").data = *option.deprecated;
148+
}
149+
}
150+
return xml_cmdline;
151+
}
152+
153+
cmdline_definitiont
154+
operator+(cmdline_definitiont first, const cmdline_definitiont &second)
155+
{
156+
first.concat(second);
157+
return first;
158+
}

src/util/cmdline_definition.h

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*******************************************************************\
2+
3+
Module: Command line parsing
4+
5+
Author: Peter Schrammel
6+
7+
\*******************************************************************/
8+
9+
// \file Command line options definition
10+
11+
#ifndef CPROVER_UTIL_CMDLINE_DEFINITION_H
12+
#define CPROVER_UTIL_CMDLINE_DEFINITION_H
13+
14+
#include <list>
15+
#include <string>
16+
#include <vector>
17+
18+
#include "optional.h"
19+
20+
class json_arrayt;
21+
class xmlt;
22+
23+
struct cmdline_optiont
24+
{
25+
struct argumentt
26+
{
27+
argumentt(std::string name, std::string type);
28+
29+
std::string name;
30+
std::string type;
31+
};
32+
33+
typedef std::string deprecatedt;
34+
35+
cmdline_optiont(
36+
std::string name,
37+
optionalt<argumentt> argument,
38+
std::string help_text,
39+
std::string option_group,
40+
optionalt<deprecatedt> deprecated);
41+
42+
std::string name;
43+
optionalt<argumentt> argument;
44+
std::string help_text;
45+
std::string option_group;
46+
optionalt<deprecatedt> deprecated;
47+
};
48+
49+
class cmdline_definitiont
50+
{
51+
public:
52+
explicit cmdline_definitiont(
53+
std::initializer_list<cmdline_optiont> &&initializer_list);
54+
55+
void concat(const cmdline_definitiont &other);
56+
57+
std::string
58+
to_help_text(std::size_t option_width, std::size_t total_width) const;
59+
std::string to_option_string() const;
60+
json_arrayt to_json() const;
61+
xmlt to_xml() const;
62+
63+
private:
64+
std::vector<cmdline_optiont> cmdline_options;
65+
};
66+
67+
cmdline_definitiont
68+
operator+(cmdline_definitiont first, const cmdline_definitiont &second);
69+
70+
#endif // CPROVER_UTIL_CMDLINE_DEFINITION_H

0 commit comments

Comments
 (0)