Mercurial > hg > sv-dependency-builds
comparison win32-mingw/include/kj/main.h @ 135:38d1c0e7850b
Headers for KJ/Capnp Win32
| author | Chris Cannam <cannam@all-day-breakfast.com> | 
|---|---|
| date | Wed, 26 Oct 2016 13:18:45 +0100 | 
| parents | |
| children | eccd51b72864 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 134:41e769c91eca | 135:38d1c0e7850b | 
|---|---|
| 1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors | |
| 2 // Licensed under the MIT License: | |
| 3 // | |
| 4 // Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 5 // of this software and associated documentation files (the "Software"), to deal | |
| 6 // in the Software without restriction, including without limitation the rights | |
| 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 8 // copies of the Software, and to permit persons to whom the Software is | |
| 9 // furnished to do so, subject to the following conditions: | |
| 10 // | |
| 11 // The above copyright notice and this permission notice shall be included in | |
| 12 // all copies or substantial portions of the Software. | |
| 13 // | |
| 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 20 // THE SOFTWARE. | |
| 21 | |
| 22 #ifndef KJ_MAIN_H_ | |
| 23 #define KJ_MAIN_H_ | |
| 24 | |
| 25 #if defined(__GNUC__) && !KJ_HEADER_WARNINGS | |
| 26 #pragma GCC system_header | |
| 27 #endif | |
| 28 | |
| 29 #include "array.h" | |
| 30 #include "string.h" | |
| 31 #include "vector.h" | |
| 32 #include "function.h" | |
| 33 | |
| 34 namespace kj { | |
| 35 | |
| 36 class ProcessContext { | |
| 37 // Context for command-line programs. | |
| 38 | |
| 39 public: | |
| 40 virtual StringPtr getProgramName() = 0; | |
| 41 // Get argv[0] as passed to main(). | |
| 42 | |
| 43 KJ_NORETURN(virtual void exit()) = 0; | |
| 44 // Indicates program completion. The program is considered successful unless `error()` was | |
| 45 // called. Typically this exits with _Exit(), meaning that the stack is not unwound, buffers | |
| 46 // are not flushed, etc. -- it is the responsibility of the caller to flush any buffers that | |
| 47 // matter. However, an alternate context implementation e.g. for unit testing purposes could | |
| 48 // choose to throw an exception instead. | |
| 49 // | |
| 50 // At first this approach may sound crazy. Isn't it much better to shut down cleanly? What if | |
| 51 // you lose data? However, it turns out that if you look at each common class of program, _Exit() | |
| 52 // is almost always preferable. Let's break it down: | |
| 53 // | |
| 54 // * Commands: A typical program you might run from the command line is single-threaded and | |
| 55 // exits quickly and deterministically. Commands often use buffered I/O and need to flush | |
| 56 // those buffers before exit. However, most of the work performed by destructors is not | |
| 57 // flushing buffers, but rather freeing up memory, placing objects into freelists, and closing | |
| 58 // file descriptors. All of this is irrelevant if the process is about to exit anyway, and | |
| 59 // for a command that runs quickly, time wasted freeing heap space may make a real difference | |
| 60 // in the overall runtime of a script. Meanwhile, it is usually easy to determine exactly what | |
| 61 // resources need to be flushed before exit, and easy to tell if they are not being flushed | |
| 62 // (because the command fails to produce the expected output). Therefore, it is reasonably | |
| 63 // easy for commands to explicitly ensure all output is flushed before exiting, and it is | |
| 64 // probably a good idea for them to do so anyway, because write failures should be detected | |
| 65 // and handled. For commands, a good strategy is to allocate any objects that require clean | |
| 66 // destruction on the stack, and allow them to go out of scope before the command exits. | |
| 67 // Meanwhile, any resources which do not need to be cleaned up should be allocated as members | |
| 68 // of the command's main class, whose destructor normally will not be called. | |
| 69 // | |
| 70 // * Interactive apps: Programs that interact with the user (whether they be graphical apps | |
| 71 // with windows or console-based apps like emacs) generally exit only when the user asks them | |
| 72 // to. Such applications may store large data structures in memory which need to be synced | |
| 73 // to disk, such as documents or user preferences. However, relying on stack unwind or global | |
| 74 // destructors as the mechanism for ensuring such syncing occurs is probably wrong. First of | |
| 75 // all, it's 2013, and applications ought to be actively syncing changes to non-volatile | |
| 76 // storage the moment those changes are made. Applications can crash at any time and a crash | |
| 77 // should never lose data that is more than half a second old. Meanwhile, if a user actually | |
| 78 // does try to close an application while unsaved changes exist, the application UI should | |
| 79 // prompt the user to decide what to do. Such a UI mechanism is obviously too high level to | |
| 80 // be implemented via destructors, so KJ's use of _Exit() shouldn't make a difference here. | |
| 81 // | |
| 82 // * Servers: A good server is fault-tolerant, prepared for the possibility that at any time | |
| 83 // it could crash, the OS could decide to kill it off, or the machine it is running on could | |
| 84 // just die. So, using _Exit() should be no problem. In fact, servers generally never even | |
| 85 // call exit anyway; they are killed externally. | |
| 86 // | |
| 87 // * Batch jobs: A long-running batch job is something between a command and a server. It | |
| 88 // probably knows exactly what needs to be flushed before exiting, and it probably should be | |
| 89 // fault-tolerant. | |
| 90 // | |
| 91 // Meanwhile, regardless of program type, if you are adhering to KJ style, then the use of | |
| 92 // _Exit() shouldn't be a problem anyway: | |
| 93 // | |
| 94 // * KJ style forbids global mutable state (singletons) in general and global constructors and | |
| 95 // destructors in particular. Therefore, everything that could possibly need cleanup either | |
| 96 // lives on the stack or is transitively owned by something living on the stack. | |
| 97 // | |
| 98 // * Calling exit() simply means "Don't clean up anything older than this stack frame.". If you | |
| 99 // have resources that require cleanup before exit, make sure they are owned by stack frames | |
| 100 // beyond the one that eventually calls exit(). To be as safe as possible, don't place any | |
| 101 // state in your program's main class, and don't call exit() yourself. Then, runMainAndExit() | |
| 102 // will do it, and the only thing on the stack at that time will be your main class, which | |
| 103 // has no state anyway. | |
| 104 // | |
| 105 // TODO(someday): Perhaps we should use the new std::quick_exit(), so that at_quick_exit() is | |
| 106 // available for those who really think they need it. Unfortunately, it is not yet available | |
| 107 // on many platforms. | |
| 108 | |
| 109 virtual void warning(StringPtr message) = 0; | |
| 110 // Print the given message to standard error. A newline is printed after the message if it | |
| 111 // doesn't already have one. | |
| 112 | |
| 113 virtual void error(StringPtr message) = 0; | |
| 114 // Like `warning()`, but also sets a flag indicating that the process has failed, and that when | |
| 115 // it eventually exits it should indicate an error status. | |
| 116 | |
| 117 KJ_NORETURN(virtual void exitError(StringPtr message)) = 0; | |
| 118 // Equivalent to `error(message)` followed by `exit()`. | |
| 119 | |
| 120 KJ_NORETURN(virtual void exitInfo(StringPtr message)) = 0; | |
| 121 // Displays the given non-error message to the user and then calls `exit()`. This is used to | |
| 122 // implement things like --help. | |
| 123 | |
| 124 virtual void increaseLoggingVerbosity() = 0; | |
| 125 // Increase the level of detail produced by the debug logging system. `MainBuilder` invokes | |
| 126 // this if the caller uses the -v flag. | |
| 127 | |
| 128 // TODO(someday): Add interfaces representing standard OS resources like the filesystem, so that | |
| 129 // these things can be mocked out. | |
| 130 }; | |
| 131 | |
| 132 class TopLevelProcessContext final: public ProcessContext { | |
| 133 // A ProcessContext implementation appropriate for use at the actual entry point of a process | |
| 134 // (as opposed to when you are trying to call a program's main function from within some other | |
| 135 // program). This implementation writes errors to stderr, and its `exit()` method actually | |
| 136 // calls the C `quick_exit()` function. | |
| 137 | |
| 138 public: | |
| 139 explicit TopLevelProcessContext(StringPtr programName); | |
| 140 | |
| 141 struct CleanShutdownException { int exitCode; }; | |
| 142 // If the environment variable KJ_CLEAN_SHUTDOWN is set, then exit() will actually throw this | |
| 143 // exception rather than exiting. `kj::runMain()` catches this exception and returns normally. | |
| 144 // This is useful primarily for testing purposes, to assist tools like memory leak checkers that | |
| 145 // are easily confused by quick_exit(). | |
| 146 | |
| 147 StringPtr getProgramName() override; | |
| 148 KJ_NORETURN(void exit() override); | |
| 149 void warning(StringPtr message) override; | |
| 150 void error(StringPtr message) override; | |
| 151 KJ_NORETURN(void exitError(StringPtr message) override); | |
| 152 KJ_NORETURN(void exitInfo(StringPtr message) override); | |
| 153 void increaseLoggingVerbosity() override; | |
| 154 | |
| 155 private: | |
| 156 StringPtr programName; | |
| 157 bool cleanShutdown; | |
| 158 bool hadErrors = false; | |
| 159 }; | |
| 160 | |
| 161 typedef Function<void(StringPtr programName, ArrayPtr<const StringPtr> params)> MainFunc; | |
| 162 | |
| 163 int runMainAndExit(ProcessContext& context, MainFunc&& func, int argc, char* argv[]); | |
| 164 // Runs the given main function and then exits using the given context. If an exception is thrown, | |
| 165 // this will catch it, report it via the context and exit with an error code. | |
| 166 // | |
| 167 // Normally this function does not return, because returning would probably lead to wasting time | |
| 168 // on cleanup when the process is just going to exit anyway. However, to facilitate memory leak | |
| 169 // checkers and other tools that require a clean shutdown to do their job, if the environment | |
| 170 // variable KJ_CLEAN_SHUTDOWN is set, the function will in fact return an exit code, which should | |
| 171 // then be returned from main(). | |
| 172 // | |
| 173 // Most users will use the KJ_MAIN() macro rather than call this function directly. | |
| 174 | |
| 175 #define KJ_MAIN(MainClass) \ | |
| 176 int main(int argc, char* argv[]) { \ | |
| 177 ::kj::TopLevelProcessContext context(argv[0]); \ | |
| 178 MainClass mainObject(context); \ | |
| 179 return ::kj::runMainAndExit(context, mainObject.getMain(), argc, argv); \ | |
| 180 } | |
| 181 // Convenience macro for declaring a main function based on the given class. The class must have | |
| 182 // a constructor that accepts a ProcessContext& and a method getMain() which returns | |
| 183 // kj::MainFunc (probably building it using a MainBuilder). | |
| 184 | |
| 185 class MainBuilder { | |
| 186 // Builds a main() function with nice argument parsing. As options and arguments are parsed, | |
| 187 // corresponding callbacks are called, so that you never have to write a massive switch() | |
| 188 // statement to interpret arguments. Additionally, this approach encourages you to write | |
| 189 // main classes that have a reasonable API that can be used as an alternative to their | |
| 190 // command-line interface. | |
| 191 // | |
| 192 // All StringPtrs passed to MainBuilder must remain valid until option parsing completes. The | |
| 193 // assumption is that these strings will all be literals, making this an easy requirement. If | |
| 194 // not, consider allocating them in an Arena. | |
| 195 // | |
| 196 // Some flags are automatically recognized by the main functions built by this class: | |
| 197 // --help: Prints help text and exits. The help text is constructed based on the | |
| 198 // information you provide to the builder as you define each flag. | |
| 199 // --verbose: Increase logging verbosity. | |
| 200 // --version: Print version information and exit. | |
| 201 // | |
| 202 // Example usage: | |
| 203 // | |
| 204 // class FooMain { | |
| 205 // public: | |
| 206 // FooMain(kj::ProcessContext& context): context(context) {} | |
| 207 // | |
| 208 // bool setAll() { all = true; return true; } | |
| 209 // // Enable the --all flag. | |
| 210 // | |
| 211 // kj::MainBuilder::Validity setOutput(kj::StringPtr name) { | |
| 212 // // Set the output file. | |
| 213 // | |
| 214 // if (name.endsWith(".foo")) { | |
| 215 // outputFile = name; | |
| 216 // return true; | |
| 217 // } else { | |
| 218 // return "Output file must have extension .foo."; | |
| 219 // } | |
| 220 // } | |
| 221 // | |
| 222 // kj::MainBuilder::Validity processInput(kj::StringPtr name) { | |
| 223 // // Process an input file. | |
| 224 // | |
| 225 // if (!exists(name)) { | |
| 226 // return kj::str(name, ": file not found"); | |
| 227 // } | |
| 228 // // ... process the input file ... | |
| 229 // return true; | |
| 230 // } | |
| 231 // | |
| 232 // kj::MainFunc getMain() { | |
| 233 // return MainBuilder(context, "Foo Builder v1.5", "Reads <source>s and builds a Foo.") | |
| 234 // .addOption({'a', "all"}, KJ_BIND_METHOD(*this, setAll), | |
| 235 // "Frob all the widgets. Otherwise, only some widgets are frobbed.") | |
| 236 // .addOptionWithArg({'o', "output"}, KJ_BIND_METHOD(*this, setOutput), | |
| 237 // "<filename>", "Output to <filename>. Must be a .foo file.") | |
| 238 // .expectOneOrMoreArgs("<source>", KJ_BIND_METHOD(*this, processInput)) | |
| 239 // .build(); | |
| 240 // } | |
| 241 // | |
| 242 // private: | |
| 243 // bool all = false; | |
| 244 // kj::StringPtr outputFile; | |
| 245 // kj::ProcessContext& context; | |
| 246 // }; | |
| 247 | |
| 248 public: | |
| 249 MainBuilder(ProcessContext& context, StringPtr version, | |
| 250 StringPtr briefDescription, StringPtr extendedDescription = nullptr); | |
| 251 ~MainBuilder() noexcept(false); | |
| 252 | |
| 253 class OptionName { | |
| 254 public: | |
| 255 OptionName() = default; | |
| 256 inline OptionName(char shortName): isLong(false), shortName(shortName) {} | |
| 257 inline OptionName(const char* longName): isLong(true), longName(longName) {} | |
| 258 | |
| 259 private: | |
| 260 bool isLong; | |
| 261 union { | |
| 262 char shortName; | |
| 263 const char* longName; | |
| 264 }; | |
| 265 friend class MainBuilder; | |
| 266 }; | |
| 267 | |
| 268 class Validity { | |
| 269 public: | |
| 270 inline Validity(bool valid) { | |
| 271 if (!valid) errorMessage = heapString("invalid argument"); | |
| 272 } | |
| 273 inline Validity(const char* errorMessage) | |
| 274 : errorMessage(heapString(errorMessage)) {} | |
| 275 inline Validity(String&& errorMessage) | |
| 276 : errorMessage(kj::mv(errorMessage)) {} | |
| 277 | |
| 278 inline const Maybe<String>& getError() const { return errorMessage; } | |
| 279 inline Maybe<String> releaseError() { return kj::mv(errorMessage); } | |
| 280 | |
| 281 private: | |
| 282 Maybe<String> errorMessage; | |
| 283 friend class MainBuilder; | |
| 284 }; | |
| 285 | |
| 286 MainBuilder& addOption(std::initializer_list<OptionName> names, Function<Validity()> callback, | |
| 287 StringPtr helpText); | |
| 288 // Defines a new option (flag). `names` is a list of characters and strings that can be used to | |
| 289 // specify the option on the command line. Single-character names are used with "-" while string | |
| 290 // names are used with "--". `helpText` is a natural-language description of the flag. | |
| 291 // | |
| 292 // `callback` is called when the option is seen. Its return value indicates whether the option | |
| 293 // was accepted. If not, further option processing stops, and error is written, and the process | |
| 294 // exits. | |
| 295 // | |
| 296 // Example: | |
| 297 // | |
| 298 // builder.addOption({'a', "all"}, KJ_BIND_METHOD(*this, showAll), "Show all files."); | |
| 299 // | |
| 300 // This option could be specified in the following ways: | |
| 301 // | |
| 302 // -a | |
| 303 // --all | |
| 304 // | |
| 305 // Note that single-character option names can be combined into a single argument. For example, | |
| 306 // `-abcd` is equivalent to `-a -b -c -d`. | |
| 307 // | |
| 308 // The help text for this option would look like: | |
| 309 // | |
| 310 // -a, --all | |
| 311 // Show all files. | |
| 312 // | |
| 313 // Note that help text is automatically word-wrapped. | |
| 314 | |
| 315 MainBuilder& addOptionWithArg(std::initializer_list<OptionName> names, | |
| 316 Function<Validity(StringPtr)> callback, | |
| 317 StringPtr argumentTitle, StringPtr helpText); | |
| 318 // Like `addOption()`, but adds an option which accepts an argument. `argumentTitle` is used in | |
| 319 // the help text. The argument text is passed to the callback. | |
| 320 // | |
| 321 // Example: | |
| 322 // | |
| 323 // builder.addOptionWithArg({'o', "output"}, KJ_BIND_METHOD(*this, setOutput), | |
| 324 // "<filename>", "Output to <filename>."); | |
| 325 // | |
| 326 // This option could be specified with an argument of "foo" in the following ways: | |
| 327 // | |
| 328 // -ofoo | |
| 329 // -o foo | |
| 330 // --output=foo | |
| 331 // --output foo | |
| 332 // | |
| 333 // Note that single-character option names can be combined, but only the last option can have an | |
| 334 // argument, since the characters after the option letter are interpreted as the argument. E.g. | |
| 335 // `-abofoo` would be equivalent to `-a -b -o foo`. | |
| 336 // | |
| 337 // The help text for this option would look like: | |
| 338 // | |
| 339 // -o FILENAME, --output=FILENAME | |
| 340 // Output to FILENAME. | |
| 341 | |
| 342 MainBuilder& addSubCommand(StringPtr name, Function<MainFunc()> getSubParser, | |
| 343 StringPtr briefHelpText); | |
| 344 // If exactly the given name is seen as an argument, invoke getSubParser() and then pass all | |
| 345 // remaining arguments to the parser it returns. This is useful for implementing commands which | |
| 346 // have lots of sub-commands, like "git" (which has sub-commands "checkout", "branch", "pull", | |
| 347 // etc.). | |
| 348 // | |
| 349 // `getSubParser` is only called if the command is seen. This avoids building main functions | |
| 350 // for commands that aren't used. | |
| 351 // | |
| 352 // `briefHelpText` should be brief enough to show immediately after the command name on a single | |
| 353 // line. It will not be wrapped. Users can use the built-in "help" command to get extended | |
| 354 // help on a particular command. | |
| 355 | |
| 356 MainBuilder& expectArg(StringPtr title, Function<Validity(StringPtr)> callback); | |
| 357 MainBuilder& expectOptionalArg(StringPtr title, Function<Validity(StringPtr)> callback); | |
| 358 MainBuilder& expectZeroOrMoreArgs(StringPtr title, Function<Validity(StringPtr)> callback); | |
| 359 MainBuilder& expectOneOrMoreArgs(StringPtr title, Function<Validity(StringPtr)> callback); | |
| 360 // Set callbacks to handle arguments. `expectArg()` and `expectOptionalArg()` specify positional | |
| 361 // arguments with special handling, while `expect{Zero,One}OrMoreArgs()` specifies a handler for | |
| 362 // an argument list (the handler is called once for each argument in the list). `title` | |
| 363 // specifies how the argument should be represented in the usage text. | |
| 364 // | |
| 365 // All options callbacks are called before argument callbacks, regardless of their ordering on | |
| 366 // the command line. This matches GNU getopt's behavior of permuting non-flag arguments to the | |
| 367 // end of the argument list. Also matching getopt, the special option "--" indicates that the | |
| 368 // rest of the command line is all arguments, not options, even if they start with '-'. | |
| 369 // | |
| 370 // The interpretation of positional arguments is fairly flexible. The non-optional arguments can | |
| 371 // be expected at the beginning, end, or in the middle. If more arguments are specified than | |
| 372 // the number of non-optional args, they are assigned to the optional argument handlers in the | |
| 373 // order of registration. | |
| 374 // | |
| 375 // For example, say you called: | |
| 376 // builder.expectArg("<foo>", ...); | |
| 377 // builder.expectOptionalArg("<bar>", ...); | |
| 378 // builder.expectArg("<baz>", ...); | |
| 379 // builder.expectZeroOrMoreArgs("<qux>", ...); | |
| 380 // builder.expectArg("<corge>", ...); | |
| 381 // | |
| 382 // This command requires at least three arguments: foo, baz, and corge. If four arguments are | |
| 383 // given, the second is assigned to bar. If five or more arguments are specified, then the | |
| 384 // arguments between the third and last are assigned to qux. Note that it never makes sense | |
| 385 // to call `expect*OrMoreArgs()` more than once since only the first call would ever be used. | |
| 386 // | |
| 387 // In practice, you probably shouldn't create such complicated commands as in the above example. | |
| 388 // But, this flexibility seems necessary to support commands where the first argument is special | |
| 389 // as well as commands (like `cp`) where the last argument is special. | |
| 390 | |
| 391 MainBuilder& callAfterParsing(Function<Validity()> callback); | |
| 392 // Call the given function after all arguments have been parsed. | |
| 393 | |
| 394 MainFunc build(); | |
| 395 // Build the "main" function, which simply parses the arguments. Once this returns, the | |
| 396 // `MainBuilder` is no longer valid. | |
| 397 | |
| 398 private: | |
| 399 struct Impl; | |
| 400 Own<Impl> impl; | |
| 401 | |
| 402 class MainImpl; | |
| 403 }; | |
| 404 | |
| 405 } // namespace kj | |
| 406 | |
| 407 #endif // KJ_MAIN_H_ | 
