diff --git a/BUILD.gn b/BUILD.gn index cb3219b..e9c1129 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -51,6 +51,7 @@ ohos_executable("restool") { "src/resource_table.cpp", "src/resource_util.cpp", "src/restool.cpp", + "src/restool_errors.cpp", "src/select_compile_parse.cpp", "src/thread_pool.cpp", "src/translatable_parser.cpp", diff --git a/include/reference_parser.h b/include/reference_parser.h index c6b1582..a8e97f4 100644 --- a/include/reference_parser.h +++ b/include/reference_parser.h @@ -31,7 +31,7 @@ public: uint32_t ParseRefInResources(std::map> &items, const std::string &output); uint32_t ParseRefInResourceItem(ResourceItem &resourceItem) const; uint32_t ParseRefInJsonFile(ResourceItem &resourceItem, const std::string &output, const bool isIncrement = false); - uint32_t ParseRefInString(std::string &value, bool &update) const; + uint32_t ParseRefInString(std::string &value, bool &update, const std::string &filePath = "") const; static std::map> &GetLayerIconIds(); private: bool ParseRefJson(const std::string &from, const std::string &to); @@ -42,9 +42,10 @@ private: bool IsMediaRef(const ResourceItem &resourceItem) const; bool IsProfileRef(const ResourceItem &resourceItem) const; bool ParseRefString(std::string &key) const; - bool ParseRefString(std::string &key, bool &update) const; - bool ParseRefImpl(std::string &key, const std::map &refs, bool isSystem) const; - bool ParseRefJsonImpl(cJSON *root, bool &needSave) const; + bool ParseRefString(std::string &key, bool &update, const std::string &filePath = "") const; + bool ParseRefImpl(std::string &key, const std::map &refs, bool isSystem, + const std::string &filePath = "") const; + bool ParseRefJsonImpl(cJSON *root, bool &needSave, const std::string &filePath) const; const IdWorker &idWorker_; static const std::map ID_REFS; static const std::map ID_OHOS_REFS; diff --git a/include/resource_data.h b/include/resource_data.h index 490cc12..68bd0b1 100644 --- a/include/resource_data.h +++ b/include/resource_data.h @@ -49,7 +49,7 @@ const static std::string SOLUTIONS_ARROW = "> "; const static std::string LONG_PATH_HEAD = "\\\\?\\"; 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 5.1.0.006" }; +static const int8_t RESTOOL_VERSION[VERSION_MAX_LEN] = { "Restool 5.1.0.007" }; const static int32_t TAG_LEN = 4; constexpr static int DEFAULT_POOL_SIZE = 8; static std::set g_resourceSet; diff --git a/include/resource_util.h b/include/resource_util.h index 0431c41..8f487ec 100644 --- a/include/resource_util.h +++ b/include/resource_util.h @@ -86,6 +86,12 @@ public: */ static ResType GetResTypeByDir(const std::string &name); + /** + * @brief get all resource type directorys. + * @return all resource type. + */ + static std::string GetAllResTypeDirs(); + /** * @brief ResType to string * @param type: ResType diff --git a/include/restool_errors.h b/include/restool_errors.h index 76535aa..052fb79 100644 --- a/include/restool_errors.h +++ b/include/restool_errors.h @@ -16,7 +16,11 @@ #ifndef OHOS_RESTOOL_ERRORS_H #define OHOS_RESTOOL_ERRORS_H +#include +#include +#include #include + #include "resource_data.h" namespace OHOS { @@ -24,6 +28,180 @@ namespace Global { namespace Restool { constexpr uint32_t RESTOOL_SUCCESS = 0; constexpr uint32_t RESTOOL_ERROR = -1; +constexpr uint16_t BUFFER_SIZE = 4096; +// 11200xxx unknown error + +// 11201xxx dependency error +const std::string ERR_TYPE_DEPENDENCY = "Dependency Error"; +constexpr uint32_t ERR_CODE_LOAD_LIBRARY_FAIL = 11201001; +// 11202xxx script error + +// 11203xxx config error +const std::string ERR_TYPE_CONFIG = "Config Error"; +constexpr uint32_t ERR_CODE_OPEN_JSON_FAIL = 11203001; +constexpr uint32_t ERR_CODE_JSON_FORMAT_ERROR = 11203002; +constexpr uint32_t ERR_CODE_JSON_NODE_MISMATCH = 11203003; +constexpr uint32_t ERR_CODE_JSON_NODE_MISSING = 11203004; +constexpr uint32_t ERR_CODE_JSON_NODE_EMPTY = 11203005; +constexpr uint32_t ERR_CODE_JSON_NOT_ONE_MEMBER = 11203006; +constexpr uint32_t ERR_CODE_JSON_INVALID_NODE_NAME = 11203007; + +// 11204xxx file resource error +const std::string ERR_TYPE_FILE_RESOURCE = "File Resource Error"; +constexpr uint32_t ERR_CODE_CREATE_FILE_ERROR = 11204001; +constexpr uint32_t ERR_CODE_FILE_NOT_EXIST = 11204002; +constexpr uint32_t ERR_CODE_REMOVE_FILE_ERROR = 11204003; +constexpr uint32_t ERR_CODE_COPY_FILE_ERROR = 11204004; +constexpr uint32_t ERR_CODE_OPEN_FILE_ERROR = 11204005; +constexpr uint32_t ERR_CODE_FILE_EMPTY = 11204006; +constexpr uint32_t ERR_CODE_FILE_STREAM_ERROR = 11204007; +constexpr uint32_t ERR_CODE_FILE_MAP_ERROR = 11204008; + +// 11205xxx syntax error +const std::string ERR_TYPE_SYNTAX = "Syntax Error"; +constexpr uint32_t ERR_CODE_SET_DATA_ERROR = 11205001; +constexpr uint32_t ERR_CODE_ITEM_DATA_NULL = 11205002; +constexpr uint32_t ERR_CODE_MEMCPY_ERROR = 11205003; +constexpr uint32_t ERR_CODE_CREATE_JSON_ERROR = 11205004; + +// 11210xxx parse command error +const std::string ERR_TYPE_COMMAND_PARSE = "Command Parse Error"; +constexpr uint32_t ERR_CODE_UNKNOWN_COMMAND_ERROR = 11210000; +constexpr uint32_t ERR_CODE_UNKNOWN_OPTION = 11210001; +constexpr uint32_t ERR_CODE_MISSING_ARGUMENT = 11210002; +constexpr uint32_t ERR_CODE_INVALID_ARGUMENT = 11210003; +constexpr uint32_t ERR_CODE_INVALID_INPUT = 11210004; +constexpr uint32_t ERR_CODE_DUPLICATE_INPUT = 11210005; +constexpr uint32_t ERR_CODE_DOUBLE_PACKAGE_NAME = 11210006; +constexpr uint32_t ERR_CODE_INVALID_OUTPUT = 11210007; +constexpr uint32_t ERR_CODE_DOUBLE_OUTPUT = 11210008; +constexpr uint32_t ERR_CODE_DUPLICATE_RES_HEADER = 11210009; +constexpr uint32_t ERR_CODE_DOUBLE_MODULES = 11210010; +constexpr uint32_t ERR_CODE_DUPLICATE_MODULE_NAME = 11210011; +constexpr uint32_t ERR_CODE_DOUBLE_CONFIG_JSON = 11210012; +constexpr uint32_t ERR_CODE_INVALID_START_ID = 11210013; +constexpr uint32_t ERR_CODE_DUPLICATE_APPEND_PATH = 11210014; +constexpr uint32_t ERR_CODE_DOUBLE_TARGET_CONFIG = 11210015; +constexpr uint32_t ERR_CODE_INVALID_TARGET_CONFIG = 11210016; +constexpr uint32_t ERR_CODE_INVALID_SYSTEM_ID_DEFINED = 11210017; +constexpr uint32_t ERR_CODE_DUPLICATE_SYSTEM_ID_DEFINED = 11210018; +constexpr uint32_t ERR_CODE_DOUBLE_COMPRESSION_PATH = 11210019; +constexpr uint32_t ERR_CODE_NON_ASCII = 11210020; +constexpr uint32_t ERR_CODE_EXCLUSIVE_OPTION = 11210021; +constexpr uint32_t ERR_CODE_PACKAGE_NAME_EMPTY = 11210022; +constexpr uint32_t ERR_CODE_RES_HEADER_PATH_EMPTY = 11210023; +constexpr uint32_t ERR_CODE_DUMP_MISSING_INPUT = 11210024; +constexpr uint32_t ERR_CODE_DUMP_INVALID_INPUT = 11210025; +constexpr uint32_t ERR_CODE_INVALID_THREAD_COUNT = 11210026; + +// 11211xxx resource pack error +const std::string ERR_TYPE_RESOURCE_PACK = "Resource Pack Error"; +constexpr uint32_t ERR_CODE_OUTPUT_EXIST = 11211001; +constexpr uint32_t ERR_CODE_CONFIG_JSON_MISSING = 11211002; +constexpr uint32_t ERR_CODE_INVALID_MODULE_TYPE = 11211003; +constexpr uint32_t ERR_CODE_EXCLUSIVE_START_ID = 11211004; +constexpr uint32_t ERR_CODE_ID_DEFINED_NODE_MISSING = 11211005; +constexpr uint32_t ERR_CODE_ID_DEFINED_NODE_MISMATCH = 11211006; +constexpr uint32_t ERR_CODE_ID_DEFINED_INVALID_TYPE = 11211007; +constexpr uint32_t ERR_CODE_ID_DEFINED_INVALID_ID = 11211008; +constexpr uint32_t ERR_CODE_ID_DEFINED_ID_OUT_RANGE = 11211009; +constexpr uint32_t ERR_CODE_ID_DEFINED_ORDER_MISMATCH = 11211010; +constexpr uint32_t ERR_CODE_ID_DEFINED_INVALID_START_ID = 11211011; +constexpr uint32_t ERR_CODE_ID_DEFINED_SAME_ID = 11211012; +constexpr uint32_t ERR_CODE_ID_DEFINED_SAME_RESOURCE = 11211013; +constexpr uint32_t ERR_CODE_MODULE_NAME_NOT_FOUND = 11211014; + +constexpr uint32_t ERR_CODE_RESOURCE_PATH_NOT_DIR = 11211101; +constexpr uint32_t ERR_CODE_INVALID_FILE_PATH = 11211102; +constexpr uint32_t ERR_CODE_INVALID_LIMIT_KEY = 11211103; +constexpr uint32_t ERR_CODE_INVALID_RESOURCE_DIR = 11211104; +constexpr uint32_t ERR_CODE_RESOURCE_PATH_NOT_FILE = 11211105; +constexpr uint32_t ERR_CODE_INVALID_TRANSLATE_PRIORITY = 11211106; +constexpr uint32_t ERR_CODE_INVALID_ELEMENT_TYPE = 11211107; +constexpr uint32_t ERR_CODE_INVALID_COLOR_VALUE = 11211108; +constexpr uint32_t ERR_CODE_INVALID_RESOURCE_REF = 11211109; +constexpr uint32_t ERR_CODE_PARENT_EMPTY = 11211110; +constexpr uint32_t ERR_CODE_ARRAY_TOO_LARGE = 11211111; +constexpr uint32_t ERR_CODE_INVALID_QUANTITY = 11211112; +constexpr uint32_t ERR_CODE_DUPLICATE_QUANTITY = 11211113; +constexpr uint32_t ERR_CODE_QUANTITY_NO_OTHER = 11211114; +constexpr uint32_t ERR_CODE_INVALID_SYMBOL = 11211115; +constexpr uint32_t ERR_CODE_INVALID_RESOURCE_NAME = 11211116; +constexpr uint32_t ERR_CODE_RESOURCE_DUPLICATE = 11211117; +constexpr uint32_t ERR_CODE_RESOURCE_ID_EXCEED = 11211118; +constexpr uint32_t ERR_CODE_RESOURCE_ID_NOT_DEFINED = 11211119; +constexpr uint32_t ERR_CODE_REF_NOT_DEFINED = 11211120; +constexpr uint32_t ERR_CODE_ARRAY_DECOMPOSE_ERROR = 11211121; +constexpr uint32_t ERR_CODE_ARRAY_COMPOSE_ERROR = 11211122; +constexpr uint32_t ERR_CODE_FA_ENTRY_NO_ICON_LABEL = 11211123; +constexpr uint32_t ERR_CODE_INVALID_RESOURCE_INDEX = 11211124; +constexpr uint32_t ERR_CODE_RESOURCE_INDEX_ID_NOT_FOUND = 11211125; +constexpr uint32_t ERR_CODE_RESOURCE_INDEX_ITEM_EMPTY = 11211126; +constexpr uint32_t ERR_CODE_RESOURCE_INDEX_INVALID_RESTYPE = 11211127; +constexpr uint32_t ERR_CODE_SAVE_INDEX_ERROR = 11211128; +constexpr uint32_t ERR_CODE_CREATE_ID_DEFINED_ERROR = 11211129; + +// 11212xxx resource dump error +const std::string ERR_TYPE_RESOURCE_DUMP = "Resource Dump Error"; +constexpr uint32_t ERR_CODE_PARSE_HAP_ERROR = 11212001; + +struct MoreInfo { + std::string cn; + std::string en; +}; + +class ErrorInfo { +public: + uint32_t code_; + std::string description_; + std::string cause_; + std::string position_; + std::vector solutions_; + MoreInfo moreInfo_; + + template + ErrorInfo &FormatDescription(Args... args) + { + description_ = FormatString(description_, std::forward(args)...); + return *this; + } + + template + ErrorInfo &FormatCause(Args... args) + { + cause_ = FormatString(cause_, std::forward(args)...); + return *this; + } + + ErrorInfo &SetPosition(const std::string &position) + { + position_ = position; + return *this; + } + +private: + template + std::string FormatString(const std::string &fmt, Args... args) + { + if (fmt.empty()) { + return fmt; + } + int paramCount = sizeof...(args); + if (paramCount == 0) { + return fmt; + } + std::unique_ptr buf = std::make_unique(BUFFER_SIZE); + auto realSize = snprintf_s(buf.get(), BUFFER_SIZE, BUFFER_SIZE - 1, fmt.c_str(), args...); + if (realSize == -1) { + return fmt; + } + return std::string(buf.get(), buf.get() + realSize); + } +}; + +ErrorInfo GetError(const uint32_t &errCode); +void PrintError(const uint32_t &errCode); +void PrintError(const ErrorInfo &error); } } } diff --git a/include/translatable_parser.h b/include/translatable_parser.h index 4b96be4..c7886f6 100755 --- a/include/translatable_parser.h +++ b/include/translatable_parser.h @@ -27,10 +27,10 @@ public: static bool ParseTranslatable(cJSON *objectNode, const FileInfo &fileInfo, const std::string &name); private: static bool ParseTranslatable(cJSON *objectNode, const std::string &filePath); - static bool CheckBaseStringAttr(const cJSON *objectNode); - static bool CheckBaseStringTranslatable(const cJSON *attrNode); - static bool CheckBaseStringPriority(const cJSON *attrNode); - static bool ReplaceTranslateTags(cJSON *node, const char *key); + static bool CheckBaseStringAttr(const cJSON *objectNode, const std::string &filePath); + static bool CheckBaseStringTranslatable(const cJSON *attrNode, const std::string &filePath); + static bool CheckBaseStringPriority(const cJSON *attrNode, const std::string &filePath); + static bool ReplaceTranslateTags(cJSON *node, const char *key, const std::string &filePath); static bool GetReplaceStringTranslate(std::string &str); static bool FindTranslatePairs(const std::string &str, std::vector &posData); }; diff --git a/src/append_compiler.cpp b/src/append_compiler.cpp index f23a772..800b423 100644 --- a/src/append_compiler.cpp +++ b/src/append_compiler.cpp @@ -33,7 +33,8 @@ uint32_t AppendCompiler::CompileSingleFile(const FileInfo &fileInfo) string data = fileInfo.filePath; if (!resourceItem.SetData(reinterpret_cast(data.c_str()), data.length())) { - cerr << "Error: resource item set data fail, data: " << data << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_SET_DATA_ERROR).FormatCause(resourceItem.GetName().c_str()) + .SetPosition(fileInfo.filePath)); return RESTOOL_ERROR; } diff --git a/src/binary_file_packer.cpp b/src/binary_file_packer.cpp index 8b0522c..e123dd8 100644 --- a/src/binary_file_packer.cpp +++ b/src/binary_file_packer.cpp @@ -59,12 +59,10 @@ uint32_t BinaryFilePacker::CopyBinaryFile(const string &input) { string rawfilePath = FileEntry::FilePath(input).Append(RAW_FILE_DIR).GetPath(); if (CopyBinaryFile(rawfilePath, RAW_FILE_DIR) == RESTOOL_ERROR) { - cerr << "Error: copy raw file failed." << NEW_LINE_PATH << rawfilePath << endl; return RESTOOL_ERROR; } string resfilePath = FileEntry::FilePath(input).Append(RES_FILE_DIR).GetPath(); if (CopyBinaryFile(resfilePath, RES_FILE_DIR) == RESTOOL_ERROR) { - cerr << "Error: copy res file failed." << NEW_LINE_PATH << resfilePath << endl; return RESTOOL_ERROR; } return RESTOOL_SUCCESS; @@ -77,7 +75,7 @@ uint32_t BinaryFilePacker::CopyBinaryFile(const string &filePath, const string & } if (!FileEntry::IsDirectory(filePath)) { - cerr << "Error: '" << filePath << "' not directory." << endl; + PrintError(GetError(ERR_CODE_RESOURCE_PATH_NOT_DIR).FormatCause(filePath.c_str())); return RESTOOL_ERROR; } @@ -91,7 +89,6 @@ uint32_t BinaryFilePacker::CopyBinaryFile(const string &filePath, const string & uint32_t BinaryFilePacker::CopyBinaryFileImpl(const string &src, const string &dst) { if (!ResourceUtil::CreateDirs(dst)) { - cerr << "Error: copy rawfile of resfile, create dirs failed." << NEW_LINE_PATH << dst << endl; return RESTOOL_ERROR; } @@ -136,7 +133,7 @@ bool BinaryFilePacker::IsDuplicated(const unique_ptr &entry, string s if (g_hapResourceSet.count(subPath)) { g_hapResourceSet.erase(subPath); } else if (!g_resourceSet.emplace(subPath).second) { - cerr << "Warning: '" << entry->GetFilePath().GetPath() << "' is defined repeatedly." << endl; + cout << "Warning: '" << entry->GetFilePath().GetPath() << "' is defined repeatedly." << endl; return true; } return false; @@ -146,13 +143,11 @@ uint32_t BinaryFilePacker::CopySingleFile(const std::string &path, std::string & { if (moduleName_ == "har" || CompressionParser::GetCompressionParser()->GetDefaultCompress()) { if (!ResourceUtil::CopyFileInner(path, subPath)) { - cerr << "Error: copy rawfile or resfile failed." << NEW_LINE_PATH << path << endl; return RESTOOL_ERROR; } return RESTOOL_SUCCESS; } if (!CompressionParser::GetCompressionParser()->CopyAndTranscode(path, subPath, true)) { - cerr << "Error: copy rawfile or resfile, CopyAndTranscode failed." << NEW_LINE_PATH << endl; return RESTOOL_ERROR; } return RESTOOL_SUCCESS; @@ -167,7 +162,6 @@ uint32_t BinaryFilePacker::CheckCopyResults() } uint32_t ret = res.get(); if (ret != RESTOOL_SUCCESS) { - cerr << "Error: copy binary file failed." << endl; return RESTOOL_ERROR; } } diff --git a/src/cmd/dump_parser.cpp b/src/cmd/dump_parser.cpp index a2c0a5b..0b46804 100644 --- a/src/cmd/dump_parser.cpp +++ b/src/cmd/dump_parser.cpp @@ -27,12 +27,12 @@ using namespace std; uint32_t DumpParserBase::ParseOption(int argc, char *argv[], int currentIndex) { if (currentIndex >= argc) { - cerr << "Error: missing input path." << endl; + PrintError(ERR_CODE_DUMP_MISSING_INPUT); return RESTOOL_ERROR; } inputPath_ = ResourceUtil::RealPath(argv[currentIndex]); if (inputPath_.empty()) { - cerr << "Error: invalid input path: '" << argv[currentIndex] << "'" << endl; + PrintError(ERR_CODE_DUMP_INVALID_INPUT); return RESTOOL_ERROR; } return RESTOOL_SUCCESS; diff --git a/src/cmd/package_parser.cpp b/src/cmd/package_parser.cpp index 7b4532d..5dc80d6 100644 --- a/src/cmd/package_parser.cpp +++ b/src/cmd/package_parser.cpp @@ -125,13 +125,13 @@ uint32_t PackageParser::AddInput(const string& argValue) { string inputPath = ResourceUtil::RealPath(argValue); if (inputPath.empty()) { - cerr << "Error: invalid input '" << argValue << "'" << endl; + PrintError(GetError(ERR_CODE_INVALID_INPUT).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } auto ret = find_if(inputs_.begin(), inputs_.end(), [inputPath](auto iter) {return inputPath == iter;}); if (ret != inputs_.end()) { - cerr << "Error: repeat input '" << argValue << "'" << endl; + PrintError(GetError(ERR_CODE_DUPLICATE_INPUT).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } @@ -153,14 +153,14 @@ uint32_t PackageParser::AddSysIdDefined(const std::string& argValue) { string sysIdDefinedPath = ResourceUtil::RealPath(argValue); if (sysIdDefinedPath.empty()) { - cerr << "Error: invalid system id_defined.json path: '" << argValue << "'" << endl; + PrintError(GetError(ERR_CODE_INVALID_SYSTEM_ID_DEFINED).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } auto ret = find_if(sysIdDefinedPaths_.begin(), sysIdDefinedPaths_.end(), [sysIdDefinedPath](auto iter) {return sysIdDefinedPath == iter;}); if (ret != sysIdDefinedPaths_.end()) { - cerr << "Error: repeat system id_defined.json path: '" << argValue << "'" << endl; + PrintError(GetError(ERR_CODE_DUPLICATE_SYSTEM_ID_DEFINED).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } @@ -174,7 +174,7 @@ uint32_t PackageParser::AddSysIdDefined(const std::string& argValue) uint32_t PackageParser::AddPackageName(const string& argValue) { if (!packageName_.empty()) { - cerr << "Error: double package name " << packageName_ << " vs " << argValue << endl; + PrintError(GetError(ERR_CODE_DOUBLE_PACKAGE_NAME).FormatCause(packageName_.c_str(), argValue.c_str())); return RESTOOL_ERROR; } @@ -185,13 +185,13 @@ uint32_t PackageParser::AddPackageName(const string& argValue) uint32_t PackageParser::AddOutput(const string& argValue) { if (!output_.empty()) { - cerr << "Error: double output " << output_ << " vs " << argValue << endl; + PrintError(GetError(ERR_CODE_DOUBLE_OUTPUT).FormatCause(output_.c_str(), argValue.c_str())); return RESTOOL_ERROR; } output_ = ResourceUtil::RealPath(argValue); if (output_.empty()) { - cerr << "Error: invalid output '" << argValue << "'" << endl; + PrintError(GetError(ERR_CODE_INVALID_OUTPUT).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } if (!IsAscii(output_)) { @@ -200,10 +200,10 @@ uint32_t PackageParser::AddOutput(const string& argValue) return RESTOOL_SUCCESS; } -uint32_t PackageParser::AddResourceHeader(const string& argValue) +uint32_t PackageParser::AddResourceHeader(const string &argValue) { if (find(resourceHeaderPaths_.begin(), resourceHeaderPaths_.end(), argValue) != resourceHeaderPaths_.end()) { - cerr << "Error: '" << argValue << "' input duplicated." << endl; + PrintError(GetError(ERR_CODE_DUPLICATE_RES_HEADER).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } resourceHeaderPaths_.push_back(argValue); @@ -226,7 +226,7 @@ uint32_t PackageParser::PrintVersion() uint32_t PackageParser::AddMoudleNames(const string& argValue) { if (!moduleNames_.empty()) { - cerr << "Error: -m double module name '" << argValue << "'" << endl; + PrintError(GetError(ERR_CODE_DOUBLE_MODULES).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } @@ -234,7 +234,7 @@ uint32_t PackageParser::AddMoudleNames(const string& argValue) 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; + PrintError(GetError(ERR_CODE_DUPLICATE_MODULE_NAME).FormatCause(it->c_str())); return RESTOOL_ERROR; } } @@ -244,7 +244,7 @@ uint32_t PackageParser::AddMoudleNames(const string& argValue) uint32_t PackageParser::AddConfig(const string& argValue) { if (!configPath_.empty()) { - cerr << "Error: double config.json " << configPath_ << " vs " << argValue << endl; + PrintError(GetError(ERR_CODE_DOUBLE_CONFIG_JSON).FormatCause(configPath_.c_str(), argValue.c_str())); return RESTOOL_ERROR; } @@ -258,7 +258,7 @@ uint32_t PackageParser::AddStartId(const string& argValue) if ((startId_ >= 0x01000000 && startId_ < 0x06ffffff) || (startId_ >= 0x08000000 && startId_ < 0xffffffff)) { return RESTOOL_SUCCESS; } - cerr << "Error: invalid start id " << argValue << endl; + PrintError(GetError(ERR_CODE_INVALID_START_ID).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } @@ -275,17 +275,17 @@ void PackageParser::AdaptResourcesDirForInput() uint32_t PackageParser::CheckParam() const { if (inputs_.empty() && append_.empty()) { - cerr << "Error: input path empty." << endl; + PrintError(GetError(ERR_CODE_INVALID_INPUT).FormatCause("")); return RESTOOL_ERROR; } if (output_.empty()) { - cerr << "Error: output path empty." << endl; + PrintError(GetError(ERR_CODE_INVALID_OUTPUT).FormatCause("")); return RESTOOL_ERROR; } if (isTtargetConfig_ && !append_.empty()) { - cerr << "Error: -x and --target-config cannot be used together." << endl; + PrintError(GetError(ERR_CODE_EXCLUSIVE_OPTION).FormatCause("-x", "--target-config")); return RESTOOL_ERROR; } @@ -294,17 +294,17 @@ uint32_t PackageParser::CheckParam() const } if (packageName_.empty()) { - cerr << "Error: package name empty." << endl; + PrintError(ERR_CODE_PACKAGE_NAME_EMPTY); return RESTOOL_ERROR; } if (resourceHeaderPaths_.empty()) { - cerr << "Error: resource header path empty." << endl; + PrintError(ERR_CODE_RES_HEADER_PATH_EMPTY); return RESTOOL_ERROR; } if (startId_ != 0 && !idDefinedInputPath_.empty()) { - cerr << "Error: set -e and --defined-ids cannot be used together." << endl; + PrintError(GetError(ERR_CODE_EXCLUSIVE_OPTION).FormatCause("-e", "--defined-ids")); return RESTOOL_ERROR; } @@ -325,7 +325,7 @@ uint32_t PackageParser::AddAppend(const string& argValue) } auto ret = find_if(append_.begin(), append_.end(), [appendPath](auto iter) {return appendPath == iter;}); if (ret != append_.end()) { - cerr << "Error: repeat input '" << argValue << "'" << endl; + PrintError(GetError(ERR_CODE_DUPLICATE_APPEND_PATH).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } if (!IsAscii(appendPath)) { @@ -401,11 +401,11 @@ bool PackageParser::GetIconCheck() const uint32_t PackageParser::ParseTargetConfig(const string& argValue) { if (isTtargetConfig_) { - cerr << "Error: repeat input '--target-config'" << endl; + PrintError(ERR_CODE_DOUBLE_TARGET_CONFIG); return RESTOOL_ERROR; } if (!SelectCompileParse::ParseTargetConfig(argValue, targetConfig_)) { - cerr << "Error: '" << argValue << "' is not valid parameter." << endl; + PrintError(GetError(ERR_CODE_INVALID_TARGET_CONFIG).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } isTtargetConfig_ = true; @@ -421,11 +421,11 @@ uint32_t PackageParser::ParseThread(const std::string &argValue) errno = 0; int count = static_cast(strtol(argValue.c_str(), &end, 10)); if (end == argValue.c_str() || errno == ERANGE || *end != '\0' || count == INT_MIN || count == INT_MAX) { - cerr << "Error: Invalid thread count: " << argValue << endl; + PrintError(GetError(ERR_CODE_INVALID_THREAD_COUNT).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } if (count <= 0) { - cerr << "Error: Invalid thread count: " << count << endl; + PrintError(GetError(ERR_CODE_INVALID_THREAD_COUNT).FormatCause(argValue.c_str())); return RESTOOL_ERROR; } threadCount_ = count; @@ -457,7 +457,7 @@ bool PackageParser::IsAscii(const string& argValue) const return false; }); if (result != argValue.end()) { - cerr << "Error: '" << argValue << "' must be ASCII" << endl; + PrintError(GetError(ERR_CODE_NON_ASCII).FormatCause(argValue.c_str())); return false; } #endif @@ -467,7 +467,7 @@ bool PackageParser::IsAscii(const string& argValue) const uint32_t PackageParser::AddCompressionPath(const std::string& argValue) { if (!compressionPath_.empty()) { - cerr << "Error: double opt-compression.json " << compressionPath_ << " vs " << argValue << endl; + PrintError(GetError(ERR_CODE_DOUBLE_COMPRESSION_PATH).FormatCause(compressionPath_.c_str(), argValue.c_str())); return RESTOOL_ERROR; } compressionPath_ = argValue; @@ -513,11 +513,11 @@ void PackageParser::InitCommand() handles_.emplace(Option::THREAD, bind(&PackageParser::ParseThread, this, _1)); } -uint32_t PackageParser::HandleProcess(int c, const string& argValue) +uint32_t PackageParser::HandleProcess(int c, const string &argValue) { auto handler = handles_.find(c); if (handler == handles_.end()) { - cerr << "Error: unsupport " << c << endl; + cout << "Warning: unsupport " << c << endl; return RESTOOL_ERROR; } return handler->second(argValue); @@ -544,7 +544,7 @@ uint32_t PackageParser::CheckError(int argc, char *argv[], int c, int optIndex) } string curOpt = (optarg == nullptr) ? argv[optind - 1] : argv[optind - 2]; if (curOpt != ("--" + string(CMD_OPTS[optIndex].name))) { - cerr << "Error: unknown option " << curOpt << endl; + PrintError(GetError(ERR_CODE_UNKNOWN_OPTION).FormatCause(curOpt.c_str())); return RESTOOL_ERROR; } } @@ -553,7 +553,7 @@ uint32_t PackageParser::CheckError(int argc, char *argv[], int c, int optIndex) return RESTOOL_ERROR; } string optUnknown = (optopt == 0) ? argv[optind - 1] : ("-" + string(1, optopt)); - cerr << "Error: unknown option " << optUnknown << endl; + PrintError(GetError(ERR_CODE_UNKNOWN_OPTION).FormatCause(optUnknown.c_str())); return RESTOOL_ERROR; } if (c == Option::NO_ARGUMENT) { @@ -561,9 +561,9 @@ uint32_t PackageParser::CheckError(int argc, char *argv[], int c, int optIndex) return RESTOOL_ERROR; } if (IsLongOpt(argc, argv)) { - cerr << "Error: option " << argv[optind - 1] << " must have argument" << endl; + PrintError(GetError(ERR_CODE_MISSING_ARGUMENT).FormatCause(argv[optind - 1])); } else { - cerr << "Error: unknown option " << argv[optind - 1] << endl; + PrintError(GetError(ERR_CODE_UNKNOWN_OPTION).FormatCause(argv[optind - 1])); } return RESTOOL_ERROR; } @@ -583,11 +583,11 @@ uint32_t PackageParser::ParseCommand(int argc, char *argv[]) if (argc == optind) { break; } - string errmsg = "Error: invalid arguments : "; + string errmsg; for (int i = optind; i < argc; i++) { errmsg.append(argv[i]).append(" "); } - cerr << errmsg << endl; + PrintError(GetError(ERR_CODE_INVALID_ARGUMENT).FormatCause(errmsg.c_str())); return RESTOOL_ERROR; } diff --git a/src/compression_parser.cpp b/src/compression_parser.cpp index 4feb177..68c7e9b 100644 --- a/src/compression_parser.cpp +++ b/src/compression_parser.cpp @@ -92,7 +92,7 @@ uint32_t CompressionParser::Init() return RESTOOL_ERROR; } if (!root_ || !cJSON_IsObject(root_)) { - cerr << "Error: JSON file parsing failed, please check the JSON file." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_FORMAT_ERROR).SetPosition(filePath_)); return RESTOOL_ERROR; } cJSON *contextNode = cJSON_GetObjectItem(root_, "context"); @@ -112,13 +112,11 @@ uint32_t CompressionParser::Init() } cJSON *filtersNode = cJSON_GetObjectItem(compressionNode, "filters"); if (!ParseFilters(filtersNode)) { - cerr << NEW_LINE_PATH << filePath_ << endl; return RESTOOL_ERROR; } string caches = outPath_; caches.append(SEPARATOR_FILE).append(CACHES_DIR); if (!ResourceUtil::CreateDirs(caches)) { - cerr << "Error: create caches dir failed. dir = " << caches << endl; return RESTOOL_ERROR; } return RESTOOL_SUCCESS; @@ -127,32 +125,32 @@ uint32_t CompressionParser::Init() bool CompressionParser::ParseCompression(const cJSON *compressionNode) { if (!compressionNode) { - cerr << "Warning: get 'compression' node is empty, the compiled images are not transcoded."; - cerr << NEW_LINE_PATH << filePath_ << endl; + cout << "Warning: get 'compression' node is empty, the compiled images are not transcoded."; + cout << NEW_LINE_PATH << filePath_ << endl; return true; } if (!cJSON_IsObject(compressionNode)) { - cerr << "Error: 'compression' must be object." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("compression", "object")); return false; } cJSON *mediaNode = cJSON_GetObjectItem(compressionNode, "media"); if (!mediaNode) { - cerr << "Warning: get 'media' node is empty, the compiled images are not transcoded."; - cerr << NEW_LINE_PATH << filePath_ << endl; + cout << "Warning: get 'media' node is empty, the compiled images are not transcoded."; + cout << NEW_LINE_PATH << filePath_ << endl; return true; } if (!cJSON_IsObject(mediaNode)) { - cerr << "Error: 'media' must be object." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("media", "object")); return false; } cJSON *enableNode = cJSON_GetObjectItem(mediaNode, "enable"); if (!enableNode) { - cerr << "Warning: get 'enable' node is empty, the compiled images are not transcoded."; - cerr << NEW_LINE_PATH << filePath_ << endl; + cout << "Warning: get 'enable' node is empty, the compiled images are not transcoded."; + cout << NEW_LINE_PATH << filePath_ << endl; return true; } if (!cJSON_IsBool(enableNode)) { - cerr << "Error: 'enable' must be bool." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("enable", "bool")); return false; } mediaSwitch_ = cJSON_IsTrue(enableNode); @@ -189,29 +187,30 @@ bool CompressionParser::ParseContext(const cJSON *contextNode) bool CompressionParser::ParseFilters(const cJSON *filtersNode) { if (!filtersNode) { - cerr << "Error: if image transcoding is supported, the 'filters' node cannot be empty."; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause("filters").SetPosition(filePath_)); return false; } if (!cJSON_IsArray(filtersNode)) { - cerr << "Error: 'filters' must be array."; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("filters", "array").SetPosition(filePath_)); return false; } if (cJSON_GetArraySize(filtersNode) == 0) { - cerr << "Error: 'filters' value cannot be empty."; + PrintError(GetError(ERR_CODE_JSON_NODE_EMPTY).FormatCause("filters").SetPosition(filePath_)); return false; } for (cJSON *item = filtersNode->child; item; item = item->next) { if (!cJSON_IsObject(item)) { - cerr << "Error: 'filters' value type must be object."; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("filters's value", "object") + .SetPosition(filePath_)); return false; } cJSON *methodNode = cJSON_GetObjectItem(item, "method"); if (!methodNode) { - cerr << "Error: if image transcoding is supported, the 'method' node cannot be empty."; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause("method").SetPosition(filePath_)); return false; } if (!cJSON_IsObject(methodNode)) { - cerr << "Error: 'method' must be object."; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("method", "object").SetPosition(filePath_)); return false; } shared_ptr compressFilter = make_shared(); @@ -310,9 +309,9 @@ bool CompressionParser::LoadImageTranscoder() LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); - const char *msg = static_cast(lpMsgBuf); - cerr << "Error: open '" << extensionPath_.c_str() << "' fail." << endl; - cerr << "Error: LoadLibrary failed with error: " << err << ", " << msg << endl; + const char *msg = static_cast(lpMsgBuf); + std::string errMsg = "(" + std::to_string(err) + ")" + string(msg); + PrintError(GetError(ERR_CODE_LOAD_LIBRARY_FAIL).FormatCause(extensionPath_.c_str(), errMsg.c_str())); LocalFree(lpMsgBuf); return false; } @@ -321,14 +320,13 @@ bool CompressionParser::LoadImageTranscoder() if (!handle_) { string realPath = ResourceUtil::RealPath(extensionPath_); if (realPath.empty()) { - cerr << "Error: open '" << extensionPath_.c_str() << "' fail, real path empty." << endl; + PrintError(GetError(ERR_CODE_LOAD_LIBRARY_FAIL).FormatCause(extensionPath_.c_str(), "path invalid")); return false; } handle_ = dlopen(realPath.c_str(), RTLD_LAZY); if (!handle_) { char *err = dlerror(); - cerr << "Error: open '" << realPath.c_str() << "' fail." << endl; - cerr << "Error: dlopen failed with error: " << err << endl; + PrintError(GetError(ERR_CODE_LOAD_LIBRARY_FAIL).FormatCause(realPath.c_str(), err)); return false; } } @@ -592,7 +590,7 @@ bool CompressionParser::CopyAndTranscode(const string &src, string &dst, const b auto index = dst.find_last_of(SEPARATOR_FILE); if (index == string::npos) { - cerr << "Error: invalid output path." << NEW_LINE_PATH << dst << endl; + PrintError(GetError(ERR_CODE_INVALID_FILE_PATH).FormatCause(dst.c_str())); return false; } uint32_t startIndex = outPath_.size() + RESOURCES_DIR.size() + 1; @@ -600,7 +598,6 @@ bool CompressionParser::CopyAndTranscode(const string &src, string &dst, const b string output = outPath_ + SEPARATOR_FILE + CACHES_DIR + endStr; string originDst = dst; if (!ResourceUtil::CreateDirs(output)) { - cerr << "Error: create output dir failed. dir = " << output << endl; return false; } for (const auto &compressFilter : compressFilters_) { @@ -624,14 +621,13 @@ bool CompressionParser::CheckAndScaleIcon(const std::string &src, const std::str } auto index = originDst.find_last_of(SEPARATOR_FILE); if (index == string::npos) { - cerr << "Error: invalid output path." << NEW_LINE_PATH << originDst << endl; + PrintError(GetError(ERR_CODE_INVALID_FILE_PATH).FormatCause(originDst.c_str())); return false; } uint32_t startIndex = outPath_.size() + RESOURCES_DIR.size() + 1; string qualifierDir = originDst.substr(startIndex, index - startIndex); string outputCache = outPath_ + SEPARATOR_FILE + CACHES_DIR + qualifierDir; if (!ResourceUtil::CreateDirs(outputCache)) { - cerr << "Error: scale icon create output dir failed. dir = " << outputCache << endl; return false; } string fileName = originDst.substr(index + 1); diff --git a/src/config_parser.cpp b/src/config_parser.cpp index 78643c4..9d9f060 100644 --- a/src/config_parser.cpp +++ b/src/config_parser.cpp @@ -79,7 +79,7 @@ uint32_t ConfigParser::Init() } if (!root_ || !cJSON_IsObject(root_)) { - cerr << "Error: JSON file parsing failed, please check the JSON file." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_FORMAT_ERROR).SetPosition(filePath_)); return RESTOOL_ERROR; } @@ -135,7 +135,7 @@ bool ConfigParser::SetAppIcon(string &icon, int64_t id) { cJSON *appNode = cJSON_GetObjectItem(root_, "app"); if (!appNode || !cJSON_IsObject(appNode)) { - cerr << "Error: 'app' not object" << endl; + cout << "Warning: 'app' not object" << endl; return false; } cJSON_AddStringToObject(appNode, "icon", icon.c_str()); @@ -147,7 +147,7 @@ bool ConfigParser::SetAppLabel(string &label, int64_t id) { cJSON *appNode = cJSON_GetObjectItem(root_, "app"); if (!appNode || !cJSON_IsObject(appNode)) { - cerr << "Error: 'app' not object" << endl; + cout << "Warning: 'app' not object" << endl; return false; } cJSON_AddStringToObject(appNode, "label", label.c_str()); @@ -159,11 +159,11 @@ bool ConfigParser::SetAppLabel(string &label, int64_t id) bool ConfigParser::ParseModule(cJSON *moduleNode) { if (!moduleNode || !cJSON_IsObject(moduleNode)) { - cerr << "Error: 'module' not object." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("module", "object").SetPosition(filePath_)); return false; } if (cJSON_GetArraySize(moduleNode) == 0) { - cerr << "Error: 'module' empty." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_EMPTY).FormatCause("module").SetPosition(filePath_)); return false; } @@ -184,7 +184,7 @@ bool ConfigParser::ParseModule(cJSON *moduleNode) } if (moduleName_.empty()) { - cerr << "Error: 'name' don't found in 'module'." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause("module.name").SetPosition(filePath_)); return false; } cJSON *typeNode = cJSON_GetObjectItem(moduleNode, "type"); @@ -213,11 +213,11 @@ bool ConfigParser::ParseAbilitiesForDepend(cJSON *moduleNode) bool ConfigParser::ParseDistro(cJSON *distroNode) { if (!distroNode || !cJSON_IsObject(distroNode)) { - cerr << "Error: 'distro' not object." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("distro", "object").SetPosition(filePath_)); return false; } if (cJSON_GetArraySize(distroNode) == 0) { - cerr << "Error: 'distro' empty." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_EMPTY).FormatCause("distro").SetPosition(filePath_)); return false; } @@ -227,7 +227,7 @@ bool ConfigParser::ParseDistro(cJSON *distroNode) } if (moduleName_.empty()) { - cerr << "Error: 'moduleName' don't found in 'distro'." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause("distro.moduleName").SetPosition(filePath_)); return false; } @@ -241,7 +241,7 @@ bool ConfigParser::ParseDistro(cJSON *distroNode) bool ConfigParser::ParseAbilities(const cJSON *abilities) { if (!abilities || !cJSON_IsArray(abilities)) { - cerr << "Error: abilites not array." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("abilites", "array").SetPosition(filePath_)); return false; } if (cJSON_GetArraySize(abilities) == 0) { @@ -250,7 +250,6 @@ bool ConfigParser::ParseAbilities(const cJSON *abilities) bool isMainAbility = false; for (cJSON *ability = abilities->child; ability; ability = ability->next) { if (!ParseAbilitiy(ability, isMainAbility)) { - cerr << "Error: ParseAbilitiy fail." << endl; return false; } if (isMainAbility) { @@ -263,7 +262,7 @@ bool ConfigParser::ParseAbilities(const cJSON *abilities) bool ConfigParser::ParseAbilitiy(const cJSON *ability, bool &isMainAbility) { if (!ability || !cJSON_IsObject(ability)) { - cerr << "Error: ability not object." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("ability", "object").SetPosition(filePath_)); return false; } if (cJSON_GetArraySize(ability) == 0) { @@ -271,6 +270,8 @@ bool ConfigParser::ParseAbilitiy(const cJSON *ability, bool &isMainAbility) } cJSON *nameNode = cJSON_GetObjectItem(ability, "name"); if (!nameNode || !cJSON_IsString(nameNode)) { + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("ability.name", "object") + .SetPosition(filePath_)); return false; } string name = nameNode->valuestring; @@ -285,7 +286,7 @@ bool ConfigParser::ParseAbilitiy(const cJSON *ability, bool &isMainAbility) abilityIconId_ = iconIdNode->valueint; } if (abilityIconId_ <= 0) { - cerr << "Error: iconId don't found in 'ability'." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause("ability.iconId").SetPosition(filePath_)); return false; } cJSON *labelIdNode = cJSON_GetObjectItem(ability, "labelId"); @@ -293,7 +294,7 @@ bool ConfigParser::ParseAbilitiy(const cJSON *ability, bool &isMainAbility) abilityLabelId_ = labelIdNode->valueint; } if (abilityLabelId_ <= 0) { - cerr << "Error: labelId don't found in 'ability'." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause("ability.labelId").SetPosition(filePath_)); return false; } isMainAbility = true; @@ -363,20 +364,21 @@ bool ConfigParser::ParseRefImpl(cJSON *parent, const string &key, cJSON *node) bool ConfigParser::ParseJsonArrayRef(cJSON *parent, const string &key, cJSON *node) { if (!node || !cJSON_IsArray(node)) { - cerr << "Error: '"<< key << "'node not array." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(key.c_str(), "array") + .SetPosition(filePath_)); return false; } cJSON *array = cJSON_CreateArray(); for (cJSON *item = node->child; item; item = item->next) { if (!cJSON_IsString(item)) { - cerr << "Error: '" << key << "' invalid value." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(string(key + " value").c_str(), "string") + .SetPosition(filePath_)); cJSON_Delete(array); return false; } string value = item->valuestring; bool update = false; if (!GetRefIdFromString(value, update, JSON_ARRAY_IDS.at(key))) { - cerr << "Error: '" << key << "' value " << value << " invalid." << NEW_LINE_PATH << filePath_ << endl; cJSON_Delete(array); return false; } @@ -395,16 +397,12 @@ bool ConfigParser::ParseJsonStringRef(cJSON *parent, const string &key, cJSON *n return true; } if (!node || !cJSON_IsString(node)) { - cerr << "Error: '" << key << "' invalid value." << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(key.c_str(), "string").SetPosition(filePath_)); return false; } string value = node->valuestring; bool update = false; if (!GetRefIdFromString(value, update, JSON_STRING_IDS.at(key))) { - cerr << "Error: '" << key << "' value " << value << " invalid value." << NEW_LINE_PATH << filePath_ << endl; - cerr << SOLUTIONS << endl; - cerr << SOLUTIONS_ARROW << "Please check the module.json5/config.json file in the src/main directory of the " - << GetModuleName() << " module." << endl; return false; } if (update) { @@ -436,8 +434,7 @@ void ConfigParser::AddCheckNode(const string &key, uint32_t id) bool ConfigParser::GetRefIdFromString(string &value, bool &update, const string &match) const { ReferenceParser refParser; - string error = "Error: '" + value + "' must start with '" + match.substr(match.find("\\") + 1) + "'"; - if (refParser.ParseRefInString(value, update) != RESTOOL_SUCCESS) { + if (refParser.ParseRefInString(value, update, filePath_) != RESTOOL_SUCCESS) { return false; } if (!update) { @@ -448,7 +445,8 @@ bool ConfigParser::GetRefIdFromString(string &value, bool &update, const string value = value.substr(result[0].str().length()); return true; } - cerr << error << endl; + string ref = match.substr(match.find("\\") + 1); + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_REF).FormatCause(value.c_str(), ref.c_str()).SetPosition(filePath_)); return false; } @@ -456,7 +454,7 @@ bool ConfigParser::ParseModuleType(const string &type) { const auto &result = MODULE_TYPES.find(type); if (result == MODULE_TYPES.end()) { - cerr << "Error: moduleType='" << type << "' invalid value." << NEW_LINE_PATH << filePath_ << endl; + PrintError(GetError(ERR_CODE_INVALID_MODULE_TYPE).FormatCause(type.c_str()).SetPosition(filePath_)); return false; } moduleType_ = result->second; diff --git a/src/file_entry.cpp b/src/file_entry.cpp index 18befeb..171b190 100644 --- a/src/file_entry.cpp +++ b/src/file_entry.cpp @@ -25,6 +25,7 @@ #include "windows.h" #endif #include "resource_data.h" +#include "restool_errors.h" namespace OHOS { namespace Global { @@ -49,7 +50,7 @@ bool FileEntry::Init() { string filePath = filePath_.GetPath(); if (!Exist(filePath)) { - cerr << "Error: '" << filePath << "' not exists." << endl; + PrintError(GetError(ERR_CODE_FILE_NOT_EXIST).FormatCause(filePath.c_str())); return false; } @@ -131,7 +132,7 @@ bool FileEntry::RemoveAllDir(const string &path) } if (f.IsFile()) { - cerr << "Error: RemoveAllDir '" << path << "' not directory." << endl; + PrintError(GetError(ERR_CODE_REMOVE_FILE_ERROR).FormatCause(path.c_str(), "not directory")); return false; } return RemoveAllDirInner(f); @@ -155,14 +156,14 @@ bool FileEntry::CopyFileInner(const string &src, const string &dst) { #ifdef _WIN32 if (!CopyFile(AdaptLongPath(src).c_str(), AdaptLongPath(dst).c_str(), false)) { - cerr << "Error: copy file fail from '" << src << "' to '" << dst << "'. reason:" << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_COPY_FILE_ERROR).FormatCause(src.c_str(), dst.c_str(), strerror(errno))); return false; } #else ifstream in(src, ios::binary); ofstream out(dst, ios::binary); if (!in || !out) { - cerr << "Error: open failed '" << src << "' or '" << dst << "'. reason:" << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_COPY_FILE_ERROR).FormatCause(src.c_str(), dst.c_str(), strerror(errno))); return false; } out << in.rdbuf(); @@ -303,7 +304,7 @@ bool FileEntry::RemoveAllDirInner(const FileEntry &entry) bool result = remove(path.c_str()) == 0; #endif if (!result) { - cerr << "Error: remove file '" << path << "' failed, reason: " << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_REMOVE_FILE_ERROR).FormatCause(path.c_str(), strerror(errno))); return false; } return true; @@ -320,7 +321,7 @@ bool FileEntry::RemoveAllDirInner(const FileEntry &entry) bool result = rmdir(path.c_str()) == 0; #endif if (!result) { - cerr << "Error: remove directory '" << path << "' failed, reason: " << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_REMOVE_FILE_ERROR).FormatCause(path.c_str(), strerror(errno))); return false; } return true; diff --git a/src/file_manager.cpp b/src/file_manager.cpp index 284d528..e0a4be7 100644 --- a/src/file_manager.cpp +++ b/src/file_manager.cpp @@ -132,7 +132,7 @@ bool FileManager::ScaleIcon(const string &output, ResourceItem &item) const string currentData(reinterpret_cast(item.GetData()), item.GetDataLength()); auto outIndex = currentData.find_last_of(SEPARATOR); if (outIndex == string::npos) { - cerr << "Error: ScaleIcon invalid output name: " << currentData << endl; + PrintError(GetError(ERR_CODE_INVALID_OUTPUT).FormatCause(currentData.c_str())); return false; } // get current output file name and full path @@ -146,7 +146,6 @@ bool FileManager::ScaleIcon(const string &output, ResourceItem &item) const string fullOutPath = fullFilePath.GetPath(); // delete current output file if (!ResourceUtil::RmoveFile(fullOutPath)) { - cout << "Error: ScaleIcon RmoveFile failed: " << fullOutPath << endl; return false; } // get origin icon output full path with the origin icon file name in src @@ -166,8 +165,8 @@ bool FileManager::ScaleIcon(const string &output, ResourceItem &item) std::string newData = moduleName_ + SEPARATOR + RESOURCES_DIR + SEPARATOR + item.GetLimitKey() + SEPARATOR + media + SEPARATOR + newFileName; if (!item.SetData(reinterpret_cast(newData.c_str()), newData.length())) { - cerr << "Error: ScaleIcon resource item set data fail, data: " << newData << NEW_LINE_PATH - << item.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_SET_DATA_ERROR).FormatCause(item.GetName().c_str()) + .SetPosition(item.GetFilePath())); return false; } return true; diff --git a/src/generic_compiler.cpp b/src/generic_compiler.cpp index 3ad8f66..e4211a3 100644 --- a/src/generic_compiler.cpp +++ b/src/generic_compiler.cpp @@ -76,14 +76,15 @@ bool GenericCompiler::PostMediaFile(const FileInfo &fileInfo, const std::string auto index = output.find_last_of(SEPARATOR_FILE); if (index == string::npos) { - cerr << "Error: invalid output path." << NEW_LINE_PATH << output << endl; + PrintError(GetError(ERR_CODE_INVALID_FILE_PATH).FormatCause(output.c_str())); return false; } string data = output.substr(index + 1); data = moduleName_ + SEPARATOR + RESOURCES_DIR + SEPARATOR + \ fileInfo.limitKey + SEPARATOR + fileInfo.fileCluster + SEPARATOR + data; if (!resourceItem.SetData(reinterpret_cast(data.c_str()), data.length())) { - cerr << "Error: resource item set data fail, data: " << data << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_SET_DATA_ERROR).FormatCause(resourceItem.GetName().c_str()) + .SetPosition(fileInfo.filePath)); return false; } @@ -108,7 +109,7 @@ bool GenericCompiler::IsIgnore(const FileInfo &fileInfo) if (g_hapResourceSet.count(output)) { g_hapResourceSet.erase(output); } else if (!g_resourceSet.emplace(output).second) { - cerr << "Warning: '" << fileInfo.filePath << "' is defined repeatedly." << endl; + cout << "Warning: '" << fileInfo.filePath << "' is defined repeatedly." << endl; return true; } return false; @@ -118,7 +119,6 @@ bool GenericCompiler::CopyMediaFile(const FileInfo &fileInfo, std::string &outpu { string outputFolder = GetOutputFolder(fileInfo); if (!ResourceUtil::CreateDirs(outputFolder)) { - cerr << "Error: CopyMediaFile create dirs failed." << NEW_LINE_PATH << outputFolder << endl; return false; } output = GetOutputFilePath(fileInfo); diff --git a/src/header.cpp b/src/header.cpp index ac6e935..3be2444 100644 --- a/src/header.cpp +++ b/src/header.cpp @@ -53,7 +53,7 @@ uint32_t Header::Create(HandleHeaderTail headerHandler, HandleBody bodyHandler, ofstream out(outputPath_, ofstream::out | ofstream::binary); if (!out.is_open()) { - cerr << "Error: open failed '" << outputPath_ << "', reason: " << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_OPEN_FILE_ERROR).FormatCause(outputPath_.c_str(), strerror(errno))); return RESTOOL_ERROR; } diff --git a/src/i_resource_compiler.cpp b/src/i_resource_compiler.cpp index ac75925..6b094dc 100644 --- a/src/i_resource_compiler.cpp +++ b/src/i_resource_compiler.cpp @@ -52,7 +52,7 @@ uint32_t IResourceCompiler::Compile(const vector &directoryInfos) } if (!it->IsFile()) { - cerr << "Error: '" << it->GetFilePath().GetPath() << "' must be a file." << endl; + PrintError(GetError(ERR_CODE_RESOURCE_PATH_NOT_FILE).FormatCause(it->GetFilePath().GetPath().c_str())); return RESTOOL_ERROR; } @@ -120,8 +120,9 @@ uint32_t IResourceCompiler::PostCommit() for (const auto &nameInfo : nameInfos_) { int64_t id = idWorker.GenerateId(nameInfo.first.first, nameInfo.first.second); if (id < 0) { - cerr << "Error: restype='" << ResourceUtil::ResTypeToString(nameInfo.first.first) << "' name='"; - cerr << nameInfo.first.second << "' id not be defined." << endl; + PrintError(GetError(ERR_CODE_RESOURCE_ID_NOT_DEFINED) + .FormatCause(ResourceUtil::ResTypeToString(nameInfo.first.first).c_str(), + nameInfo.first.second.c_str())); return RESTOOL_ERROR; } resourceInfos_.emplace(id, nameInfo.second); @@ -133,9 +134,8 @@ bool IResourceCompiler::MergeResourceItem(const ResourceItem &resourceItem) { string idName = ResourceUtil::GetIdName(resourceItem.GetName(), resourceItem.GetResType()); if (!ResourceUtil::IsValidName(idName)) { - cerr << "Error: invalid idName '" << idName << "'."<< NEW_LINE_PATH << resourceItem.GetFilePath() << endl; - cerr << SOLUTIONS << endl; - cerr << SOLUTIONS_ARROW << "Modify the name '" << idName << "' to match [a-zA-Z0-9_]." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_NAME).FormatCause(idName.c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } auto item = nameInfos_.find(make_pair(resourceItem.GetResType(), idName)); @@ -148,8 +148,8 @@ bool IResourceCompiler::MergeResourceItem(const ResourceItem &resourceItem) return resourceItem.GetLimitKey() == iter.GetLimitKey(); }); if (ret != item->second.end()) { - cerr << "Error: resource '" << idName << "' first declared." << NEW_LINE_PATH << ret->GetFilePath() << endl; - cerr << "but declare again." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_RESOURCE_DUPLICATE) + .FormatCause(idName.c_str(), ret->GetFilePath().c_str(), resourceItem.GetFilePath().c_str())); return false; } nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem); diff --git a/src/id_defined_parser.cpp b/src/id_defined_parser.cpp index 28a0116..4f22893 100755 --- a/src/id_defined_parser.cpp +++ b/src/id_defined_parser.cpp @@ -50,7 +50,7 @@ uint32_t IdDefinedParser::Init() idDefinedPath = ResourceUtil::GetBaseElementPath(inputPath).Append(ID_DEFINED_FILE).GetPath(); } if (ResourceUtil::FileExist(idDefinedPath) && startId > 0) { - cerr << "Error: the set start_id and id_defined.json cannot be used together." << endl; + PrintError(ERR_CODE_EXCLUSIVE_START_ID); return RESTOOL_ERROR; } if (Init(idDefinedPath, isSys) != RESTOOL_SUCCESS) { @@ -94,26 +94,25 @@ uint32_t IdDefinedParser::Init(const string &filePath, bool isSystem) } if (!root_ || !cJSON_IsObject(root_)) { - cerr << "Error: JSON file parsing failed, please check the JSON file."; - cerr << NEW_LINE_PATH << filePath << endl; + PrintError(GetError(ERR_CODE_JSON_FORMAT_ERROR).SetPosition(filePath)); return RESTOOL_ERROR; } cJSON *recordNode = cJSON_GetObjectItem(root_, "record"); if (!recordNode || !cJSON_IsArray(recordNode)) { - cerr << "Error: 'record' node is not an array, please check the JSON file."; - cerr << NEW_LINE_PATH << filePath << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("record", "array").SetPosition(filePath)); return RESTOOL_ERROR; } if (cJSON_GetArraySize(recordNode) == 0) { - cerr << "Warning: 'record' node is empty, please check the JSON file."; - cerr << NEW_LINE_PATH << filePath << endl; + cout << "Warning: 'record' node is empty, please check the JSON file."; + cout << NEW_LINE_PATH << filePath << endl; return RESTOOL_SUCCESS; } int64_t startSysId = 0; if (isSystem) { startSysId = GetStartId(); if (startSysId < 0) { + PrintError(ERR_CODE_ID_DEFINED_INVALID_START_ID); return RESTOOL_ERROR; } } @@ -140,6 +139,8 @@ uint32_t IdDefinedParser::IdDefinedToResourceIds(const std::string &filePath, co for (cJSON *item = record->child; item; item = item->next) { index++; if (!cJSON_IsObject(item)) { + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("record's child", "object") + .SetPosition(filePath)); return RESTOOL_ERROR; } ResourceId resourceId; @@ -165,7 +166,8 @@ bool IdDefinedParser::PushResourceId(const std::string &filePath, const Resource ResType resType = ResourceUtil::GetResTypeFromString(resourceId.type); auto ret = idDefineds_.emplace(resourceId.id, resourceId); if (!ret.second) { - cerr << "Error: '" << ret.first->second.name << "' and '" << resourceId.name << "' defind the same ID." << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_SAME_ID).FormatCause(ret.first->second.name.c_str(), + resourceId.name.c_str())); return false; } auto checkRet = checkDefinedIds_.find(filePath); @@ -175,7 +177,8 @@ bool IdDefinedParser::PushResourceId(const std::string &filePath, const Resource return (resType == iterItem.first) && (resourceId.name == iterItem.second); }); if (found) { - cerr << "Error: the same resource of '" << resourceId.name << "' exists in the " << filePath << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_SAME_RESOURCE).FormatCause(resourceId.name.c_str(), + filePath.c_str())); return false; } checkRet->second.push_back(make_pair(resType, resourceId.name)); @@ -195,23 +198,21 @@ bool IdDefinedParser::PushResourceId(const std::string &filePath, const Resource bool IdDefinedParser::ParseId(const cJSON *origId, ResourceId &resourceId) { if (!origId) { - cerr << "Error: id_defined.json seq =" << resourceId.seq << " id empty." << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_NODE_MISSING).FormatCause(resourceId.seq, "id")); return false; } if (!cJSON_IsString(origId)) { - cerr << "Error: id_defined.json seq =" << resourceId.seq << " id not string." << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_NODE_MISMATCH).FormatCause(resourceId.seq, "id", "string")); return false; } string idStr = origId->valuestring; if (!ResourceUtil::CheckHexStr(idStr)) { - cerr << "Error: id_defined.json seq =" << resourceId.seq; - cerr << " id must be a hex string, eg:^0[xX][0-9a-fA-F]{8}" << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_INVALID_ID).FormatCause(resourceId.seq)); return false; } int64_t id = strtoll(idStr.c_str(), nullptr, 16); if (id < 0x01000000 || (id > 0x06FFFFFF && id < 0x08000000) || id > 0xFFFFFFFF) { - cerr << "Error: id_defined.json seq = "<< resourceId.seq; - cerr << " id must in [0x01000000,0x06FFFFFF],[0x08000000,0xFFFFFFFF]." << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_ID_OUT_RANGE).FormatCause(resourceId.seq)); return false; } resourceId.id = id; @@ -221,16 +222,15 @@ bool IdDefinedParser::ParseId(const cJSON *origId, ResourceId &resourceId) bool IdDefinedParser::ParseType(const cJSON *type, ResourceId &resourceId) { if (!type) { - cerr << "Error: id_defined.json seq =" << resourceId.seq << " type empty." << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_NODE_MISSING).FormatCause(resourceId.seq, "type")); return false; } if (!cJSON_IsString(type)) { - cerr << "Error: id_defined.json seq =" << resourceId.seq << " type not string." << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_NODE_MISMATCH).FormatCause(resourceId.seq, "type", "string")); return false; } if (ResourceUtil::GetResTypeFromString(type->valuestring) == ResType::INVALID_RES_TYPE) { - cerr << "Error: id_defined.json seq =" << resourceId.seq << " type '"; - cerr << type->valuestring << "' invalid." << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_INVALID_TYPE).FormatCause(resourceId.seq, type->valuestring)); return false; } resourceId.type = type->valuestring; @@ -240,20 +240,19 @@ bool IdDefinedParser::ParseType(const cJSON *type, ResourceId &resourceId) bool IdDefinedParser::ParseName(const cJSON *name, ResourceId &resourceId) { if (!name) { - cerr << "Error: id_defined.json seq =" << resourceId.seq << " name empty." << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_NODE_MISSING).FormatCause(resourceId.seq, "name")); return false; } if (!cJSON_IsString(name)) { - cerr << "Error: id_defined.json seq =" << resourceId.seq << " name not string." << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_NODE_MISMATCH).FormatCause(resourceId.seq, "name", "string")); return false; } resourceId.name = name->valuestring; if (type_ == ResourceIdCluster::RES_ID_SYS && (static_cast(resourceId.id) & static_cast(START_SYS_ID)) == START_SYS_ID && !ResourceUtil::IsValidName(resourceId.name)) { - cerr << "Error: id_defined.json."<< endl; - cerr << SOLUTIONS << endl; - cerr << SOLUTIONS_ARROW << "Modify the name '" << resourceId.name << "' to match [a-zA-Z0-9_]." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_NAME).FormatCause(resourceId.name.c_str()) + .SetPosition("id_defined.json")); return false; } return true; @@ -262,17 +261,16 @@ bool IdDefinedParser::ParseName(const cJSON *name, ResourceId &resourceId) bool IdDefinedParser::ParseOrder(const cJSON *order, ResourceId &resourceId) { if (!order) { - cerr << "Error: id_defined.json seq =" << resourceId.seq << " order empty." << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_NODE_MISSING).FormatCause(resourceId.seq, "order")); return false; } if (!ResourceUtil::IsIntValue(order)) { - cerr << "Error: id_defined.json seq =" << resourceId.seq << " order not int." << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_NODE_MISMATCH).FormatCause(resourceId.seq, "order", "int")); return false; } int64_t orderId = order->valueint; if (orderId != resourceId.seq) { - cerr << "Error: id_defined.json seq =" << resourceId.seq << " order value "; - cerr << orderId << " vs expect " << resourceId.seq << endl; + PrintError(GetError(ERR_CODE_ID_DEFINED_ORDER_MISMATCH).FormatCause(resourceId.seq, orderId, resourceId.seq)); return false; } resourceId.id = resourceId.id + orderId; @@ -283,18 +281,18 @@ int64_t IdDefinedParser::GetStartId() const { cJSON *startIdNode = cJSON_GetObjectItem(root_, "startId"); if (!startIdNode) { - cerr << "Error: id_defined.json 'startId' empty." << endl; + cout << "Warning: id_defined.json 'startId' empty." << endl; return -1; } if (!cJSON_IsString(startIdNode)) { - cerr << "Error: id_defined.json 'startId' not string." << endl; + cout << "Warning: id_defined.json 'startId' not string." << endl; return -1; } int64_t id = strtoll(startIdNode->valuestring, nullptr, 16); if (id == 0) { - cerr << "Error: id_defined.json 'startId' is not a valid hexadecimal string." << endl; + cout << "Warning: id_defined.json 'startId' is not a valid hexadecimal string." << endl; return -1; } return id; diff --git a/src/id_worker.cpp b/src/id_worker.cpp index c5147ae..406573a 100644 --- a/src/id_worker.cpp +++ b/src/id_worker.cpp @@ -119,7 +119,7 @@ int64_t IdWorker::GenerateAppId(ResType resType, const string &name) } if (appId_ > maxId_) { - cerr << "Error: id count exceed " << appId_ << ">" << maxId_ << endl; + PrintError(GetError(ERR_CODE_RESOURCE_ID_EXCEED).FormatCause(appId_, maxId_)); return -1; } int64_t id = -1; @@ -151,7 +151,7 @@ int64_t IdWorker::GetCurId() } appId_++; } - cerr << "Error: id count exceed in id_defined." << appId_ << ">" << maxId_ << endl; + PrintError(GetError(ERR_CODE_RESOURCE_ID_EXCEED).FormatCause(appId_, maxId_).SetPosition("id_defined.json")); return -1; } diff --git a/src/json_compiler.cpp b/src/json_compiler.cpp index 046c266..04004f3 100644 --- a/src/json_compiler.cpp +++ b/src/json_compiler.cpp @@ -56,22 +56,19 @@ uint32_t JsonCompiler::CompileSingleFile(const FileInfo &fileInfo) return RESTOOL_ERROR; } if (!root_ || !cJSON_IsObject(root_)) { - cerr << "Error: JSON file parsing failed, please check the JSON file."; - cerr << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_JSON_FORMAT_ERROR).SetPosition(fileInfo.filePath)); return RESTOOL_ERROR; } cJSON *item = root_->child; if (cJSON_GetArraySize(root_) != 1) { - cerr << "Error: node of a JSON file can only have one member, please check the JSON file."; - cerr << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_JSON_NOT_ONE_MEMBER).FormatCause("root").SetPosition(fileInfo.filePath)); return RESTOOL_ERROR; } string tag = item->string; auto ret = g_contentClusterMap.find(tag); if (ret == g_contentClusterMap.end()) { - cerr << "Error: invalid tag name '" << tag << "', please check the JSON file."; - cerr << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_JSON_INVALID_NODE_NAME).FormatCause(tag.c_str()).SetPosition(fileInfo.filePath)); return RESTOOL_ERROR; } isBaseString_ = (fileInfo.limitKey == "base" && @@ -104,21 +101,24 @@ void JsonCompiler::InitParser() bool JsonCompiler::ParseJsonArrayLevel(const cJSON *arrayNode, const FileInfo &fileInfo) { if (!arrayNode || !cJSON_IsArray(arrayNode)) { - cerr << "Error: '" << ResourceUtil::ResTypeToString(fileInfo.fileType) << "' must be array."; - cerr << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(ResourceUtil::ResTypeToString(fileInfo.fileType).c_str(), "array") + .SetPosition(fileInfo.filePath)); return false; } if (cJSON_GetArraySize(arrayNode) == 0) { - cerr << "Error: '" << ResourceUtil::ResTypeToString(fileInfo.fileType) << "' empty."; - cerr << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_EMPTY) + .FormatCause(ResourceUtil::ResTypeToString(fileInfo.fileType).c_str()) + .SetPosition(fileInfo.filePath)); return false; } int32_t index = -1; for (cJSON *item = arrayNode->child; item; item = item->next) { index++; if (!item || !cJSON_IsObject(item)) { - cerr << "Error: the seq=" << index << " item must be object." << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause("item", "object") + .SetPosition(fileInfo.filePath)); return false; } if (!ParseJsonObjectLevel(item, fileInfo)) { @@ -132,12 +132,13 @@ bool JsonCompiler::ParseJsonObjectLevel(cJSON *objectNode, const FileInfo &fileI { cJSON *nameNode = cJSON_GetObjectItem(objectNode, TAG_NAME.c_str()); if (!nameNode) { - cerr << "Error: name empty." << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause("name").SetPosition(fileInfo.filePath)); return false; } if (!cJSON_IsString(nameNode)) { - cerr << "Error: name must string." << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(TAG_NAME.c_str(), "string") + .SetPosition(fileInfo.filePath)); return false; } @@ -149,7 +150,8 @@ bool JsonCompiler::ParseJsonObjectLevel(cJSON *objectNode, const FileInfo &fileI resourceItem.SetLimitKey(fileInfo.limitKey); auto ret = handles_.find(fileInfo.fileType); if (ret == handles_.end()) { - cerr << "Error: json parser don't support " << ResourceUtil::ResTypeToString(fileInfo.fileType) << endl; + PrintError(GetError(ERR_CODE_INVALID_ELEMENT_TYPE) + .FormatCause(ResourceUtil::ResTypeToString(fileInfo.fileType).c_str())); return false; } @@ -192,22 +194,23 @@ bool JsonCompiler::HandleBoolean(const cJSON *objectNode, ResourceItem &resource { cJSON *valueNode = cJSON_GetObjectItem(objectNode, TAG_VALUE.c_str()); if (valueNode == nullptr) { - cerr << "Error: '" << resourceItem.GetName() << "' value not json."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause(string(resourceItem.GetName() + " value").c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } if (cJSON_IsString(valueNode)) { regex ref("^\\$(ohos:)?boolean:.*"); if (!regex_match(valueNode->valuestring, ref)) { - cerr << "Error: '" << valueNode->valuestring << "' only refer '$boolean:xxx'."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_REF).FormatCause(valueNode->valuestring, "$(ohos:)?boolean:") + .SetPosition(resourceItem.GetFilePath())); return false; } return PushString(valueNode->valuestring, resourceItem); } if (!cJSON_IsBool(valueNode)) { - cerr << "Error: '" << resourceItem.GetName() << "' value not boolean."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(string(resourceItem.GetName() + " value").c_str(), "bool") + .SetPosition(resourceItem.GetFilePath())); return false; } return PushString(cJSON_IsTrue(valueNode) == 1 ? "true" : "false", resourceItem); @@ -229,8 +232,9 @@ bool JsonCompiler::HandleStringArray(const cJSON *objectNode, ResourceItem &reso return ParseValueArray(objectNode, resourceItem, extra, [this](const cJSON *arrayItem, const ResourceItem &resourceItem, vector &values) -> bool { if (!cJSON_IsObject(arrayItem)) { - cerr << "Error: '" << resourceItem.GetName() << "' value array item not object."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(string(resourceItem.GetName() + " value").c_str(), "object") + .SetPosition(resourceItem.GetFilePath())); return false; } cJSON *valueNode = cJSON_GetObjectItem(arrayItem, TAG_VALUE.c_str()); @@ -291,8 +295,9 @@ bool JsonCompiler::HandlePlural(const cJSON *objectNode, ResourceItem &resourceI } string quantityValue = quantityNode->valuestring; if (find(attrs.begin(), attrs.end(), quantityValue) != attrs.end()) { - cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity '" << quantityValue; - cerr << "' duplicated." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_DUPLICATE_QUANTITY) + .FormatCause(resourceItem.GetName().c_str(), quantityValue.c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } attrs.push_back(quantityValue); @@ -308,8 +313,8 @@ bool JsonCompiler::HandlePlural(const cJSON *objectNode, ResourceItem &resourceI return false; } if (find(attrs.begin(), attrs.end(), "other") == attrs.end()) { - cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity must contains 'other'."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_QUANTITY_NO_OTHER).FormatCause(resourceItem.GetName().c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } return true; @@ -327,8 +332,8 @@ bool JsonCompiler::HandleSymbol(const cJSON *objectNode, ResourceItem &resourceI bool JsonCompiler::PushString(const string &value, ResourceItem &resourceItem) const { if (!resourceItem.SetData(reinterpret_cast(value.c_str()), value.length())) { - cerr << "Error: resourceItem setdata fail,'" << resourceItem.GetName() << "'."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_SET_DATA_ERROR).FormatCause(resourceItem.GetName().c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } return true; @@ -337,8 +342,9 @@ bool JsonCompiler::PushString(const string &value, ResourceItem &resourceItem) c bool JsonCompiler::CheckJsonStringValue(const cJSON *valueNode, const ResourceItem &resourceItem) const { if (!valueNode || !cJSON_IsString(valueNode)) { - cerr << "Error: '" << resourceItem.GetName() << "' value not string."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(string(resourceItem.GetName() + " value").c_str(), "string") + .SetPosition(resourceItem.GetFilePath())); return false; } @@ -352,16 +358,15 @@ bool JsonCompiler::CheckJsonStringValue(const cJSON *valueNode, const ResourceIt string value = valueNode->valuestring; ResType type = resourceItem.GetResType(); if (type == ResType::COLOR && !CheckColorValue(value.c_str())) { - string error = "invalid color value '" + value + \ - "', only support refer '$color:xxx' or '#rgb','#argb','#rrggbb','#aarrggbb'."; - cerr << "Error: " << error << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_INVALID_COLOR_VALUE).FormatCause(value.c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } regex ref("^\\$.+:"); smatch result; if (regex_search(value, result, ref) && !regex_match(result[0].str(), regex(REFS.at(type)))) { - cerr << "Error: '" << value << "', only refer '"<< REFS.at(type) << "xxx'."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_REF).FormatCause(value.c_str(), REFS.at(type).c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } return true; @@ -370,20 +375,21 @@ bool JsonCompiler::CheckJsonStringValue(const cJSON *valueNode, const ResourceIt bool JsonCompiler::CheckJsonIntegerValue(const cJSON *valueNode, const ResourceItem &resourceItem) const { if (!valueNode) { - cerr << "Error: '" << resourceItem.GetName() << "' value is empty"; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause(string(resourceItem.GetName() + " value").c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } if (cJSON_IsString(valueNode)) { regex ref("^\\$(ohos:)?integer:.*"); if (!regex_match(valueNode->valuestring, ref)) { - cerr << "Error: '" << valueNode->valuestring << "', only refer '$integer:xxx'."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_REF).FormatCause(valueNode->valuestring, "$(ohos:)?integer:") + .SetPosition(resourceItem.GetFilePath())); return false; } } else if (!ResourceUtil::IsIntValue(valueNode)) { - cerr << "Error: '" << resourceItem.GetName() << "' value not integer."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(string(resourceItem.GetName() + " value").c_str(), "integer") + .SetPosition(resourceItem.GetFilePath())); return false; } return true; @@ -392,8 +398,9 @@ bool JsonCompiler::CheckJsonIntegerValue(const cJSON *valueNode, const ResourceI bool JsonCompiler::CheckJsonSymbolValue(const cJSON *valueNode, const ResourceItem &resourceItem) const { if (!valueNode || !cJSON_IsString(valueNode)) { - cerr << "Error: '" << resourceItem.GetName() << "' value not string."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(string(resourceItem.GetName() + " value").c_str(), "string") + .SetPosition(resourceItem.GetFilePath())); return false; } string unicodeStr = valueNode->valuestring; @@ -402,8 +409,8 @@ bool JsonCompiler::CheckJsonSymbolValue(const cJSON *valueNode, const ResourceIt } int unicode = strtol(unicodeStr.c_str(), nullptr, 16); if (!ResourceUtil::isUnicodeInPlane15or16(unicode)) { - cerr << "Error: '" << resourceItem.GetName() << "' value must in 0xF0000 ~ 0xFFFFF or 0x100000 ~ 0x10FFFF."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_INVALID_SYMBOL).FormatCause(resourceItem.GetName().c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } return true; @@ -414,20 +421,23 @@ bool JsonCompiler::ParseValueArray(const cJSON *objectNode, ResourceItem &resour { cJSON *arrayNode = cJSON_GetObjectItem(objectNode, TAG_VALUE.c_str()); if (arrayNode == nullptr) { - cerr << "Error: '" << resourceItem.GetName() << "' value not json."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING) + .FormatCause(string(resourceItem.GetName() + " value").c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } if (!cJSON_IsArray(arrayNode)) { - cerr << "Error: '" << resourceItem.GetName() << "' value not array."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(string(resourceItem.GetName() + " value").c_str(), "array") + .SetPosition(resourceItem.GetFilePath())); return false; } if (cJSON_GetArraySize(arrayNode) == 0) { - cerr << "Error: '" << resourceItem.GetName() << "' value empty."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_EMPTY) + .FormatCause(string(resourceItem.GetName() + " value").c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } @@ -445,8 +455,8 @@ bool JsonCompiler::ParseValueArray(const cJSON *objectNode, ResourceItem &resour string data = ResourceUtil::ComposeStrings(contents); if (data.empty()) { - cerr << "Error: '" << resourceItem.GetName() << "' array too large."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_ARRAY_TOO_LARGE).FormatCause(resourceItem.GetName().c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } return PushString(data, resourceItem); @@ -459,14 +469,16 @@ bool JsonCompiler::ParseParent(const cJSON *objectNode, const ResourceItem &reso string type = ResourceUtil::ResTypeToString(resourceItem.GetResType()); if (parentNode) { if (!cJSON_IsString(parentNode)) { - cerr << "Error: " << type << " '" << resourceItem.GetName() << "' parent not string."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(string(resourceItem.GetName() + " parent").c_str(), "string") + .SetPosition(resourceItem.GetFilePath())); return false; } string parentValue = parentNode->valuestring; if (parentValue.empty()) { - cerr << "Error: " << type << " '"<< resourceItem.GetName() << "' parent empty."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_PARENT_EMPTY) + .FormatCause(type.c_str(), resourceItem.GetName().c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } if (regex_match(parentValue, regex("^ohos:" + type + ":.+"))) { @@ -483,33 +495,36 @@ bool JsonCompiler::ParseAttribute(const cJSON *arrayItem, const ResourceItem &re vector &values) const { string type = ResourceUtil::ResTypeToString(resourceItem.GetResType()); + string nodeAttr = string(resourceItem.GetName() + " attribute"); + string filePath = resourceItem.GetFilePath(); if (!arrayItem || !cJSON_IsObject(arrayItem)) { - cerr << "Error: " << type << " '" << resourceItem.GetName() << "' attribute not object."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(nodeAttr.c_str(), "object") + .SetPosition(filePath)); return false; } cJSON *nameNode = cJSON_GetObjectItem(arrayItem, TAG_NAME.c_str()); if (!nameNode) { - cerr << "Error: " << type << " '" << resourceItem.GetName() << "' attribute name empty."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause(nodeAttr.c_str()).SetPosition(filePath)); return false; } if (!cJSON_IsString(nameNode)) { - cerr << "Error: " << type << " '" << resourceItem.GetName() << "' attribute name not string."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(string(nodeAttr + " name").c_str(), "string") + .SetPosition(filePath)); return false; } values.push_back(nameNode->valuestring); cJSON *valueNode = cJSON_GetObjectItem(arrayItem, TAG_VALUE.c_str()); if (!valueNode) { - cerr << "Error: " << type << " '" << resourceItem.GetName() << "' attribute '" << nameNode->valuestring; - cerr << "' value empty." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING) + .FormatCause(string(nodeAttr + " '" + nameNode->valuestring + "'").c_str()) + .SetPosition(filePath)); return false; } if (!cJSON_IsString(valueNode)) { - cerr << "Error: " << type << " '" << resourceItem.GetName() << "' attribute '" << nameNode->valuestring; - cerr << "' value not string." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(string(nodeAttr + " '" + nameNode->valuestring + "'").c_str(), "object") + .SetPosition(filePath)); return false; } values.push_back(valueNode->valuestring); @@ -518,20 +533,24 @@ bool JsonCompiler::ParseAttribute(const cJSON *arrayItem, const ResourceItem &re bool JsonCompiler::CheckPluralValue(const cJSON *arrayItem, const ResourceItem &resourceItem) const { + string filePath = resourceItem.GetFilePath(); if (!arrayItem || !cJSON_IsObject(arrayItem)) { - cerr << "Error: Plural '" << resourceItem.GetName() << "' array item not object."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(string(resourceItem.GetName() + " array item").c_str(), "object") + .SetPosition(filePath)); return false; } cJSON *quantityNode = cJSON_GetObjectItem(arrayItem, TAG_QUANTITY.c_str()); if (!quantityNode) { - cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity empty."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING) + .FormatCause(string(resourceItem.GetName() + " quantity").c_str()) + .SetPosition(filePath)); return false; } if (!cJSON_IsString(quantityNode)) { - cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity not string."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(string(resourceItem.GetName() + " quantity").c_str(), "string") + .SetPosition(filePath)); return false; } string quantityValue = quantityNode->valuestring; @@ -540,20 +559,23 @@ bool JsonCompiler::CheckPluralValue(const cJSON *arrayItem, const ResourceItem & for_each(QUANTITY_ATTRS.begin(), QUANTITY_ATTRS.end(), [&buffer](auto iter) { buffer.append(iter).append(" "); }); - cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity '" << quantityValue; - cerr << "' not in [" << buffer << "]." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_INVALID_QUANTITY) + .FormatCause(resourceItem.GetName().c_str(), quantityValue.c_str(), buffer.c_str()) + .SetPosition(filePath)); return false; } cJSON *valueNode = cJSON_GetObjectItem(arrayItem, TAG_VALUE.c_str()); if (!valueNode) { - cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity '" << quantityValue; - cerr << "' value empty." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING) + .FormatCause(string(resourceItem.GetName() + " '" + quantityValue + "' value").c_str()) + .SetPosition(filePath)); return false; } if (!cJSON_IsString(valueNode)) { - cerr << "Error: Plural '" << resourceItem.GetName() << "' quantity '" << quantityValue; - cerr << "' value not string." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(string(resourceItem.GetName() + " '" + quantityValue + "' value").c_str(), "string") + .SetPosition(filePath)); return false; } return true; diff --git a/src/overlap_binary_file_packer.cpp b/src/overlap_binary_file_packer.cpp index 34121ae..7dc0bd6 100644 --- a/src/overlap_binary_file_packer.cpp +++ b/src/overlap_binary_file_packer.cpp @@ -37,7 +37,6 @@ uint32_t OverlapBinaryFilePacker::CopyBinaryFile(const vector &inputs) BinaryFilePacker rawFilePacker(packageParser_, moduleName_); std::future copyFuture = rawFilePacker.CopyBinaryFileAsync(resource); if (copyFuture.get() != RESTOOL_SUCCESS) { - cerr << "Error: copy binary file failed." << endl; return RESTOOL_ERROR; } return RESTOOL_SUCCESS; @@ -47,7 +46,7 @@ bool OverlapBinaryFilePacker::IsDuplicated(const unique_ptr &entry, s { lock_guard lock(mutex_); if (!g_hapResourceSet.emplace(subPath).second || !g_resourceSet.emplace(subPath).second) { - cerr << "Warning: '" << entry->GetFilePath().GetPath() << "' is defined repeatedly in hap." << endl; + cout << "Warning: '" << entry->GetFilePath().GetPath() << "' is defined repeatedly in hap." << endl; return true; } return false; diff --git a/src/overlap_compiler.cpp b/src/overlap_compiler.cpp index 297bddf..0007f44 100644 --- a/src/overlap_compiler.cpp +++ b/src/overlap_compiler.cpp @@ -31,7 +31,7 @@ bool OverlapCompiler::IsIgnore(const FileInfo &fileInfo) lock_guard lock(mutex_); string output = GetOutputFilePath(fileInfo); if (!g_hapResourceSet.emplace(output).second || !g_resourceSet.emplace(output).second) { - cerr << "Warning: '" << fileInfo.filePath << "' is defined repeatedly." << endl; + cout << "Warning: '" << fileInfo.filePath << "' is defined repeatedly." << endl; return true; } return false; diff --git a/src/reference_parser.cpp b/src/reference_parser.cpp index 407fc96..fabdf01 100644 --- a/src/reference_parser.cpp +++ b/src/reference_parser.cpp @@ -92,12 +92,11 @@ uint32_t ReferenceParser::ParseRefInResourceItem(ResourceItem &resourceItem) con bool update = false; if (IsStringOfResourceItem(resType)) { if (resourceItem.GetData() == nullptr) { - cerr << "Error: parse ref in resource item failed, data is null." << endl; + PrintError(GetError(ERR_CODE_ITEM_DATA_NULL).FormatCause(resourceItem.GetName().c_str())); return RESTOOL_ERROR; } data = string(reinterpret_cast(resourceItem.GetData()), resourceItem.GetDataLength()); - if (!ParseRefString(data, update)) { - cerr << "Error: please check JSON file." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + if (!ParseRefString(data, update, resourceItem.GetFilePath())) { return RESTOOL_ERROR; } if (!update) { @@ -112,8 +111,8 @@ uint32_t ReferenceParser::ParseRefInResourceItem(ResourceItem &resourceItem) con } } if (update && !resourceItem.SetData(reinterpret_cast(data.c_str()), data.length())) { - cerr << "Error: set data fail. name = '" << resourceItem.GetName() << "' data = '" << data << "'."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_SET_DATA_ERROR).FormatCause(resourceItem.GetName().c_str()) + .SetPosition(resourceItem.GetFilePath())); return RESTOOL_ERROR; } return RESTOOL_SUCCESS; @@ -150,9 +149,9 @@ uint32_t ReferenceParser::ParseRefInJsonFile(ResourceItem &resourceItem, const s return RESTOOL_SUCCESS; } -uint32_t ReferenceParser::ParseRefInString(string &value, bool &update) const +uint32_t ReferenceParser::ParseRefInString(string &value, bool &update, const std::string &filePath) const { - if (ParseRefString(value, update)) { + if (ParseRefString(value, update, filePath)) { return RESTOOL_SUCCESS; } return RESTOOL_ERROR; @@ -164,12 +163,11 @@ bool ReferenceParser::ParseRefJson(const string &from, const string &to) return false; } if (!root_ || !cJSON_IsObject(root_)) { - cerr << "Error: JSON file parsing failed, please check the JSON file." << NEW_LINE_PATH << from << endl; + PrintError(GetError(ERR_CODE_JSON_FORMAT_ERROR).SetPosition(from)); return RESTOOL_ERROR; } bool needSave = false; - if (!ParseRefJsonImpl(root_, needSave)) { - cerr << "Error: please check JSON file." << NEW_LINE_PATH << from << endl; + if (!ParseRefJsonImpl(root_, needSave, from)) { return false; } @@ -190,21 +188,20 @@ bool ReferenceParser::ParseRefJson(const string &from, const string &to) bool ReferenceParser::ParseRefResourceItemData(const ResourceItem &resourceItem, string &data, bool &update) const { if (resourceItem.GetData() == nullptr) { - cerr << "Error: parse ref resource item data failed, data is null." << endl; + PrintError(GetError(ERR_CODE_ITEM_DATA_NULL).FormatCause(resourceItem.GetName().c_str())); return false; } data = string(reinterpret_cast(resourceItem.GetData()), resourceItem.GetDataLength()); vector contents = ResourceUtil::DecomposeStrings(data); if (contents.empty()) { - cerr << "Error: DecomposeStrings fail. name = '" << resourceItem.GetName() << "' data = '" << data << "'."; - cerr << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_ARRAY_DECOMPOSE_ERROR).FormatCause(resourceItem.GetName().c_str(), data.c_str()) + .SetPosition(resourceItem.GetFilePath())); return false; } for (auto &content : contents) { bool flag = false; - if (!ParseRefString(content, flag)) { - cerr << "Error: please check JSON file." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + if (!ParseRefString(content, flag, resourceItem.GetFilePath())) { return false; } update = (update || flag); @@ -216,8 +213,8 @@ bool ReferenceParser::ParseRefResourceItemData(const ResourceItem &resourceItem, data = ResourceUtil::ComposeStrings(contents); if (data.empty()) { - cerr << "Error: ComposeStrings fail. name = '" << resourceItem.GetName(); - cerr << "' contents size is " << contents.size() << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; + PrintError(GetError(ERR_CODE_ARRAY_COMPOSE_ERROR).FormatCause(resourceItem.GetName().c_str(), contents.size()) + .SetPosition(resourceItem.GetFilePath())); return false; } return true; @@ -278,20 +275,21 @@ bool ReferenceParser::ParseRefString(string &key) const return ParseRefString(key, update); } -bool ReferenceParser::ParseRefString(std::string &key, bool &update) const +bool ReferenceParser::ParseRefString(std::string &key, bool &update, const std::string &filePath) const { update = false; if (regex_match(key, regex("^\\$ohos:[a-z]+:.+"))) { update = true; - return ParseRefImpl(key, ID_OHOS_REFS, true); + return ParseRefImpl(key, ID_OHOS_REFS, true, filePath); } else if (regex_match(key, regex("^\\$[a-z]+:.+"))) { update = true; - return ParseRefImpl(key, ID_REFS, false); + return ParseRefImpl(key, ID_REFS, false, filePath); } return true; } -bool ReferenceParser::ParseRefImpl(string &key, const map &refs, bool isSystem) const +bool ReferenceParser::ParseRefImpl(string &key, const map &refs, bool isSystem, + const std::string &filePath) const { for (const auto &ref : refs) { smatch result; @@ -306,7 +304,7 @@ bool ReferenceParser::ParseRefImpl(string &key, const map &refs id = idWorker_.GetSystemId(ref.second, name); } if (id < 0) { - cerr << "Error: ref '" << key << "' don't be defined." << endl; + PrintError(GetError(ERR_CODE_REF_NOT_DEFINED).FormatCause(key.c_str()).SetPosition(filePath)); return false; } @@ -317,22 +315,26 @@ bool ReferenceParser::ParseRefImpl(string &key, const map &refs return true; } } - cerr << "Error: reference '" << key << "' invalid." << endl; + string refer; + for (const auto &ref:refs) { + refer.append(ref.first).append(" "); + } + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_REF).FormatCause(key.c_str(), refer.c_str()).SetPosition(filePath)); return false; } -bool ReferenceParser::ParseRefJsonImpl(cJSON *node, bool &needSave) const +bool ReferenceParser::ParseRefJsonImpl(cJSON *node, bool &needSave, const std::string &filePath) const { if (cJSON_IsObject(node) || cJSON_IsArray(node)) { for (cJSON *item = node->child; item; item = item->next) { - if (!ParseRefJsonImpl(item, needSave)) { + if (!ParseRefJsonImpl(item, needSave, filePath)) { return false; } } } else if (cJSON_IsString(node)) { string value = node->valuestring; bool update = false; - if (!ParseRefString(value, update)) { + if (!ParseRefString(value, update, filePath)) { return false; } if (update) { diff --git a/src/resconfig_parser.cpp b/src/resconfig_parser.cpp index 60ae763..017f334 100644 --- a/src/resconfig_parser.cpp +++ b/src/resconfig_parser.cpp @@ -34,7 +34,7 @@ uint32_t ResConfigParser::Init(const string &filePath, HandleBack callback) return RESTOOL_ERROR; } if (!root_ || !cJSON_IsObject(root_)) { - cerr << "Error: JSON file parsing failed, please check the JSON file." << NEW_LINE_PATH << filePath << endl; + PrintError(GetError(ERR_CODE_JSON_FORMAT_ERROR).SetPosition(filePath)); return RESTOOL_ERROR; } if (!callback) { @@ -99,7 +99,7 @@ void ResConfigParser::InitFileListCommand(HandleBack callback) uint32_t ResConfigParser::GetString(const cJSON *node, int c, HandleBack callback) { if (!node || !cJSON_IsString(node)) { - cerr << "Error: GetString node not string. Option = " << c << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(node->string, "string")); return RESTOOL_ERROR; } @@ -112,12 +112,13 @@ uint32_t ResConfigParser::GetString(const cJSON *node, int c, HandleBack callbac uint32_t ResConfigParser::GetArray(const cJSON *node, int c, HandleBack callback) { if (!node || !cJSON_IsArray(node)) { - cerr << "Error: GetArray node not array. Option = " << c << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(node->string, "array")); return RESTOOL_ERROR; } for (cJSON *item = node->child; item; item = item->next) { if (!cJSON_IsString(item)) { + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(item->string, "string")); return RESTOOL_ERROR; } if (callback(c, item->valuestring) != RESTOOL_SUCCESS) { @@ -130,7 +131,7 @@ uint32_t ResConfigParser::GetArray(const cJSON *node, int c, HandleBack callback uint32_t ResConfigParser::GetModuleNames(const cJSON *node, int c, HandleBack callback) { if (!node) { - cerr << "Error: GetModuleNames node is null. Option = " << c << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISSING).FormatCause(node->string)); return RESTOOL_ERROR; } if (cJSON_IsString(node)) { @@ -156,7 +157,7 @@ uint32_t ResConfigParser::GetModuleNames(const cJSON *node, int c, HandleBack ca uint32_t ResConfigParser::GetBool(const cJSON *node, int c, HandleBack callback) { if (!node || !cJSON_IsBool(node)) { - cerr << "Error: GetBool node not bool. Option = " << c << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(node->string, "bool")); return RESTOOL_ERROR; } @@ -169,7 +170,7 @@ uint32_t ResConfigParser::GetBool(const cJSON *node, int c, HandleBack callback) uint32_t ResConfigParser::GetNumber(const cJSON *node, int c, HandleBack callback) { if (!node || !cJSON_IsNumber(node)) { - cerr << "Error: GetNumber node not number. Option = " << c << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(node->string, "number")); return RESTOOL_ERROR; } diff --git a/src/resource_append.cpp b/src/resource_append.cpp index d212e19..6eb2d76 100644 --- a/src/resource_append.cpp +++ b/src/resource_append.cpp @@ -86,7 +86,7 @@ bool ResourceAppend::Combine(const string &folderPath) itemsForModule_.clear(); for (const auto &child : entry.GetChilds()) { if (!child->IsFile()) { - cerr << "Error:" << child->GetFilePath().GetPath() << " not file" << endl; + PrintError(GetError(ERR_CODE_RESOURCE_PATH_NOT_FILE).FormatCause(child->GetFilePath().GetPath().c_str())); return false; } if (child->GetFilePath().GetFilename() == ID_DEFINED_FILE) { @@ -119,7 +119,7 @@ bool ResourceAppend::ScanResources(const string &resourcePath, const string &out if (!ResourceUtil::FileExist(resourcePath)) { string filePath = FileEntry::FilePath(outputPath).Append(ResourceUtil::GenerateHash(resourcePath)).GetPath(); if (remove(filePath.c_str()) != 0) { - cerr << "Error: remove failed '" << filePath << "', reason: " << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_REMOVE_FILE_ERROR).FormatCause(filePath.c_str(), strerror(errno))); return false; } return true; @@ -176,7 +176,7 @@ bool ResourceAppend::ScanSubLimitkeyResources(const FileEntry entry, const strin } if (child->IsFile()) { - cerr << "Error: " << child->GetFilePath().GetPath() << " not directory" << endl; + PrintError(GetError(ERR_CODE_RESOURCE_PATH_NOT_DIR).FormatCause(child->GetFilePath().GetPath().c_str())); return false; } @@ -205,8 +205,8 @@ bool ResourceAppend::ScanLimitKey(const unique_ptr &entry, { vector keyParams; if (!KeyParser::Parse(limitKey, keyParams)) { - cerr << "Error: invalid limit key '" << limitKey << "'."; - cerr << NEW_LINE_PATH << entry->GetFilePath().GetPath() << endl; + PrintError(GetError(ERR_CODE_INVALID_LIMIT_KEY).FormatCause(limitKey.c_str()) + .SetPosition(entry->GetFilePath().GetPath().c_str())); return false; } @@ -217,13 +217,15 @@ bool ResourceAppend::ScanLimitKey(const unique_ptr &entry, } if (child->IsFile()) { - cerr << "Error: " << child->GetFilePath().GetPath() << " not directory" << endl; + PrintError(GetError(ERR_CODE_RESOURCE_PATH_NOT_DIR).FormatCause(child->GetFilePath().GetPath().c_str())); return false; } ResType resType = ResourceUtil::GetResTypeByDir(fileCuster); if (resType == ResType::INVALID_RES_TYPE) { - cerr << "Error: invalid resType." << NEW_LINE_PATH << child->GetFilePath().GetPath() << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_DIR) + .FormatCause(fileCuster.c_str(), ResourceUtil::GetAllResTypeDirs().c_str()) + .SetPosition(child->GetFilePath().GetPath().c_str())); return false; } @@ -246,7 +248,7 @@ bool ResourceAppend::ScanFiles(const unique_ptr &entry, } if (!child->IsFile()) { - cerr << "Error: '" << child->GetFilePath().GetPath() << "' not file." << endl; + PrintError(GetError(ERR_CODE_RESOURCE_PATH_NOT_FILE).FormatCause(child->GetFilePath().GetPath().c_str())); return false; } @@ -308,14 +310,16 @@ bool ResourceAppend::ScanSingleFile(const string &filePath, const string &output string fileCuster = path.GetParent().GetFilename(); ResType resType = ResourceUtil::GetResTypeByDir(fileCuster); if (resType == ResType::INVALID_RES_TYPE) { - cerr << "Error: invalid resType." << NEW_LINE_PATH << filePath << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_DIR) + .FormatCause(fileCuster.c_str(), ResourceUtil::GetAllResTypeDirs().c_str()) + .SetPosition(filePath)); return false; } string limitKey = path.GetParent().GetParent().GetFilename(); vector keyParams; if (!KeyParser::Parse(limitKey, keyParams)) { - cerr << "Error: invalid limit key." << NEW_LINE_PATH << filePath << endl; + PrintError(GetError(ERR_CODE_INVALID_LIMIT_KEY).FormatCause(limitKey.c_str()).SetPosition(filePath)); return false; } @@ -333,13 +337,15 @@ bool ResourceAppend::WriteFileInner(ostringstream &outStream, const string &outp HANDLE hWriteFile = CreateFile(outputPath.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (hWriteFile == INVALID_HANDLE_VALUE) { - cerr << "Error: '" << outputPath << "' " << GetLastError() << endl; + PrintError(GetError(ERR_CODE_CREATE_FILE_ERROR) + .FormatCause(outputPath.c_str(), to_string(GetLastError()).c_str())); return false; } DWORD writeBytes; if (!WriteFile(hWriteFile, outStream.str().c_str(), outStream.tellp(), &writeBytes, nullptr)) { - cerr << "Error: write '" << outputPath << "' " << GetLastError() << endl; + PrintError(GetError(ERR_CODE_OPEN_FILE_ERROR) + .FormatCause(outputPath.c_str(), to_string(GetLastError()).c_str())); CloseHandle(hWriteFile); return false; } @@ -347,7 +353,7 @@ bool ResourceAppend::WriteFileInner(ostringstream &outStream, const string &outp #else ofstream out(outputPath, ofstream::out | ofstream::binary); if (!out.is_open()) { - cerr << "Error: open failed '" << outputPath << "', reason: " << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_OPEN_FILE_ERROR).FormatCause(outputPath.c_str(), strerror(errno))); return false; } out << outStream.str(); @@ -392,7 +398,7 @@ bool ResourceAppend::LoadResourceItem(const string &filePath) #else ifstream in(filePath, ifstream::in | ifstream::binary); if (!in.is_open()) { - cerr << "Error: open failed '" << filePath << "', reason: " << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_OPEN_FILE_ERROR).FormatCause(filePath.c_str(), strerror(errno))); return false; } @@ -400,7 +406,7 @@ bool ResourceAppend::LoadResourceItem(const string &filePath) int32_t length = in.tellg(); in.seekg(0, in.beg); if (length <= 0) { - cerr << "Error: invalid file size = " << length << NEW_LINE_PATH << filePath << endl; + PrintError(GetError(ERR_CODE_FILE_EMPTY).FormatCause(filePath.c_str())); return false; } char buffer[length]; @@ -440,7 +446,7 @@ bool ResourceAppend::WriteRawFilesOrResFiles(const string &filePath, const strin { string::size_type pos = filePath.find(limit); if (pos == string::npos) { - cerr << "Error: invalid file path." << NEW_LINE_PATH << filePath << endl; + PrintError(GetError(ERR_CODE_INVALID_FILE_PATH).FormatCause(filePath.c_str())); return false; } @@ -471,6 +477,9 @@ bool ResourceAppend::Push(const shared_ptr &resourceItem) string idName = ResourceUtil::GetIdName(resourceItem->GetName(), resourceItem->GetResType()); int64_t id = IdWorker::GetInstance().GenerateId(resourceItem->GetResType(), idName); if (id < 0) { + PrintError(GetError(ERR_CODE_RESOURCE_ID_NOT_DEFINED) + .FormatCause(ResourceUtil::ResTypeToString(resourceItem->GetResType()).c_str(), + resourceItem->GetName().c_str())); return false; } @@ -628,9 +637,9 @@ bool ResourceAppend::CheckModuleResourceItem(const shared_ptr &res }); if (ret != result->second.end()) { - cerr << "Error: '" << resourceItem->GetName() << "' conflict, first declared."; - cerr << NEW_LINE_PATH << (*ret)->GetFilePath() << endl; - cerr << "but declared again." << NEW_LINE_PATH << resourceItem->GetFilePath() << endl; + PrintError(GetError(ERR_CODE_RESOURCE_DUPLICATE) + .FormatCause(resourceItem->GetName().c_str(), (*ret)->GetFilePath().c_str(), + resourceItem->GetFilePath().c_str())); return false; } @@ -645,21 +654,24 @@ bool ResourceAppend::LoadResourceItemWin(const string &filePath) HANDLE hReadFile = CreateFile(filePath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS, nullptr); if (hReadFile == INVALID_HANDLE_VALUE) { - cerr << "Error: "<< GetLastError() << NEW_LINE_PATH << filePath << endl; + PrintError(GetError(ERR_CODE_CREATE_FILE_ERROR) + .FormatCause(filePath.c_str(), to_string(GetLastError()).c_str()).SetPosition(filePath)); return result; } DWORD fileSize = GetFileSize(hReadFile, nullptr); HANDLE hFileMap = CreateFileMapping(hReadFile, nullptr, PAGE_READONLY, 0, fileSize, nullptr); if (hFileMap == INVALID_HANDLE_VALUE) { - cerr << "Error: create file mapping " << GetLastError() << endl; + string errMsg = "create mapping error: " + to_string(GetLastError()); + PrintError(GetError(ERR_CODE_FILE_MAP_ERROR).FormatCause(errMsg.c_str()).SetPosition(filePath)); CloseHandle(hReadFile); return result; } void* pBuffer = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0); if (pBuffer == nullptr) { - cerr << "Error: map view of file " << GetLastError() << endl; + string errMsg = "map view of file error: " + to_string(GetLastError()); + PrintError(GetError(ERR_CODE_FILE_MAP_ERROR).FormatCause(errMsg.c_str()).SetPosition(filePath)); CloseHandle(hReadFile); return result; } diff --git a/src/resource_check.cpp b/src/resource_check.cpp index da84785..9312ab4 100755 --- a/src/resource_check.cpp +++ b/src/resource_check.cpp @@ -72,7 +72,7 @@ void ResourceCheck::CheckNodeInResourceItem(const string &key, const ResourceIte return; } if (width != height) { - cerr << "Warning: the png width and height not equal" << NEW_LINE_PATH << filePath << endl; + cout << "Warning: the png width and height not equal" << NEW_LINE_PATH << filePath << endl; return; } auto result = g_keyNodeIndexs.find(key); @@ -83,7 +83,7 @@ void ResourceCheck::CheckNodeInResourceItem(const string &key, const ResourceIte if (normalSize != 0 && width > normalSize) { string warningMsg = "Warning: The width or height of the png file referenced by the " + key + \ " exceeds the limit (" + to_string(normalSize) + " pixels)" + NEW_LINE_PATH + filePath; - cerr << warningMsg << endl; + cout << warningMsg << endl; } } diff --git a/src/resource_directory.cpp b/src/resource_directory.cpp index fc985a9..c646273 100644 --- a/src/resource_directory.cpp +++ b/src/resource_directory.cpp @@ -14,9 +14,12 @@ */ #include "resource_directory.h" + #include + #include "file_entry.h" #include "resource_util.h" +#include "restool_errors.h" #include "select_compile_parse.h" namespace OHOS { @@ -37,7 +40,7 @@ bool ResourceDirectory::ScanResources(const string &resourcesDir, functionIsFile()) { - cerr << "Error: '" << it->GetFilePath().GetPath() << "' not directory." << endl; + PrintError(GetError(ERR_CODE_RESOURCE_PATH_NOT_DIR).FormatCause(it->GetFilePath().GetPath().c_str())); return false; } @@ -58,7 +61,7 @@ bool ResourceDirectory::ScanResourceLimitKeyDir(const string &resourceTypeDir, c { vector keyParams; if (!KeyParser::Parse(limitKey, keyParams)) { - cerr << "Error: invalid limit key '" << limitKey << "'." << NEW_LINE_PATH << resourceTypeDir << endl; + PrintError(GetError(ERR_CODE_INVALID_LIMIT_KEY).FormatCause(limitKey.c_str()).SetPosition(resourceTypeDir)); return false; } if (!SelectCompileParse::IsSelectCompile(keyParams)) { @@ -76,19 +79,19 @@ bool ResourceDirectory::ScanResourceLimitKeyDir(const string &resourceTypeDir, c } if (it->IsFile()) { - cerr << "Error: '" << dirPath << "' not directory." << endl; + PrintError(GetError(ERR_CODE_RESOURCE_PATH_NOT_DIR).FormatCause(dirPath.c_str())); return false; } ResType type = ResourceUtil::GetResTypeByDir(fileCluster); if (type == ResType::INVALID_RES_TYPE) { - string array("[ "); + string array; for (auto item : g_fileClusterMap) { array.append("'" + item.first + "' "); } - array.append("]"); - cerr << "Error: '" << dirPath << "', invalid directory name '"; - cerr << fileCluster << "', must in " << array << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_DIR) + .FormatCause(fileCluster.c_str(), ResourceUtil::GetAllResTypeDirs().c_str()) + .SetPosition(dirPath)); return false; } DirectoryInfo info = { limitKey, fileCluster, dirPath, keyParams, type }; diff --git a/src/resource_dumper.cpp b/src/resource_dumper.cpp index 7652bd2..02321c9 100644 --- a/src/resource_dumper.cpp +++ b/src/resource_dumper.cpp @@ -57,7 +57,7 @@ uint32_t ResourceDumper::LoadHap() { unzFile zipFile = unzOpen64(inputPath_.c_str()); if (!zipFile) { - std::cerr << "Error: Open file is failed. filename: " << inputPath_ << std::endl; + PrintError(GetError(ERR_CODE_PARSE_HAP_ERROR).FormatCause("can't unzip hap").SetPosition(inputPath_)); return RESTOOL_ERROR; } std::unique_ptr buffer; @@ -108,31 +108,40 @@ uint32_t ResourceDumper::ReadFileFromZip( { unz_file_info fileInfo; if (unzLocateFile2(zipFile, fileName, 1) != UNZ_OK) { - std::cerr << "Error: Not found filename: " << fileName << " in " << inputPath_ << std::endl; + std::string msg; + msg.append("file not found: ").append(fileName); + PrintError(GetError(ERR_CODE_PARSE_HAP_ERROR).FormatCause(msg.c_str()).SetPosition(inputPath_)); return RESTOOL_ERROR; } char filenameInZip[256]; int err = unzGetCurrentFileInfo(zipFile, &fileInfo, filenameInZip, sizeof(filenameInZip), nullptr, 0, nullptr, 0); if (err != UNZ_OK) { - std::cerr << "Error: Get file info error. filename: " << fileName << " errorCode: " << err << std::endl; + std::string msg; + msg.append("get file info error: ").append(std::to_string(err)); + msg.append(", filename: ").append(fileName); + PrintError(GetError(ERR_CODE_PARSE_HAP_ERROR).FormatCause(msg.c_str()).SetPosition(inputPath_)); return RESTOOL_ERROR; } len = fileInfo.compressed_size; buffer = std::make_unique(len); if (!buffer) { - std::cerr << "Error: Allocating memory failed for buffer in ReadFileFromZip."<< std::endl; + PrintError(GetError(ERR_CODE_PARSE_HAP_ERROR).FormatCause("allocating memory failed")); return RESTOOL_ERROR; } err = unzOpenCurrentFilePassword(zipFile, nullptr); if (err != UNZ_OK) { - std::cerr << "Error: in unzOpenCurrentFilePassword. ErrorCode: " << err <> root(cJSON_CreateObject(), [](cJSON* node) { cJSON_Delete(node); }); if (!root) { - std::cerr << "Error: failed to create cJSON object for root object." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("unable to create cJSON object for root object")); return RESTOOL_ERROR; } if (!bundleName_.empty() && !moduleName_.empty()) { @@ -158,7 +167,8 @@ uint32_t CommonDumper::DumpRes(std::string &out) const } cJSON *resource = cJSON_CreateArray(); if (!resource) { - std::cerr << "Error: failed to create cJSON object for resource array." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR) + .FormatCause("unable to create cJSON object for resource array")); return RESTOOL_ERROR; } cJSON_AddItemToObject(root.get(), "resource", resource); @@ -169,7 +179,7 @@ uint32_t CommonDumper::DumpRes(std::string &out) const } char *rawStr = cJSON_Print(root.get()); if (!rawStr) { - std::cerr << "Error: covert json object to str failed" << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("covert json object to str failed")); return RESTOOL_ERROR; } out = rawStr; @@ -181,14 +191,14 @@ uint32_t CommonDumper::DumpRes(std::string &out) const uint32_t CommonDumper::AddKeyParamsToJson(const std::vector &keyParams, cJSON *json) const { if (!json) { - std::cerr << "Error: Add keyParam to null json object." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("add keyparam to null json object")); return RESTOOL_ERROR; } for (const auto &keyParam : keyParams) { std::string valueStr = ResourceUtil::GetKeyParamValue(keyParam); cJSON *value = cJSON_CreateString(valueStr.c_str()); if (!value) { - std::cerr << "Error: failed to create cJSON object for keyparam." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("unable to create cJSON object for keyparam")); return RESTOOL_ERROR; } cJSON_AddItemToObject(json, ResourceUtil::KeyTypeToStr(keyParam.keyType).c_str(), value); @@ -199,26 +209,26 @@ uint32_t CommonDumper::AddKeyParamsToJson(const std::vector &keyParams uint32_t CommonDumper::AddItemCommonPropToJson(int32_t resId, const ResourceItem &item, cJSON* json) const { if (!json) { - std::cerr << "Error: add item common property to null json object." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("add item common property to null json object")); return RESTOOL_ERROR; } cJSON *id = cJSON_CreateNumber(resId); if (!id) { - std::cerr << "Error: failed to create cJSON object for resource id." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("unable to create cJSON object for resource id")); return RESTOOL_ERROR; } cJSON_AddItemToObject(json, "id", id); cJSON *name = cJSON_CreateString(item.GetName().c_str()); if (!name) { - std::cerr << "Error: failed to create cJSON object for resource name." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("unable to create cJSON object for resource name")); return RESTOOL_ERROR; } cJSON_AddItemToObject(json, "name", name); cJSON *type = cJSON_CreateString((ResourceUtil::ResTypeToString(item.GetResType())).c_str()); if (!type) { - std::cerr << "Error: failed to create cJSON object for resource type." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("unable to create cJSON object for resource type")); return RESTOOL_ERROR; } cJSON_AddItemToObject(json, "type", type); @@ -228,16 +238,16 @@ uint32_t CommonDumper::AddItemCommonPropToJson(int32_t resId, const ResourceItem uint32_t CommonDumper::AddResourceToJson(int64_t resId, const std::vector &items, cJSON *json) const { if (items.empty()) { - std::cerr << "Error: reourceItem is empty." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("resource items is empty")); return RESTOOL_ERROR; } if (!json) { - std::cerr << "Error: add Resource to null json object." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("add resource to null json object")); return RESTOOL_ERROR; } cJSON *resource = cJSON_CreateObject(); if (!resource) { - std::cerr << "Error: failed to create cJSON object for resource item." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("unable to create cJSON object for resource item")); return RESTOOL_ERROR; } cJSON_AddItemToArray(json, resource); @@ -246,14 +256,16 @@ uint32_t CommonDumper::AddResourceToJson(int64_t resId, const std::vector(item.GetData()), item.GetDataLength()); cJSON *value = cJSON_CreateString(rawValue.c_str()); if (!value) { - std::cerr << "Error: failed to create cJSON object for value." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("unable to create cJSON object for value")); return RESTOOL_ERROR; } cJSON_AddItemToObject(json, "value", value); @@ -351,12 +367,12 @@ uint32_t ConfigDumper::DumpRes(std::string &out) const std::unique_ptr> root(cJSON_CreateObject(), [](cJSON* node) { cJSON_Delete(node); }); if (!root) { - std::cerr << "Error: failed to create cJSON object for root object." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("unable to create cJSON object for root object")); return RESTOOL_ERROR; } cJSON *configs = cJSON_CreateArray(); if (!configs) { - std::cerr << "Error: failed to create cJSON object for config array." << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("unable to create cJSON object for config array")); return RESTOOL_ERROR; } cJSON_AddItemToObject(root.get(), "config", configs); @@ -371,7 +387,8 @@ uint32_t ConfigDumper::DumpRes(std::string &out) const configSet.emplace(limitKey); cJSON *config = cJSON_CreateString(limitKey.c_str()); if (!config) { - std::cerr << "Error: failed to create cJSON object for limitkey." << std::endl; + PrintError( + GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("unable to create cJSON object for limitkey")); return RESTOOL_ERROR; } cJSON_AddItemToArray(configs, config); @@ -379,7 +396,7 @@ uint32_t ConfigDumper::DumpRes(std::string &out) const } char *rawStr = cJSON_Print(root.get()); if (!rawStr) { - std::cerr << "Error: covert config json object to str failed" << std::endl; + PrintError(GetError(ERR_CODE_CREATE_JSON_ERROR).FormatCause("covert config json object to str failed")); return RESTOOL_ERROR; } out = rawStr; diff --git a/src/resource_module.cpp b/src/resource_module.cpp index 9f2b257..89202b2 100644 --- a/src/resource_module.cpp +++ b/src/resource_module.cpp @@ -96,9 +96,9 @@ uint32_t ResourceModule::MergeResourceItem(map> &a continue; } if (tipError) { - cerr << "Error: '"<< resourceItem.GetName() <<"' conflict, first declared."; - cerr << NEW_LINE_PATH << ret->GetFilePath() << endl; - cerr << "but declared again." <GetFilePath().c_str(), + resourceItem.GetFilePath().c_str())); return RESTOOL_ERROR; } cout << "Warning: '"<< resourceItem.GetName() <<"' conflict, first declared."; diff --git a/src/resource_overlap.cpp b/src/resource_overlap.cpp index a220f6c..9dc1e3a 100644 --- a/src/resource_overlap.cpp +++ b/src/resource_overlap.cpp @@ -34,13 +34,11 @@ uint32_t ResourceOverlap::Pack() cout << "Info: Pack: overlap pack mode" << endl; if (InitResourcePack() != RESTOOL_SUCCESS) { - cerr << "Error: ResourcePack init failed." << endl; return RESTOOL_ERROR; } ResourceMerge resourceMerge; if (resourceMerge.Init(packageParser_) != RESTOOL_SUCCESS) { - cerr << "Error: resourceMerge init failed." << endl; return RESTOOL_ERROR; } @@ -49,18 +47,15 @@ uint32_t ResourceOverlap::Pack() if (LoadHapResources() != RESTOOL_SUCCESS) { rawFilePacker.StopCopy(); - cerr << "Error: load hap resources failed." << endl; return RESTOOL_ERROR; } if (PackResources(resourceMerge) != RESTOOL_SUCCESS) { rawFilePacker.StopCopy(); - cerr << "Error: pack resources failed." << endl; return RESTOOL_ERROR; } if (copyFuture.get() != RESTOOL_SUCCESS) { - cerr << "Error: copy binary file failed." << endl; return RESTOOL_ERROR; } return RESTOOL_SUCCESS; @@ -72,14 +67,12 @@ uint32_t ResourceOverlap::ScanResources(const std::vector &inputs, fileManager.SetModuleName(moduleName_); vector hapResInput{inputs[0]}; if (fileManager.ScanModules(hapResInput, output, configJson_.IsHar()) != RESTOOL_SUCCESS) { - cerr << "Error: scan hap error" << endl; return RESTOOL_ERROR; } fileManager.SetScanHap(false); vector resInputs(inputs.begin() + 1, inputs.end()); if (fileManager.ScanModules(resInputs, output, configJson_.IsHar()) != RESTOOL_SUCCESS) { - cerr << "Error: scan resources error" << endl; return RESTOOL_ERROR; } return RESTOOL_SUCCESS; diff --git a/src/resource_pack.cpp b/src/resource_pack.cpp index 92a4716..e835a2c 100644 --- a/src/resource_pack.cpp +++ b/src/resource_pack.cpp @@ -121,7 +121,7 @@ uint32_t ResourcePack::InitModule() for_each(moduleNames.begin(), moduleNames.end(), [&buffer](const auto &iter) { buffer.append(" " + iter + " "); }); - cerr << "Error: module name '" << moduleName_ << "' not in [" << buffer << "]" << endl; + PrintError(GetError(ERR_CODE_MODULE_NAME_NOT_FOUND).FormatCause(moduleName_.c_str(), buffer.c_str())); return RESTOOL_ERROR; } @@ -150,7 +150,7 @@ uint32_t ResourcePack::InitOutput() const string resourcesPath = FileEntry::FilePath(output).Append(RESOURCES_DIR).GetPath(); if (ResourceUtil::FileExist(resourcesPath)) { if (!forceWrite) { - cerr << "Error: output path exists." << NEW_LINE_PATH << resourcesPath << endl; + PrintError(GetError(ERR_CODE_OUTPUT_EXIST).SetPosition(resourcesPath)); return RESTOOL_ERROR; } @@ -185,7 +185,7 @@ uint32_t ResourcePack::InitConfigJson() string config = packageParser_.GetConfig(); if (config.empty()) { if (packageParser_.GetInputs().size() > 1) { - cerr << "Error: more input path, -j config.json empty" << endl; + PrintError(ERR_CODE_CONFIG_JSON_MISSING); return RESTOOL_ERROR; } config = ResourceUtil::GetMainPath(packageParser_.GetInputs()[0]).Append(CONFIG_JSON).GetPath(); @@ -301,13 +301,11 @@ uint32_t ResourcePack::Pack() cout << "Info: Pack: normal pack mode" << endl; if (InitResourcePack() != RESTOOL_SUCCESS) { - cerr << "Error: ResourcePack init failed." << endl; return RESTOOL_ERROR; } ResourceMerge resourceMerge; if (resourceMerge.Init(packageParser_) != RESTOOL_SUCCESS) { - cerr << "Error: resourceMerge init failed." << endl; return RESTOOL_ERROR; } @@ -316,12 +314,10 @@ uint32_t ResourcePack::Pack() if (PackResources(resourceMerge) != RESTOOL_SUCCESS) { rawFilePacker.StopCopy(); - cerr << "Error: pack resources failed." << endl; return RESTOOL_ERROR; } if (copyFuture.get() != RESTOOL_SUCCESS) { - cerr << "Error: copy binary file failed." << endl; return RESTOOL_ERROR; } return RESTOOL_SUCCESS; @@ -376,27 +372,24 @@ uint32_t ResourcePack::HandleFeature() ConfigParser entryJson(jsonFile); entryJson.SetDependEntry(true); if (entryJson.Init() != RESTOOL_SUCCESS) { - cerr << "Error: config json invalid." << NEW_LINE_PATH << jsonFile << endl; return RESTOOL_ERROR; } int64_t labelId = entryJson.GetAbilityLabelId(); int64_t iconId = entryJson.GetAbilityIconId(); if (labelId <= 0 || iconId <= 0) { - cerr << "Error: Entry MainAbility must have 'icon' and 'label'." << endl; + PrintError(ERR_CODE_FA_ENTRY_NO_ICON_LABEL); return RESTOOL_ERROR; } string path = FileEntry::FilePath(featureDependEntry).Append(RESOURCE_INDEX_FILE).GetPath(); map> resInfoLocal; ResourceTable resourceTable; if (resourceTable.LoadResTable(path, resInfoLocal) != RESTOOL_SUCCESS) { - cerr << "Error: LoadResTable fail." << endl; return RESTOOL_ERROR; } jsonFile = FileEntry::FilePath(output).Append(CONFIG_JSON).GetPath(); ConfigParser config(jsonFile); if (config.Init() != RESTOOL_SUCCESS) { - cerr << "Error: config json invalid." << NEW_LINE_PATH << jsonFile << endl; return RESTOOL_ERROR; } vector items; @@ -422,13 +415,13 @@ uint32_t ResourcePack::FindResourceItems(const map { auto ret = resInfoLocal.find(id); if (ret == resInfoLocal.end()) { - cerr << "Error: FindResourceItems don't found '" << id << "'." << endl; + PrintError(GetError(ERR_CODE_RESOURCE_INDEX_ID_NOT_FOUND).FormatCause(id)); return RESTOOL_ERROR; } ResType type = ResType::INVALID_RES_TYPE; items = ret->second; if (items.empty()) { - cerr << "Error: FindResourceItems resource item empty '" << id << "'." << endl; + PrintError(GetError(ERR_CODE_RESOURCE_INDEX_ITEM_EMPTY).FormatCause(id)); return RESTOOL_ERROR; } for (auto &it : items) { @@ -436,8 +429,9 @@ uint32_t ResourcePack::FindResourceItems(const map type = it.GetResType(); } if (type != it.GetResType()) { - cerr << "Error: FindResourceItems invalid restype '" << ResourceUtil::ResTypeToString(type); - cerr << "' vs '" << ResourceUtil::ResTypeToString(it.GetResType()) << "'." << endl; + string typePre = ResourceUtil::ResTypeToString(type); + string typeCur = ResourceUtil::ResTypeToString(it.GetResType()); + PrintError(GetError(ERR_CODE_RESOURCE_INDEX_INVALID_RESTYPE).FormatCause(typeCur.c_str(), typePre.c_str())); return RESTOOL_ERROR; } } @@ -450,8 +444,9 @@ uint32_t ResourcePack::HandleLabel(vector &items, ConfigParser &co string idName; for (auto it : items) { if (it.GetResType() != ResType::STRING) { - cerr << "Error: HandleLabel invalid restype '"; - cerr << ResourceUtil::ResTypeToString(it.GetResType()) << "'." << endl; + PrintError(GetError(ERR_CODE_RESOURCE_INDEX_INVALID_RESTYPE) + .FormatCause(ResourceUtil::ResTypeToString(it.GetResType()).c_str(), + ResourceUtil::ResTypeToString(ResType::STRING).c_str())); return RESTOOL_ERROR; } idName = it.GetName() + "_entry"; @@ -486,11 +481,9 @@ bool ResourcePack::CopyIcon(string &dataPath, const string &idName, string &file string dstDir = FileEntry::FilePath(output).Append(dataPath).GetParent().GetPath(); string dst = FileEntry::FilePath(dstDir).Append(fileName).GetPath(); if (!ResourceUtil::CreateDirs(dstDir)) { - cerr << "Error: Create Dirs fail '" << dstDir << "'."<< endl; return false; } if (!ResourceUtil::CopyFileInner(source, dst)) { - cerr << "Error: copy file fail from '" << source << "' to '" << dst << "'." << endl; return false; } return true; @@ -502,14 +495,15 @@ uint32_t ResourcePack::HandleIcon(vector &items, ConfigParser &con string idName; for (auto it : items) { if (it.GetResType() != ResType::MEDIA) { - cerr << "Error: HandleLabel invalid restype '"; - cerr << ResourceUtil::ResTypeToString(it.GetResType()) << "'." << endl; + PrintError(GetError(ERR_CODE_RESOURCE_INDEX_INVALID_RESTYPE) + .FormatCause(ResourceUtil::ResTypeToString(it.GetResType()).c_str(), + ResourceUtil::ResTypeToString(ResType::MEDIA).c_str())); return RESTOOL_ERROR; } string dataPath(reinterpret_cast(it.GetData())); string::size_type pos = dataPath.find_first_of(SEPARATOR); if (pos == string::npos) { - cerr << "Error: HandleIcon invalid '" << dataPath << "'."<< endl; + PrintError(GetError(ERR_CODE_INVALID_FILE_PATH).FormatCause(dataPath.c_str())); return RESTOOL_ERROR; } dataPath = dataPath.substr(pos + 1); diff --git a/src/resource_packer_factory.cpp b/src/resource_packer_factory.cpp index 7405b09..1d335f7 100644 --- a/src/resource_packer_factory.cpp +++ b/src/resource_packer_factory.cpp @@ -28,7 +28,7 @@ unique_ptr ResourcePackerFactory::CreatePacker(PackType type, cons } else if (type == PackType::OVERLAP) { return make_unique(packageParser); } else { - cerr << "Error: ResourcePackerFactory: Unknown input PackType." << endl; + cout << "Warning: ResourcePackerFactory: Unknown input PackType." << endl; return nullptr; } } diff --git a/src/resource_table.cpp b/src/resource_table.cpp index eb363af..6659c23 100644 --- a/src/resource_table.cpp +++ b/src/resource_table.cpp @@ -104,7 +104,7 @@ uint32_t ResourceTable::LoadResTable(const string path, map &in, map> &resInfos) { if (!in) { - cerr << "Error: istream state is bad. stateCode: " << in.rdstate() << endl; + PrintError(GetError(ERR_CODE_FILE_STREAM_ERROR).FormatCause(in.rdstate())); return RESTOOL_ERROR; } in.seekg(0, ios::end); @@ -161,20 +161,23 @@ uint32_t ResourceTable::CreateIdDefined(const map> cJSON *root = cJSON_CreateObject(); cJSON *recordArray = cJSON_CreateArray(); if (recordArray == nullptr) { - cerr << "Error: failed to create cJSON object for record array." << endl; + PrintError(GetError(ERR_CODE_CREATE_ID_DEFINED_ERROR) + .FormatCause(idDefinedPath_.c_str(), "failed to create cJSON object for record array")); cJSON_Delete(root); return RESTOOL_ERROR; } cJSON_AddItemToObject(root, "record", recordArray); for (const auto &pairPtr : allResource) { if (pairPtr.second.empty()) { - cerr << "Error: resource item vector is empty." << endl; + PrintError(GetError(ERR_CODE_CREATE_ID_DEFINED_ERROR) + .FormatCause(idDefinedPath_.c_str(), "resource item vector is empty")); cJSON_Delete(root); return RESTOOL_ERROR; } cJSON *jsonItem = cJSON_CreateObject(); if (jsonItem == nullptr) { - cerr << "Error: failed to create cJSON object for resource item." << endl; + PrintError(GetError(ERR_CODE_CREATE_ID_DEFINED_ERROR) + .FormatCause(idDefinedPath_.c_str(), "failed to create cJSON object for resource item")); cJSON_Delete(root); return RESTOOL_ERROR; } @@ -184,8 +187,10 @@ uint32_t ResourceTable::CreateIdDefined(const map> string name = item.GetName(); int64_t id = pairPtr.first; if (type.empty()) { - cerr << "Error : name = " << name << " ,ResType must is"; - cerr << ResourceUtil::GetAllRestypeString() << endl; + string errMsg = "name = "; + errMsg.append(name); + errMsg.append("invalid restype, type must in [").append(ResourceUtil::GetAllRestypeString()).append("]"); + PrintError(GetError(ERR_CODE_CREATE_ID_DEFINED_ERROR).FormatCause(idDefinedPath_.c_str(), errMsg.c_str())); cJSON_Delete(jsonItem); cJSON_Delete(root); return RESTOOL_ERROR; @@ -221,7 +226,7 @@ uint32_t ResourceTable::SaveToResouorceIndex(const map ofstream out(indexFilePath_, ofstream::out | ofstream::binary); if (!out.is_open()) { - cerr << "Error: open failed '" << indexFilePath_ << "', reason: " << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_OPEN_FILE_ERROR).FormatCause(indexFilePath_.c_str(), strerror(errno))); return RESTOOL_ERROR; } @@ -243,7 +248,7 @@ uint32_t ResourceTable::SaveToResouorceIndex(const map bool ResourceTable::InitIndexHeader(IndexHeader &indexHeader, uint32_t count) const { if (memcpy_s(indexHeader.version, VERSION_MAX_LEN, RESTOOL_VERSION, VERSION_MAX_LEN) != EOK) { - cerr << "Error: InitIndexHeader memcpy_s fail." << endl; + PrintError(GetError(ERR_CODE_MEMCPY_ERROR).FormatCause("InitIndexHeader")); return false; } indexHeader.limitKeyConfigSize = count; @@ -270,7 +275,7 @@ bool ResourceTable::Prepare(const map> &configs, for (const auto &config : configs) { auto limitKeyConfig = limitKeyConfigs.find(config.first); if (limitKeyConfig == limitKeyConfigs.end()) { - cerr << "Error: limit key config don't find '" << config.first << "'." << endl; + PrintError(GetError(ERR_CODE_INVALID_LIMIT_KEY).FormatCause(config.first.c_str())); return false; } limitKeyConfig->second.offset = pos; @@ -293,13 +298,15 @@ bool ResourceTable::SaveRecordItem(const map> &configs for (const auto &config : configs) { auto idSet = idSets.find(config.first); if (idSet == idSets.end()) { - cerr << "Error: id set don't find '" << config.first << "'." << endl; + string errMsg = "id set of limit key '" + config.first + "' not found"; + PrintError(GetError(ERR_CODE_SAVE_INDEX_ERROR).FormatCause(errMsg.c_str())); return false; } for (const auto &tableData : config.second) { if (idSet->second.data.find(tableData.id) == idSet->second.data.end()) { - cerr << "Error: resource table don't find id '" << tableData.id << "'." << endl; + string errMsg = "the resource table id " + to_string(tableData.id) + " not found"; + PrintError(GetError(ERR_CODE_SAVE_INDEX_ERROR).FormatCause(errMsg.c_str())); return false; } idSet->second.data[tableData.id] = pos; @@ -361,7 +368,7 @@ bool ResourceTable::ReadFileHeader(basic_istream &in, IndexHeader &indexHe { pos += sizeof(indexHeader); if (pos > length) { - cerr << "Error: invalid resources.index File Header." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("file header")); return false; } in.read(reinterpret_cast(indexHeader.version), VERSION_MAX_LEN); @@ -376,14 +383,14 @@ bool ResourceTable::ReadLimitKeys(basic_istream &in, map length) { - cerr << "Error: invalid resources.index KEYS." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("KEYS")); return false; } LimitKeyConfig limitKey; in.read(reinterpret_cast(limitKey.keyTag), TAG_LEN); string keyTag(reinterpret_cast(limitKey.keyTag), TAG_LEN); if (keyTag != "KEYS") { - cerr << "Error: invalid resources.index key tag = " << keyTag << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause(string("key tag = " + keyTag).c_str())); return false; } in.read(reinterpret_cast(&limitKey.offset), INT_TO_BYTES); @@ -393,7 +400,7 @@ bool ResourceTable::ReadLimitKeys(basic_istream &in, map length) { - cerr << "Error: invalid resources.index keyParams." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("keyParams")); return false; } KeyParam keyParam; @@ -412,7 +419,7 @@ bool ResourceTable::ReadIdTables(basic_istream &in, std::map length) { - cerr << "Error: invalid resources.index IDSS." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("IDSS")); return false; } IdSet idss; @@ -420,7 +427,7 @@ bool ResourceTable::ReadIdTables(basic_istream &in, std::map(idss.idTag), TAG_LEN); string idTag(reinterpret_cast(idss.idTag), TAG_LEN); if (idTag != "IDSS") { - cerr << "Error: invalid resources.index id tag = " << idTag << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause(string("id tag = " + idTag).c_str())); return false; } in.read(reinterpret_cast(&idss.idCount), INT_TO_BYTES); @@ -428,7 +435,7 @@ bool ResourceTable::ReadIdTables(basic_istream &in, std::map length) { - cerr << "Error: invalid resources.index id data." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("id data")); return false; } IdData data; @@ -444,13 +451,13 @@ bool ResourceTable::ReadDataRecordPrepare(basic_istream &in, RecordItem &r { pos = pos + INT_TO_BYTES; if (pos > length) { - cerr << "Error: invalid resources.index data record." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("data record")); return false; } in.read(reinterpret_cast(&record.size), INT_TO_BYTES); pos = pos + record.size; if (pos > length) { - cerr << "Error: invalid resources.index record.size." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("record.size")); return false; } in.read(reinterpret_cast(&record.resType), INT_TO_BYTES); @@ -468,7 +475,7 @@ bool ResourceTable::ReadDataRecordStart(basic_istream &in, RecordItem &rec uint16_t value_size = 0; in.read(reinterpret_cast(&value_size), sizeof(uint16_t)); if (value_size + sizeof(uint16_t) > record.size) { - cerr << "Error: invalid resources.index value size." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("value size")); return false; } int8_t values[value_size]; @@ -477,7 +484,7 @@ bool ResourceTable::ReadDataRecordStart(basic_istream &in, RecordItem &rec uint16_t name_size = 0; in.read(reinterpret_cast(&name_size), sizeof(uint16_t)); if (value_size + sizeof(uint16_t) + name_size + sizeof(uint16_t) > record.size) { - cerr << "Error: invalid resources.index name size." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("name size")); return false; } int8_t name[name_size]; @@ -486,17 +493,17 @@ bool ResourceTable::ReadDataRecordStart(basic_istream &in, RecordItem &rec auto idTableOffset = datas.find(offset); if (idTableOffset == datas.end()) { - cerr << "Error: invalid resources.index id offset." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("id offset")); return false; } if (idTableOffset->second.first != record.id) { - cerr << "Error: invalid resources.index id." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("id")); return false; } if (limitKeys.find(idTableOffset->second.second) == limitKeys.end()) { - cerr << "Error: invalid resources.index limit key offset." << endl; + PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause("limit key offset")); return false; } diff --git a/src/resource_util.cpp b/src/resource_util.cpp index efef4cc..c67c77e 100644 --- a/src/resource_util.cpp +++ b/src/resource_util.cpp @@ -23,6 +23,7 @@ #include #include #include "file_entry.h" +#include "restool_errors.h" namespace OHOS { namespace Global { @@ -82,17 +83,14 @@ bool ResourceUtil::OpenJsonFile(const string &path, cJSON **root) { ifstream ifs(FileEntry::AdaptLongPath(path), ios::binary); if (!ifs.is_open()) { - cerr << "Error: open json failed '" << path << "', reason: " << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_OPEN_JSON_FAIL).FormatCause(path.c_str(), strerror(errno))); return false; } string jsonString((istreambuf_iterator(ifs)), istreambuf_iterator()); *root = cJSON_Parse(jsonString.c_str()); if (!*root) { - cerr << "Error: cJSON_Parse failed, please check the JSON file." << NEW_LINE_PATH << path << endl; - cerr << SOLUTIONS << endl; - cerr << SOLUTIONS_ARROW << "Check the JSON file and delete unnecessary commas (,)." << endl; - cerr << SOLUTIONS_ARROW << "Check the JSON file to make sure the root bracket is {}" << endl; + PrintError(GetError(ERR_CODE_JSON_FORMAT_ERROR).SetPosition(path)); ifs.close(); return false; } @@ -104,7 +102,7 @@ bool ResourceUtil::SaveToJsonFile(const string &path, const cJSON *root) { ofstream out(FileEntry::AdaptLongPath(path), ofstream::out | ofstream::binary); if (!out.is_open()) { - cerr << "Error: SaveToJsonFile open failed '" << path <<"', reason: " << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_OPEN_FILE_ERROR).FormatCause(path.c_str(), strerror(errno))); return false; } char *jsonString = cJSON_Print(root); @@ -124,6 +122,15 @@ ResType ResourceUtil::GetResTypeByDir(const string &name) return ret->second; } +string ResourceUtil::GetAllResTypeDirs() +{ + string dirs; + for (auto iter = g_fileClusterMap.begin(); iter != g_fileClusterMap.end(); ++iter) { + dirs.append(iter->first + ", "); + } + return dirs; +} + string ResourceUtil::ResTypeToString(ResType type) { auto ret = find_if(g_fileClusterMap.begin(), g_fileClusterMap.end(), [type](auto iter) { @@ -230,7 +237,7 @@ bool ResourceUtil::CreateDirs(const string &filePath) } if (!FileEntry::CreateDirs(filePath)) { - cerr << "Error: create dir '" << filePath << "' failed, reason:" << strerror(errno) << endl; + PrintError(GetError(ERR_CODE_CREATE_FILE_ERROR).FormatCause(filePath.c_str(), strerror(errno))); return false; } return true; @@ -462,7 +469,6 @@ bool ResourceUtil::IsIntValue(const cJSON *node) bool ResourceUtil::IsValidName(const string &name) { if (!regex_match(name, regex("[a-zA-Z0-9_]+"))) { - cerr << "Error: the name '" << name << "' can only contain [a-zA-Z0-9_]." << endl; return false; } return true; @@ -471,8 +477,8 @@ bool ResourceUtil::IsValidName(const string &name) void ResourceUtil::PrintWarningMsg(vector> &noBaseResource) { for (const auto &item : noBaseResource) { - cerr << "Warning: the " << ResourceUtil::ResTypeToString(item.first); - cerr << " of '" << item.second << "' does not have a base resource." << endl; + cout << "Warning: the " << ResourceUtil::ResTypeToString(item.first); + cout << " of '" << item.second << "' does not have a base resource." << endl; } } diff --git a/src/restool.cpp b/src/restool.cpp index bbc7f2c..a70de84 100644 --- a/src/restool.cpp +++ b/src/restool.cpp @@ -27,7 +27,7 @@ int main(int argc, char *argv[]) SetConsoleOutputCP(CP_UTF8); #endif if (argv == nullptr) { - cerr << "Error: argv null" << endl; + PrintError(GetError(ERR_CODE_UNKNOWN_COMMAND_ERROR).FormatCause("argv null")); return RESTOOL_ERROR; } auto &parser = CmdParser::GetInstance(); diff --git a/src/restool_errors.cpp b/src/restool_errors.cpp new file mode 100644 index 0000000..b01c36b --- /dev/null +++ b/src/restool_errors.cpp @@ -0,0 +1,646 @@ +/* + * Copyright (c) 2025 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 + +#include "restool_errors.h" + +namespace OHOS { +namespace Global { +namespace Restool { +const std::map ERRORS_MAP = { + // 11201xxx + { ERR_CODE_LOAD_LIBRARY_FAIL, + { ERR_CODE_LOAD_LIBRARY_FAIL, + ERR_TYPE_DEPENDENCY, + "Load library failed, path: '%s', %s", + "", + { "Make sure the library path is correct and has access permissions." }, + {} } }, + + // 11203xxx + { ERR_CODE_OPEN_JSON_FAIL, + { ERR_CODE_OPEN_JSON_FAIL, + ERR_TYPE_CONFIG, + "Open json file '%s' failed, %s.", + "", + { "Make sure the json file path is correct and has access permissions." }, + {} } }, + { ERR_CODE_JSON_FORMAT_ERROR, + { ERR_CODE_JSON_FORMAT_ERROR, + ERR_TYPE_CONFIG, + "Parse json file failed, please check the file.", + "", + { "Check the JSON file and delete unnecessary commas (,).", + "Check the JSON file to make sure the root bracket is {}." }, + {} } }, + { ERR_CODE_JSON_NODE_MISMATCH, + { ERR_CODE_JSON_NODE_MISMATCH, + ERR_TYPE_CONFIG, + "Parse json file failed, the '%s' node type mismatch, expected type: '%s'.", + "", + {}, + {} } }, + { ERR_CODE_JSON_NODE_MISSING, + { ERR_CODE_JSON_NODE_MISSING, ERR_TYPE_CONFIG, "The required node '%s' is missing.", "", {}, {} } }, + { ERR_CODE_JSON_NODE_EMPTY, + { ERR_CODE_JSON_NODE_EMPTY, ERR_TYPE_CONFIG, "The array or object node '%s' cannot be empty.", "", {}, {} } }, + { ERR_CODE_JSON_NOT_ONE_MEMBER, + { ERR_CODE_JSON_NOT_ONE_MEMBER, + ERR_TYPE_CONFIG, + "The node '%s' of the json file can only have one member.", + "", + {}, + {} } }, + { ERR_CODE_JSON_INVALID_NODE_NAME, + { ERR_CODE_JSON_INVALID_NODE_NAME, ERR_TYPE_CONFIG, "Invalid node name '%s'.", "", {}, {} } }, + + // 11204xxx + { ERR_CODE_CREATE_FILE_ERROR, + { ERR_CODE_CREATE_FILE_ERROR, + ERR_TYPE_FILE_RESOURCE, + "Create directory or file '%s' failed, %s.", + "", + { "Make sure the file path is correct and has access permissions." }, + {} } }, + { ERR_CODE_FILE_NOT_EXIST, + { ERR_CODE_FILE_NOT_EXIST, + ERR_TYPE_FILE_RESOURCE, + "File not exists, '%s'.", + "", + { "Make sure the file path is correct." }, + {} } }, + { ERR_CODE_REMOVE_FILE_ERROR, + { ERR_CODE_REMOVE_FILE_ERROR, + ERR_TYPE_FILE_RESOURCE, + "Remove dir/file '%s' failed, %s.", + "", + { "Make sure the file path is correct." }, + {} } }, + { ERR_CODE_COPY_FILE_ERROR, + { ERR_CODE_COPY_FILE_ERROR, + ERR_TYPE_FILE_RESOURCE, + "Copy file from '%s' to '%s' failed, %s.", + "", + { "Make sure the src and dest file path is correct and has access permissions." }, + {} } }, + { ERR_CODE_OPEN_FILE_ERROR, + { ERR_CODE_OPEN_FILE_ERROR, + ERR_TYPE_FILE_RESOURCE, + "Open file failed '%s', %s.", + "", + { "Make sure the src and dest file path is correct and has access permissions." }, + {} } }, + { ERR_CODE_FILE_EMPTY, { ERR_CODE_FILE_EMPTY, ERR_TYPE_FILE_RESOURCE, "File is empty '%s'.", "", {}, {} } }, + { ERR_CODE_FILE_STREAM_ERROR, + { ERR_CODE_FILE_STREAM_ERROR, ERR_TYPE_FILE_RESOURCE, "File stream bad, state code: %d.", "", {}, {} } }, + { ERR_CODE_FILE_MAP_ERROR, + { ERR_CODE_FILE_MAP_ERROR, ERR_TYPE_FILE_RESOURCE, "File mapping failed, %s.", "", {}, {} } }, + + // 11205xxx + { ERR_CODE_SET_DATA_ERROR, + { ERR_CODE_SET_DATA_ERROR, + ERR_TYPE_SYNTAX, + "Set resource item data of '%s' failed, it may be due to insufficient memory.", + "", + { "Retry compile." }, + {} } }, + { ERR_CODE_ITEM_DATA_NULL, + { ERR_CODE_ITEM_DATA_NULL, + ERR_TYPE_SYNTAX, + "Get resource item data of '%s' failed, null.", + "", + { "Retry compile." }, + {} } }, + { ERR_CODE_MEMCPY_ERROR, + { ERR_CODE_MEMCPY_ERROR, ERR_TYPE_SYNTAX, "Memory copy failed in '%s'.", "", { "Retry compile." }, {} } }, + { ERR_CODE_CREATE_JSON_ERROR, + { ERR_CODE_CREATE_JSON_ERROR, + ERR_TYPE_SYNTAX, + "Generate JSON failed, %s.", + "", + { "Run the command again." }, + {} } }, + + // 11210xxx + { ERR_CODE_UNKNOWN_COMMAND_ERROR, + { ERR_CODE_UNKNOWN_COMMAND_ERROR, + ERR_TYPE_COMMAND_PARSE, + "Unknown error: %s", + "", + { "For details, see the help with option -h/--help." }, + {} } }, + { ERR_CODE_UNKNOWN_OPTION, + { ERR_CODE_UNKNOWN_OPTION, + ERR_TYPE_COMMAND_PARSE, + "Unknown option: '%s'", + "", + { "For details, see the help with option -h/--help." }, + {} } }, + { ERR_CODE_MISSING_ARGUMENT, + { ERR_CODE_MISSING_ARGUMENT, + ERR_TYPE_COMMAND_PARSE, + "Option '%s' must have argument", + "", + { "For details, see the help with option -h/--help." }, + {} } }, + { ERR_CODE_INVALID_ARGUMENT, + { ERR_CODE_INVALID_ARGUMENT, + ERR_TYPE_COMMAND_PARSE, + "Invalid arguments : '%s'", + "", + { "For details, see the help with option -h/--help." }, + {} } }, + { ERR_CODE_INVALID_INPUT, + { ERR_CODE_INVALID_INPUT, + ERR_TYPE_COMMAND_PARSE, + "Invalid input '%s'", + "", + { "Make sure the input path of option -i/--inputPath is correct." }, + {} } }, + { ERR_CODE_DUPLICATE_INPUT, + { ERR_CODE_DUPLICATE_INPUT, + ERR_TYPE_COMMAND_PARSE, + "Duplicated input '%s'", + "", + { "Make sure the input path of option -i/--inputPath is unique." }, + {} } }, + { ERR_CODE_DOUBLE_PACKAGE_NAME, + { ERR_CODE_DOUBLE_PACKAGE_NAME, + ERR_TYPE_COMMAND_PARSE, + "Double package name '%s' vs '%s'", + "", + { "Make sure the option -p/--packageName only specified once." }, + {} } }, + { ERR_CODE_INVALID_OUTPUT, + { ERR_CODE_INVALID_OUTPUT, + ERR_TYPE_COMMAND_PARSE, + "Invalid output '%s'", + "", + { "Make sure the output path of option -o/--outputPath is correct." }, + {} } }, + { ERR_CODE_DOUBLE_OUTPUT, + { ERR_CODE_DOUBLE_OUTPUT, + ERR_TYPE_COMMAND_PARSE, + "Double output '%s' vs '%s'", + "", + { "Make sure the option -o/--outputPath only specified once." }, + {} } }, + { ERR_CODE_DUPLICATE_RES_HEADER, + { ERR_CODE_DUPLICATE_RES_HEADER, + ERR_TYPE_COMMAND_PARSE, + "Duplicated res header path '%s'", + "", + { "Make sure the path of option -r/--resHeader is unique." }, + {} } }, + { ERR_CODE_DOUBLE_MODULES, + { ERR_CODE_DOUBLE_MODULES, + ERR_TYPE_COMMAND_PARSE, + "Double module name '%s'", + "", + { "Make sure the option -m/--modules only specified once." }, + {} } }, + { ERR_CODE_DUPLICATE_MODULE_NAME, + { ERR_CODE_DUPLICATE_MODULE_NAME, + ERR_TYPE_COMMAND_PARSE, + "Duplicated module name '%s'", + "", + { "Make sure the module name is unique." }, + {} } }, + { ERR_CODE_DOUBLE_CONFIG_JSON, + { ERR_CODE_DOUBLE_CONFIG_JSON, + ERR_TYPE_COMMAND_PARSE, + "Double config json '%s' vs '%s'", + "", + { "Make sure the option -j/--json only specified once." }, + {} } }, + { ERR_CODE_INVALID_START_ID, + { ERR_CODE_INVALID_START_ID, + ERR_TYPE_COMMAND_PARSE, + "Invalid start id '%s'", + "", + { "Make sure the start id in the scope [0x01000000, 0x06FFFFFF) or [0x08000000, 0xFFFFFFFF)" }, + {} } }, + { ERR_CODE_DUPLICATE_APPEND_PATH, + { ERR_CODE_DUPLICATE_APPEND_PATH, + ERR_TYPE_COMMAND_PARSE, + "Duplicated input append path '%s'", + "", + { "Make sure the path of option -x/--append is unique." }, + {} } }, + { ERR_CODE_DOUBLE_TARGET_CONFIG, + { ERR_CODE_DOUBLE_TARGET_CONFIG, + ERR_TYPE_COMMAND_PARSE, + "Double option '--target-config'", + "", + { "Make sure the option --target-config only specified once." }, + {} } }, + { ERR_CODE_INVALID_TARGET_CONFIG, + { ERR_CODE_INVALID_TARGET_CONFIG, + ERR_TYPE_COMMAND_PARSE, + "Invalid target config argument '%s'", + "", + { "The argument format of option --target-config is supposed to be like 'Locale[zh_CN,en_US];Device[phone]', " + "for details, see the developer documentation." }, + {} } }, + { ERR_CODE_INVALID_SYSTEM_ID_DEFINED, + { ERR_CODE_INVALID_SYSTEM_ID_DEFINED, + ERR_TYPE_COMMAND_PARSE, + "Invalid system id_defined.json path '%s'", + "", + { "Make sure the system id_defined.json path is correct." }, + {} } }, + { ERR_CODE_DUPLICATE_SYSTEM_ID_DEFINED, + { ERR_CODE_DUPLICATE_SYSTEM_ID_DEFINED, + ERR_TYPE_COMMAND_PARSE, + "Duplicated system id_defined.json path '%s'", + "", + { "Make sure the system id_defined.json path is unique." }, + {} } }, + { ERR_CODE_DOUBLE_COMPRESSION_PATH, + { ERR_CODE_DOUBLE_COMPRESSION_PATH, + ERR_TYPE_COMMAND_PARSE, + "Double compression json path '%s' vs '%s'", + "", + { "Make sure the option --compressed-config only specified once." }, + {} } }, + { ERR_CODE_NON_ASCII, + { ERR_CODE_NON_ASCII, + ERR_TYPE_COMMAND_PARSE, + "'%s' must be ASCII", + "", + { "Make sure all the argument's characters is ASCII." }, + {} } }, + { ERR_CODE_EXCLUSIVE_OPTION, + { ERR_CODE_EXCLUSIVE_OPTION, ERR_TYPE_COMMAND_PARSE, "Option %s and %s cannot be used together.", "", {}, {} } }, + { ERR_CODE_PACKAGE_NAME_EMPTY, + { ERR_CODE_PACKAGE_NAME_EMPTY, + ERR_TYPE_COMMAND_PARSE, + "Package name empty.", + "", + { "Specifies the package name with option -p/--packageName." }, + {} } }, + { ERR_CODE_RES_HEADER_PATH_EMPTY, + { ERR_CODE_RES_HEADER_PATH_EMPTY, + ERR_TYPE_COMMAND_PARSE, + "Resource header path empty.", + "", + { "Specifies header path with option -r/--resHeader." }, + {} } }, + { ERR_CODE_DUMP_MISSING_INPUT, + { ERR_CODE_DUMP_MISSING_INPUT, + ERR_TYPE_COMMAND_PARSE, + "Resource dump missing input path.", + "", + { "Specifies input path after dump command." }, + {} } }, + { ERR_CODE_DUMP_INVALID_INPUT, + { ERR_CODE_DUMP_INVALID_INPUT, + ERR_TYPE_COMMAND_PARSE, + "Resource dump invalid input path.", + "", + { "Make sure the input path after dump command is correct." }, + {} } }, + { ERR_CODE_INVALID_THREAD_COUNT, + { ERR_CODE_INVALID_THREAD_COUNT, ERR_TYPE_COMMAND_PARSE, "Invalid thread count: %s.", "", {}, {} } }, + + // 11211xxx + { ERR_CODE_OUTPUT_EXIST, + { ERR_CODE_OUTPUT_EXIST, + ERR_TYPE_RESOURCE_PACK, + "Output path exists, but option -f/--forceWrite not specified.", + "", + { "Remove the exist output dir or use option -f to force write." }, + {} } }, + { ERR_CODE_CONFIG_JSON_MISSING, + { ERR_CODE_CONFIG_JSON_MISSING, + ERR_TYPE_RESOURCE_PACK, + "More input path, but -j config.json not specified.", + "", + { "Specifies the config.json with option -j/--json." }, + {} } }, + { ERR_CODE_INVALID_MODULE_TYPE, + { ERR_CODE_INVALID_MODULE_TYPE, + ERR_TYPE_RESOURCE_PACK, + "Invalid module type '%s', expected type is one of [entry, har, shared, feature].", + "", + {}, + {} } }, + { ERR_CODE_EXCLUSIVE_START_ID, + { ERR_CODE_EXCLUSIVE_START_ID, + ERR_TYPE_RESOURCE_PACK, + "The set start_id and id_defined.json cannot be used together.", + "", + {}, + {} } }, + { ERR_CODE_ID_DEFINED_NODE_MISSING, + { ERR_CODE_ID_DEFINED_NODE_MISSING, + ERR_TYPE_RESOURCE_PACK, + "The id_defined.json seq = %lu %s empty.", + "", + {}, + {} } }, + { ERR_CODE_ID_DEFINED_NODE_MISMATCH, + { ERR_CODE_ID_DEFINED_NODE_MISMATCH, + ERR_TYPE_RESOURCE_PACK, + "The id_defined.json seq = %lu %s not %s.", + "", + {}, + {} } }, + { ERR_CODE_ID_DEFINED_INVALID_TYPE, + { ERR_CODE_ID_DEFINED_INVALID_TYPE, + ERR_TYPE_RESOURCE_PACK, + "The id_defined.json seq = %lu type '%s' invalid.", + "", + {}, + {} } }, + { ERR_CODE_ID_DEFINED_INVALID_ID, + { ERR_CODE_ID_DEFINED_INVALID_ID, + ERR_TYPE_RESOURCE_PACK, + "The id_defined.json seq = %lu id must be a hex string, eg:^0[xX][0-9a-fA-F]{8}.", + "", + {}, + {} } }, + { ERR_CODE_ID_DEFINED_ID_OUT_RANGE, + { ERR_CODE_ID_DEFINED_ID_OUT_RANGE, + ERR_TYPE_RESOURCE_PACK, + "The id_defined.json seq = %lu id must in [0x01000000,0x06FFFFFF],[0x08000000,0xFFFFFFFF].", + "", + {}, + {} } }, + { ERR_CODE_ID_DEFINED_ORDER_MISMATCH, + { ERR_CODE_ID_DEFINED_ORDER_MISMATCH, + ERR_TYPE_RESOURCE_PACK, + "The id_defined.json seq = %lu order value %lu vs expect %lu.", + "", + {}, + {} } }, + { ERR_CODE_ID_DEFINED_INVALID_START_ID, + { ERR_CODE_ID_DEFINED_INVALID_START_ID, + ERR_TYPE_RESOURCE_PACK, + "The id_defined.json 'startId' is invalid.", + "", + {}, + {} } }, + { ERR_CODE_ID_DEFINED_SAME_ID, + { ERR_CODE_ID_DEFINED_SAME_ID, + ERR_TYPE_RESOURCE_PACK, + "The id_defined.json '%s' and '%s' defind the same ID.", + "", + {}, + {} } }, + { ERR_CODE_ID_DEFINED_SAME_RESOURCE, + { ERR_CODE_ID_DEFINED_SAME_RESOURCE, + ERR_TYPE_RESOURCE_PACK, + "The same resource of '%s' exists in the %s", + "", + {}, + {} } }, + { ERR_CODE_MODULE_NAME_NOT_FOUND, + { ERR_CODE_MODULE_NAME_NOT_FOUND, + ERR_TYPE_RESOURCE_PACK, + "The module name '%s' in config.json not found in [%s] which specifies with -m/--modules.", + "", + { "Make sure the module name in config.json is correct." }, + {} } }, + { ERR_CODE_RESOURCE_PATH_NOT_DIR, + { ERR_CODE_RESOURCE_PATH_NOT_DIR, + ERR_TYPE_RESOURCE_PACK, + "Scan resource failed, the path '%s' is not directory.", + "", + {}, + {} } }, + { ERR_CODE_INVALID_FILE_PATH, + { ERR_CODE_INVALID_FILE_PATH, + ERR_TYPE_RESOURCE_PACK, + "Invalid file path '%s'.", + "", + { "Make sure the path is correct." }, + {} } }, + { ERR_CODE_INVALID_LIMIT_KEY, + { ERR_CODE_INVALID_LIMIT_KEY, ERR_TYPE_RESOURCE_PACK, "Invalid limit key '%s'.", "", {}, {} } }, + { ERR_CODE_INVALID_RESOURCE_DIR, + { ERR_CODE_INVALID_RESOURCE_DIR, + ERR_TYPE_RESOURCE_PACK, + "Invalid resource directory name '%s', must in [%s].", + "", + {}, + {} } }, + { ERR_CODE_RESOURCE_PATH_NOT_FILE, + { ERR_CODE_RESOURCE_PATH_NOT_FILE, + ERR_TYPE_RESOURCE_PACK, + "Scan resource failed, the resource '%s' must be a file.", + "", + {}, + {} } }, + { ERR_CODE_INVALID_TRANSLATE_PRIORITY, + { ERR_CODE_INVALID_TRANSLATE_PRIORITY, + ERR_TYPE_RESOURCE_PACK, + "Invalid translate priority value '%s', must in [%s].", + "", + {}, + {} } }, + { ERR_CODE_INVALID_ELEMENT_TYPE, + { ERR_CODE_INVALID_ELEMENT_TYPE, ERR_TYPE_RESOURCE_PACK, "Unsupport element resource type '%s'.", "", {}, {} } }, + { ERR_CODE_INVALID_COLOR_VALUE, + { ERR_CODE_INVALID_COLOR_VALUE, + ERR_TYPE_RESOURCE_PACK, + "Invalid color value '%s', only support refer '$color:xxx' or '#rgb','#argb','#rrggbb','#aarrggbb'.", + "", + {}, + {} } }, + { ERR_CODE_INVALID_RESOURCE_REF, + { ERR_CODE_INVALID_RESOURCE_REF, + ERR_TYPE_RESOURCE_PACK, + "Invalid resource reference '%s', only support refer '%sxxx'.", + "", + {}, + {} } }, + { ERR_CODE_PARENT_EMPTY, + { ERR_CODE_PARENT_EMPTY, + ERR_TYPE_RESOURCE_PACK, + "The resource's parent is emptry, type: '%s', name: '%s'.", + "", + {}, + {} } }, + { ERR_CODE_ARRAY_TOO_LARGE, + { ERR_CODE_ARRAY_TOO_LARGE, ERR_TYPE_RESOURCE_PACK, "The array resource '%s' is to large.", "", {}, {} } }, + { ERR_CODE_INVALID_QUANTITY, + { ERR_CODE_INVALID_QUANTITY, + ERR_TYPE_RESOURCE_PACK, + "Invalid quantity resource, name: '%s', quantity: '%s', the quantity must be one of [%s].", + "", + {}, + {} } }, + { ERR_CODE_DUPLICATE_QUANTITY, + { ERR_CODE_DUPLICATE_QUANTITY, + ERR_TYPE_RESOURCE_PACK, + "Duplicated quantity resource, name: '%s', quantity: '%s'.", + "", + {}, + {} } }, + { ERR_CODE_QUANTITY_NO_OTHER, + { ERR_CODE_QUANTITY_NO_OTHER, + ERR_TYPE_RESOURCE_PACK, + "The quantity resource '%s' must contains 'other' quantity.", + "", + {}, + {} } }, + { ERR_CODE_INVALID_SYMBOL, + { ERR_CODE_INVALID_SYMBOL, + ERR_TYPE_RESOURCE_PACK, + "The symbol resource '%s' invalid, value must in 0xF0000 ~ 0xFFFFF or 0x100000 ~ 0x10FFFF.", + "", + {}, + {} } }, + { ERR_CODE_INVALID_RESOURCE_NAME, + { ERR_CODE_INVALID_RESOURCE_NAME, + ERR_TYPE_RESOURCE_PACK, + "Invalid resource name '%s', the name can only contain [a-zA-Z0-9_].", + "", + { "Modify the name to match [a-zA-Z0-9_]." }, + {} } }, + { ERR_CODE_RESOURCE_DUPLICATE, + { ERR_CODE_RESOURCE_DUPLICATE, + ERR_TYPE_RESOURCE_PACK, + "Resource '%s' conflict, first declared at %s, but declare again at %s.", + "", + { "Make sure the resource names of same type are unique." }, + {} } }, + { ERR_CODE_RESOURCE_ID_EXCEED, + { ERR_CODE_RESOURCE_ID_EXCEED, + ERR_TYPE_RESOURCE_PACK, + "The resource id %lu exceed, greater than the max id %lu", + "", + {}, + {} } }, + { ERR_CODE_RESOURCE_ID_NOT_DEFINED, + { ERR_CODE_RESOURCE_ID_NOT_DEFINED, + ERR_TYPE_RESOURCE_PACK, + "The resource id not be defined, resource type: %s, name: '%s'.", + "", + {}, + {} } }, + { ERR_CODE_REF_NOT_DEFINED, + { ERR_CODE_REF_NOT_DEFINED, + ERR_TYPE_RESOURCE_PACK, + "The resource reference '%s' don't be defined.", + "", + {}, + {} } }, + { ERR_CODE_ARRAY_DECOMPOSE_ERROR, + { ERR_CODE_ARRAY_DECOMPOSE_ERROR, + ERR_TYPE_RESOURCE_PACK, + "Decompose strings failed, name: '%s', data: '%s'.", + "", + {}, + {} } }, + { ERR_CODE_ARRAY_COMPOSE_ERROR, + { ERR_CODE_ARRAY_COMPOSE_ERROR, + ERR_TYPE_RESOURCE_PACK, + "Compose strings failed, name: '%s', content size: '%lu'.", + "", + {}, + {} } }, + { ERR_CODE_FA_ENTRY_NO_ICON_LABEL, + { ERR_CODE_FA_ENTRY_NO_ICON_LABEL, + ERR_TYPE_RESOURCE_PACK, + "Entry MainAbility must have 'icon' and 'label'.", + "", + {}, + {} } }, + { ERR_CODE_INVALID_RESOURCE_INDEX, + { ERR_CODE_INVALID_RESOURCE_INDEX, ERR_TYPE_RESOURCE_PACK, "Invalid resources.index %s.", "", {}, {} } }, + { ERR_CODE_RESOURCE_INDEX_ID_NOT_FOUND, + { ERR_CODE_RESOURCE_INDEX_ID_NOT_FOUND, + ERR_TYPE_RESOURCE_PACK, + "Find resource items in resources.index failed, the id %lu not found.", + "", + {}, + {} } }, + { ERR_CODE_RESOURCE_INDEX_ITEM_EMPTY, + { ERR_CODE_RESOURCE_INDEX_ITEM_EMPTY, + ERR_TYPE_RESOURCE_PACK, + "Find resource items in resources.index failed, the items of id %lu is empty.", + "", + {}, + {} } }, + { ERR_CODE_RESOURCE_INDEX_INVALID_RESTYPE, + { ERR_CODE_RESOURCE_INDEX_INVALID_RESTYPE, + ERR_TYPE_RESOURCE_PACK, + "Find resource items in resources.index failed, invalid restype '%s', expected type '%s'.", + "", + {}, + {} } }, + { ERR_CODE_SAVE_INDEX_ERROR, + { ERR_CODE_SAVE_INDEX_ERROR, + ERR_TYPE_RESOURCE_PACK, + "Save resources to resources.index failed, %s.", + "", + {}, + {} } }, + { ERR_CODE_CREATE_ID_DEFINED_ERROR, + { ERR_CODE_CREATE_ID_DEFINED_ERROR, + ERR_TYPE_RESOURCE_PACK, + "Create id defined json '%s' failed, %s.", + "", + {}, + {} } }, + + // 11212xxx + { ERR_CODE_PARSE_HAP_ERROR, + { ERR_CODE_PARSE_HAP_ERROR, ERR_TYPE_RESOURCE_PACK, "Parse hap failed, %s.", "", {}, {} } }, +}; + +ErrorInfo GetError(const uint32_t &errCode) +{ + ErrorInfo error; + if (ERRORS_MAP.count(errCode) == 0) { + return error; + } + auto it = ERRORS_MAP.find(errCode); + if (it != ERRORS_MAP.end()) { + return it->second; + } + return error; +} + +void PrintError(const uint32_t &errCode) +{ + PrintError(GetError(errCode)); +} + +void PrintError(const ErrorInfo &error) +{ + std::string errMsg; + errMsg.append("Error Code: ").append(std::to_string(error.code_)).append("\n"); + errMsg.append("Error: ").append(error.description_).append("\n"); + errMsg.append("Error Message: ").append(error.cause_); + if (!error.position_.empty()) { + errMsg.append(" At ").append(error.position_); + } + errMsg.append("\n"); + if (!error.solutions_.empty()) { + errMsg.append("* Try the following:").append("\n"); + for (const auto &solution : error.solutions_) { errMsg.append(" > ").append(solution).append("\n"); } + if (!error.moreInfo_.cn.empty()) { + errMsg.append("> More info: ").append(error.moreInfo_.cn).append("\n"); + } + } + std::cerr << errMsg; +} +} // namespace Restool +} // namespace Global +} // namespace OHOS diff --git a/src/translatable_parser.cpp b/src/translatable_parser.cpp index aed9675..55524c1 100755 --- a/src/translatable_parser.cpp +++ b/src/translatable_parser.cpp @@ -16,6 +16,7 @@ #include "translatable_parser.h" #include #include +#include "restool_errors.h" #include "resource_util.h" namespace OHOS { @@ -37,22 +38,22 @@ bool TranslatableParse::ParseTranslatable(cJSON *objectNode, const FileInfo &fil } cJSON *arrayNode = cJSON_GetObjectItem(objectNode, TAG_VALUE.c_str()); if (!arrayNode || !cJSON_IsArray(arrayNode)) { - cerr << "Error: '" << name << "' value not array."; - cerr << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(name.c_str(), "array") + .SetPosition(fileInfo.filePath)); return false; } if (cJSON_GetArraySize(arrayNode) == 0) { - cerr << "Error: '" << name << "' value empty."; - cerr << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_EMPTY).FormatCause(name.c_str()).SetPosition(fileInfo.filePath)); return false; } int32_t index = -1; for (cJSON *item = arrayNode->child; item; item = item->next) { index++; if (!item || !cJSON_IsObject(item)) { - cerr << "Error: '" << name << "' value the seq=" << index << " item must be object."; - cerr << NEW_LINE_PATH << fileInfo.filePath << endl; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause("value's child", "object") + .SetPosition(fileInfo.filePath)); return false; } @@ -65,18 +66,16 @@ bool TranslatableParse::ParseTranslatable(cJSON *objectNode, const FileInfo &fil bool TranslatableParse::ParseTranslatable(cJSON *objectNode, const string &filePath) { - if (!CheckBaseStringAttr(objectNode)) { - cerr << NEW_LINE_PATH << filePath << endl; + if (!CheckBaseStringAttr(objectNode, filePath)) { return false; } - if (!ReplaceTranslateTags(objectNode, TAG_VALUE.c_str())) { - cerr << NEW_LINE_PATH << filePath << endl; + if (!ReplaceTranslateTags(objectNode, TAG_VALUE.c_str(), filePath)) { return false; } return true; } -bool TranslatableParse::CheckBaseStringAttr(const cJSON *objectNode) +bool TranslatableParse::CheckBaseStringAttr(const cJSON *objectNode, const std::string &filePath) { cJSON *attrNode = cJSON_GetObjectItem(objectNode, TAG_ATTR.c_str()); if (!attrNode) { @@ -84,53 +83,60 @@ bool TranslatableParse::CheckBaseStringAttr(const cJSON *objectNode) } if (!cJSON_IsObject(attrNode)) { - cerr << "Error: attr node not obeject."; + PrintError( + GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(TAG_ATTR.c_str(), "object").SetPosition(filePath)); return false; } - return CheckBaseStringTranslatable(attrNode); + return CheckBaseStringTranslatable(attrNode, filePath); } -bool TranslatableParse::CheckBaseStringTranslatable(const cJSON *attrNode) +bool TranslatableParse::CheckBaseStringTranslatable(const cJSON *attrNode, const std::string &filePath) { cJSON *translatableNode = cJSON_GetObjectItem(attrNode, TAG_TRANSLATABLE.c_str()); if (!translatableNode) { - return CheckBaseStringPriority(attrNode); + return CheckBaseStringPriority(attrNode, filePath); } if (!cJSON_IsBool(translatableNode)) { - cerr << "Error: invalid value for '" << TAG_TRANSLATABLE << "'. Must be a boolean."; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(TAG_TRANSLATABLE.c_str(), "bool") + .SetPosition(filePath)); return false; } - return CheckBaseStringPriority(attrNode); + return CheckBaseStringPriority(attrNode, filePath); } -bool TranslatableParse::CheckBaseStringPriority(const cJSON *attrNode) +bool TranslatableParse::CheckBaseStringPriority(const cJSON *attrNode, const std::string &filePath) { cJSON *priorityNode = cJSON_GetObjectItem(attrNode, TAG_PRIORITY.c_str()); if (!priorityNode) { return true; } if (!cJSON_IsString(priorityNode)) { - cerr << "Error: invalid value for '" << TAG_PRIORITY << "'. Must be a string."; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH) + .FormatCause(TAG_PRIORITY.c_str(), "string") + .SetPosition(filePath)); return false; } string priorityValue = priorityNode->valuestring; if (find(PRIORITY_ATTRS.begin(), PRIORITY_ATTRS.end(), priorityValue) == PRIORITY_ATTRS.end()) { - string message("[ "); + string message(""); for (const auto &value : PRIORITY_ATTRS) { message.append("'" + value + "' "); } - message.append("]"); - cerr << "Error: invalid value for '" << TAG_PRIORITY << "'. Must in " << message; + PrintError(GetError(ERR_CODE_INVALID_TRANSLATE_PRIORITY) + .FormatCause(priorityValue.c_str(), message.c_str()) + .SetPosition(filePath)); return false; } return true; } -bool TranslatableParse::ReplaceTranslateTags(cJSON *node, const char *key) +bool TranslatableParse::ReplaceTranslateTags(cJSON *node, const char *key, const std::string &filePath) { cJSON *valueNode = cJSON_GetObjectItem(node, TAG_VALUE.c_str()); if (!valueNode || !cJSON_IsString(valueNode)) { - cerr << "Error: value not string."; + PrintError(GetError(ERR_CODE_JSON_NODE_MISMATCH).FormatCause(TAG_VALUE.c_str(), "string") + .SetPosition(filePath)); return false; }