/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "cmd_parser.h" #include<algorithm> #include "resource_util.h" #include "cmd_list.h" namespace OHOS { namespace Global { namespace Restool { using namespace std; const struct option PackageParser::CMD_OPTS[] = { { "inputPath", required_argument, nullptr, 'i' }, { "packageName", required_argument, nullptr, 'p' }, { "outputPath", required_argument, nullptr, 'o' }, { "resHeader", required_argument, nullptr, 'r' }, { "forceWrite", no_argument, nullptr, 'f' }, { "version", no_argument, nullptr, 'v'}, { "modules", optional_argument, nullptr, 'm' }, { "json", optional_argument, nullptr, 'j' }, { "startId", optional_argument, nullptr, 'e' }, { "cache", optional_argument, nullptr, 'c' }, { "fileList", required_argument, nullptr, 'l' }, { "preview", no_argument, nullptr, 'a' }, { "priority", required_argument, nullptr, 'g' }, { "dependEntry", required_argument, nullptr, 'd' }, }; const string PackageParser::CMD_PARAMS = "i:p:o:r:m:j:e:c:l:g:d:afv"; uint32_t PackageParser::Parse(int argc, char *argv[]) { InitCommand(); if (ParseCommand(argc, argv) != RESTOOL_SUCCESS) { return RESTOOL_ERROR; } return CheckParam(); } const vector<string> &PackageParser::GetInputs() const { return inputs_; } const string &PackageParser::GetPackageName() const { return packageName_; } const string &PackageParser::GetOutput() const { return output_; } const vector<string> &PackageParser::GetResourceHeaders() const { return resourceHeaderPaths_; } bool PackageParser::GetForceWrite() const { return forceWrite_; } const vector<string> &PackageParser::GetModuleNames() const { return moduleNames_; } const string &PackageParser::GetConfig() const { return configPath_; } const string &PackageParser::GetRestoolPath() const { return restoolPath_; } int32_t PackageParser::GetStartId() const { return startId_; } const string &PackageParser::GetCachePath() const { return cachePath_; } const string &PackageParser::GetDependEntry() const { return dependEntry_; } uint32_t PackageParser::AddInput(const string& argValue) { auto ret = find_if(inputs_.begin(), inputs_.end(), [argValue](auto iter) {return argValue == iter;}); if (ret != inputs_.end()) { cerr << "Error: repeat input '" << argValue << "'" << endl; return RESTOOL_ERROR; } inputs_.push_back(argValue); return RESTOOL_SUCCESS; } uint32_t PackageParser::AddPackageName(const string& argValue) { if (!packageName_.empty()) { cerr << "Error: double package name " << packageName_ << " vs " << argValue << endl; return RESTOOL_ERROR; } packageName_ = argValue; return RESTOOL_SUCCESS; } uint32_t PackageParser::AddOutput(const string& argValue) { if (!output_.empty()) { cerr << "Error: double output " << output_ << " vs " << argValue << endl; return RESTOOL_ERROR; } output_ = argValue; return RESTOOL_SUCCESS; } uint32_t PackageParser::AddResourceHeader(const string& argValue) { if (find(resourceHeaderPaths_.begin(), resourceHeaderPaths_.end(), argValue) != resourceHeaderPaths_.end()) { cerr << "Error: '" << argValue << "' input duplicated." << endl; return RESTOOL_ERROR; } resourceHeaderPaths_.push_back(argValue); return RESTOOL_SUCCESS; } uint32_t PackageParser::ForceWrite() { forceWrite_ = true; return RESTOOL_SUCCESS; } uint32_t PackageParser::PrintVersion() { cout << "Info: Restool version= " << RESTOOL_VERSION << endl; exit(RESTOOL_SUCCESS); return RESTOOL_SUCCESS; } uint32_t PackageParser::AddMoudleNames(const string& argValue) { if (!moduleNames_.empty()) { cerr << "Error: -m double module name '" << argValue << "'" << endl; return RESTOOL_ERROR; } ResourceUtil::Split(argValue, moduleNames_, ","); for (auto it = moduleNames_.begin(); it != moduleNames_.end(); it++) { auto ret = find_if(moduleNames_.begin(), moduleNames_.end(), [it](auto iter) {return *it == iter;}); if (ret != it) { cerr << "Error: double module name '" << *it << "'" << endl; return RESTOOL_ERROR; } } return RESTOOL_SUCCESS; } uint32_t PackageParser::AddConfig(const string& argValue) { if (!configPath_.empty()) { cerr << "Error: double config.json " << configPath_ << " vs " << argValue << endl; return RESTOOL_ERROR; } configPath_ = argValue; return RESTOOL_SUCCESS; } uint32_t PackageParser::AddStartId(const string& argValue) { startId_ = strtol(argValue.c_str(), nullptr, 16); if ((startId_ >= 0x01000000 && startId_ < 0x06ffffff) || (startId_ >= 0x08000000 && startId_ < 0x41ffffff)) { return RESTOOL_SUCCESS; } cerr << "Error: invalid start id " << argValue << endl; return RESTOOL_ERROR; } uint32_t PackageParser::AddCachePath(const string& argValue) { cachePath_ = argValue; return RESTOOL_SUCCESS; } uint32_t PackageParser::CheckParam() const { if (inputs_.empty()) { cerr << "Error: input path empty." << endl; return RESTOOL_ERROR; } if (output_.empty()) { cerr << "Error: output path empty." << endl; return RESTOOL_ERROR; } if (previewMode_) { return RESTOOL_SUCCESS; } if (packageName_.empty()) { cerr << "Error: package name empty." << endl; return RESTOOL_ERROR; } if (resourceHeaderPaths_.empty()) { cerr << "Error: resource header path empty." << endl; return RESTOOL_ERROR; } return RESTOOL_SUCCESS; } bool PackageParser::IsFileList() const { return isFileList_; } uint32_t PackageParser::SetPreviewMode() { previewMode_ = true; return RESTOOL_SUCCESS; } bool PackageParser::GetPreviewMode() const { return previewMode_; } int32_t PackageParser::GetPriority() const { return priority_; } uint32_t PackageParser::SetPriority(const string& argValue) { priority_ = atoi(argValue.c_str()); return RESTOOL_SUCCESS; } uint32_t PackageParser::AddDependEntry(const string& argValue) { dependEntry_ = argValue; return RESTOOL_SUCCESS; } void PackageParser::InitCommand() { using namespace placeholders; handles_.emplace('i', bind(&PackageParser::AddInput, this, _1)); handles_.emplace('p', bind(&PackageParser::AddPackageName, this, _1)); handles_.emplace('o', bind(&PackageParser::AddOutput, this, _1)); handles_.emplace('r', bind(&PackageParser::AddResourceHeader, this, _1)); handles_.emplace('f', [this](const string &) -> uint32_t { return ForceWrite(); }); handles_.emplace('v', [this](const string &) -> uint32_t { return PrintVersion(); }); handles_.emplace('m', bind(&PackageParser::AddMoudleNames, this, _1)); handles_.emplace('j', bind(&PackageParser::AddConfig, this, _1)); handles_.emplace('e', bind(&PackageParser::AddStartId, this, _1)); handles_.emplace('c', bind(&PackageParser::AddCachePath, this, _1)); handles_.emplace('a', [this](const string &) -> uint32_t { return SetPreviewMode(); }); handles_.emplace('g', bind(&PackageParser::SetPriority, this, _1)); handles_.emplace('d', bind(&PackageParser::AddDependEntry, this, _1)); } uint32_t PackageParser::HandleProcess(int c, const string& argValue) { auto handler = handles_.find(c); if (handler == handles_.end()) { cout << "Warning: unsupport " << c << endl; return RESTOOL_SUCCESS; } return handler->second(argValue); } uint32_t PackageParser::ParseFileList(const string& fileListPath) { isFileList_ = true; CmdList cmdList; if (cmdList.Init(fileListPath, [this](int c, const string &argValue) -> int32_t { return HandleProcess(c, argValue); }) != RESTOOL_SUCCESS) { return RESTOOL_ERROR; } return RESTOOL_SUCCESS; } uint32_t PackageParser::ParseCommand(int argc, char *argv[]) { restoolPath_ = string(argv[0]); while (true) { int optIndex = 0; int c = getopt_long(argc, argv, CMD_PARAMS.c_str(), CMD_OPTS, &optIndex); if (c == -1) { break; } string argValue = (optarg != nullptr) ? optarg : ""; if (c == 'l') { return ParseFileList(argValue); } if (HandleProcess(c, argValue) != RESTOOL_SUCCESS) { return RESTOOL_ERROR; } } return RESTOOL_SUCCESS; } } } }