js/src/shell/jsoptparse.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: set ts=8 sts=4 et sw=4 tw=99:
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef shell_jsoptparse_h
michael@0 8 #define shell_jsoptparse_h
michael@0 9
michael@0 10 #include <stdio.h>
michael@0 11
michael@0 12 #include "jsalloc.h"
michael@0 13 #include "jsutil.h"
michael@0 14
michael@0 15 #include "js/Vector.h"
michael@0 16
michael@0 17 namespace js {
michael@0 18 namespace cli {
michael@0 19
michael@0 20 namespace detail {
michael@0 21
michael@0 22 struct BoolOption;
michael@0 23 struct MultiStringOption;
michael@0 24 struct ValuedOption;
michael@0 25 struct StringOption;
michael@0 26 struct IntOption;
michael@0 27
michael@0 28 enum OptionKind
michael@0 29 {
michael@0 30 OptionKindBool,
michael@0 31 OptionKindString,
michael@0 32 OptionKindInt,
michael@0 33 OptionKindMultiString,
michael@0 34 OptionKindInvalid
michael@0 35 };
michael@0 36
michael@0 37 struct Option
michael@0 38 {
michael@0 39 const char *longflag;
michael@0 40 const char *help;
michael@0 41 OptionKind kind;
michael@0 42 char shortflag;
michael@0 43 bool terminatesOptions;
michael@0 44
michael@0 45 Option(OptionKind kind, char shortflag, const char *longflag, const char *help)
michael@0 46 : longflag(longflag), help(help), kind(kind), shortflag(shortflag), terminatesOptions(false)
michael@0 47 {}
michael@0 48
michael@0 49 virtual ~Option() = 0;
michael@0 50
michael@0 51 void setTerminatesOptions(bool enabled) { terminatesOptions = enabled; }
michael@0 52 bool getTerminatesOptions() const { return terminatesOptions; }
michael@0 53
michael@0 54 virtual bool isValued() const { return false; }
michael@0 55
michael@0 56 /* Only some valued options are variadic (like MultiStringOptions). */
michael@0 57 virtual bool isVariadic() const { return false; }
michael@0 58
michael@0 59 /*
michael@0 60 * For arguments, the shortflag field is used to indicate whether the
michael@0 61 * argument is optional.
michael@0 62 */
michael@0 63 bool isOptional() { return shortflag; }
michael@0 64
michael@0 65 void setFlagInfo(char shortflag, const char *longflag, const char *help) {
michael@0 66 this->shortflag = shortflag;
michael@0 67 this->longflag = longflag;
michael@0 68 this->help = help;
michael@0 69 }
michael@0 70
michael@0 71 ValuedOption *asValued();
michael@0 72 const ValuedOption *asValued() const;
michael@0 73
michael@0 74 #define OPTION_CONVERT_DECL(__cls) \
michael@0 75 bool is##__cls##Option() const; \
michael@0 76 __cls##Option *as##__cls##Option(); \
michael@0 77 const __cls##Option *as##__cls##Option() const;
michael@0 78
michael@0 79 OPTION_CONVERT_DECL(Bool)
michael@0 80 OPTION_CONVERT_DECL(String)
michael@0 81 OPTION_CONVERT_DECL(Int)
michael@0 82 OPTION_CONVERT_DECL(MultiString)
michael@0 83 };
michael@0 84
michael@0 85 inline Option::~Option() {}
michael@0 86
michael@0 87 struct BoolOption : public Option
michael@0 88 {
michael@0 89 size_t argno;
michael@0 90 bool value;
michael@0 91
michael@0 92 BoolOption(char shortflag, const char *longflag, const char *help)
michael@0 93 : Option(OptionKindBool, shortflag, longflag, help), value(false)
michael@0 94 {}
michael@0 95
michael@0 96 virtual ~BoolOption() {}
michael@0 97 };
michael@0 98
michael@0 99 struct ValuedOption : public Option
michael@0 100 {
michael@0 101 const char *metavar;
michael@0 102
michael@0 103 ValuedOption(OptionKind kind, char shortflag, const char *longflag, const char *help,
michael@0 104 const char *metavar)
michael@0 105 : Option(kind, shortflag, longflag, help), metavar(metavar)
michael@0 106 {}
michael@0 107
michael@0 108 virtual ~ValuedOption() = 0;
michael@0 109 virtual bool isValued() const { return true; }
michael@0 110 };
michael@0 111
michael@0 112 inline ValuedOption::~ValuedOption() {}
michael@0 113
michael@0 114 struct StringOption : public ValuedOption
michael@0 115 {
michael@0 116 const char *value;
michael@0 117
michael@0 118 StringOption(char shortflag, const char *longflag, const char *help, const char *metavar)
michael@0 119 : ValuedOption(OptionKindString, shortflag, longflag, help, metavar), value(nullptr)
michael@0 120 {}
michael@0 121
michael@0 122 virtual ~StringOption() {}
michael@0 123 };
michael@0 124
michael@0 125 struct IntOption : public ValuedOption
michael@0 126 {
michael@0 127 int value;
michael@0 128
michael@0 129 IntOption(char shortflag, const char *longflag, const char *help, const char *metavar,
michael@0 130 int defaultValue)
michael@0 131 : ValuedOption(OptionKindInt, shortflag, longflag, help, metavar), value(defaultValue)
michael@0 132 {}
michael@0 133
michael@0 134 virtual ~IntOption() {}
michael@0 135 };
michael@0 136
michael@0 137 struct StringArg
michael@0 138 {
michael@0 139 char *value;
michael@0 140 size_t argno;
michael@0 141
michael@0 142 StringArg(char *value, size_t argno) : value(value), argno(argno) {}
michael@0 143 };
michael@0 144
michael@0 145 struct MultiStringOption : public ValuedOption
michael@0 146 {
michael@0 147 Vector<StringArg, 0, SystemAllocPolicy> strings;
michael@0 148
michael@0 149 MultiStringOption(char shortflag, const char *longflag, const char *help, const char *metavar)
michael@0 150 : ValuedOption(OptionKindMultiString, shortflag, longflag, help, metavar)
michael@0 151 {}
michael@0 152
michael@0 153 virtual ~MultiStringOption() {}
michael@0 154
michael@0 155 virtual bool isVariadic() const { return true; }
michael@0 156 };
michael@0 157
michael@0 158 } /* namespace detail */
michael@0 159
michael@0 160 class MultiStringRange
michael@0 161 {
michael@0 162 typedef detail::StringArg StringArg;
michael@0 163 const StringArg *cur;
michael@0 164 const StringArg *end;
michael@0 165
michael@0 166 public:
michael@0 167 explicit MultiStringRange(const StringArg *cur, const StringArg *end)
michael@0 168 : cur(cur), end(end) {
michael@0 169 JS_ASSERT(end - cur >= 0);
michael@0 170 }
michael@0 171
michael@0 172 bool empty() const { return cur == end; }
michael@0 173 void popFront() { JS_ASSERT(!empty()); ++cur; }
michael@0 174 char *front() const { JS_ASSERT(!empty()); return cur->value; }
michael@0 175 size_t argno() const { JS_ASSERT(!empty()); return cur->argno; }
michael@0 176 };
michael@0 177
michael@0 178 /*
michael@0 179 * Builder for describing a command line interface and parsing the resulting
michael@0 180 * specification.
michael@0 181 *
michael@0 182 * - A multi-option is an option that can appear multiple times and still
michael@0 183 * parse as valid command line arguments.
michael@0 184 * - An "optional argument" is supported for backwards compatibility with prior
michael@0 185 * command line interface usage. Once one optional argument has been added,
michael@0 186 * *only* optional arguments may be added.
michael@0 187 */
michael@0 188 class OptionParser
michael@0 189 {
michael@0 190 public:
michael@0 191 enum Result
michael@0 192 {
michael@0 193 Okay = 0,
michael@0 194 Fail, /* As in, allocation fail. */
michael@0 195 ParseError, /* Successfully parsed but with an error. */
michael@0 196 ParseHelp /* Aborted on help flag. */
michael@0 197 };
michael@0 198
michael@0 199 private:
michael@0 200 typedef Vector<detail::Option *, 0, SystemAllocPolicy> Options;
michael@0 201 typedef detail::Option Option;
michael@0 202 typedef detail::BoolOption BoolOption;
michael@0 203
michael@0 204 Options options;
michael@0 205 Options arguments;
michael@0 206 BoolOption helpOption;
michael@0 207 const char *usage;
michael@0 208 const char *ver;
michael@0 209 const char *descr;
michael@0 210 size_t descrWidth;
michael@0 211 size_t helpWidth;
michael@0 212 size_t nextArgument;
michael@0 213
michael@0 214 // If '--' is passed, all remaining arguments should be interpreted as the
michael@0 215 // argument at index 'restArgument'. Defaults to the next unassigned
michael@0 216 // argument.
michael@0 217 int restArgument;
michael@0 218
michael@0 219 static const char prognameMeta[];
michael@0 220
michael@0 221 Option *findOption(char shortflag);
michael@0 222 const Option *findOption(char shortflag) const;
michael@0 223 Option *findOption(const char *longflag);
michael@0 224 const Option *findOption(const char *longflag) const;
michael@0 225 int findArgumentIndex(const char *name) const;
michael@0 226 Option *findArgument(const char *name);
michael@0 227 const Option *findArgument(const char *name) const;
michael@0 228
michael@0 229 Result error(const char *fmt, ...);
michael@0 230 Result extractValue(size_t argc, char **argv, size_t *i, char **value);
michael@0 231 Result handleArg(size_t argc, char **argv, size_t *i, bool *optsAllowed);
michael@0 232 Result handleOption(Option *opt, size_t argc, char **argv, size_t *i, bool *optsAllowed);
michael@0 233
michael@0 234 public:
michael@0 235 explicit OptionParser(const char *usage)
michael@0 236 : helpOption('h', "help", "Display help information"),
michael@0 237 usage(usage), ver(nullptr), descr(nullptr), descrWidth(80), helpWidth(80),
michael@0 238 nextArgument(0), restArgument(-1)
michael@0 239 {}
michael@0 240
michael@0 241 ~OptionParser();
michael@0 242
michael@0 243 Result parseArgs(int argc, char **argv);
michael@0 244 Result printHelp(const char *progname);
michael@0 245
michael@0 246 /* Metadata */
michael@0 247
michael@0 248 void setVersion(const char *version) { ver = version; }
michael@0 249 void setHelpWidth(size_t width) { helpWidth = width; }
michael@0 250 void setDescriptionWidth(size_t width) { descrWidth = width; }
michael@0 251 void setDescription(const char *description) { descr = description; }
michael@0 252 void setHelpOption(char shortflag, const char *longflag, const char *help);
michael@0 253 void setArgTerminatesOptions(const char *name, bool enabled);
michael@0 254 void setArgCapturesRest(const char *name);
michael@0 255
michael@0 256 /* Arguments: no further arguments may be added after a variadic argument. */
michael@0 257
michael@0 258 bool addOptionalStringArg(const char *name, const char *help);
michael@0 259 bool addOptionalMultiStringArg(const char *name, const char *help);
michael@0 260
michael@0 261 const char *getStringArg(const char *name) const;
michael@0 262 MultiStringRange getMultiStringArg(const char *name) const;
michael@0 263
michael@0 264 /* Options */
michael@0 265
michael@0 266 bool addBoolOption(char shortflag, const char *longflag, const char *help);
michael@0 267 bool addStringOption(char shortflag, const char *longflag, const char *help,
michael@0 268 const char *metavar);
michael@0 269 bool addIntOption(char shortflag, const char *longflag, const char *help,
michael@0 270 const char *metavar, int defaultValue);
michael@0 271 bool addMultiStringOption(char shortflag, const char *longflag, const char *help,
michael@0 272 const char *metavar);
michael@0 273 bool addOptionalVariadicArg(const char *name);
michael@0 274
michael@0 275 int getIntOption(char shortflag) const;
michael@0 276 int getIntOption(const char *longflag) const;
michael@0 277 const char *getStringOption(char shortflag) const;
michael@0 278 const char *getStringOption(const char *longflag) const;
michael@0 279 bool getBoolOption(char shortflag) const;
michael@0 280 bool getBoolOption(const char *longflag) const;
michael@0 281 MultiStringRange getMultiStringOption(char shortflag) const;
michael@0 282 MultiStringRange getMultiStringOption(const char *longflag) const;
michael@0 283
michael@0 284 /*
michael@0 285 * Return whether the help option was present (and thus help was already
michael@0 286 * displayed during parse_args).
michael@0 287 */
michael@0 288 bool getHelpOption() const;
michael@0 289 };
michael@0 290
michael@0 291 } /* namespace cli */
michael@0 292 } /* namespace js */
michael@0 293
michael@0 294 #endif /* shell_jsoptparse_h */

mercurial