blob: 693a5db6e39596abe255bc7537c6605cb2d8fe66 [file] [log] [blame]
scroggo@google.com161e1ba2013-03-04 16:41:06 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
scroggo@google.comd9ba9a02013-03-21 19:43:15 +00008#ifndef SK_COMMAND_LINE_FLAGS_H
9#define SK_COMMAND_LINE_FLAGS_H
scroggo@google.com161e1ba2013-03-04 16:41:06 +000010
bungemanbf521ff2016-02-17 13:13:44 -080011#include "../private/SkTArray.h"
bungemana7e9f052016-02-18 08:53:33 -080012#include "../private/SkTDArray.h"
scroggo@google.com161e1ba2013-03-04 16:41:06 +000013#include "SkString.h"
scroggo@google.com161e1ba2013-03-04 16:41:06 +000014
15/**
scroggo@google.comd9ba9a02013-03-21 19:43:15 +000016 * Including this file (and compiling SkCommandLineFlags.cpp) provides command line
scroggo@google.com161e1ba2013-03-04 16:41:06 +000017 * parsing. In order to use it, use the following macros in global
18 * namespace:
19 *
20 * DEFINE_bool(name, defaultValue, helpString);
21 * DEFINE_string(name, defaultValue, helpString);
22 * DEFINE_int32(name, defaultValue, helpString);
23 * DEFINE_double(name, defaultValue, helpString);
24 *
scroggo@google.comd9ba9a02013-03-21 19:43:15 +000025 * Then, in main, call SkCommandLineFlags::SetUsage() to describe usage and call
26 * SkCommandLineFlags::Parse() to parse the flags. Henceforth, each flag can
scroggo@google.com161e1ba2013-03-04 16:41:06 +000027 * be referenced using
28 *
29 * FLAGS_name
30 *
31 * For example, the line
32 *
33 * DEFINE_bool(boolean, false, "The variable boolean does such and such");
34 *
35 * will create the following variable:
36 *
37 * bool FLAGS_boolean;
38 *
39 * which will initially be set to false, and can be set to true by using the
40 * flag "--boolean" on the commandline. "--noboolean" will set FLAGS_boolean
scroggo@google.com5dc4ca12013-03-21 13:10:59 +000041 * to false. FLAGS_boolean can also be set using "--boolean=true" or
42 * "--boolean true" (where "true" can be replaced by "false", "TRUE", "FALSE",
43 * "1" or "0").
44 *
scroggo@google.com5dc4ca12013-03-21 13:10:59 +000045 * The helpString will be printed if the help flag (-h or -help) is used.
scroggo@google.com161e1ba2013-03-04 16:41:06 +000046 *
47 * Similarly, the line
48 *
49 * DEFINE_int32(integer, .., ..);
50 *
51 * will create
52 *
53 * int32_t FLAGS_integer;
54 *
55 * and
56 *
57 * DEFINE_double(real, .., ..);
58 *
59 * will create
60 *
61 * double FLAGS_real;
62 *
Michael Ludwig3ad86d02018-09-28 16:00:38 -040063 * and
64 *
65 * DEFINE_uint32(unsigned, ...);
66 *
67 * will create
68 *
69 * uint32_t FLAGS_unsigned;
70 *
scroggo@google.com161e1ba2013-03-04 16:41:06 +000071 * These flags can be set by specifying, for example, "--integer 7" and
Michael Ludwig3ad86d02018-09-28 16:00:38 -040072 * "--real 3.14" on the command line. Unsigned integers are parsed from the
73 * command line using strtoul() so will detect the base (0 for octal, and
74 * 0x or 0X for hex, otherwise assumes decimal).
scroggo@google.com161e1ba2013-03-04 16:41:06 +000075 *
76 * Unlike the others, the line
77 *
78 * DEFINE_string(args, .., ..);
79 *
80 * creates an array:
81 *
scroggo@google.comb7dbf632013-04-23 15:38:09 +000082 * SkCommandLineFlags::StringArray FLAGS_args;
scroggo@google.com161e1ba2013-03-04 16:41:06 +000083 *
84 * If the default value is the empty string, FLAGS_args will default to a size
85 * of zero. Otherwise it will default to a size of 1 with the default string
86 * as its value. All strings that follow the flag on the command line (until
87 * a string that begins with '-') will be entries in the array.
88 *
kkinnunen3e980c32015-12-23 01:33:00 -080089 * DEFINE_extended_string(args, .., .., extendedHelpString);
90 *
91 * creates a similar string array flag as DEFINE_string. The flag will have extended help text
92 * (extendedHelpString) that can the user can see with '--help <args>' flag.
93 *
scroggo@google.com161e1ba2013-03-04 16:41:06 +000094 * Any flag can be referenced from another file after using the following:
95 *
96 * DECLARE_x(name);
97 *
98 * (where 'x' is the type specified in the DEFINE).
99 *
100 * Inspired by gflags (https://code.google.com/p/gflags/). Is not quite as
101 * robust as gflags, but suits our purposes. For example, allows creating
scroggo@google.comd9ba9a02013-03-21 19:43:15 +0000102 * a flag -h or -help which will never be used, since SkCommandLineFlags handles it.
103 * SkCommandLineFlags will also allow creating --flag and --noflag. Uses the same input
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000104 * format as gflags and creates similarly named variables (i.e. FLAGS_name).
105 * Strings are handled differently (resulting variable will be an array of
106 * strings) so that a flag can be followed by multiple parameters.
107 */
108
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000109class SkFlagInfo;
110
scroggo@google.comd9ba9a02013-03-21 19:43:15 +0000111class SkCommandLineFlags {
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000112
113public:
114 /**
115 * Call to set the help message to be displayed. Should be called before
scroggo@google.comd9ba9a02013-03-21 19:43:15 +0000116 * Parse.
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000117 */
118 static void SetUsage(const char* usage);
119
120 /**
msarett3478f752016-02-12 14:47:09 -0800121 * Call this to display the help message. Should be called after SetUsage.
122 */
123 static void PrintUsage();
124
125 /**
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000126 * Call at the beginning of main to parse flags created by DEFINE_x, above.
127 * Must only be called once.
128 */
Cary Clark7265ea32017-09-14 12:12:32 -0400129 static void Parse(int argc, const char* const * argv);
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000130
scroggo@google.comb7dbf632013-04-23 15:38:09 +0000131 /**
132 * Custom class for holding the arguments for a string flag.
133 * Publicly only has accessors so the strings cannot be modified.
134 */
135 class StringArray {
136 public:
kkinnunen3e980c32015-12-23 01:33:00 -0800137 StringArray() { }
138 explicit StringArray(const SkTArray<SkString>& strings)
139 : fStrings(strings) {
140 }
scroggo@google.comb7dbf632013-04-23 15:38:09 +0000141 const char* operator[](int i) const {
142 SkASSERT(i >= 0 && i < fStrings.count());
143 return fStrings[i].c_str();
144 }
145
146 int count() const {
147 return fStrings.count();
148 }
149
150 bool isEmpty() const { return this->count() == 0; }
151
epoger@google.comdefc4872013-09-19 06:18:27 +0000152 /**
153 * Returns true iff string is equal to one of the strings in this array.
154 */
155 bool contains(const char* string) const {
156 for (int i = 0; i < fStrings.count(); i++) {
157 if (fStrings[i].equals(string)) {
158 return true;
159 }
160 }
161 return false;
162 }
163
caryclark936b7342014-07-11 12:14:51 -0700164 void set(int i, const char* str) {
Cary Clark3bdaa462018-10-31 16:16:54 -0400165 if (i >= fStrings.count()) {
166 this->append(str);
167 return;
168 }
caryclark936b7342014-07-11 12:14:51 -0700169 fStrings[i].set(str);
170 }
171
Florin Malita094ccde2017-12-30 12:27:00 -0500172 const SkString* begin() const { return fStrings.begin(); }
173 const SkString* end() const { return fStrings.end(); }
174
scroggo@google.comb7dbf632013-04-23 15:38:09 +0000175 private:
176 void reset() { fStrings.reset(); }
177
178 void append(const char* string) {
179 fStrings.push_back().set(string);
180 }
181
scroggo@google.com58104a92013-04-24 19:25:26 +0000182 void append(const char* string, size_t length) {
183 fStrings.push_back().set(string, length);
184 }
185
scroggo@google.comb7dbf632013-04-23 15:38:09 +0000186 SkTArray<SkString> fStrings;
187
188 friend class SkFlagInfo;
189 };
190
commit-bot@chromium.orga6f37e72013-08-30 15:52:46 +0000191 /* Takes a list of the form [~][^]match[$]
192 ~ causes a matching test to always be skipped
193 ^ requires the start of the test to match
194 $ requires the end of the test to match
195 ^ and $ requires an exact match
196 If a test does not match any list entry, it is skipped unless some list entry starts with ~
197 */
198 static bool ShouldSkip(const SkTDArray<const char*>& strings, const char* name);
199 static bool ShouldSkip(const StringArray& strings, const char* name);
200
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000201private:
202 static SkFlagInfo* gHead;
203 static SkString gUsage;
204
205 // For access to gHead.
206 friend class SkFlagInfo;
207};
208
209#define TO_STRING2(s) #s
210#define TO_STRING(s) TO_STRING2(s)
211
212#define DEFINE_bool(name, defaultValue, helpString) \
213bool FLAGS_##name; \
fmalita523beb72015-06-10 10:46:50 -0700214SK_UNUSED static bool unused_##name = SkFlagInfo::CreateBoolFlag(TO_STRING(name), \
halcanary96fcdcc2015-08-27 07:41:13 -0700215 nullptr, \
fmalita523beb72015-06-10 10:46:50 -0700216 &FLAGS_##name, \
217 defaultValue, \
218 helpString)
scroggo@google.com09fd4d22013-03-20 14:20:18 +0000219
220// bool 2 allows specifying a short name. No check is done to ensure that shortName
221// is actually shorter than name.
222#define DEFINE_bool2(name, shortName, defaultValue, helpString) \
223bool FLAGS_##name; \
fmalita523beb72015-06-10 10:46:50 -0700224SK_UNUSED static bool unused_##name = SkFlagInfo::CreateBoolFlag(TO_STRING(name), \
225 TO_STRING(shortName),\
226 &FLAGS_##name, \
227 defaultValue, \
228 helpString)
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000229
230#define DECLARE_bool(name) extern bool FLAGS_##name;
231
232#define DEFINE_string(name, defaultValue, helpString) \
scroggo@google.comb7dbf632013-04-23 15:38:09 +0000233SkCommandLineFlags::StringArray FLAGS_##name; \
fmalita523beb72015-06-10 10:46:50 -0700234SK_UNUSED static bool unused_##name = SkFlagInfo::CreateStringFlag(TO_STRING(name), \
halcanary96fcdcc2015-08-27 07:41:13 -0700235 nullptr, \
fmalita523beb72015-06-10 10:46:50 -0700236 &FLAGS_##name, \
237 defaultValue, \
kkinnunen3e980c32015-12-23 01:33:00 -0800238 helpString, nullptr)
239#define DEFINE_extended_string(name, defaultValue, helpString, extendedHelpString) \
240SkCommandLineFlags::StringArray FLAGS_##name; \
241SK_UNUSED static bool unused_##name = SkFlagInfo::CreateStringFlag(TO_STRING(name), \
242 nullptr, \
243 &FLAGS_##name, \
244 defaultValue, \
245 helpString, \
246 extendedHelpString)
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000247
scroggo@google.com604e0c22013-04-09 21:25:46 +0000248// string2 allows specifying a short name. There is an assert that shortName
249// is only 1 character.
scroggo@google.com09fd4d22013-03-20 14:20:18 +0000250#define DEFINE_string2(name, shortName, defaultValue, helpString) \
scroggo@google.comb7dbf632013-04-23 15:38:09 +0000251SkCommandLineFlags::StringArray FLAGS_##name; \
fmalita523beb72015-06-10 10:46:50 -0700252SK_UNUSED static bool unused_##name = SkFlagInfo::CreateStringFlag(TO_STRING(name), \
253 TO_STRING(shortName), \
254 &FLAGS_##name, \
255 defaultValue, \
kkinnunen3e980c32015-12-23 01:33:00 -0800256 helpString, nullptr)
scroggo@google.com09fd4d22013-03-20 14:20:18 +0000257
scroggo@google.comb7dbf632013-04-23 15:38:09 +0000258#define DECLARE_string(name) extern SkCommandLineFlags::StringArray FLAGS_##name;
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000259
robertphillips5ce341f2015-09-18 09:04:43 -0700260
261
262
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000263#define DEFINE_int32(name, defaultValue, helpString) \
264int32_t FLAGS_##name; \
fmalita523beb72015-06-10 10:46:50 -0700265SK_UNUSED static bool unused_##name = SkFlagInfo::CreateIntFlag(TO_STRING(name), \
266 &FLAGS_##name, \
267 defaultValue, \
268 helpString)
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000269
robertphillips5ce341f2015-09-18 09:04:43 -0700270#define DEFINE_int32_2(name, shortName, defaultValue, helpString) \
271int32_t FLAGS_##name; \
272SK_UNUSED static bool unused_##name = SkFlagInfo::CreateIntFlag(TO_STRING(name), \
273 TO_STRING(shortName), \
274 &FLAGS_##name, \
275 defaultValue, \
276 helpString)
277
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000278#define DECLARE_int32(name) extern int32_t FLAGS_##name;
279
Michael Ludwig3ad86d02018-09-28 16:00:38 -0400280
281#define DEFINE_uint32(name, defaultValue, helpString) \
282uint32_t FLAGS_##name; \
283SK_UNUSED static bool unused_##name = SkFlagInfo::CreateUintFlag(TO_STRING(name), \
284 &FLAGS_##name, \
285 defaultValue, \
286 helpString)
287
288#define DEFINE_uint32_2(name, shortName, defaultValue, helpString) \
289uint32_t FLAGS_##name; \
290SK_UNUSED static bool unused_##name = SkFlagInfo::CreateUintFlag(TO_STRING(name), \
291 TO_STRING(shortName),\
292 &FLAGS_##name, \
293 defaultValue, \
294 helpString)
295
296#define DECLARE_uint32(name) extern uint32_t FLAGS_##name;
297
298
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000299#define DEFINE_double(name, defaultValue, helpString) \
300double FLAGS_##name; \
fmalita523beb72015-06-10 10:46:50 -0700301SK_UNUSED static bool unused_##name = SkFlagInfo::CreateDoubleFlag(TO_STRING(name), \
302 &FLAGS_##name, \
303 defaultValue, \
304 helpString)
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000305
306#define DECLARE_double(name) extern double FLAGS_##name;
307
308class SkFlagInfo {
309
310public:
311 enum FlagTypes {
312 kBool_FlagType,
313 kString_FlagType,
314 kInt_FlagType,
Michael Ludwig3ad86d02018-09-28 16:00:38 -0400315 kUint_FlagType,
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000316 kDouble_FlagType,
317 };
318
scroggo@google.com58104a92013-04-24 19:25:26 +0000319 /**
320 * Each Create<Type>Flag function creates an SkFlagInfo of the specified type. The SkFlagInfo
321 * object is appended to a list, which is deleted when SkCommandLineFlags::Parse is called.
322 * Therefore, each call should be made before the call to ::Parse. They are not intended
323 * to be called directly. Instead, use the macros described above.
324 * @param name Long version (at least 2 characters) of the name of the flag. This name can
325 * be referenced on the command line as "--name" to set the value of this flag.
326 * @param shortName Short version (one character) of the name of the flag. This name can
327 * be referenced on the command line as "-shortName" to set the value of this flag.
328 * @param p<Type> Pointer to a global variable which holds the value set by SkCommandLineFlags.
329 * @param defaultValue The default value of this flag. The variable pointed to by p<Type> will
330 * be set to this value initially. This is also displayed as part of the help output.
331 * @param helpString Explanation of what this flag changes in the program.
332 */
scroggo@google.com09fd4d22013-03-20 14:20:18 +0000333 static bool CreateBoolFlag(const char* name, const char* shortName, bool* pBool,
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000334 bool defaultValue, const char* helpString) {
kkinnunen3e980c32015-12-23 01:33:00 -0800335 SkFlagInfo* info = new SkFlagInfo(name, shortName, kBool_FlagType, helpString, nullptr);
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000336 info->fBoolValue = pBool;
337 *info->fBoolValue = info->fDefaultBool = defaultValue;
338 return true;
339 }
340
scroggo@google.com58104a92013-04-24 19:25:26 +0000341 /**
342 * See comments for CreateBoolFlag.
343 * @param pStrings Unlike the others, this is a pointer to an array of values.
344 * @param defaultValue Thise default will be parsed so that strings separated by spaces
345 * will be added to pStrings.
346 */
scroggo@google.com09fd4d22013-03-20 14:20:18 +0000347 static bool CreateStringFlag(const char* name, const char* shortName,
scroggo@google.comb7dbf632013-04-23 15:38:09 +0000348 SkCommandLineFlags::StringArray* pStrings,
kkinnunen3e980c32015-12-23 01:33:00 -0800349 const char* defaultValue, const char* helpString,
350 const char* extendedHelpString);
skia.committer@gmail.com075b0892013-03-05 07:09:08 +0000351
scroggo@google.com58104a92013-04-24 19:25:26 +0000352 /**
353 * See comments for CreateBoolFlag.
354 */
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000355 static bool CreateIntFlag(const char* name, int32_t* pInt,
356 int32_t defaultValue, const char* helpString) {
kkinnunen3e980c32015-12-23 01:33:00 -0800357 SkFlagInfo* info = new SkFlagInfo(name, nullptr, kInt_FlagType, helpString, nullptr);
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000358 info->fIntValue = pInt;
359 *info->fIntValue = info->fDefaultInt = defaultValue;
360 return true;
361 }
362
robertphillips5ce341f2015-09-18 09:04:43 -0700363 static bool CreateIntFlag(const char* name, const char* shortName, int32_t* pInt,
364 int32_t defaultValue, const char* helpString) {
kkinnunen3e980c32015-12-23 01:33:00 -0800365 SkFlagInfo* info = new SkFlagInfo(name, shortName, kInt_FlagType, helpString, nullptr);
robertphillips5ce341f2015-09-18 09:04:43 -0700366 info->fIntValue = pInt;
367 *info->fIntValue = info->fDefaultInt = defaultValue;
368 return true;
369 }
370
scroggo@google.com58104a92013-04-24 19:25:26 +0000371 /**
372 * See comments for CreateBoolFlag.
373 */
Michael Ludwig3ad86d02018-09-28 16:00:38 -0400374 static bool CreateUintFlag(const char* name, uint32_t* pUint,
375 uint32_t defaultValue, const char* helpString) {
376 SkFlagInfo* info = new SkFlagInfo(name, nullptr, kUint_FlagType, helpString, nullptr);
377 info->fUintValue = pUint;
378 *info->fUintValue = info->fDefaultUint = defaultValue;
379 return true;
380 }
381
382 static bool CreateUintFlag(const char* name, const char* shortName, uint32_t* pUint,
383 uint32_t defaultValue, const char* helpString) {
384 SkFlagInfo* info = new SkFlagInfo(name, shortName, kUint_FlagType, helpString, nullptr);
385 info->fUintValue = pUint;
386 *info->fUintValue = info->fDefaultUint = defaultValue;
387 return true;
388 }
389
390 /**
391 * See comments for CreateBoolFlag.
392 */
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000393 static bool CreateDoubleFlag(const char* name, double* pDouble,
394 double defaultValue, const char* helpString) {
kkinnunen3e980c32015-12-23 01:33:00 -0800395 SkFlagInfo* info = new SkFlagInfo(name, nullptr, kDouble_FlagType, helpString, nullptr);
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000396 info->fDoubleValue = pDouble;
397 *info->fDoubleValue = info->fDefaultDouble = defaultValue;
398 return true;
399 }
400
401 /**
scroggo@google.com5dc4ca12013-03-21 13:10:59 +0000402 * Returns true if the string matches this flag.
403 * For a boolean flag, also sets the value, since a boolean flag can be set in a number of ways
404 * without looking at the following string:
405 * --name
406 * --noname
407 * --name=true
408 * --name=false
409 * --name=1
410 * --name=0
411 * --name=TRUE
412 * --name=FALSE
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000413 */
scroggo@google.com5dc4ca12013-03-21 13:10:59 +0000414 bool match(const char* string);
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000415
416 FlagTypes getFlagType() const { return fFlagType; }
417
418 void resetStrings() {
419 if (kString_FlagType == fFlagType) {
420 fStrings->reset();
421 } else {
mtklein@google.com330313a2013-08-22 15:37:26 +0000422 SkDEBUGFAIL("Can only call resetStrings on kString_FlagType");
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000423 }
424 }
425
426 void append(const char* string) {
427 if (kString_FlagType == fFlagType) {
scroggo@google.comb7dbf632013-04-23 15:38:09 +0000428 fStrings->append(string);
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000429 } else {
mtklein@google.com330313a2013-08-22 15:37:26 +0000430 SkDEBUGFAIL("Can only append to kString_FlagType");
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000431 }
432 }
433
434 void setInt(int32_t value) {
435 if (kInt_FlagType == fFlagType) {
436 *fIntValue = value;
437 } else {
mtklein@google.com330313a2013-08-22 15:37:26 +0000438 SkDEBUGFAIL("Can only call setInt on kInt_FlagType");
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000439 }
440 }
441
Michael Ludwig3ad86d02018-09-28 16:00:38 -0400442 void setUint(uint32_t value) {
443 if (kUint_FlagType == fFlagType) {
444 *fUintValue = value;
445 } else {
446 SkDEBUGFAIL("Can only call setUint on kUint_FlagType");
447 }
448 }
449
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000450 void setDouble(double value) {
451 if (kDouble_FlagType == fFlagType) {
452 *fDoubleValue = value;
453 } else {
mtklein@google.com330313a2013-08-22 15:37:26 +0000454 SkDEBUGFAIL("Can only call setDouble on kDouble_FlagType");
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000455 }
456 }
457
scroggo@google.com5dc4ca12013-03-21 13:10:59 +0000458 void setBool(bool value) {
459 if (kBool_FlagType == fFlagType) {
460 *fBoolValue = value;
461 } else {
mtklein@google.com330313a2013-08-22 15:37:26 +0000462 SkDEBUGFAIL("Can only call setBool on kBool_FlagType");
scroggo@google.com5dc4ca12013-03-21 13:10:59 +0000463 }
464 }
465
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000466 SkFlagInfo* next() { return fNext; }
467
468 const SkString& name() const { return fName; }
469
scroggo@google.com8366df02013-03-20 19:50:41 +0000470 const SkString& shortName() const { return fShortName; }
471
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000472 const SkString& help() const { return fHelpString; }
kkinnunen3e980c32015-12-23 01:33:00 -0800473 const SkString& extendedHelp() const { return fExtendedHelpString; }
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000474
475 SkString defaultValue() const {
476 SkString result;
477 switch (fFlagType) {
478 case SkFlagInfo::kBool_FlagType:
479 result.printf("%s", fDefaultBool ? "true" : "false");
480 break;
481 case SkFlagInfo::kString_FlagType:
482 return fDefaultString;
483 case SkFlagInfo::kInt_FlagType:
484 result.printf("%i", fDefaultInt);
485 break;
Michael Ludwig3ad86d02018-09-28 16:00:38 -0400486 case SkFlagInfo::kUint_FlagType:
487 result.printf("0x%08x", fDefaultUint);
488 break;
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000489 case SkFlagInfo::kDouble_FlagType:
490 result.printf("%2.2f", fDefaultDouble);
491 break;
492 default:
mtklein@google.com330313a2013-08-22 15:37:26 +0000493 SkDEBUGFAIL("Invalid flag type");
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000494 }
495 return result;
496 }
497
498 SkString typeAsString() const {
499 switch (fFlagType) {
500 case SkFlagInfo::kBool_FlagType:
501 return SkString("bool");
502 case SkFlagInfo::kString_FlagType:
503 return SkString("string");
504 case SkFlagInfo::kInt_FlagType:
505 return SkString("int");
Michael Ludwig3ad86d02018-09-28 16:00:38 -0400506 case SkFlagInfo::kUint_FlagType:
507 return SkString("uint");
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000508 case SkFlagInfo::kDouble_FlagType:
509 return SkString("double");
510 default:
mtklein@google.com330313a2013-08-22 15:37:26 +0000511 SkDEBUGFAIL("Invalid flag type");
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000512 return SkString();
513 }
514 }
515
516private:
kkinnunen3e980c32015-12-23 01:33:00 -0800517 SkFlagInfo(const char* name, const char* shortName, FlagTypes type, const char* helpString,
518 const char* extendedHelpString)
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000519 : fName(name)
scroggo@google.com604e0c22013-04-09 21:25:46 +0000520 , fShortName(shortName)
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000521 , fFlagType(type)
522 , fHelpString(helpString)
kkinnunen3e980c32015-12-23 01:33:00 -0800523 , fExtendedHelpString(extendedHelpString)
halcanary96fcdcc2015-08-27 07:41:13 -0700524 , fBoolValue(nullptr)
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000525 , fDefaultBool(false)
halcanary96fcdcc2015-08-27 07:41:13 -0700526 , fIntValue(nullptr)
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000527 , fDefaultInt(0)
Michael Ludwig3ad86d02018-09-28 16:00:38 -0400528 , fUintValue(nullptr)
529 , fDefaultUint(0)
halcanary96fcdcc2015-08-27 07:41:13 -0700530 , fDoubleValue(nullptr)
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000531 , fDefaultDouble(0)
halcanary96fcdcc2015-08-27 07:41:13 -0700532 , fStrings(nullptr) {
scroggo@google.comd9ba9a02013-03-21 19:43:15 +0000533 fNext = SkCommandLineFlags::gHead;
534 SkCommandLineFlags::gHead = this;
bsalomon49f085d2014-09-05 13:34:00 -0700535 SkASSERT(name && strlen(name) > 1);
halcanary96fcdcc2015-08-27 07:41:13 -0700536 SkASSERT(nullptr == shortName || 1 == strlen(shortName));
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000537 }
scroggo@google.com58104a92013-04-24 19:25:26 +0000538
539 /**
540 * Set a StringArray to hold the values stored in defaultStrings.
541 * @param array The StringArray to modify.
542 * @param defaultStrings Space separated list of strings that should be inserted into array
543 * individually.
544 */
545 static void SetDefaultStrings(SkCommandLineFlags::StringArray* array,
546 const char* defaultStrings);
547
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000548 // Name of the flag, without initial dashes
549 SkString fName;
scroggo@google.com09fd4d22013-03-20 14:20:18 +0000550 SkString fShortName;
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000551 FlagTypes fFlagType;
552 SkString fHelpString;
kkinnunen3e980c32015-12-23 01:33:00 -0800553 SkString fExtendedHelpString;
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000554 bool* fBoolValue;
555 bool fDefaultBool;
556 int32_t* fIntValue;
557 int32_t fDefaultInt;
Michael Ludwig3ad86d02018-09-28 16:00:38 -0400558 uint32_t* fUintValue;
559 uint32_t fDefaultUint;
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000560 double* fDoubleValue;
561 double fDefaultDouble;
scroggo@google.comb7dbf632013-04-23 15:38:09 +0000562 SkCommandLineFlags::StringArray* fStrings;
scroggo@google.com161e1ba2013-03-04 16:41:06 +0000563 // Both for the help string and in case fStrings is empty.
564 SkString fDefaultString;
565
566 // In order to keep a linked list.
567 SkFlagInfo* fNext;
568};
scroggo@google.comd9ba9a02013-03-21 19:43:15 +0000569#endif // SK_COMMAND_LINE_FLAGS_H