• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "cmd_list.h"
19 #include "resource_util.h"
20 
21 namespace OHOS {
22 namespace Global {
23 namespace Restool {
24 using namespace std;
25 const struct option PackageParser::CMD_OPTS[] = {
26     { "inputPath", required_argument, nullptr, 'i' },
27     { "packageName", required_argument, nullptr, 'p' },
28     { "outputPath", required_argument, nullptr, 'o' },
29     { "resHeader", required_argument, nullptr, 'r' },
30     { "forceWrite", no_argument, nullptr, 'f' },
31     { "version", no_argument, nullptr, 'v'},
32     { "modules", optional_argument, nullptr, 'm' },
33     { "json", optional_argument, nullptr, 'j' },
34     { "startId", optional_argument, nullptr, 'e' },
35     { "cache", optional_argument, nullptr, 'c' },
36     { "fileList", required_argument, nullptr, 'l' },
37     { "preview", no_argument, nullptr, 'a' },
38     { "priority", required_argument, nullptr, 'g' },
39     { "append", required_argument, nullptr, 'x' },
40     { "combine", required_argument, nullptr, 'z' },
41     { "dependEntry", required_argument, nullptr, 'd' },
42     { "help", no_argument, nullptr, 'h'},
43 };
44 
45 const string PackageParser::CMD_PARAMS = "i:p:o:r:m:j:e:c:l:g:x:d:afhvz";
46 
Parse(int argc,char * argv[])47 uint32_t PackageParser::Parse(int argc, char *argv[])
48 {
49     InitCommand();
50     if (ParseCommand(argc, argv) != RESTOOL_SUCCESS) {
51         return RESTOOL_ERROR;
52     }
53     return CheckParam();
54 }
55 
GetInputs() const56 const vector<string> &PackageParser::GetInputs() const
57 {
58     return inputs_;
59 }
60 
GetPackageName() const61 const string &PackageParser::GetPackageName() const
62 {
63     return packageName_;
64 }
65 
GetOutput() const66 const string &PackageParser::GetOutput() const
67 {
68     return output_;
69 }
70 
GetResourceHeaders() const71 const vector<string> &PackageParser::GetResourceHeaders() const
72 {
73     return resourceHeaderPaths_;
74 }
75 
GetForceWrite() const76 bool PackageParser::GetForceWrite() const
77 {
78     return forceWrite_;
79 }
80 
GetModuleNames() const81 const vector<string> &PackageParser::GetModuleNames() const
82 {
83     return moduleNames_;
84 }
85 
GetConfig() const86 const string &PackageParser::GetConfig() const
87 {
88     return configPath_;
89 }
90 
GetRestoolPath() const91 const string &PackageParser::GetRestoolPath() const
92 {
93     return restoolPath_;
94 }
95 
GetStartId() const96 int32_t PackageParser::GetStartId() const
97 {
98     return startId_;
99 }
100 
GetCachePath() const101 const string &PackageParser::GetCachePath() const
102 {
103     return cachePath_;
104 }
105 
GetDependEntry() const106 const string &PackageParser::GetDependEntry() const
107 {
108     return dependEntry_;
109 }
110 
AddInput(const string & argValue)111 uint32_t PackageParser::AddInput(const string& argValue)
112 {
113     string inputPath = ResourceUtil::RealPath(argValue);
114     if (inputPath.empty()) {
115         cerr << "Error: invalid input '" << argValue << "'" << endl;
116         return RESTOOL_ERROR;
117     }
118 
119     auto ret = find_if(inputs_.begin(), inputs_.end(), [inputPath](auto iter) {return inputPath == iter;});
120     if (ret != inputs_.end()) {
121         cerr << "Error: repeat input '" << argValue << "'" << endl;
122         return RESTOOL_ERROR;
123     }
124 
125     if (!IsAscii(inputPath)) {
126         return RESTOOL_ERROR;
127     }
128     inputs_.push_back(inputPath);
129     return RESTOOL_SUCCESS;
130 }
131 
AddPackageName(const string & argValue)132 uint32_t PackageParser::AddPackageName(const string& argValue)
133 {
134     if (!packageName_.empty()) {
135         cerr << "Error: double package name " << packageName_ << " vs " << argValue << endl;
136         return RESTOOL_ERROR;
137     }
138 
139     packageName_ = argValue;
140     return RESTOOL_SUCCESS;
141 }
142 
AddOutput(const string & argValue)143 uint32_t PackageParser::AddOutput(const string& argValue)
144 {
145     if (!output_.empty()) {
146         cerr << "Error: double output " << output_ << " vs " << argValue << endl;
147         return RESTOOL_ERROR;
148     }
149 
150     output_ = ResourceUtil::RealPath(argValue);
151     if (output_.empty()) {
152         cerr << "Error: invalid output '" << argValue << "'" << endl;
153         return RESTOOL_ERROR;
154     }
155     if (!IsAscii(output_)) {
156         return RESTOOL_ERROR;
157     }
158     return RESTOOL_SUCCESS;
159 }
160 
AddResourceHeader(const string & argValue)161 uint32_t PackageParser::AddResourceHeader(const string& argValue)
162 {
163     if (find(resourceHeaderPaths_.begin(), resourceHeaderPaths_.end(), argValue) != resourceHeaderPaths_.end()) {
164         cerr << "Error: '" << argValue << "' input duplicated." << endl;
165         return RESTOOL_ERROR;
166     }
167     resourceHeaderPaths_.push_back(argValue);
168     return RESTOOL_SUCCESS;
169 }
170 
ForceWrite()171 uint32_t PackageParser::ForceWrite()
172 {
173     forceWrite_ = true;
174     return RESTOOL_SUCCESS;
175 }
176 
PrintVersion()177 uint32_t PackageParser::PrintVersion()
178 {
179     cout << "Info: Restool version= " << RESTOOL_VERSION << endl;
180     exit(RESTOOL_SUCCESS);
181     return RESTOOL_SUCCESS;
182 }
183 
AddMoudleNames(const string & argValue)184 uint32_t PackageParser::AddMoudleNames(const string& argValue)
185 {
186     if (!moduleNames_.empty()) {
187         cerr << "Error: -m double module name '" << argValue << "'" << endl;
188         return RESTOOL_ERROR;
189     }
190 
191     ResourceUtil::Split(argValue, moduleNames_, ",");
192     for (auto it = moduleNames_.begin(); it != moduleNames_.end(); it++) {
193         auto ret = find_if(moduleNames_.begin(), moduleNames_.end(), [it](auto iter) {return *it == iter;});
194         if (ret != it) {
195             cerr << "Error: double module name '" << *it << "'" << endl;
196             return RESTOOL_ERROR;
197         }
198     }
199     return RESTOOL_SUCCESS;
200 }
201 
AddConfig(const string & argValue)202 uint32_t PackageParser::AddConfig(const string& argValue)
203 {
204     if (!configPath_.empty()) {
205         cerr << "Error: double config.json " << configPath_ << " vs " << argValue << endl;
206         return RESTOOL_ERROR;
207     }
208 
209     configPath_ = argValue;
210     return RESTOOL_SUCCESS;
211 }
212 
AddStartId(const string & argValue)213 uint32_t PackageParser::AddStartId(const string& argValue)
214 {
215     startId_ = strtol(argValue.c_str(), nullptr, 16); // 16 is hexadecimal number
216     if ((startId_ >= 0x01000000 && startId_ < 0x06ffffff) || (startId_ >= 0x08000000 && startId_ < 0x41ffffff)) {
217         return RESTOOL_SUCCESS;
218     }
219     cerr << "Error: invalid start id " << argValue << endl;
220     return RESTOOL_ERROR;
221 }
222 
AddCachePath(const string & argValue)223 uint32_t PackageParser::AddCachePath(const string& argValue)
224 {
225     cachePath_ = argValue;
226     return RESTOOL_SUCCESS;
227 }
228 
CheckParam() const229 uint32_t PackageParser::CheckParam() const
230 {
231     if (inputs_.empty() && append_.empty()) {
232         cerr << "Error: input path empty." << endl;
233         return RESTOOL_ERROR;
234     }
235 
236     if (output_.empty()) {
237         cerr << "Error: output path empty." << endl;
238         return RESTOOL_ERROR;
239     }
240 
241     if (previewMode_ || !append_.empty()) {
242         return RESTOOL_SUCCESS;
243     }
244     if (packageName_.empty()) {
245         cerr << "Error: package name empty." << endl;
246         return RESTOOL_ERROR;
247     }
248 
249     if (resourceHeaderPaths_.empty()) {
250         cerr << "Error: resource header path empty." << endl;
251         return RESTOOL_ERROR;
252     }
253     return RESTOOL_SUCCESS;
254 }
255 
IsFileList() const256 bool PackageParser::IsFileList() const
257 {
258     return isFileList_;
259 }
260 
SetPreviewMode()261 uint32_t PackageParser::SetPreviewMode()
262 {
263     previewMode_ = true;
264     return RESTOOL_SUCCESS;
265 }
266 
GetPreviewMode() const267 bool PackageParser::GetPreviewMode() const
268 {
269     return previewMode_;
270 }
271 
GetPriority() const272 int32_t PackageParser::GetPriority() const
273 {
274     return priority_;
275 }
276 
SetPriority(const string & argValue)277 uint32_t PackageParser::SetPriority(const string& argValue)
278 {
279     priority_ = atoi(argValue.c_str());
280     return RESTOOL_SUCCESS;
281 }
282 
AddAppend(const string & argValue)283 uint32_t PackageParser::AddAppend(const string& argValue)
284 {
285     string appendPath = ResourceUtil::RealPath(argValue);
286     if (appendPath.empty()) {
287         cout << "Warning: invaild compress '" << argValue << "'" << endl;
288         appendPath = argValue;
289     }
290     auto ret = find_if(append_.begin(), append_.end(), [appendPath](auto iter) {return appendPath == iter;});
291     if (ret != append_.end()) {
292         cerr << "Error: repeat input '" << argValue << "'" << endl;
293         return RESTOOL_ERROR;
294     }
295     if (!IsAscii(appendPath)) {
296         return RESTOOL_ERROR;
297     }
298     append_.push_back(appendPath);
299     return RESTOOL_SUCCESS;
300 }
301 
GetAppend() const302 const vector<string> &PackageParser::GetAppend() const
303 {
304     return append_;
305 }
306 
SetCombine()307 uint32_t PackageParser::SetCombine()
308 {
309     combine_ = true;
310     return RESTOOL_SUCCESS;
311 }
312 
GetCombine() const313 bool PackageParser::GetCombine() const
314 {
315     return combine_;
316 }
317 
AddDependEntry(const string & argValue)318 uint32_t PackageParser::AddDependEntry(const string& argValue)
319 {
320     dependEntry_ = argValue;
321     return RESTOOL_SUCCESS;
322 }
323 
ShowHelp() const324 uint32_t PackageParser::ShowHelp() const
325 {
326     auto &parser = CmdParser<PackageParser>::GetInstance();
327     parser.ShowUseage();
328     exit(RESTOOL_SUCCESS);
329     return RESTOOL_SUCCESS;
330 }
331 
IsAscii(const string & argValue) const332 bool PackageParser::IsAscii(const string& argValue) const
333 {
334 #ifdef __WIN32
335     auto result = find_if(argValue.begin(), argValue.end(), [](auto iter) {
336         if ((iter & 0x80) != 0) {
337             return true;
338         }
339         return false;
340     });
341     if (result != argValue.end()) {
342         cerr << "Error: '" << argValue << "' must be ASCII" << endl;
343         return false;
344     }
345 #endif
346     return true;
347 }
348 
InitCommand()349 void PackageParser::InitCommand()
350 {
351     using namespace placeholders;
352     handles_.emplace('i', bind(&PackageParser::AddInput, this, _1));
353     handles_.emplace('p', bind(&PackageParser::AddPackageName, this, _1));
354     handles_.emplace('o', bind(&PackageParser::AddOutput, this, _1));
355     handles_.emplace('r', bind(&PackageParser::AddResourceHeader, this, _1));
356     handles_.emplace('f', [this](const string &) -> uint32_t { return ForceWrite(); });
357     handles_.emplace('v', [this](const string &) -> uint32_t { return PrintVersion(); });
358     handles_.emplace('m', bind(&PackageParser::AddMoudleNames, this, _1));
359     handles_.emplace('j', bind(&PackageParser::AddConfig, this,  _1));
360     handles_.emplace('e', bind(&PackageParser::AddStartId, this, _1));
361     handles_.emplace('c', bind(&PackageParser::AddCachePath, this, _1));
362     handles_.emplace('a', [this](const string &) -> uint32_t { return SetPreviewMode(); });
363     handles_.emplace('g', bind(&PackageParser::SetPriority, this, _1));
364     handles_.emplace('x', bind(&PackageParser::AddAppend, this, _1));
365     handles_.emplace('z', [this](const string &) -> uint32_t { return SetCombine(); });
366     handles_.emplace('d', bind(&PackageParser::AddDependEntry, this, _1));
367     handles_.emplace('h', [this](const string &) -> uint32_t { return ShowHelp(); });
368 }
369 
HandleProcess(int c,const string & argValue)370 uint32_t PackageParser::HandleProcess(int c, const string& argValue)
371 {
372     auto handler = handles_.find(c);
373     if (handler == handles_.end()) {
374         cout << "Warning: unsupport " << c << endl;
375         return RESTOOL_SUCCESS;
376     }
377     return handler->second(argValue);
378 }
379 
ParseFileList(const string & fileListPath)380 uint32_t PackageParser::ParseFileList(const string& fileListPath)
381 {
382     isFileList_ = true;
383     CmdList cmdList;
384     if (cmdList.Init(fileListPath, [this](int c, const string &argValue) -> int32_t {
385         return HandleProcess(c, argValue);
386     }) != RESTOOL_SUCCESS) {
387         return RESTOOL_ERROR;
388     }
389     return RESTOOL_SUCCESS;
390 }
391 
ParseCommand(int argc,char * argv[])392 uint32_t PackageParser::ParseCommand(int argc, char *argv[])
393 {
394     restoolPath_ = string(argv[0]);
395     while (true) {
396         int optIndex = 0;
397         int c = getopt_long(argc, argv, CMD_PARAMS.c_str(), CMD_OPTS, &optIndex);
398         if (c == -1) {
399             break;
400         }
401 
402         string argValue = (optarg != nullptr) ? optarg : "";
403         if (c == 'l') {
404             return ParseFileList(argValue);
405         }
406         if (HandleProcess(c, argValue) != RESTOOL_SUCCESS) {
407             return RESTOOL_ERROR;
408         }
409     }
410     return RESTOOL_SUCCESS;
411 }
412 }
413 }
414 }
415