SST  14.0.0
StructuralSimulationToolkit
configBase.h
1 // Copyright 2009-2024 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2024, NTESS
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 #ifndef SST_CORE_CONFIGBASE_H
13 #define SST_CORE_CONFIGBASE_H
14 
15 #include "sst/core/sst_types.h"
16 
17 #include <functional>
18 #include <getopt.h>
19 #include <iostream>
20 #include <map>
21 #include <string>
22 #include <vector>
23 
24 /* Forward declare for Friendship */
25 extern int main(int argc, char** argv);
26 
27 namespace SST {
28 
29 /**
30  Struct that holds all the getopt_long options along with the
31  docuementation for the option
32 */
33 struct LongOption
34 {
35  struct option opt;
36  std::string argname;
37  std::string desc;
38  std::function<int(const char* arg)> callback;
39  bool header; // if true, desc is actually the header
40  std::vector<bool> annotations;
41  std::function<std::string(void)> ext_help;
42  mutable bool set_cmdline;
43 
44  LongOption(
45  struct option opt, const char* argname, const char* desc, const std::function<int(const char* arg)>& callback,
46  bool header, std::vector<bool> annotations, std::function<std::string(void)> ext_help, bool set_cmdline) :
47  opt(opt),
48  argname(argname),
49  desc(desc),
50  callback(callback),
51  header(header),
52  annotations(annotations),
53  ext_help(ext_help),
54  set_cmdline(set_cmdline)
55  {}
56 };
57 
59 {
60  char annotation;
61  std::string help;
62 };
63 
64 // Macros to make defining options easier. These must be called
65 // inside of a member function of a class inheriting from ConfigBase
66 // Nomenaclature is:
67 
68 // FLAG - value is either true or false. FLAG defaults to no arguments allowed
69 // ARG - value is a string. ARG defaults to required argument
70 // OPTVAL - Takes an optional paramater
71 
72 // longName - multicharacter name referenced using --
73 // shortName - single character name referenced using -
74 // text - help text
75 // func - function called if option is found
76 #define DEF_FLAG_OPTVAL(longName, shortName, text, func, ...) \
77  addOption({ longName, optional_argument, 0, shortName }, "[BOOL]", text, func, { __VA_ARGS__ });
78 
79 #define DEF_FLAG(longName, shortName, text, func, ...) \
80  addOption({ longName, no_argument, 0, shortName }, "", text, func, { __VA_ARGS__ });
81 
82 #define DEF_ARG(longName, shortName, argName, text, func, ...) \
83  addOption({ longName, required_argument, 0, shortName }, argName, text, func, { __VA_ARGS__ });
84 
85 #define DEF_ARG_OPTVAL(longName, shortName, argName, text, func, ...) \
86  addOption({ longName, optional_argument, 0, shortName }, "[" argName "]", text, func, { __VA_ARGS__ });
87 
88 // Macros that include extended help
89 #define DEF_ARG_EH(longName, shortName, argName, text, func, eh, ...) \
90  addOption({ longName, required_argument, 0, shortName }, argName, text, func, { __VA_ARGS__ }, eh);
91 
92 
93 #define DEF_SECTION_HEADING(text) addHeading(text);
94 
95 
96 /**
97  * Base class to parse command line options for SST Simulation
98  * Configuration variables.
99  *
100  * NOTE: This class contains only state for parsing the command line.
101  * All options will be stored in classes derived from this class.
102  * This means that we don't need to be able to serialize anything in
103  * this class.
104  */
106 {
107 protected:
108  /**
109  ConfigBase constructor. Meant to only be created by main
110  function
111  */
112  ConfigBase(bool suppress_print) : suppress_print_(suppress_print) {}
113 
114  /**
115  Default constructor used for serialization. After
116  serialization, the Config object is only used to get the values
117  of set options and it can no longer parse arguments. Given
118  that, it will no longer print anything, so set suppress_print_
119  to true. None of this class needs to be serialized because it
120  it's state is only for parsing the arguments.
121  */
122  ConfigBase() : suppress_print_(true) { options.reserve(100); }
123 
124 
125  ConfigBase(bool suppress_print, std::vector<AnnotationInfo> annotations) :
126  annotations_(annotations),
127  suppress_print_(suppress_print)
128  {}
129 
130  /**
131  Called to print the help/usage message
132  */
133  int printUsage();
134 
135 
136  /**
137  Called to print the extended help for an option
138  */
139  int printExtHelp(const std::string& option);
140 
141  /**
142  Add options to the Config object. The options will be added in
143  the order they are in the input array, and across calls to the
144  function.
145  */
146  void addOption(
147  struct option opt, const char* argname, const char* desc, std::function<int(const char* arg)> callback,
148  std::vector<bool> annotations, std::function<std::string(void)> ext_help = std::function<std::string(void)>());
149 
150  /**
151  Adds a heading to the usage output
152  */
153  void addHeading(const char* desc);
154 
155  /**
156  Called to get the prelude for the help/usage message
157  */
158  virtual std::string getUsagePrelude();
159 
160  // Function that will be called at the end of parsing so that
161  // error checking can be done
162  virtual int checkArgsAfterParsing();
163 
164  // Enable support for everything after -- to be passed to a
165  // callback. Each arg will be passed independently to the callback
166  // function
167  void enableDashDashSupport(std::function<int(const char* arg)> callback);
168 
169  // Add support for positional args. Must be added in the order the
170  // args show up on the command line
171  void addPositionalCallback(std::function<int(int num, const char* arg)> callback);
172 
173 
174  /**
175  Get the name of the executable being run. This is only
176  avaialable after parseCmdLine() is called.
177  */
178  std::string getRunName() { return run_name_; }
179 
180  /** Set a configuration string to update configuration values */
181  bool setOptionExternal(const std::string& entryName, const std::string& value);
182 
183  /** Get the value of an annotation for an option */
184  bool getAnnotation(const std::string& entryName, char annotation);
185 
186 public:
187  // Function to uniformly parse boolean values for command line
188  // arguments
189  static bool parseBoolean(const std::string& arg, bool& success, const std::string& option);
190 
191  virtual ~ConfigBase() {}
192 
193  /**
194  Parse command-line arguments to update configuration values.
195 
196  @return Returns 0 if execution should continue. Returns -1 if
197  there was an error. Returns 1 if run command line only asked
198  for information to be print (e.g. --help or -V, for example).
199  */
200  int parseCmdLine(int argc, char* argv[], bool ignore_unknown = false);
201 
202  /**
203  Check to see if an option was set on the command line
204 
205  @return True if option was set on command line, false
206  otherwise. Will also return false if option is unknown.
207  */
208  bool wasOptionSetOnCmdLine(const std::string& option);
209 
210 private:
211  std::vector<LongOption> options;
212  std::map<char, int> short_options;
213  std::string short_options_string;
214  size_t longest_option = 0;
215  size_t num_options = 0;
216  std::function<int(const char* arg)> dashdash_callback;
217  std::function<int(int num, const char* arg)> positional_args;
218 
219  // Map to hold extended help function calls
220  std::map<std::string, std::function<std::string(void)>> extra_help_map;
221 
222  // Annotations
223  std::vector<AnnotationInfo> annotations_;
224 
225  std::string run_name_;
226  bool suppress_print_;
227  bool has_extended_help_ = false;
228 };
229 
230 } // namespace SST
231 
232 #endif // SST_CORE_CONFIGBASE_H
void addOption(struct option opt, const char *argname, const char *desc, std::function< int(const char *arg)> callback, std::vector< bool > annotations, std::function< std::string(void)> ext_help=std::function< std::string(void)>())
Add options to the Config object.
Definition: configBase.cc:62
bool wasOptionSetOnCmdLine(const std::string &option)
Check to see if an option was set on the command line.
Definition: configBase.cc:413
void addHeading(const char *desc)
Adds a heading to the usage output.
Definition: configBase.cc:107
Struct that holds all the getopt_long options along with the docuementation for the option...
Definition: configBase.h:33
bool getAnnotation(const std::string &entryName, char annotation)
Get the value of an annotation for an option.
Definition: configBase.cc:423
virtual std::string getUsagePrelude()
Called to get the prelude for the help/usage message.
Definition: configBase.cc:116
Definition: action.cc:18
Definition: configBase.h:58
int printUsage()
Called to print the help/usage message.
Definition: configBase.cc:141
int parseCmdLine(int argc, char *argv[], bool ignore_unknown=false)
Parse command-line arguments to update configuration values.
Definition: configBase.cc:264
int printExtHelp(const std::string &option)
Called to print the extended help for an option.
Definition: configBase.cc:246
ConfigBase(bool suppress_print)
ConfigBase constructor.
Definition: configBase.h:112
ConfigBase()
Default constructor used for serialization.
Definition: configBase.h:122
Base class to parse command line options for SST Simulation Configuration variables.
Definition: configBase.h:105
bool setOptionExternal(const std::string &entryName, const std::string &value)
Set a configuration string to update configuration values.
Definition: configBase.cc:397
std::string getRunName()
Get the name of the executable being run.
Definition: configBase.h:178