Clingo
Loading...
Searching...
No Matches
app.hh
1#pragma once
2
3#include <clingo/control.hh>
4
5#include <clingo/app.h>
6
7#include <forward_list>
8
9namespace Clingo {
10
15
17class Options {
18 public:
23 using Parser = std::function<bool(std::string_view value)>;
25 using ParserList = std::forward_list<Parser>;
26
33 Options(clingo_options_t *opts, ParserList &parsers) : opts_{opts}, parsers_{&parsers} {}
34
36 friend auto c_cast(Options const &x) -> clingo_options_t * { return x.opts_; }
37
55 void add(std::string_view group, std::string_view option, std::string_view description, Parser parser,
56 bool multi = false, std::optional<std::string_view> argument = std::nullopt) {
57 parsers_->emplace_front(std::move(parser));
58 static constexpr auto cparser = [](char const *value, size_t size, void *data, bool *result) -> bool {
59 auto &parser = *static_cast<Parser *>(data);
60 CLINGO_TRY {
61 *result = parser({value, size});
62 }
63 CLINGO_CATCH;
64 };
65 Detail::handle_error(
66 clingo_options_add(opts_, group.data(), group.size(), option.data(), option.size(), description.data(),
67 description.size(), cparser, static_cast<void *>(&parsers_->front()), multi,
68 argument ? argument->data() : nullptr, argument ? argument->size() : 0));
69 }
70
82 void add_flag(std::string_view group, std::string_view option, std::string_view description, bool &flag) {
83 Detail::handle_error(clingo_options_add_flag(opts_, group.data(), group.size(), option.data(), option.size(),
84 description.data(), description.size(), &flag));
85 }
86
87 private:
88 clingo_options_t *opts_;
89 ParserList *parsers_;
90};
91
93using ModelPrinter = std::function<void()>;
94
96class App {
97 public:
99 App() = default;
101 App(App &&other) = delete;
103 virtual ~App() = default;
104
110 auto program_name() noexcept -> std::string_view { return do_program_name(); }
111
117 auto program_version() noexcept -> std::string_view { return do_version(); }
118
125 void main(Control const &control, std::span<std::string_view const> files) { do_main(control, files); }
126
133 void print_model(ConstModel model, ModelPrinter const &printer) { do_print_model(model, printer); }
134
138 void register_options(Options options) { do_register_options(options); }
139
143 void validate_options() { do_validate_options(); }
144
145 private:
146 virtual void do_main(Control const &control, std::span<std::string_view const> files) {
147 control.parse_files(files);
148 control.main();
149 }
150 virtual void do_print_model([[maybe_unused]] ConstModel model, ModelPrinter const &printer) { printer(); }
151 virtual void do_register_options([[maybe_unused]] Options options) {}
152 virtual void do_validate_options() {}
153 virtual auto do_program_name() noexcept -> std::string_view { return CLINGO_EXECUTABLE; }
154 virtual auto do_version() noexcept -> std::string_view { return CLINGO_VERSION; }
155};
156
157namespace Detail {
158
159struct AppData {
160 App *app;
161 Options::ParserList parsers;
162};
163
164static constexpr clingo_application_t c_app = {
165 [](void *data, clingo_string_t *name) -> void {
166 auto &app_data = *static_cast<AppData *>(data);
167 auto str = app_data.app->program_name();
168 name->data = str.data();
169 name->size = str.size();
170 },
171 [](void *data, clingo_string_t *version) -> void {
172 auto &app_data = *static_cast<AppData *>(data);
173 auto str = app_data.app->program_version();
174 version->data = str.data();
175 version->size = str.size();
176 },
177 [](clingo_control_t *ctl, clingo_string_t const *files, size_t size, void *data) -> bool {
178 auto &app_data = *static_cast<AppData *>(data);
179 CLINGO_TRY {
180 auto cpp_ctl = Control{ctl, true};
181 auto cpp_files =
182 transform(std::span{files, size}, [](auto const &x) { return std::string_view{x.data, x.size}; });
183 app_data.app->main(cpp_ctl, cpp_files);
184 }
185 CLINGO_CATCH;
186 },
187 [](clingo_model_t const *model, clingo_default_model_printer_t printer, void *printer_data, void *data) -> bool {
188 auto &app_data = *static_cast<AppData *>(data);
189 CLINGO_TRY {
190 app_data.app->print_model(ConstModel{model},
191 [printer, printer_data]() { handle_error(printer(printer_data)); });
192 }
193 CLINGO_CATCH;
194 },
195 [](clingo_options_t *options, void *data) -> bool {
196 auto &app_data = *static_cast<AppData *>(data);
197 CLINGO_TRY {
198 app_data.app->register_options(Options{options, app_data.parsers});
199 }
200 CLINGO_CATCH;
201 },
202 [](void *data) -> bool {
203 auto &app_data = *static_cast<AppData *>(data);
204 CLINGO_TRY {
205 app_data.app->validate_options();
206 }
207 CLINGO_CATCH;
208 }};
209
210} // namespace Detail
211
219inline auto main(Library &lib, std::span<std::string_view const> arguments = {}, App *app = nullptr,
220 bool raise_errors = false) -> int {
221 auto code = 1;
222 try {
223 auto c_args = Detail::transform(arguments, [](auto const &x) { return clingo_string_t{x.data(), x.size()}; });
224 auto data = Detail::AppData{app, {}};
225 Detail::handle_error_no_code(clingo_main(c_cast(lib), c_args.data(), c_args.size(),
226 app != nullptr ? &Detail::c_app : nullptr,
227 app != nullptr ? static_cast<void *>(&data) : nullptr, &code));
228 } catch (std::exception const &e) {
229 if (raise_errors) {
230 throw;
231 }
232 auto name = app != nullptr ? app->program_name() : CLINGO_EXECUTABLE;
233 fprintf(stderr, "*** ERROR: (%.*s): %s\n", static_cast<int>(name.size()), name.data(), e.what());
234 }
235 return code;
236}
237
247inline auto main(Library &lib, std::initializer_list<std::string_view const> arguments, App *app = nullptr,
248 bool raise_errors = false) -> int {
249 return main(lib, std::span{arguments}, app, raise_errors);
250}
251
253
254} // namespace Clingo
Interface to build applications on top of clingo.
Definition app.hh:96
App(App &&other)=delete
Disable copying and moving.
void print_model(ConstModel model, ModelPrinter const &printer)
Customize model printing.
Definition app.hh:133
App()=default
The default constructor.
void main(Control const &control, std::span< std::string_view const > files)
Run the main control flow.
Definition app.hh:125
void validate_options()
Validate previously parsed options.
Definition app.hh:143
auto program_name() noexcept -> std::string_view
Get the name of the application.
Definition app.hh:110
void register_options(Options options)
Optionally register additional application options.
Definition app.hh:138
virtual ~App()=default
The default destructor.
auto program_version() noexcept -> std::string_view
Get the version of the application.
Definition app.hh:117
Class to provide an immutable view of a model.
Definition solve.hh:121
The main control class for grounding and solving logic programs.
Definition control.hh:179
void parse_files(StringSpan files) const
Parse files with the given paths.
Definition control.hh:242
void main() const
Run the default ground and solve flow.
Definition control.hh:345
The main library class for managing global information and logging.
Definition core.hh:471
Object to add command-line options.
Definition app.hh:17
void add(std::string_view group, std::string_view option, std::string_view description, Parser parser, bool multi=false, std::optional< std::string_view > argument=std::nullopt)
Add an option that is processed with a custom parser.
Definition app.hh:55
std::function< bool(std::string_view value)> Parser
An option parser.
Definition app.hh:23
Options(clingo_options_t *opts, ParserList &parsers)
Construct an options object.
Definition app.hh:33
friend auto c_cast(Options const &x) -> clingo_options_t *
Convert the class to it's underlying C type.
Definition app.hh:36
std::forward_list< Parser > ParserList
A list of option parsers.
Definition app.hh:25
void add_flag(std::string_view group, std::string_view option, std::string_view description, bool &flag)
Add an option that is a simple flag.
Definition app.hh:82
bool(* clingo_default_model_printer_t)(void *data)
Callback to print a model in default format.
Definition app.h:62
struct clingo_options clingo_options_t
Object to add command-line options.
Definition app.h:46
CLINGO_VISIBILITY_DEFAULT bool clingo_options_add_flag(clingo_options_t *options, char const *group, size_t group_size, char const *option, size_t option_size, char const *description, size_t description_size, bool *target)
Add an option that is a simple flag.
CLINGO_VISIBILITY_DEFAULT bool clingo_main(clingo_lib_t *lib, clingo_string_t const *arguments, size_t size, clingo_application_t const *app, void *data, int *code)
Run an application with the given library and arguments.
CLINGO_VISIBILITY_DEFAULT bool clingo_options_add(clingo_options_t *options, char const *group, size_t group_size, char const *option, size_t option_size, char const *description, size_t description_size, clingo_option_parser_t parser, void *data, bool multi, char const *argument, size_t argument_size)
Add an option that is processed with a custom parser.
#define CLINGO_VERSION
String representation of version.
Definition core.h:73
#define CLINGO_EXECUTABLE
The name of the clingo executable.
Definition core.h:75
struct clingo_model clingo_model_t
Object representing a model.
Definition model.h:43
@ model
The model represents a stable model.
std::function< void()> ModelPrinter
A callback to print the current model.
Definition app.hh:93
auto main(Library &lib, std::span< std::string_view const > arguments={}, App *app=nullptr, bool raise_errors=false) -> int
Run a clingo based application with the given arguments.
Definition app.hh:219
@ tuple
Theory tuples "(t1,...,tn)".
@ value
The configuration entry is a double value.
auto version() -> std::tuple< int, int, int >
Get the version of the Clingo library as a tuple.
Definition core.hh:730
constexpr auto transform(std::optional< T > &x, F &&f) -> Detail::transform_result< T &, F >
Implemenatation of std::optional<T>::transform.
Definition optional.hh:28
This struct contains a set of functions to customize the clingo application.
Definition app.h:75
void(* program_name)(void *data, clingo_string_t *string)
callback to obtain program name
Definition app.h:76
Struct to capture strings that are not null-terminated.
Definition core.h:91
char const * data
pointer to the beginning of the string
Definition core.h:92