mCRL2
Loading...
Searching...
No Matches
tool.h
Go to the documentation of this file.
1// Author(s): Wieger Wesselink
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9/// \file mcrl2/utilities/tool.h
10/// \brief add your file description here.
11
12#ifndef MCRL2_UTILITIES_TOOL_H
13#define MCRL2_UTILITIES_TOOL_H
14
15#include "mcrl2/utilities/logger.h"
16
17#include "mcrl2/utilities/command_line_interface.h"
18#include "mcrl2/utilities/execution_timer.h"
19#include "mcrl2/utilities/platform.h"
20
21#ifdef MCRL2_PLATFORM_WINDOWS
22 #include <io.h>
23 #include <fcntl.h>
24#endif
25
26/// \brief The namespace for command line tool classes
27namespace mcrl2::utilities::tools
28{
29
30/// \brief Base class for command line tools.
31/// as result.
32class tool
33{
34 protected:
35 /// The name of the tool
37
38 /// The name of the developer(s)
40
41 /// One-line "what is" description of the tool
43
44 /// The description of the tool
46
47 /// Known issues of the tool
49
50 /// The filename to which timings must be written
52
53 /// The timer which can be used by the tools
55
56 /// Determines whether timing output should be written
57 bool m_timing_enabled = false;
58
59 /// \brief Add options to an interface description.
60 /// \param desc An interface description
62 {
63 desc.add_option("timings", make_optional_argument<std::string>("FILE", ""),
64 "append timing measurements to FILE. Measurements are written to "
65 "standard error if no FILE is provided");
66 }
67
68 /// \brief Parse non-standard options
69 /// \param parser A command line parser
70 virtual void parse_options(const command_line_parser& parser)
71 {
72 if (parser.options.count("timings") > 0)
73 {
74 m_timing_enabled = true;
75 log::logger::set_report_time_info();
76 m_timing_filename = parser.option_argument("timings");
77 }
78 }
79
80 /// \brief Executed only if run would be executed and invoked before run.
81 /// \return Whether run should still be executed
82 virtual bool pre_run(int& /*argc*/, char** /*argv*/)
83 {
84 return true;
85 }
86
87 /// \brief Parse standard options
88 /// \param parser A command line parser
89 virtual void check_standard_options(const command_line_parser& parser)
90 {
91 if (parser.options.count("quiet"))
92 {
93 if (parser.options.count("debug"))
94 {
95 parser.error("options -q/--quiet and -d/--debug cannot be used together\n");
96 }
97 if (parser.options.count("verbose"))
98 {
99 parser.error("options -q/--quiet and -v/--verbose cannot be used together\n");
100 }
101 }
102#ifndef MCRL2_TOOL_CLASSES_NO_CORE
103 if (parser.options.count("quiet"))
104 {
105 log::logger::set_reporting_level(log::log_level_t::quiet);
106 }
107 if (parser.options.count("verbose"))
108 {
109 log::logger::set_reporting_level(log::log_level_t::verbose);
110 }
111 if (parser.options.count("debug"))
112 {
113 log::logger::set_reporting_level(log::log_level_t::debug);
114 }
115 if (parser.options.count("log-level"))
116 {
117 log::logger::set_reporting_level(log::log_level_from_string(parser.option_argument("log-level")));
118 }
119#endif
120 }
121
122 /// \brief Checks if the number of positional options is OK.
123 /// By default this function handles standard options: -v, -d and -q
124 /// Furthermore, it checks that all options occur at most once
125 /// \param parser A command line parser
127 {
129 }
130
131 /// \brief Returns the synopsis of the tool
132 /// \return The string "[OPTION]...\n"
133 virtual std::string synopsis() const
134 {
135 return "[OPTION]...\n";
136 }
137
138 public:
139 /// \brief Constructor.
140 tool(const std::string& name,
141 const std::string& author,
142 const std::string& what_is,
143 const std::string& tool_description,
144 std::string known_issues = ""
145 )
146 : m_name(name),
153 {}
154
155 /// \brief Destructor.
156 virtual ~tool() = default;
157
158 /// \brief Run the tool. The options must be set manually.
159 /// \return True if the tool execution was successful.
160 virtual bool run() = 0;
161
162 /// \brief Return the filename in which timings must be saved.
163 const std::string& timing_filename() const
164 {
165 return m_timing_filename;
166 }
167
168 /// \brief Return reference to the timer that can be used.
170 {
171 return m_timer;
172 }
173
174 /// \brief Run the tool with the given command line options.
175 /// \param argc Number of command line arguments
176 /// \param argv Command line arguments
177 /// \return The execution result
178 /// \post If timing was enabled, timer().report() has been called
179 int execute(int argc, char** argv)
180 {
181#ifdef MCRL2_PLATFORM_WINDOWS
182 // All tools expect their std::cin to be binary streams. In Windows,
183 // this is the way to guarantee this. In applications that do not have
184 // a standard input attached (Windows-mode applications for instance),
185 // _fileno(stdin) returns a value less than 0.
186 if (_fileno(stdin) >= 0 && _setmode(_fileno(stdin), _O_BINARY) == -1)
187 {
188 throw std::runtime_error("Cannot set stdin to binary mode");
189 }
190#endif
191 try
192 {
193 interface_description clinterface(argv[0], m_name, m_author, m_what_is, synopsis(), m_tool_description, m_known_issues);
194 add_options(clinterface);
195 command_line_parser parser(clinterface, argc, argv);
197
198 if (parser.continue_execution())
199 {
201 parse_options(parser);
202
203 // If pre_run succeeds, then do the actual running.
204 bool result = pre_run(argc, argv);
205 if (result)
206 {
207 // Create timer, and by default measure running time of run()
208 // method.
209 m_timer = execution_timer(m_name, timing_filename());
210
211 timer().start("total");
212 result = run();
213 timer().finish("total");
214
216 {
218 }
219 }
220
221 // Either pre_run or run failed.
222 if (!result)
223 {
224 return EXIT_FAILURE;
225 }
226 }
227
228 return EXIT_SUCCESS;
229 }
230 catch (mcrl2::runtime_error& e)
231 {
232 mCRL2log(mcrl2::log::log_level_t::error) << e.what() << std::endl;
233 }
234 catch (std::exception& e)
235 {
236 mCRL2log(mcrl2::log::log_level_t::error) << e.what() << std::endl;
237 }
238 return EXIT_FAILURE;
239 }
240};
241
242} // namespace mcrl2::utilities::tools
243
244#endif // MCRL2_UTILITIES_TOOL_H
Main parsing component for command line strings as well as interface to the results of parsing....
bool continue_execution() const
Whether main program execution should continue.
void check_no_duplicate_arguments() const
Checks that all arguments are passed at most once.
Simple timer to time the CPU time used by a piece of code.
void report()
Write all timing information that has been recorded.
Command line interface description component.
Base class for command line tools. as result.
Definition tool.h:33
const std::string & timing_filename() const
Return the filename in which timings must be saved.
Definition tool.h:163
std::string m_timing_filename
The filename to which timings must be written.
Definition tool.h:51
virtual void parse_options(const command_line_parser &parser)
Parse non-standard options.
Definition tool.h:70
virtual bool pre_run(int &, char **)
Executed only if run would be executed and invoked before run.
Definition tool.h:82
virtual void add_options(interface_description &desc)
Add options to an interface description.
Definition tool.h:61
std::string m_name
The name of the tool.
Definition tool.h:36
virtual ~tool()=default
Destructor.
tool(const std::string &name, const std::string &author, const std::string &what_is, const std::string &tool_description, std::string known_issues="")
Constructor.
Definition tool.h:140
virtual bool run()=0
Run the tool. The options must be set manually.
std::string m_tool_description
The description of the tool.
Definition tool.h:45
bool m_timing_enabled
Determines whether timing output should be written.
Definition tool.h:57
execution_timer m_timer
The timer which can be used by the tools.
Definition tool.h:54
execution_timer & timer()
Return reference to the timer that can be used.
Definition tool.h:169
virtual void check_standard_options(const command_line_parser &parser)
Parse standard options.
Definition tool.h:89
int execute(int argc, char **argv)
Run the tool with the given command line options.
Definition tool.h:179
std::string m_known_issues
Known issues of the tool.
Definition tool.h:48
std::string m_what_is
One-line "what is" description of the tool.
Definition tool.h:42
virtual std::string synopsis() const
Returns the synopsis of the tool.
Definition tool.h:133
virtual void check_positional_options(const command_line_parser &parser)
Checks if the number of positional options is OK. By default this function handles standard options: ...
Definition tool.h:126
std::string m_author
The name of the developer(s)
Definition tool.h:39
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:435
The namespace for command line tool classes.