helics  3.0.1
helicsCLI11.hpp
1 /*
2 Copyright (c) 2017-2021,
3 Battelle Memorial Institute; Lawrence Livermore National Security, LLC; Alliance for Sustainable
4 Energy, LLC. See the top-level NOTICE for additional details. All rights reserved.
5 SPDX-License-Identifier: BSD-3-Clause
6 */
7 
8 #pragma once
9 
10 #define CLI11_EXPERIMENTAL_OPTIONAL 0
11 #include "helics/external/CLI11/CLI11.hpp"
12 
13 #include <string>
14 #include <utility>
15 #include <vector>
16 #undef CLI11_EXPERIMENTAL_OPTIONAL
17 #include "CoreTypes.hpp"
18 #include "helicsTime.hpp"
19 #if defined HELICS_SHARED_LIBRARY || !defined HELICS_STATIC_CORE_LIBRARY
20 # include "../application_api/timeOperations.hpp"
21 # include "../application_api/typeOperations.hpp"
22 
25 using helics::to_string;
26 #else
27 # include "../utilities/timeStringOps.hpp"
28 # include "coreTypeOperations.hpp"
29 
30 using helics::core::coreTypeFromString;
31 using helics::core::to_string;
33 inline helics::Time loadTimeFromString(const std::string& str, time_units defUnit)
34 {
35  return gmlc::utilities::loadTimeFromString<helics::Time>(str, defUnit);
36 }
37 
38 #endif
39 #include "helicsVersion.hpp"
40 namespace helics {
41 class helicsCLI11App: public CLI::App {
42  public:
43  explicit helicsCLI11App(std::string app_description = "", const std::string& app_name = ""):
44  CLI::App(std::move(app_description), app_name, nullptr)
45  {
46  set_help_flag("-h,-?,--help", "Print this help message and exit");
47  set_config("--config-file,--config",
48  "helics_config.toml",
49  "specify base configuration file");
50  set_version_flag("--version", helics::versionString);
51  add_option_group("quiet")->immediate_callback()->add_flag("--quiet",
52  quiet,
53  "silence most print output");
54  }
55 
56  enum class parse_output : int {
57  ok = 0,
58  help_call = 1,
59  help_all_call = 2,
60  version_call = 4,
61  parse_error = -4,
62  };
63  bool quiet{false};
64  bool passConfig{true};
65  parse_output last_output{parse_output::ok};
66 
67  template<typename... Args>
68  parse_output helics_parse(Args&&... args) noexcept
69  {
70  try {
71  parse(std::forward<Args>(args)...);
72  last_output = parse_output::ok;
73  remArgs = remaining_for_passthrough();
74  if (passConfig) {
75  auto* opt = get_option_no_throw("--config");
76  if (opt != nullptr && opt->count() > 0) {
77  remArgs.push_back(opt->as<std::string>());
78  remArgs.emplace_back("--config");
79  }
80  }
81 
82  return parse_output::ok;
83  }
84  catch (const CLI::CallForHelp& ch) {
85  if (!quiet) {
86  exit(ch);
87  }
88  last_output = parse_output::help_call;
89  return parse_output::help_call;
90  }
91  catch (const CLI::CallForAllHelp& ca) {
92  if (!quiet) {
93  exit(ca);
94  }
95  last_output = parse_output::help_all_call;
96  return parse_output::help_all_call;
97  }
98  catch (const CLI::CallForVersion& cv) {
99  if (!quiet) {
100  exit(cv);
101  }
102  last_output = parse_output::version_call;
103  return parse_output::version_call;
104  }
105  catch (const CLI::Error& ce) {
106  CLI::App::exit(ce);
107  last_output = parse_output::parse_error;
108  return parse_output::parse_error;
109  }
110  catch (...) {
111  last_output = parse_output::parse_error;
112  return parse_output::parse_error;
113  }
114  }
115  std::vector<std::string>& remainArgs() { return remArgs; }
116  void remove_helics_specifics()
117  {
118  set_help_flag();
119  set_config();
120  try {
121  remove_option(get_option_no_throw("-v"));
122  remove_subcommand(get_option_group("quiet"));
123  }
124  catch (const CLI::Error&) {
125  // must have been removed earlier
126  }
127  }
129  void add_callback(std::function<void()> cback)
130  {
131  if (cbacks.empty()) {
132  callback([this]() {
133  for (auto& cb : cbacks) {
134  cb();
135  }
136  });
137  }
138  cbacks.push_back(std::move(cback));
139  }
140 
141  void addTypeOption(bool includeEnvironmentVariable = true)
142  {
143  auto* og = add_option_group("network type")->immediate_callback();
144  auto* typeOption =
145  og->add_option_function<std::string>(
146  "--coretype,-t",
147  [this](const std::string& val) {
148  coreType = coreTypeFromString(val);
149  if (coreType == CoreType::UNRECOGNIZED) {
150  throw CLI::ValidationError(val + " is NOT a recognized core type");
151  }
152  },
153  "type of the core to connect to")
154  ->default_str("(" + to_string(coreType) + ")")
155  ->ignore_case()
156  ->ignore_underscore();
157  if (includeEnvironmentVariable) {
158  typeOption->envname("HELICS_CORE_TYPE");
159  }
160  }
161  CoreType getCoreType() const { return coreType; }
163  void setDefaultCoreType(CoreType type) { coreType = type; }
164 
165  private:
166  std::vector<std::function<void()>> cbacks;
167  std::vector<std::string> remArgs;
168  CoreType coreType{CoreType::DEFAULT};
169 };
170 } // namespace helics
171 
172 // use the CLI lexical cast function overload to convert a string into a time
173 namespace CLI {
174 namespace detail {
175  template<>
176  inline bool lexical_cast<helics::Time>(const std::string& input, helics::Time& output)
177  {
178  try {
179  output = loadTimeFromString(input, time_units::ms);
180  }
181  catch (std::invalid_argument&) {
182  return false;
183  }
184  return true;
185  }
186 
187  template<>
188  constexpr const char* type_name<helics::Time>()
189  {
190  return "TIME";
191  }
192 } // namespace detail
193 } // namespace CLI
helics::helicsCLI11App::add_callback
void add_callback(std::function< void()> cback)
Definition: helicsCLI11.hpp:129
helics::CoreType
CoreType
Definition: CoreTypes.hpp:36
helics::helicsCLI11App::setDefaultCoreType
void setDefaultCoreType(CoreType type)
Definition: helicsCLI11.hpp:163
helics::coreTypeFromString
CoreType coreTypeFromString(std::string type) noexcept
Definition: typeOperations.cpp:17
helics::Time
TimeRepresentation< count_time< 9 > > Time
Definition: helicsTime.hpp:27
coreTypeOperations.hpp
helics::CoreType::DEFAULT
@ DEFAULT
ZMQ if available or UDP.
helics::helicsCLI11App
Definition: helicsCLI11.hpp:41
helics::versionString
constexpr auto versionString
Definition: helicsVersion.hpp:16
helics::CoreType::UNRECOGNIZED
@ UNRECOGNIZED
unknown
helics
the main namespace for the helics co-simulation library User functions will be in the helics namespac...
Definition: AsyncFedCallInfo.hpp:14
helics::loadTimeFromString
Time loadTimeFromString(const std::string &timeString)
Definition: timeOperations.cpp:19
helics::to_string
std::string to_string(CoreType type)
Definition: typeOperations.cpp:12
CoreTypes.hpp
helicsTime.hpp
helicsVersion.hpp