1 /*
2 * Copyright (C) 2015 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 #include "command.h"
18
19 #include <algorithm>
20 #include <map>
21 #include <string>
22 #include <vector>
23
24 #include <android-base/logging.h>
25
NextArgumentOrError(const std::vector<std::string> & args,size_t * pi)26 bool Command::NextArgumentOrError(const std::vector<std::string>& args, size_t* pi) {
27 if (*pi + 1 == args.size()) {
28 LOG(ERROR) << "No argument following " << args[*pi] << " option. Try `simpleperf help " << name_
29 << "`";
30 return false;
31 }
32 ++*pi;
33 return true;
34 }
35
ReportUnknownOption(const std::vector<std::string> & args,size_t i)36 void Command::ReportUnknownOption(const std::vector<std::string>& args, size_t i) {
37 LOG(ERROR) << "Unknown option for " << name_ << " command: '" << args[i]
38 << "'. Try `simpleperf help " << name_ << "`";
39 }
40
41 typedef std::function<std::unique_ptr<Command>(void)> callback_t;
42
CommandMap()43 static std::map<std::string, callback_t>& CommandMap() {
44 // commands is used in the constructor of Command. Defining it as a static
45 // variable in a function makes sure it is initialized before use.
46 static std::map<std::string, callback_t> command_map;
47 return command_map;
48 }
49
RegisterCommand(const std::string & cmd_name,std::function<std::unique_ptr<Command> (void)> callback)50 void RegisterCommand(const std::string& cmd_name,
51 std::function<std::unique_ptr<Command>(void)> callback) {
52 CommandMap().insert(std::make_pair(cmd_name, callback));
53 }
54
UnRegisterCommand(const std::string & cmd_name)55 void UnRegisterCommand(const std::string& cmd_name) {
56 CommandMap().erase(cmd_name);
57 }
58
CreateCommandInstance(const std::string & cmd_name)59 std::unique_ptr<Command> CreateCommandInstance(const std::string& cmd_name) {
60 auto it = CommandMap().find(cmd_name);
61 return (it == CommandMap().end()) ? nullptr : (it->second)();
62 }
63
GetAllCommandNames()64 const std::vector<std::string> GetAllCommandNames() {
65 std::vector<std::string> names;
66 for (auto pair : CommandMap()) {
67 names.push_back(pair.first);
68 }
69 return names;
70 }
71
72 extern void RegisterDumpRecordCommand();
73 extern void RegisterHelpCommand();
74 extern void RegisterListCommand();
75 extern void RegisterRecordCommand();
76 extern void RegisterReportCommand();
77 extern void RegisterStatCommand();
78
79 class CommandRegister {
80 public:
CommandRegister()81 CommandRegister() {
82 RegisterDumpRecordCommand();
83 RegisterHelpCommand();
84 RegisterReportCommand();
85 #if defined(__linux__)
86 RegisterListCommand();
87 RegisterRecordCommand();
88 RegisterStatCommand();
89 #endif
90 }
91 };
92
93 CommandRegister command_register;
94