• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef AAPT_COMMAND_H
18 #define AAPT_COMMAND_H
19 
20 #include <functional>
21 #include <optional>
22 #include <ostream>
23 #include <string>
24 #include <unordered_set>
25 #include <vector>
26 
27 #include "androidfw/StringPiece.h"
28 
29 namespace aapt {
30 
31 class Command {
32  public:
Command(const android::StringPiece & name)33   explicit Command(const android::StringPiece& name)
34       : name_(name.to_string()), full_subcommand_name_(name.to_string()){};
35 
Command(const android::StringPiece & name,const android::StringPiece & short_name)36   explicit Command(const android::StringPiece& name, const android::StringPiece& short_name)
37       : name_(name.to_string()),
38         short_name_(short_name.to_string()),
39         full_subcommand_name_(name.to_string()){};
40 
41   Command(Command&&) = default;
42   Command& operator=(Command&&) = default;
43 
44   virtual ~Command() = default;
45 
46   // Behavior flags used with the following functions that change how the command flags are parsed
47   // displayed.
48   enum : uint32_t {
49     // Indicates the arguments are file or folder paths. On Windows, paths that exceed the maximum
50     // path length will be converted to use the extended path prefix '//?/'. Without this
51     // conversion, files with long paths cannot be opened.
52     kPath = 1 << 0,
53   };
54 
55   void AddRequiredFlag(const android::StringPiece& name, const android::StringPiece& description,
56                        std::string* value, uint32_t flags = 0);
57 
58   void AddRequiredFlagList(const android::StringPiece& name,
59                            const android::StringPiece& description, std::vector<std::string>* value,
60                            uint32_t flags = 0);
61 
62   void AddOptionalFlag(const android::StringPiece& name, const android::StringPiece& description,
63                        std::optional<std::string>* value, uint32_t flags = 0);
64 
65   void AddOptionalFlagList(const android::StringPiece& name,
66                            const android::StringPiece& description, std::vector<std::string>* value,
67                            uint32_t flags = 0);
68 
69   void AddOptionalFlagList(const android::StringPiece& name,
70                            const android::StringPiece& description,
71                            std::unordered_set<std::string>* value);
72 
73   void AddOptionalSwitch(const android::StringPiece& name, const android::StringPiece& description,
74                          bool* value);
75 
76   void AddOptionalSubcommand(std::unique_ptr<Command>&& subcommand, bool experimental = false);
77 
78   void SetDescription(const android::StringPiece& name);
79 
80   // Prints the help menu of the command.
81   void Usage(std::ostream* out);
82 
83   // Parses the command line arguments, sets the flag variable values, and runs the action of
84   // the command. If the arguments fail to parse to the command and its subcommands, then the action
85   // will not be run and the usage will be printed instead.
86   int Execute(const std::vector<android::StringPiece>& args, std::ostream* outError);
87 
88   // The action to preform when the command is executed.
89   virtual int Action(const std::vector<std::string>& args) = 0;
90 
91  private:
92   struct Flag {
FlagFlag93     explicit Flag(const android::StringPiece& name, const android::StringPiece& description,
94                   const bool is_required, const size_t num_args,
95                   std::function<bool(const android::StringPiece& value)>&& action)
96         : name(name.to_string()), description(description.to_string()), is_required(is_required),
97           num_args(num_args), action(std::move(action)) {}
98 
99     const std::string name;
100     const std::string description;
101     const bool is_required;
102     const size_t num_args;
103     const std::function<bool(const android::StringPiece& value)> action;
104     bool found = false;
105   };
106 
107   std::string name_;
108   std::string short_name_;
109   std::string description_ = "";
110   std::string full_subcommand_name_;
111 
112   std::vector<Flag> flags_;
113   std::vector<std::unique_ptr<Command>> subcommands_;
114   std::vector<std::unique_ptr<Command>> experimental_subcommands_;
115 };
116 
117 }  // namespace aapt
118 
119 #endif  // AAPT_COMMAND_H
120