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