新增选择编译能力

Signed-off-by: zt147369 <zhangting201@huawei.com>
This commit is contained in:
zt147369
2023-12-12 17:11:14 +08:00
parent 0f137fe407
commit b399dc9e64
12 changed files with 364 additions and 2 deletions
+1
View File
@@ -41,6 +41,7 @@ ohos_executable("restool") {
"src/resource_table.cpp",
"src/resource_util.cpp",
"src/restool.cpp",
"src/select_compile_parse.cpp",
"src/task_handle.cpp",
]
+6
View File
@@ -53,6 +53,8 @@ public:
const std::string &GetIdDefinedOutput() const;
const std::string &GetIdDefinedInputPath() const;
bool GetIconCheck() const;
const TargetConfig &GetTargetConfigValues() const;
bool IsTargetConfig() const;
private:
void InitCommand();
@@ -79,6 +81,7 @@ private:
bool IsAscii(const std::string& argValue) const;
bool IsLongOpt(char *argv[]) const;
uint32_t IconCheck();
uint32_t ParseTargetConfig(const std::string& argValue);
static const struct option CMD_OPTS[];
static const std::string CMD_PARAMS;
@@ -100,6 +103,8 @@ private:
std::string idDefinedOutput_;
std::string idDefinedInputPath_;
bool isIconCheck_ = false;
TargetConfig targetConfig_;
bool isTtargetConfig_;
};
template<class T>
@@ -140,6 +145,7 @@ void CmdParser<T>::ShowUseage()
std::cout << " --dependEntry Build result directory of the specified entry module when the feature";
std::cout << " module resources are independently built in the FA model.\n";
std::cout << " --icon-check Enable the PNG image verification function for icons and startwindows.\n";
std::cout << " --target-config When used with '-i', selective compilation is supported.\n";
}
template<class T>
+2
View File
@@ -25,6 +25,8 @@ namespace Restool {
class KeyParser {
public:
static bool Parse(const std::string &folderName, std::vector<KeyParam> &keyparams);
static bool ParseLimit(const std::string &func, std::vector<std::string> &limitValues,
TargetConfig &targetConfig);
private:
typedef bool (*parse_key_founction)(const std::string &folderName, std::vector<KeyParam> &keyparams);
+54 -1
View File
@@ -39,7 +39,7 @@ const static std::string LONG_PATH_HEAD = "\\\\?\\";
const static std::string ID_DEFINED_INDENTATION = " ";
const static int32_t VERSION_MAX_LEN = 128;
const static int32_t INT_TO_BYTES = sizeof(uint32_t);
static const int8_t RESTOOL_VERSION[VERSION_MAX_LEN] = { "Restool 4.103" };
static const int8_t RESTOOL_VERSION[VERSION_MAX_LEN] = { "Restool 4.104" };
const static int32_t TAG_LEN = 4;
enum class KeyType {
@@ -55,6 +55,7 @@ enum class KeyType {
// RESERVER 9
INPUTDEVICE = 10,
KEY_TYPE_MAX,
OTHER,
};
enum class ResType {
@@ -117,6 +118,7 @@ enum Option {
DEFINED_IDS = 2,
DEPENDENTRY = 3,
ICON_CHECK = 4,
TARGET_CONFIG = 5,
STARTID = 'e',
FORCEWRITE = 'f',
HELP = 'h',
@@ -169,6 +171,10 @@ const std::map<std::string, InputDevice> g_inputDeviceMap = {
struct KeyParam {
KeyType keyType;
uint32_t value;
bool operator == (const KeyParam &other)
{
return keyType == other.keyType && value == other.value;
}
};
struct IdData {
@@ -250,6 +256,53 @@ struct FileInfo : DirectoryInfo {
std::string filename;
ResType fileType;
};
struct TargetConfig {
std::vector<KeyParam> mccmnc;
std::vector<KeyParam> locale;
std::vector<KeyParam> orientation;
std::vector<KeyParam> device;
std::vector<KeyParam> colormode;
std::vector<KeyParam> density;
};
struct Mccmnc {
KeyParam mcc;
KeyParam mnc;
bool operator == (const Mccmnc &other)
{
if (mcc.value != other.mcc.value) {
return false;
}
if (mnc.keyType != KeyType::OTHER && other.mnc.keyType != KeyType::OTHER &&
mnc.value != other.mnc.value) {
return false;
}
return true;
}
};
struct Locale {
KeyParam language;
KeyParam script;
KeyParam region;
bool operator == (const Locale &other)
{
if (language.value != other.language.value) {
return false;
}
if (script.keyType != KeyType::OTHER && other.script.keyType != KeyType::OTHER &&
script.value != other.script.value) {
return false;
}
if (region.keyType != KeyType::OTHER && other.region.keyType != KeyType::OTHER &&
region.value != other.region.value) {
return false;
}
return true;
}
};
}
}
}
+6
View File
@@ -216,6 +216,12 @@ public:
*/
static bool isUnicodeInPlane15or16(int unicode);
/**
* @brief Remove spaces before and after strings
* @param str input string
*/
static void RemoveSpaces(std::string &str);
private:
enum class IgnoreType {
IGNORE_FILE,
+41
View File
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2023 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.
*/
#ifndef OHOS_RESTOOL_SELECT_COMPILE_PARSE_H
#define OHOS_RESTOOL_SELECT_COMPILE_PARSE_H
#include "resource_data.h"
namespace OHOS {
namespace Global {
namespace Restool {
class SelectCompileParse {
public:
static bool ParseTargetConfig(const std::string &limitParams, TargetConfig &targetConfig);
static bool IsSelectCompile(std::vector<KeyParam> &keyParams);
private:
static bool IsSelectableMccmnc(std::vector<KeyParam> &keyParams, size_t &index, std::vector<KeyParam> &limit);
static bool IsSelectableLocale(std::vector<KeyParam> &keyParams, size_t &index, std::vector<KeyParam> &limit);
static bool IsSelectableOther(std::vector<KeyParam> &keyParams, size_t &index, std::vector<KeyParam> &limit);
static void InitMccmnc(std::vector<KeyParam> &limit);
static void InitLocale(std::vector<KeyParam> &limit);
static std::vector<Mccmnc> mccmncArray_;
static std::vector<Locale> localeArray_;
};
}
}
}
#endif
+33
View File
@@ -17,6 +17,7 @@
#include <algorithm>
#include "cmd_list.h"
#include "resource_util.h"
#include "select_compile_parse.h"
namespace OHOS {
namespace Global {
@@ -40,6 +41,7 @@ const struct option PackageParser::CMD_OPTS[] = {
{ "ids", required_argument, nullptr, Option::IDS},
{ "defined-ids", required_argument, nullptr, Option::DEFINED_IDS},
{ "icon-check", no_argument, nullptr, Option::ICON_CHECK},
{ "target-config", required_argument, nullptr, Option::TARGET_CONFIG},
{ 0, 0, 0, 0},
};
@@ -242,9 +244,15 @@ uint32_t PackageParser::CheckParam() const
return RESTOOL_ERROR;
}
if (isTtargetConfig_ && !append_.empty()) {
cerr << "Error: -x and --target-config cannot be used together." << endl;
return RESTOOL_ERROR;
}
if (!append_.empty()) {
return RESTOOL_SUCCESS;
}
if (packageName_.empty()) {
cerr << "Error: package name empty." << endl;
return RESTOOL_ERROR;
@@ -350,6 +358,30 @@ bool PackageParser::GetIconCheck() const
return isIconCheck_;
}
uint32_t PackageParser::ParseTargetConfig(const string& argValue)
{
if (isTtargetConfig_) {
cerr << "Error: repeat input '--target-config'" << endl;
return RESTOOL_ERROR;
}
if (!SelectCompileParse::ParseTargetConfig(argValue, targetConfig_)) {
cerr << "Error: '" << argValue << "' is not valid parameter." << endl;
return RESTOOL_ERROR;
}
isTtargetConfig_ = true;
return RESTOOL_SUCCESS;
}
const TargetConfig &PackageParser::GetTargetConfigValues() const
{
return targetConfig_;
}
bool PackageParser::IsTargetConfig() const
{
return isTtargetConfig_;
}
bool PackageParser::IsAscii(const string& argValue) const
{
#ifdef __WIN32
@@ -386,6 +418,7 @@ void PackageParser::InitCommand()
handles_.emplace(Option::IDS, bind(&PackageParser::SetIdDefinedOutput, this, _1));
handles_.emplace(Option::DEFINED_IDS, bind(&PackageParser::SetIdDefinedInputPath, this, _1));
handles_.emplace(Option::ICON_CHECK, [this](const string &) -> uint32_t { return IconCheck(); });
handles_.emplace(Option::TARGET_CONFIG, bind(&PackageParser::ParseTargetConfig, this, _1));
}
uint32_t PackageParser::HandleProcess(int c, const string& argValue)
+31
View File
@@ -73,6 +73,37 @@ bool KeyParser::ParseMatch(const vector<string> &keys,
return true;
}
bool KeyParser::ParseLimit(const string &func, std::vector<std::string> &limitValues,
TargetConfig &targetConfig)
{
map<string, function<bool(const string &)>> parseLimitFunc {
{"mccmnc", [&targetConfig](const string &limitValue) { return ParseMccMnc(limitValue,
targetConfig.mccmnc); }},
{"locale", [&targetConfig](const string &limitValue) { return ParseLSR(limitValue,
targetConfig.locale); }},
{"orientation", [&targetConfig](const string &limitValue) { return ParseOrientation(limitValue,
targetConfig.orientation); }},
{"device", [&targetConfig](const string &limitValue) { return ParseDeviceType(limitValue,
targetConfig.device); }},
{"colormode", [&targetConfig](const string &limitValue) { return ParseNightMode(limitValue,
targetConfig.colormode); }},
{"density", [&targetConfig](const string &limitValue) { return ParseResolution(limitValue,
targetConfig.density); }}
};
auto iter = parseLimitFunc.find(func);
if (iter == parseLimitFunc.end()) {
return false;
}
for (auto &limitValue : limitValues) {
ResourceUtil::RemoveSpaces(limitValue);
if (!iter->second(limitValue)) {
return false;
}
}
return true;
}
bool KeyParser::ParseMatchBySeq(const vector<string> &keys,
vector<KeyParam> &keyparams, const vector<parse_key_founction> &founctions)
{
+4
View File
@@ -25,6 +25,7 @@
#include "reference_parser.h"
#include "resource_table.h"
#include "resource_util.h"
#include "select_compile_parse.h"
#ifdef __WIN32
#include "windows.h"
#endif
@@ -532,6 +533,9 @@ bool ResourceAppend::LoadResourceItemFromMem(const char buffer[], int32_t length
keyParam.value = ParseInt32(buffer, length, offset);
keyParams.push_back(keyParam);
}
if (limitKeyStr != "base" && !limitKeyStr.empty() && !SelectCompileParse::IsSelectCompile(keyParams)) {
return true;
}
// data
string data = ParseString(buffer, length, offset);
if (resType == ResType::RAW) {
+4 -1
View File
@@ -17,6 +17,7 @@
#include<iostream>
#include "file_entry.h"
#include "resource_util.h"
#include "select_compile_parse.h"
namespace OHOS {
namespace Global {
@@ -60,7 +61,9 @@ bool ResourceDirectory::ScanResourceLimitKeyDir(const string &resourceTypeDir, c
cerr << "Error: invalid limit key '" << limitKey << "'." << NEW_LINE_PATH << resourceTypeDir << endl;
return false;
}
if (!SelectCompileParse::IsSelectCompile(keyParams)) {
return true;
}
FileEntry f(resourceTypeDir);
if (!f.Init()) {
return false;
+6
View File
@@ -428,6 +428,12 @@ bool ResourceUtil::isUnicodeInPlane15or16(int unicode)
return (unicode >= 0xF0000 && unicode <= 0xFFFFF) || (unicode >= 0x100000 && unicode <= 0x10FFFF);
}
void ResourceUtil::RemoveSpaces(string &str)
{
str.erase(0, str.find_first_not_of(" "));
str.erase(str.find_last_not_of(" ") + 1); // move back one place
}
}
}
}
+176
View File
@@ -0,0 +1,176 @@
/*
* Copyright (c) 2023 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 "select_compile_parse.h"
#include <algorithm>
#include "key_parser.h"
#include "cmd_parser.h"
#include "resource_util.h"
namespace OHOS {
namespace Global {
namespace Restool {
using namespace std;
vector<Mccmnc> SelectCompileParse::mccmncArray_ = {};
vector<Locale> SelectCompileParse::localeArray_ = {};
// eg: Device[ phone, car ];ColorMode[ dark ]
bool SelectCompileParse::ParseTargetConfig(const string &limitParams, TargetConfig &targetConfig)
{
vector<string> limitArray;
ResourceUtil::Split(limitParams, limitArray, ";");
if (limitArray.empty()) {
return false;
}
for (auto &it : limitArray) {
vector<string> limit;
ResourceUtil::Split(it, limit, "[");
if (limit.size() != 2) { // 2 means the size of the valid parameter after split by '['
return false;
}
ResourceUtil::RemoveSpaces(limit.back());
if (limit.size() < 2 || limit.back().back() != ']') { // 2 means characters other than ']'
return false;
}
limit.back().pop_back();
vector<string> limitValues;
ResourceUtil::Split(limit.back(), limitValues, ",");
if (limitValues.empty()) {
return false;
}
auto &limitType = limit.front();
ResourceUtil::RemoveSpaces(limitType);
transform(limitType.begin(), limitType.end(), limitType.begin(), ::tolower);
if (!KeyParser::ParseLimit(limitType, limitValues, targetConfig)) {
return false;
}
}
return true;
}
bool SelectCompileParse::IsSelectCompile(vector<KeyParam> &keyParams)
{
if (keyParams.empty()) {
return true;
}
auto &cmdParser = CmdParser<PackageParser>::GetInstance().GetCmdParser();
bool isTtargetConfig = cmdParser.IsTargetConfig();
if (!isTtargetConfig) {
return true;
}
TargetConfig targetConfig = cmdParser.GetTargetConfigValues();
map<KeyType, function<bool(size_t &)>> selectableFuncMatch {
{KeyType::MCC, bind(&IsSelectableMccmnc, keyParams, placeholders::_1, targetConfig.mccmnc)},
{KeyType::LANGUAGE, bind(&IsSelectableLocale, keyParams, placeholders::_1, targetConfig.locale)},
{KeyType::ORIENTATION, bind(&IsSelectableOther, keyParams, placeholders::_1, targetConfig.orientation)},
{KeyType::DEVICETYPE, bind(&IsSelectableOther, keyParams, placeholders::_1, targetConfig.device)},
{KeyType::NIGHTMODE, bind(&IsSelectableOther, keyParams, placeholders::_1, targetConfig.colormode)},
{KeyType::RESOLUTION, bind(&IsSelectableOther, keyParams, placeholders::_1, targetConfig.density)},
};
for (size_t index = 0; index < keyParams.size(); index++) {
auto iter = selectableFuncMatch.find(keyParams[index].keyType);
if (iter == selectableFuncMatch.end()) {
continue;
}
if (!iter->second(index)) {
return false;
}
}
return true;
}
// {KeyType::OTHER, 0} indicates that the default value is equal to null
void SelectCompileParse::InitMccmnc(vector<KeyParam> &limit)
{
if (!mccmncArray_.empty()) {
return;
}
for (size_t i = 0; i < limit.size(); i++) {
if (limit[i].keyType == KeyType::MCC) {
mccmncArray_.push_back({limit[i], {KeyType::OTHER, 0}});
}
if (limit[i].keyType == KeyType::MNC) {
mccmncArray_.back().mnc = limit[i];
}
}
}
bool SelectCompileParse::IsSelectableMccmnc(vector<KeyParam> &keyParams, size_t &index, vector<KeyParam> &limit)
{
if (limit.empty()) {
return true;
}
Mccmnc mccmncLimit({keyParams[index++], {KeyType::OTHER, 0}});
if (index < keyParams.size() && keyParams[index].keyType == KeyType::MNC) {
mccmncLimit.mnc = keyParams[index];
} else {
index--;
}
InitMccmnc(limit);
return find(mccmncArray_.begin(), mccmncArray_.end(), mccmncLimit) != mccmncArray_.end();
}
void SelectCompileParse::InitLocale(vector<KeyParam> &limit)
{
if (!localeArray_.empty()) {
return;
}
for (size_t i = 0; i < limit.size(); i++) {
if (limit[i].keyType == KeyType::LANGUAGE) {
localeArray_.push_back({limit[i], {KeyType::OTHER, 0},
{KeyType::OTHER, 0}});
}
if (limit[i].keyType == KeyType::SCRIPT) {
localeArray_.back().script = limit[i];
}
if (limit[i].keyType == KeyType::REGION) {
localeArray_.back().region = limit[i];
}
}
}
bool SelectCompileParse::IsSelectableLocale(vector<KeyParam> &keyParams, size_t &index, vector<KeyParam> &limit)
{
if (limit.empty()) {
return true;
}
Locale localeLimit({keyParams[index++], {KeyType::OTHER, 0}, {KeyType::OTHER, 0}});
for (; index < keyParams.size(); index++) {
if (keyParams[index].keyType == KeyType::SCRIPT) {
localeLimit.script = keyParams[index];
continue;
}
if (keyParams[index].keyType == KeyType::REGION) {
localeLimit.region = keyParams[index];
break;
}
index--;
break;
}
InitLocale(limit);
return find(localeArray_.begin(), localeArray_.end(), localeLimit) != localeArray_.end();;
}
bool SelectCompileParse::IsSelectableOther(vector<KeyParam> &keyParams, size_t &index, vector<KeyParam> &limit)
{
if (limit.empty()) {
return true;
}
return find(limit.begin(), limit.end(), keyParams[index]) != limit.end();
}
}
}
}