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
33namespace kj {
34
35class ProcessContext {
36 // Context for command-line programs.
37
38public:
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
131class 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
137public:
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
154private:
155 StringPtr programName;
156 bool cleanShutdown;
157 bool hadErrors = false;
158};
159
160typedef Function<void(StringPtr programName, ArrayPtr<const StringPtr> params)> MainFunc;
161
162int 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
184class 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
247public:
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
397private:
398 struct Impl;
399 Own<Impl> impl;
400
401 class MainImpl;
402};
403
404} // namespace kj
405