// Copyright 2016 The Fuchsia Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Provides a simple class, |CommandLine|, for dealing with command lines (and // flags and positional arguments). // // * Options (a.k.a. flags or switches) are all of the form "--name=" (or // "--name", but this is indistinguishable from "--name="), where is a // string. Not supported: "-name", "-n", "--name ", "-n ", etc. // * Option order is preserved. // * Option processing is stopped after the first positional argument[*]. Thus // in the command line "my_program --foo bar --baz", only "--foo" is an option // ("bar" and "--baz" are positional arguments). // * Options can be looked up by name. If the same option occurs multiple times, // convention is to use the last occurrence (and the provided look-up // functions behave this way). // * "--" may also be used to separate options from positional arguments. Thus // in the command line "my_program --foo -- --bar", "--bar" is a positional // argument. // * |CommandLine|s store |argv[0]| and distinguish between not having |argv[0]| // and |argv[0]| being empty. // * Apart from being copyable and movable, |CommandLine|s are immutable. // // There are factory functions to turn raw arguments into |CommandLine|s, in // accordance with the above rules. However, |CommandLine|s may be used more // generically (with the user transforming arguments using different rules, // e.g., accepting "-name" as an option), subject to certain limitations (e.g., // not being able to distinguish "no value" from "empty value"). // // [*] This is somewhat annoying for users, but: a. it's standard Unix behavior // for most command line parsers, b. it makes "my_program *" (etc.) safer (which // mostly explains a.), c. it makes parsing "subcommands", like "my_program // --flag_for_my_program subcommand --flag_for_subcommand" saner. #ifndef LIB_FXL_COMMAND_LINE_H_ #define LIB_FXL_COMMAND_LINE_H_ #include #include #include #include #include #include "flutter/fml/macros.h" #include "flutter/fml/string_view.h" namespace fml { // CommandLine ----------------------------------------------------------------- // Class that stores processed command lines ("argv[0]", options, and positional // arguments) and provides access to them. For more details, see the file-level // comment above. This class is thread-safe. class CommandLine final { private: class ConstructionHelper; public: struct Option { Option() {} explicit Option(const std::string& name); Option(const std::string& name, const std::string& value); bool operator==(const Option& other) const { return name == other.name && value == other.value; } bool operator!=(const Option& other) const { return !operator==(other); } std::string name; std::string value; }; // Default, copy, and move constructors (to be out-of-lined). CommandLine(); CommandLine(const CommandLine& from); CommandLine(CommandLine&& from); // Constructs a |CommandLine| from its "components". This is especially useful // for creating a new |CommandLine| based on an existing |CommandLine| (e.g., // adding options or arguments). explicit CommandLine(const std::string& argv0, const std::vector