nlib
Nflags.h
Go to the documentation of this file.
1 
2 #pragma once
3 #ifndef INCLUDE_NN_NLIB_NFLAGS_H_
4 #define INCLUDE_NN_NLIB_NFLAGS_H_
5 
6 #include "nn/nlib/Config.h"
7 #include "nn/nlib/UniquePtr.h"
8 
9 NLIB_NAMESPACE_BEGIN
10 
11 // You can define command line switches by using the macros:
12 // NLIB_FLAGS_DEFINE_[bool|int32|double|string](option_name, default value, "help message");
13 // Then Nflags::Parse() and you can access the specified value through NLIB_FLAGS_option_name.
14 // See misc/nflags/nflags.cpp sample codes for detailed usage.
16  public:
17  static errno_t Parse(int* argc, char*** argv) NLIB_NOEXCEPT NLIB_NONNULL;
18  static errno_t Parse(int* argc, wchar_t*** argv) NLIB_NOEXCEPT NLIB_NONNULL;
19  // use like this:
20  // if (NLIB_FLAGS_help) { Nflags::PrintHelp(); }
21  static void PrintHelp() NLIB_NOEXCEPT;
22  static const char* GetErrorMessage() NLIB_NOEXCEPT;
23 
24  static const int kMaxPath = 512;
25  static const int kMaxFileName = 256;
26  static const int kMaxDirName = 512;
27  static const int kMaxExtension = 256;
28  static errno_t GetFileName(const char* path,
29  char (&filename)[kMaxFileName]) NLIB_NOEXCEPT NLIB_NONNULL;
30  static errno_t GetDirName(const char* path,
31  char (&dirname)[kMaxDirName]) NLIB_NOEXCEPT NLIB_NONNULL;
32 
33  static errno_t GetStringCommaList(char* arg, char** vec, size_t vec_count,
34  size_t* written_count) NLIB_NOEXCEPT NLIB_NONNULL;
35  template <size_t N>
36  static errno_t
37  GetStringCommaList(char* arg, char* (&vec)[N], size_t* written_count) NLIB_NOEXCEPT {
38  return GetStringCommaList(arg, &vec[0], N, written_count);
39  }
40 
41  static errno_t GetInt32CommaList(char* arg, int32_t* vec, size_t vec_count,
42  size_t* written_count) NLIB_NOEXCEPT NLIB_NONNULL;
43  template <size_t N>
44  static errno_t
45  GetInt32CommaList(char* arg, int32_t (&vec)[N], size_t* written_count) NLIB_NOEXCEPT {
46  return GetInt32CommaList(arg, &vec[0], N, written_count);
47  }
48 
49  static errno_t GetDoubleCommaList(char* arg, double* vec, size_t vec_count,
50  size_t* written_count) NLIB_NOEXCEPT NLIB_NONNULL;
51  template <size_t N>
52  static errno_t
53  GetDoubleCommaList(char* arg, double (&vec)[N], size_t* written_count) NLIB_NOEXCEPT {
54  return GetDoubleCommaList(arg, &vec[0], N, written_count);
55  }
56 
57  // 1,t,y,yes,true -> true / 0,f,n,no,false -> false / otherwise -> defval
58  static bool GetBoolFromEnv(const char* varname, bool defval) NLIB_NOEXCEPT;
59  static int32_t GetInt32FromEnv(const char* varname, int32_t defval) NLIB_NOEXCEPT;
60  static int64_t GetInt64FromEnv(const char* varname, int64_t defval) NLIB_NOEXCEPT;
61  static double GetDoubleFromEnv(const char* varname, double defval) NLIB_NOEXCEPT;
62  // do not delete the return value.
63 #ifdef NLIB_CXX11_DEFAULT_TEMPLATE_ARGUMENT_FOR_FUNCTION_TEMPLATES
64  template<class DUMMY = void>
65 #endif
66  static const char* GetStringFromEnv(UniquePtr<char[]>& buf, // NOLINT
67  const char* varname,
68  const char* defval) NLIB_NOEXCEPT;
69 
70  private:
71  Nflags();
72 };
73 
74 #ifdef NLIB_CXX11_DEFAULT_TEMPLATE_ARGUMENT_FOR_FUNCTION_TEMPLATES
75 template<class DUMMY>
76 #endif
77 inline const char* Nflags::GetStringFromEnv(UniquePtr<char[]>& buf, // NOLINT
78  const char* varname,
79  const char* defval) NLIB_NOEXCEPT {
80  if (!varname) return defval;
81  size_t n;
82  errno_t e;
83  e = nlib_getenv(&n, NULL, 0, varname);
84  if (e != 0 || n == 0) return defval;
85  // to avoid crossing the DLL boundary
86  char* bufmem = new (std::nothrow) char[n];
87  if (!bufmem) return defval;
88  size_t n2;
89  e = nlib_getenv(&n2, bufmem, n, varname);
90  if (e != 0) {
91  delete[] bufmem;
92  return defval;
93  }
94  buf.reset(bufmem);
95  return buf.get();
96 }
97 
98 namespace nflags {
99 
100 NLIB_VIS_PUBLIC void AddDefOptBool(const char* opt_name, bool def_value, const char* desc,
101  bool* ptr) NLIB_NOEXCEPT NLIB_NONNULL;
102 NLIB_VIS_PUBLIC void AddDefOptInt32(const char* opt_name, int32_t def_value, const char* desc,
103  int32_t* ptr) NLIB_NOEXCEPT NLIB_NONNULL;
104 NLIB_VIS_PUBLIC void AddDefOptDouble(const char* opt_name, double def_value, const char* desc,
105  double* ptr) NLIB_NOEXCEPT NLIB_NONNULL;
106 NLIB_VIS_PUBLIC void AddDefOptString(const char* opt_name, const char* def_value, const char* desc,
107  const char** ptr) NLIB_NOEXCEPT NLIB_NONNULL;
108 
109 } // namespace nflags
110 
111 #define NLIB_FLAGS_DEFINE_bool(opt_name, def_value, desc) \
112 bool NLIB_FLAGS_##opt_name; \
113 class NLIB_FLAGS_CL_##opt_name { \
114  public: /* NOLINT */ \
115  NLIB_FLAGS_CL_##opt_name() { \
116  ::nlib_ns::nflags::AddDefOptBool(#opt_name, def_value, desc, &NLIB_FLAGS_##opt_name); \
117  } \
118 } NLIB_FLAGS_CL_##opt_name##_
119 
120 #define NLIB_FLAGS_DEFINE_int32(opt_name, def_value, desc) \
121 int32_t NLIB_FLAGS_##opt_name; \
122 class NLIB_FLAGS_CL_##opt_name { \
123  public: /* NOLINT */ \
124  NLIB_FLAGS_CL_##opt_name() { \
125  ::nlib_ns::nflags::AddDefOptInt32(#opt_name, def_value, desc, \
126  &NLIB_FLAGS_##opt_name); \
127  } \
128 } NLIB_FLAGS_CL_##opt_name##_
129 
130 #define NLIB_FLAGS_DEFINE_double(opt_name, def_value, desc) \
131 double NLIB_FLAGS_##opt_name; \
132 class NLIB_FLAGS_CL_##opt_name { \
133  public: /* NOLINT */ \
134  NLIB_FLAGS_CL_##opt_name() { \
135  ::nlib_ns::nflags::AddDefOptDouble(#opt_name, def_value, desc, \
136  &NLIB_FLAGS_##opt_name); \
137  } \
138 } NLIB_FLAGS_CL_##opt_name##_
139 
140 #define NLIB_FLAGS_DEFINE_string(opt_name, def_value, desc) \
141 const char* NLIB_FLAGS_##opt_name; \
142 class NLIB_FLAGS_CL_##opt_name { \
143  public: /* NOLINT */ \
144  NLIB_FLAGS_CL_##opt_name() { \
145  ::nlib_ns::nflags::AddDefOptString(#opt_name, def_value, desc, \
146  &NLIB_FLAGS_##opt_name); \
147  } \
148 } NLIB_FLAGS_CL_##opt_name##_
149 
150 #define NLIB_FLAGS_DECLARE_bool(opt_name) extern bool NLIB_FLAGS_##opt_name
151 #define NLIB_FLAGS_DECLARE_int32(opt_name) extern int32_t NLIB_FLAGS_##opt_name
152 #define NLIB_FLAGS_DECLARE_double(opt_name) extern double NLIB_FLAGS_##opt_name
153 #define NLIB_FLAGS_DECLARE_string(opt_name) extern const char* NLIB_FLAGS_##opt_name
154 
155 NLIB_NAMESPACE_END
156 
157 // Predefined option:
158 // NLIB_FLAGS_help : set with '--help'
160 
161 #endif // INCLUDE_NN_NLIB_NFLAGS_H_
static errno_t GetDoubleCommaList(char *arg, double(&vec)[N], size_t *written_count) noexcept
The function template version of GetDoubleCommaList.
Definition: Nflags.h:53
static errno_t GetStringCommaList(char *arg, char *(&vec)[N], size_t *written_count) noexcept
The function template version of GetStringCommaList.
Definition: Nflags.h:37
UniquePtr owns the pointer, and when it goes out of scope, the pointer is released by the destructor ...
Definition: UniquePtr.h:96
Defines that class that is corresponding to std::unique_ptr.
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:61
#define NLIB_FLAGS_DECLARE_bool(opt_name)
Enables the use of an NLIB_FLAGS_option name that was defined in a different place.
Definition: Nflags.h:150
The class for parsing command line flags.
Definition: Nflags.h:15
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Config.h:86
A file that contains the configuration information for each development environment.
errno_t nlib_getenv(size_t *result, char *buf, size_t bufsize, const char *varname)
Gets the value for the environment variable as a string.
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
Definition: Config.h:211
static errno_t GetInt32CommaList(char *arg, int32_t(&vec)[N], size_t *written_count) noexcept
The function template version of GetInt32CommaList.
Definition: Nflags.h:45
#define NLIB_NONNULL
Indicates that you cannot specify NULL for all arguments.
Definition: Platform_unix.h:76
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:24