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