1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "cmd_parser.h"
17 #include<algorithm>
18 #include "resource_util.h"
19
20 #include "cmd_list.h"
21
22 namespace OHOS {
23 namespace Global {
24 namespace Restool {
25 using namespace std;
26 const struct option PackageParser::CMD_OPTS[] = {
27 { "inputPath", required_argument, nullptr, 'i' },
28 { "packageName", required_argument, nullptr, 'p' },
29 { "outputPath", required_argument, nullptr, 'o' },
30 { "resHeader", required_argument, nullptr, 'r' },
31 { "forceWrite", no_argument, nullptr, 'f' },
32 { "version", no_argument, nullptr, 'v'},
33 { "modules", optional_argument, nullptr, 'm' },
34 { "json", optional_argument, nullptr, 'j' },
35 { "startId", optional_argument, nullptr, 'e' },
36 { "cache", optional_argument, nullptr, 'c' },
37 { "fileList", required_argument, nullptr, 'l' },
38 { "preview", no_argument, nullptr, 'a' },
39 { "priority", required_argument, nullptr, 'g' },
40 { "dependEntry", required_argument, nullptr, 'd' },
41 };
42
43 const string PackageParser::CMD_PARAMS = "i:p:o:r:m:j:e:c:l:g:d:afv";
44
Parse(int argc,char * argv[])45 uint32_t PackageParser::Parse(int argc, char *argv[])
46 {
47 InitCommand();
48 if (ParseCommand(argc, argv) != RESTOOL_SUCCESS) {
49 return RESTOOL_ERROR;
50 }
51 return CheckParam();
52 }
53
GetInputs() const54 const vector<string> &PackageParser::GetInputs() const
55 {
56 return inputs_;
57 }
58
GetPackageName() const59 const string &PackageParser::GetPackageName() const
60 {
61 return packageName_;
62 }
63
GetOutput() const64 const string &PackageParser::GetOutput() const
65 {
66 return output_;
67 }
68
GetResourceHeaders() const69 const vector<string> &PackageParser::GetResourceHeaders() const
70 {
71 return resourceHeaderPaths_;
72 }
73
GetForceWrite() const74 bool PackageParser::GetForceWrite() const
75 {
76 return forceWrite_;
77 }
78
GetModuleNames() const79 const vector<string> &PackageParser::GetModuleNames() const
80 {
81 return moduleNames_;
82 }
83
GetConfig() const84 const string &PackageParser::GetConfig() const
85 {
86 return configPath_;
87 }
88
GetRestoolPath() const89 const string &PackageParser::GetRestoolPath() const
90 {
91 return restoolPath_;
92 }
93
GetStartId() const94 int32_t PackageParser::GetStartId() const
95 {
96 return startId_;
97 }
98
GetCachePath() const99 const string &PackageParser::GetCachePath() const
100 {
101 return cachePath_;
102 }
103
GetDependEntry() const104 const string &PackageParser::GetDependEntry() const
105 {
106 return dependEntry_;
107 }
108
AddInput(const string & argValue)109 uint32_t PackageParser::AddInput(const string& argValue)
110 {
111 auto ret = find_if(inputs_.begin(), inputs_.end(), [argValue](auto iter) {return argValue == iter;});
112 if (ret != inputs_.end()) {
113 cerr << "Error: repeat input '" << argValue << "'" << endl;
114 return RESTOOL_ERROR;
115 }
116
117 inputs_.push_back(argValue);
118 return RESTOOL_SUCCESS;
119 }
120
AddPackageName(const string & argValue)121 uint32_t PackageParser::AddPackageName(const string& argValue)
122 {
123 if (!packageName_.empty()) {
124 cerr << "Error: double package name " << packageName_ << " vs " << argValue << endl;
125 return RESTOOL_ERROR;
126 }
127
128 packageName_ = argValue;
129 return RESTOOL_SUCCESS;
130 }
131
AddOutput(const string & argValue)132 uint32_t PackageParser::AddOutput(const string& argValue)
133 {
134 if (!output_.empty()) {
135 cerr << "Error: double output " << output_ << " vs " << argValue << endl;
136 return RESTOOL_ERROR;
137 }
138
139 output_ = argValue;
140 return RESTOOL_SUCCESS;
141 }
142
AddResourceHeader(const string & argValue)143 uint32_t PackageParser::AddResourceHeader(const string& argValue)
144 {
145 if (find(resourceHeaderPaths_.begin(), resourceHeaderPaths_.end(), argValue) != resourceHeaderPaths_.end()) {
146 cerr << "Error: '" << argValue << "' input duplicated." << endl;
147 return RESTOOL_ERROR;
148 }
149 resourceHeaderPaths_.push_back(argValue);
150 return RESTOOL_SUCCESS;
151 }
152
ForceWrite()153 uint32_t PackageParser::ForceWrite()
154 {
155 forceWrite_ = true;
156 return RESTOOL_SUCCESS;
157 }
158
PrintVersion()159 uint32_t PackageParser::PrintVersion()
160 {
161 cout << "Info: Restool version= " << RESTOOL_VERSION << endl;
162 exit(RESTOOL_SUCCESS);
163 return RESTOOL_SUCCESS;
164 }
165
AddMoudleNames(const string & argValue)166 uint32_t PackageParser::AddMoudleNames(const string& argValue)
167 {
168 if (!moduleNames_.empty()) {
169 cerr << "Error: -m double module name '" << argValue << "'" << endl;
170 return RESTOOL_ERROR;
171 }
172
173 ResourceUtil::Split(argValue, moduleNames_, ",");
174 for (auto it = moduleNames_.begin(); it != moduleNames_.end(); it++) {
175 auto ret = find_if(moduleNames_.begin(), moduleNames_.end(), [it](auto iter) {return *it == iter;});
176 if (ret != it) {
177 cerr << "Error: double module name '" << *it << "'" << endl;
178 return RESTOOL_ERROR;
179 }
180 }
181 return RESTOOL_SUCCESS;
182 }
183
AddConfig(const string & argValue)184 uint32_t PackageParser::AddConfig(const string& argValue)
185 {
186 if (!configPath_.empty()) {
187 cerr << "Error: double config.json " << configPath_ << " vs " << argValue << endl;
188 return RESTOOL_ERROR;
189 }
190
191 configPath_ = argValue;
192 return RESTOOL_SUCCESS;
193 }
194
AddStartId(const string & argValue)195 uint32_t PackageParser::AddStartId(const string& argValue)
196 {
197 startId_ = strtol(argValue.c_str(), nullptr, 16);
198 if ((startId_ >= 0x01000000 && startId_ < 0x06ffffff) || (startId_ >= 0x08000000 && startId_ < 0x41ffffff)) {
199 return RESTOOL_SUCCESS;
200 }
201 cerr << "Error: invalid start id " << argValue << endl;
202 return RESTOOL_ERROR;
203 }
204
AddCachePath(const string & argValue)205 uint32_t PackageParser::AddCachePath(const string& argValue)
206 {
207 cachePath_ = argValue;
208 return RESTOOL_SUCCESS;
209 }
210
CheckParam() const211 uint32_t PackageParser::CheckParam() const
212 {
213 if (inputs_.empty()) {
214 cerr << "Error: input path empty." << endl;
215 return RESTOOL_ERROR;
216 }
217
218 if (output_.empty()) {
219 cerr << "Error: output path empty." << endl;
220 return RESTOOL_ERROR;
221 }
222
223 if (previewMode_) {
224 return RESTOOL_SUCCESS;
225 }
226 if (packageName_.empty()) {
227 cerr << "Error: package name empty." << endl;
228 return RESTOOL_ERROR;
229 }
230
231 if (resourceHeaderPaths_.empty()) {
232 cerr << "Error: resource header path empty." << endl;
233 return RESTOOL_ERROR;
234 }
235 return RESTOOL_SUCCESS;
236 }
237
IsFileList() const238 bool PackageParser::IsFileList() const
239 {
240 return isFileList_;
241 }
242
SetPreviewMode()243 uint32_t PackageParser::SetPreviewMode()
244 {
245 previewMode_ = true;
246 return RESTOOL_SUCCESS;
247 }
248
GetPreviewMode() const249 bool PackageParser::GetPreviewMode() const
250 {
251 return previewMode_;
252 }
253
GetPriority() const254 int32_t PackageParser::GetPriority() const
255 {
256 return priority_;
257 }
258
SetPriority(const string & argValue)259 uint32_t PackageParser::SetPriority(const string& argValue)
260 {
261 priority_ = atoi(argValue.c_str());
262 return RESTOOL_SUCCESS;
263 }
264
AddDependEntry(const string & argValue)265 uint32_t PackageParser::AddDependEntry(const string& argValue)
266 {
267 dependEntry_ = argValue;
268 return RESTOOL_SUCCESS;
269 }
InitCommand()270 void PackageParser::InitCommand()
271 {
272 using namespace placeholders;
273 handles_.emplace('i', bind(&PackageParser::AddInput, this, _1));
274 handles_.emplace('p', bind(&PackageParser::AddPackageName, this, _1));
275 handles_.emplace('o', bind(&PackageParser::AddOutput, this, _1));
276 handles_.emplace('r', bind(&PackageParser::AddResourceHeader, this, _1));
277 handles_.emplace('f', [this](const string &) -> uint32_t { return ForceWrite(); });
278 handles_.emplace('v', [this](const string &) -> uint32_t { return PrintVersion(); });
279 handles_.emplace('m', bind(&PackageParser::AddMoudleNames, this, _1));
280 handles_.emplace('j', bind(&PackageParser::AddConfig, this, _1));
281 handles_.emplace('e', bind(&PackageParser::AddStartId, this, _1));
282 handles_.emplace('c', bind(&PackageParser::AddCachePath, this, _1));
283 handles_.emplace('a', [this](const string &) -> uint32_t { return SetPreviewMode(); });
284 handles_.emplace('g', bind(&PackageParser::SetPriority, this, _1));
285 handles_.emplace('d', bind(&PackageParser::AddDependEntry, this, _1));
286 }
287
HandleProcess(int c,const string & argValue)288 uint32_t PackageParser::HandleProcess(int c, const string& argValue)
289 {
290 auto handler = handles_.find(c);
291 if (handler == handles_.end()) {
292 cout << "Warning: unsupport " << c << endl;
293 return RESTOOL_SUCCESS;
294 }
295 return handler->second(argValue);
296 }
297
ParseFileList(const string & fileListPath)298 uint32_t PackageParser::ParseFileList(const string& fileListPath)
299 {
300 isFileList_ = true;
301 CmdList cmdList;
302 if (cmdList.Init(fileListPath, [this](int c, const string &argValue) -> int32_t {
303 return HandleProcess(c, argValue);
304 }) != RESTOOL_SUCCESS) {
305 return RESTOOL_ERROR;
306 }
307 return RESTOOL_SUCCESS;
308 }
309
ParseCommand(int argc,char * argv[])310 uint32_t PackageParser::ParseCommand(int argc, char *argv[])
311 {
312 restoolPath_ = string(argv[0]);
313 while (true) {
314 int optIndex = 0;
315 int c = getopt_long(argc, argv, CMD_PARAMS.c_str(), CMD_OPTS, &optIndex);
316 if (c == -1) {
317 break;
318 }
319
320 string argValue = (optarg != nullptr) ? optarg : "";
321 if (c == 'l') {
322 return ParseFileList(argValue);
323 }
324 if (HandleProcess(c, argValue) != RESTOOL_SUCCESS) {
325 return RESTOOL_ERROR;
326 }
327 }
328 return RESTOOL_SUCCESS;
329 }
330 }
331 }
332 }
333