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,const std::function<std::unique_ptr<Command> (void)> & callback)50 void RegisterCommand(const std::string& cmd_name,
51                      const 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 RegisterKmemCommand();
76 extern void RegisterRecordCommand();
77 extern void RegisterReportCommand();
78 extern void RegisterReportSampleCommand();
79 extern void RegisterStatCommand();
80 
81 class CommandRegister {
82  public:
CommandRegister()83   CommandRegister() {
84     RegisterDumpRecordCommand();
85     RegisterHelpCommand();
86     RegisterKmemCommand();
87     RegisterReportCommand();
88     RegisterReportSampleCommand();
89 #if defined(__linux__)
90     RegisterListCommand();
91     RegisterRecordCommand();
92     RegisterStatCommand();
93 #endif
94   }
95 };
96 
97 CommandRegister command_register;
98