From 9bd19a84f479eb13b7b820e95aadc51ab45746ff Mon Sep 17 00:00:00 2001 From: ma_nan Date: Fri, 24 Sep 2021 14:46:03 +0800 Subject: [PATCH 1/3] fix codestyle Signed-off-by: ma_nan --- services/applypatch/partition_record.cpp | 12 +++++---- services/fs_manager/mount.cpp | 2 +- .../script_interpreter/script_interpreter.cpp | 12 +++++++++ services/ui/drm_driver.cpp | 2 +- services/ui/drm_driver.h | 4 +-- services/ui/text_label.cpp | 26 ++++++++++++------- services/updater.cpp | 15 ++++++----- services/updater_binary/update_partitions.cpp | 11 ++++---- utils/utils.cpp | 9 ++++--- 9 files changed, 58 insertions(+), 35 deletions(-) diff --git a/services/applypatch/partition_record.cpp b/services/applypatch/partition_record.cpp index 9d758176..e6de89be 100644 --- a/services/applypatch/partition_record.cpp +++ b/services/applypatch/partition_record.cpp @@ -31,9 +31,9 @@ bool PartitionRecord::IsPartitionUpdated(const std::string &partitionName) { auto miscBlockDevice = GetMiscPartitionPath(); uint8_t buffer[PARTITION_UPDATER_RECORD_MSG_SIZE]; - char *realPath = realpath(miscBlockDevice.c_str(), NULL); - UPDATER_FILE_CHECK(realPath != nullptr, "realPath is NULL", return false); if (!miscBlockDevice.empty()) { + char *realPath = realpath(miscBlockDevice.c_str(), NULL); + UPDATER_FILE_CHECK(realPath != nullptr, "realPath is NULL", return false); int fd = open(realPath, O_RDONLY | O_EXCL | O_CLOEXEC | O_BINARY); free(realPath); UPDATER_FILE_CHECK(fd >= 0, "PartitionRecord: Open misc to recording partition failed", return false); @@ -60,9 +60,9 @@ bool PartitionRecord::IsPartitionUpdated(const std::string &partitionName) bool PartitionRecord::RecordPartitionUpdateStatus(const std::string &partitionName, bool updated) { auto miscBlockDevice = GetMiscPartitionPath(); - char *realPath = realpath(miscBlockDevice.c_str(), NULL); - UPDATER_FILE_CHECK(realPath != nullptr, "realPath is NULL", return false); if (!miscBlockDevice.empty()) { + char *realPath = realpath(miscBlockDevice.c_str(), NULL); + UPDATER_FILE_CHECK(realPath != nullptr, "realPath is NULL", return false); int fd = open(realPath, O_RDWR | O_EXCL | O_CLOEXEC | O_BINARY); free(realPath); UPDATER_FILE_CHECK(fd >= 0, "PartitionRecord: Open misc to recording partition failed", return false); @@ -76,6 +76,8 @@ bool PartitionRecord::RecordPartitionUpdateStatus(const std::string &partitionNa UPDATER_CHECK_FILE_OP(lseek(fd, PARTITION_RECORD_START + offset_, SEEK_SET) >= 0, "PartitionRecord: Seek misc to specific offset failed", fd, return false); if (offset_ + sizeof(PartitionRecordInfo) < PARTITION_UPDATER_RECORD_SIZE) { + UPDATER_CHECK_FILE_OP(memset_s(&info_, sizeof(info_), 0, sizeof(info_)) == 0, + "PartitionRecord: clear partition info failed", fd, return false); UPDATER_CHECK_FILE_OP(!strncpy_s(info_.partitionName, PARTITION_NAME_LEN, partitionName.c_str(), PARTITION_NAME_LEN - 1), "PartitionRecord: strncpy_s failed", fd, return false); info_.updated = updated; @@ -85,7 +87,7 @@ bool PartitionRecord::RecordPartitionUpdateStatus(const std::string &partitionNa UPDATER_CHECK_FILE_OP(lseek(fd, PARTITION_RECORD_OFFSET, SEEK_SET) >= 0, "PartitionRecord: Seek misc to record offset failed", fd, return false); UPDATER_CHECK_FILE_OP(write(fd, &offset_, sizeof(off_t)) == sizeof(off_t), - "PartitionRecord: Seek misc to record offset failed", fd, return false); + "PartitionRecord: write misc to record offset failed", fd, return false); LOG(DEBUG) << "PartitionRecord: offset is " << offset_; } else { LOG(WARNING) << "PartitionRecord: partition record overflow, offset = " << offset_; diff --git a/services/fs_manager/mount.cpp b/services/fs_manager/mount.cpp index 1053f2fa..20f99e76 100644 --- a/services/fs_manager/mount.cpp +++ b/services/fs_manager/mount.cpp @@ -143,7 +143,7 @@ static MountStatus GetMountStatusForMountPoint(const std::string &mountPoint) while (fgets(buffer, sizeof(buffer) - 1, fp.get()) != nullptr) { n = strlen(buffer); - if (buffer[n - 1] == '\n') { + if (n > 0 && buffer[n - 1] == '\n') { buffer[n - 1] = '\0'; } std::string line(buffer); diff --git a/services/script/script_interpreter/script_interpreter.cpp b/services/script/script_interpreter/script_interpreter.cpp index bef46fa8..0531a914 100644 --- a/services/script/script_interpreter/script_interpreter.cpp +++ b/services/script/script_interpreter/script_interpreter.cpp @@ -109,6 +109,18 @@ ScriptFunction* ScriptInterpreter::FindFunction(const std::string &name) return nullptr; } +UScriptValuePtr ScriptInterpreter::ExecuteFunction(UScriptContextPtr context, const std::string &name, + ScriptParams *params) +{ + ScriptFunction *function = FindFunction(name); + if (function == nullptr) { + USCRIPT_LOGI("Fail to find function %s", name.c_str()); + return std::make_shared(USCRIPT_NOTEXIST_INSTRUCTION); + } else { + return function->Execute(*this, context, params); + } +} + UScriptValuePtr ScriptInterpreter::FindVariable(UScriptContextPtr local, std::string id) { for (auto context = contextStack_.rbegin(); context != contextStack_.rend(); context++) { diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 648719ac..20119428 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -19,7 +19,7 @@ #include "securec.h" namespace updater { -void DrmDriver::FlipBuffer(void *buf) +void DrmDriver::FlipBuffer(const void *buf) { if (!buf) { LOG(ERROR) << "buf is null"; diff --git a/services/ui/drm_driver.h b/services/ui/drm_driver.h index 62b5385f..1e074929 100644 --- a/services/ui/drm_driver.h +++ b/services/ui/drm_driver.h @@ -42,7 +42,7 @@ class DrmDriver { protected: DrmDriver() : fd_(-1), conn_(nullptr), res_(nullptr) {} virtual ~DrmDriver(); - void FlipBuffer(void* buf); + void FlipBuffer(const void* buf); void LoadDrmDriver(); private: int ModesetCreateFb(struct BufferObject *bo); @@ -51,7 +51,7 @@ private: int fd_; drmModeConnector *conn_; drmModeRes *res_; - struct BufferObject buff_; + struct BufferObject buff_ {}; }; } // namespace updater #endif diff --git a/services/ui/text_label.cpp b/services/ui/text_label.cpp index 0b87320e..d94a90a6 100644 --- a/services/ui/text_label.cpp +++ b/services/ui/text_label.cpp @@ -78,6 +78,15 @@ static void PngInitSet(png_structp fontPngPtr, FILE *fp, int size, png_infop fon return; } +static void CheckInitFont(png_structp fontPngPtr, FILE *fp, png_infop fontInfoPtr) +{ + png_destroy_read_struct(&fontPngPtr, &fontInfoPtr, 0); + if (fp != nullptr) { + fclose(fp); + fp = nullptr; + } +} + static void PNGReadRow(png_uint_32 fontWidth, png_uint_32 fontHeight, png_structp fontPngPtr, char *fontBuf) { if ((fontWidth > MAX_FONT_BUFFER_SIZE_HW) || (fontHeight > MAX_FONT_BUFFER_SIZE_HW)) { @@ -97,12 +106,10 @@ void TextLabel::InitFont() png_infop fontInfoPtr = nullptr; png_uint_32 fontWidth = 0; png_uint_32 fontHeight = 0; - png_byte fontChannels = 0; png_structp fontPngPtr = nullptr; int fontBitDepth = 0; int fontColorType = 0; - uint32_t offset = 2; - UPDATER_CHECK_ONLY_RETURN(!memset_s(resPath, MAX_TEXT_SIZE + offset, 0, MAX_TEXT_SIZE + 1), return); + UPDATER_CHECK_ONLY_RETURN(!memset_s(resPath, MAX_TEXT_SIZE + offset_, 0, MAX_TEXT_SIZE + 1), return); switch (fontType_) { case DEFAULT_FONT: UPDATER_CHECK_ONLY_RETURN(snprintf_s(resPath, sizeof(resPath), sizeof(resPath) -1, "/resources/%s.png", @@ -115,8 +122,7 @@ void TextLabel::InitFont() } FILE* fp = fopen(resPath, "rb"); UPDATER_ERROR_CHECK(fp, "open font failed!", return); - const int headerNumber = 8; - uint8_t header[headerNumber]; + uint8_t header[headerNumber_]; size_t bytesRead = fread(header, 1, sizeof(header), fp); UPDATER_ERROR_CHECK(bytesRead == sizeof(header), "read header failed!", fclose(fp); return); if (png_sig_cmp(header, 0, sizeof(header))) { @@ -128,21 +134,21 @@ void TextLabel::InitFont() UPDATER_ERROR_CHECK(fontPngPtr, "creat font ptr_ failed!", fclose(fp); return); fontInfoPtr = png_create_info_struct(fontPngPtr); if (fontInfoPtr == nullptr) { + png_destroy_read_struct(&fontPngPtr, nullptr, nullptr); fclose(fp); return; } PngInitSet(fontPngPtr, fp, sizeof(header), fontInfoPtr); png_get_IHDR(fontPngPtr, fontInfoPtr, &fontWidth, &fontHeight, &fontBitDepth, &fontColorType, nullptr, nullptr, nullptr); - fontChannels = png_get_channels(fontPngPtr, fontInfoPtr); - const int defaultFontBitDepth = 8; - if (fontBitDepth <= defaultFontBitDepth && fontChannels == 1 && fontColorType == PNG_COLOR_TYPE_GRAY) { + png_byte fontChannels = png_get_channels(fontPngPtr, fontInfoPtr); + if (fontBitDepth <= defaultFontBitDepth_ && fontChannels == 1 && fontColorType == PNG_COLOR_TYPE_GRAY) { png_set_expand_gray_1_2_4_to_8(fontPngPtr); } - const int defaultFontWidth = 96; - fontWidth_ = fontWidth / defaultFontWidth; + fontWidth_ = fontWidth / defaultFontWidth_; fontHeight_ = fontHeight >> 1; PNGReadRow(fontWidth_, fontHeight_, fontPngPtr, fontBuf_); + CheckInitFont(fontPngPtr, fp, fontInfoPtr); } void TextLabel::SetText(const char *str) diff --git a/services/updater.cpp b/services/updater.cpp index 43fb6b6f..d19d4e64 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -116,17 +116,18 @@ int UpdatePreProcess(PkgManager::PkgManagerPtr pkgManager, const std::string &pa return ret; } -static UpdaterStatus IsSpaceCapacitySufficient(const std::string &packagePath) +static UpdaterStatus IsSpaceCapacitySufficient(PkgManager::PkgManagerPtr pkgManager, const std::string &packagePath) { - PkgManager::PkgManagerPtr pkgManager = hpackage::PkgManager::CreatePackageInstance(); + // PkgManager::PkgManagerPtr pkgManager = hpackage::PkgManager::CreatePackageInstance(); UPDATER_ERROR_CHECK(pkgManager != nullptr, "pkgManager is nullptr", return UPDATE_CORRUPT); std::vector fileIds; int ret = pkgManager->LoadPackageWithoutUnPack(packagePath, fileIds); - UPDATER_ERROR_CHECK(ret == PKG_SUCCESS, "LoadPackageWithoutUnPack failed", return UPDATE_CORRUPT); + UPDATER_ERROR_CHECK(ret == PKG_SUCCESS, "LoadPackageWithoutUnPack failed", + PkgManager::ReleasePackageInstance(pkgManager); return UPDATE_CORRUPT); const FileInfo *info = pkgManager->GetFileInfo("update.bin"); - UPDATER_ERROR_CHECK(info != nullptr, "update.bin is not exist", return UPDATE_CORRUPT); - + UPDATER_ERROR_CHECK(info != nullptr, "update.bin is not exist", + PkgManager::ReleasePackageInstance(pkgManager); return UPDATE_CORRUPT); PkgManager::ReleasePackageInstance(pkgManager); struct statvfs64 updaterVfs; @@ -184,7 +185,7 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons if (retryCount > 0) { LOG(INFO) << "Retry for " << retryCount << " time(s)"; } else { - UpdaterStatus ret = IsSpaceCapacitySufficient(packagePath); + UpdaterStatus ret = IsSpaceCapacitySufficient(pkgManager,packagePath); // Only handle UPATE_ERROR and UPDATE_SUCCESS here. // If it returns UPDATE_CORRUPT, which means something wrong with package manager. // Let package verify handle this. @@ -331,7 +332,7 @@ UpdaterStatus StartUpdaterProc(PkgManager::PkgManagerPtr pkgManager, const std:: UPDATER_ERROR_CHECK(fromChild != nullptr, "fdopen pipeRead failed", return UPDATE_ERROR); while (fgets(buffer, MAX_BUFFER_SIZE - 1, fromChild) != nullptr) { size_t n = strlen(buffer); - if (buffer[n - 1] == '\n') { + if (n > 0 && buffer[n - 1] == '\n') { buffer[n - 1] = '\0'; } HandleChildOutput(buffer, MAX_BUFFER_SIZE, retryUpdate); diff --git a/services/updater_binary/update_partitions.cpp b/services/updater_binary/update_partitions.cpp index 81f26e8b..0f431deb 100644 --- a/services/updater_binary/update_partitions.cpp +++ b/services/updater_binary/update_partitions.cpp @@ -48,24 +48,25 @@ int UpdatePartitions::ParsePartitionInfo(const std::string &partitionInfo, Parti return 0; } cJSON* thisPartition = cJSON_GetArrayItem(partitions, i); - UPDATER_ERROR_CHECK(thisPartition != nullptr, "Error get thisPartion", free(myPartition); break); + UPDATER_ERROR_CHECK(thisPartition != nullptr, "Error get thisPartion", free(myPartition); + myPartition = nullptr; break); cJSON* item = cJSON_GetObjectItem(thisPartition, "start"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get start", free(myPartition); break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get start", free(myPartition); myPartition = nullptr; break); myPartition->start = item->valueint; item = cJSON_GetObjectItem(thisPartition, "length"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get length", free(myPartition); break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get length", free(myPartition); myPartition = nullptr; break); myPartition->length = item->valueint; myPartition->partNum = 0; myPartition->devName = "mmcblk0px"; item = cJSON_GetObjectItem(thisPartition, "partName"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get partName", free(myPartition); break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get partName", free(myPartition); myPartition = nullptr; break); myPartition->partName = (item->valuestring); item = cJSON_GetObjectItem(thisPartition, "fsType"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get fsType", free(myPartition); break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get fsType", free(myPartition); myPartition = nullptr; break); myPartition->fsType = (item->valuestring); LOG(INFO) << " "; diff --git a/utils/utils.cpp b/utils/utils.cpp index 52c0b201..84b21d20 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -162,17 +162,18 @@ std::string ConvertSha256Hex(const uint8_t* shaDigest, size_t length) void DoReboot(const std::string& rebootTarget) { LOG(INFO) << ", rebootTarget: " << rebootTarget; - static const int32_t maxCommandSize = 16; LoadFstab(); auto miscBlockDevice = GetBlockDeviceByMountPoint("/misc"); struct UpdateMessage msg; if (rebootTarget == "updater") { + std::string command = "boot_updater"; bool ret = ReadUpdaterMessage(miscBlockDevice, msg); UPDATER_ERROR_CHECK(ret == true, "DoReboot read misc failed", return); - if (strcmp(msg.command, "boot_updater") != 0) { - UPDATER_ERROR_CHECK(!memcpy_s(msg.command, maxCommandSize, "boot_updater", maxCommandSize - 1), + if (strcmp(msg.command, command.c_str()) != 0) { + UPDATER_ERROR_CHECK(memset_s(msg.command, MAX_COMMAND_SIZE, 0, MAX_COMMAND_SIZE) == 0, + "Failed to clear update message", return); + UPDATER_ERROR_CHECK(!memcpy_s(msg.command, MAX_COMMAND_SIZE - 1, command.c_str(), command.size()), "Memcpy failed", return); - msg.command[maxCommandSize] = 0; } ret = WriteUpdaterMessage(miscBlockDevice, msg); if (ret != true) { -- Gitee From bade5693edb63a1fd31b89433ce9bd856cd4eacb Mon Sep 17 00:00:00 2001 From: ma_nan Date: Fri, 24 Sep 2021 15:19:04 +0800 Subject: [PATCH 2/3] fix codestyle Signed-off-by: ma_nan --- services/ui/text_label.h | 4 ++++ services/updater.cpp | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/services/ui/text_label.h b/services/ui/text_label.h index 39f4d1b2..82d5fb9a 100644 --- a/services/ui/text_label.h +++ b/services/ui/text_label.h @@ -75,6 +75,10 @@ private: char fontBuf_[MAX_FONT_BUFFER_SIZE_HW * FONT_BUFFER_SIZE] {}; unsigned int fontWidth_ = 0; unsigned int fontHeight_ = 0; + uint32_t offset_ = 2; + const int defaultFontWidth_ = 96; + const int defaultFontBitDepth_ = 8; + const int headerNumber_ = 8; }; } // namespace updater #endif diff --git a/services/updater.cpp b/services/updater.cpp index d19d4e64..f5e66db3 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -116,9 +116,9 @@ int UpdatePreProcess(PkgManager::PkgManagerPtr pkgManager, const std::string &pa return ret; } -static UpdaterStatus IsSpaceCapacitySufficient(PkgManager::PkgManagerPtr pkgManager, const std::string &packagePath) +static UpdaterStatus IsSpaceCapacitySufficient(const std::string &packagePath) { - // PkgManager::PkgManagerPtr pkgManager = hpackage::PkgManager::CreatePackageInstance(); + PkgManager::PkgManagerPtr pkgManager = hpackage::PkgManager::CreatePackageInstance(); UPDATER_ERROR_CHECK(pkgManager != nullptr, "pkgManager is nullptr", return UPDATE_CORRUPT); std::vector fileIds; int ret = pkgManager->LoadPackageWithoutUnPack(packagePath, fileIds); @@ -185,7 +185,7 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons if (retryCount > 0) { LOG(INFO) << "Retry for " << retryCount << " time(s)"; } else { - UpdaterStatus ret = IsSpaceCapacitySufficient(pkgManager,packagePath); + UpdaterStatus ret = IsSpaceCapacitySufficient(packagePath); // Only handle UPATE_ERROR and UPDATE_SUCCESS here. // If it returns UPDATE_CORRUPT, which means something wrong with package manager. // Let package verify handle this. -- Gitee From 3d3cc6ead5944dd4e43e182b36a8b9e2bde60baa Mon Sep 17 00:00:00 2001 From: ma_nan Date: Fri, 24 Sep 2021 15:24:36 +0800 Subject: [PATCH 3/3] fix codestyle Signed-off-by: ma_nan --- services/script/script_expression.cpp | 173 +++++++++++++++ services/script/script_expression.h | 206 +++++++++++++++++ services/script/script_interpreter.cpp | 210 ++++++++++++++++++ services/script/script_interpreter.h | 88 ++++++++ .../script_interpreter/script_expression.cpp | 12 +- .../script_interpreter/script_expression.h | 1 - .../script_interpreter/script_interpreter.h | 6 +- 7 files changed, 682 insertions(+), 14 deletions(-) create mode 100644 services/script/script_expression.cpp create mode 100644 services/script/script_expression.h create mode 100644 services/script/script_interpreter.cpp create mode 100644 services/script/script_interpreter.h diff --git a/services/script/script_expression.cpp b/services/script/script_expression.cpp new file mode 100644 index 00000000..048d1b38 --- /dev/null +++ b/services/script/script_expression.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "script_expression.h" +#include "script_function.h" +#include "script_interpreter.h" +#include "script_utils.h" + +using namespace std; + +namespace uscript { +UScriptExpression::UScriptExpression(ExpressionType expressType) : expressType_(expressType) {} +UScriptExpression::~UScriptExpression() {} + +UScriptExpression* AssignExpression::CreateExpression(std::string identifier, UScriptExpression *expression) +{ + return new AssignExpression(identifier, expression); +} +void AssignExpression::AddIdentifier(const std::string &identifier) +{ + multipleIdentifiers_.push_back(identifier); +} + +UScriptExpression* AssignExpression::AddIdentifier(UScriptExpression *expression, std::string identifier) +{ + auto assign = reinterpret_cast(expression); + if (assign != nullptr) { + assign->AddIdentifier(identifier); + } + return assign; +} + +// binary operator +UScriptExpression* BinaryExpression::CreateExpression(ExpressionAction action, + UScriptExpression *left, + UScriptExpression *right) +{ + return new BinaryExpression(action, left, right); +} +UScriptExpression* FunctionCallExpression::CreateExpression(std::string identifier, ScriptParams *params) +{ + return new FunctionCallExpression(identifier, params); +} +UScriptValuePtr UScriptExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) +{ + return std::make_shared(UScriptValue::VALUE_TYPE_ERROR); +} +UScriptValuePtr IntegerExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) +{ + return std::make_shared(this->value_); +} +UScriptValuePtr FloatExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) +{ + return std::make_shared(this->value_); +} +UScriptValuePtr StringExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) +{ + return std::make_shared(this->value_); +} +UScriptValuePtr IdentifierExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) +{ + INTERPRETER_LOGI(inter, local, "Execute statements identifier %s ", identifier_.c_str()); + UScriptValuePtr variable = inter.FindVariable(local, identifier_); + INTERPRETER_LOGI(inter, local, "IdentifierExpression::Execute '%s = %s ' ", identifier_.c_str(), + UScriptValue::ScriptToString(variable).c_str()); + if (variable != nullptr) { + return variable; + } + return std::make_shared(UScriptValue::VALUE_TYPE_ERROR); +} + +int32_t IdentifierExpression::GetIdentifierName(UScriptExpression *expression, std::string &name) +{ + if (expression->GetExpressType() != EXPRESSION_TYPE_IDENTIFIER) { + return USCRIPT_INVALID_PARAM; + } else { + auto identifier = reinterpret_cast(expression); + if (identifier != nullptr) { + name = identifier->GetIdentifier(); + return USCRIPT_SUCCESS; + } + } + return USCRIPT_INVALID_PARAM; +} +UScriptValuePtr AssignExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) +{ + UScriptValuePtr result = expression_->Execute(inter, local); + INTERPRETER_LOGI(inter, local, "AssignExpression::Execute update local var '%s = %s ' ", identifier_.c_str(), + UScriptValue::ScriptToString(result).c_str()); + if (result->GetValueType() == UScriptValue::VALUE_TYPE_ERROR) { + return result; + } + UScriptValuePtr var = inter.FindVariable(local, identifier_); + if (var != nullptr) { + inter.UpdateVariable(local, identifier_, result); + return result; + } + + std::vector identifiers; + identifiers.push_back(identifier_); + identifiers.insert(identifiers.begin() + 1, multipleIdentifiers_.begin(), multipleIdentifiers_.end()); + size_t index = 0; + local->UpdateVariables(inter, result, identifiers, index); + return result; +} + +UScriptValuePtr BinaryExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) +{ + static std::vector opStr = { + "", "add", "sub", "mul", "div", ">", ">=", "<", "<=", "==", "!=", "&&", "||" + }; + UScriptValuePtr left; + UScriptValuePtr right; + + INTERPRETER_LOGI(inter, local, "BinaryExpression::Execute "); + if (left_ != nullptr) { + left = left_->Execute(inter, local); + } + + if (action_ == OR_OPERATOR && left_ != nullptr && left->IsTrue()) { + INTERPRETER_LOGE(inter, local, "BinaryExpression::Execute left:%s %s", + UScriptValue::ScriptToString(left).c_str(), opStr[action_].c_str()); + return std::make_shared(1); + } + if (right_ != nullptr) { + right = right_->Execute(inter, local); + } + if (left != nullptr && right != nullptr) { + UScriptValuePtr value = left->Computer(action_, right); + INTERPRETER_LOGI(inter, local, "BinaryExpression::Execute left:%s %s right:%s result:%s", + UScriptValue::ScriptToString(left).c_str(), opStr[action_].c_str(), + UScriptValue::ScriptToString(right).c_str(), UScriptValue::ScriptToString(value).c_str()); + return value; + } + return std::make_shared(USCRIPT_ERROR_INTERPRET); +} + +UScriptValuePtr FunctionCallExpression::Execute(ScriptInterpreter &inter, UScriptContextPtr local) +{ + UScriptValuePtr v; + INTERPRETER_LOGI(inter, local, "FunctionCallExpression::Execute %s ", functionName_.c_str()); + + if (inter.IsNativeFunction(functionName_)) { + return inter.ExecuteNativeFunc(local, functionName_, params_); + } + return inter.ExecuteFunction(local, functionName_, params_); +} + +BinaryExpression::~BinaryExpression() +{ + delete left_; + delete right_; +} +AssignExpression::~AssignExpression() +{ + delete this->expression_; +} +FunctionCallExpression::~FunctionCallExpression() +{ + delete params_; +} +} // namespace uscript diff --git a/services/script/script_expression.h b/services/script/script_expression.h new file mode 100644 index 00000000..1d4e163f --- /dev/null +++ b/services/script/script_expression.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef USCRIPT_EXPRESSION_H +#define USCRIPT_EXPRESSION_H + +#include +#include "script_context.h" + +namespace uscript { +class UScriptExpression; +using UScriptExpressionPtr = std::shared_ptr; + +class ScriptParams; +class ScriptFunction; + +class UScriptExpression { +public: + enum ExpressionType { + EXPRESSION_TYPE_INTERGER, + EXPRESSION_TYPE_FLOAT, + EXPRESSION_TYPE_STRING, + EXPRESSION_TYPE_IDENTIFIER, + EXPRESSION_TYPE_BINARY, + EXPRESSION_TYPE_ASSIGN, + EXPRESSION_TYPE_INV, + EXPRESSION_TYPE_FUNC, + EXPRESSION_TYPE_INVALID, + }; + enum ExpressionAction { + ADD_OPERATOR = 1, + SUB_OPERATOR, + MUL_OPERATOR, + DIV_OPERATOR, + GT_OPERATOR, + GE_OPERATOR, + LT_OPERATOR, + LE_OPERATOR, + EQ_OPERATOR, + NE_OPERATOR, + AND_OPERATOR, + OR_OPERATOR + }; + +public: + explicit UScriptExpression(ExpressionType expressType); + virtual ~UScriptExpression(); + + virtual UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local); + static UScriptExpression* CreateExpression(ExpressionType expressType) + { + return new UScriptExpression(expressType); + } + ExpressionType GetExpressType() + { + return expressType_; + } + +private: + ExpressionType expressType_; +}; + +class IntegerExpression : public UScriptExpression { +public: + explicit IntegerExpression(int v) : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_INTERGER) + { + value_ = v; + } + + ~IntegerExpression() override {} + + UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override; + + static UScriptExpression* CreateExpression(int value) + { + return new IntegerExpression(value); + } +private: + int value_; +}; + +class FloatExpression : public UScriptExpression { +public: + explicit FloatExpression(float v) : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_FLOAT) + { + value_ = v; + } + + ~FloatExpression() override {} + + UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override; + + static UScriptExpression* CreateExpression(float value) + { + return new FloatExpression(value); + } + +private: + float value_; +}; + +class StringExpression : public UScriptExpression { +public: + explicit StringExpression(std::string str) : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_STRING), + value_(str) {} + + ~StringExpression() override {} + + UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override; + + static UScriptExpression* CreateExpression(std::string value) + { + return new StringExpression(value); + } +private: + std::string value_; +}; + +class IdentifierExpression : public UScriptExpression { +public: + explicit IdentifierExpression(std::string str) + : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_IDENTIFIER), identifier_(str) {} + + ~IdentifierExpression() override {} + + UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override; + + static UScriptExpression* CreateExpression(std::string value) + { + return new IdentifierExpression(value); + } + + const std::string GetIdentifier() + { + return identifier_; + } + + static int32_t GetIdentifierName(UScriptExpression *expression, std::string &name); +private: + std::string identifier_; +}; + +class BinaryExpression : public UScriptExpression { +public: + BinaryExpression(ExpressionAction action, UScriptExpression *left, UScriptExpression *right) + : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_BINARY), action_(action), left_(left), right_(right) {} + + ~BinaryExpression() override; + + UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override; + + static UScriptExpression* CreateExpression(ExpressionAction action, UScriptExpression *left, + UScriptExpression *right); +private: + UScriptExpression::ExpressionAction action_; + UScriptExpression* left_ = nullptr; + UScriptExpression* right_ = nullptr; +}; + +class AssignExpression : public UScriptExpression { +public: + AssignExpression(std::string identifier, UScriptExpression *expression) + : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_ASSIGN), identifier_(identifier), + expression_(expression) {} + + ~AssignExpression() override; + + UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override; + + void AddIdentifier(const std::string &identifiers); + + static UScriptExpression* CreateExpression(std::string identifier, UScriptExpression *expression); + static UScriptExpression* AddIdentifier(UScriptExpression *expression, std::string identifier); +private: + std::string identifier_; + std::vector multipleIdentifiers_; // 最大支持4个参数a,b,v = 1 + UScriptExpression* expression_ = nullptr; +}; + +class FunctionCallExpression : public UScriptExpression { +public: + FunctionCallExpression(std::string identifier, ScriptParams *params) + : UScriptExpression(UScriptExpression::EXPRESSION_TYPE_FUNC), functionName_(identifier), params_(params) {} + + ~FunctionCallExpression() override; + + UScriptValuePtr Execute(ScriptInterpreter &inter, UScriptContextPtr local) override; + + static UScriptExpression* CreateExpression(std::string identifier, ScriptParams *params); +private: + std::string functionName_; + ScriptParams* params_ = nullptr; +}; +} // namespace uscript +#endif // _HS_EXPRESSION_H diff --git a/services/script/script_interpreter.cpp b/services/script/script_interpreter.cpp new file mode 100644 index 00000000..0531a914 --- /dev/null +++ b/services/script/script_interpreter.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "script_interpreter.h" +#include +#include +#include "script_context.h" +#include "script_manager_impl.h" +#include "scanner.h" +#include "script_utils.h" + +using namespace std; + +namespace uscript { +static int32_t g_instanceId = 0; + +int32_t ScriptInterpreter::ExecuteScript(ScriptManagerImpl *manager, hpackage::PkgManager::StreamPtr pkgStream) +{ + USCRIPT_CHECK(pkgStream != nullptr, return USCRIPT_INVALID_PARAM, "Param error"); + USCRIPT_LOGI("ExecuteScript %s", pkgStream->GetFileName().c_str()); + auto inter = new ScriptInterpreter(manager); + USCRIPT_CHECK(inter != nullptr, return USCRIPT_ERROR_CREATE_OBJ, + "Fail to create ScriptInterpreter for script %s", pkgStream->GetFileName().c_str()); + int32_t ret = inter->LoadScript(pkgStream); + USCRIPT_CHECK(ret == USCRIPT_SUCCESS, return ret, "Fail to loadScript script %s", pkgStream->GetFileName().c_str()); + ret = inter->Execute(); + delete inter; + USCRIPT_LOGI("ExecuteScript finish ret: %d script: %s ", + ret, pkgStream->GetFileName().c_str()); + return ret; +} + +ScriptInterpreter::ScriptInterpreter(ScriptManagerImpl *manager) : scriptManager_(manager) +{ + instanceId_ = g_instanceId++; +} + +ScriptInterpreter::~ScriptInterpreter() +{ + delete statements_; + auto iter = functions_.begin(); + while (iter != functions_.end()) { + auto entry = iter->second; + if (entry) { + delete entry; + } + iter = functions_.erase(iter); + } + functions_.clear(); + contextStack_.clear(); + delete scanner_; + delete parser_; +} + +int32_t ScriptInterpreter::LoadScript(hpackage::PkgManager::StreamPtr pkgStream) +{ + scanner_ = new Scanner(this); + parser_ = new Parser(scanner_, this); + if (scanner_ == nullptr || parser_ == nullptr) { + USCRIPT_LOGE("Fail to open fstream %s", pkgStream->GetFileName().c_str()); + delete parser_; + delete scanner_; + return USCRIPT_ERROR_CREATE_OBJ; + } + scanner_->set_debug(0); + scanner_->SetPkgStream(pkgStream); + int32_t ret = parser_->parse(); + return ret; +} + +int32_t ScriptInterpreter::Execute() +{ + UScriptContextPtr context = std::make_shared(true); + UScriptStatementResult result = statements_->Execute(*this, context); + INTERPRETER_LOGI(*this, context, "statements_ execute result %s ", + UScriptStatementResult::ScriptToString(&result).c_str()); + if (result.GetResultType() == UScriptStatementResult::STATEMENT_RESULT_TYPE_ERROR) { + return result.GetError(); + } + return USCRIPT_SUCCESS; +} + +int32_t ScriptInterpreter::AddFunction(ScriptFunction *function) +{ + if (functions_.find(function->GetFunctionName()) != functions_.end()) { + USCRIPT_LOGI("Fail to add function %s, function exist", function->GetFunctionName().c_str()); + return USCRIPT_SUCCESS; + } + functions_[function->GetFunctionName()] = function; + return USCRIPT_SUCCESS; +} + +ScriptFunction* ScriptInterpreter::FindFunction(const std::string &name) +{ + if (functions_.find(name) != functions_.end()) { + return functions_[name]; + } + return nullptr; +} + +UScriptValuePtr ScriptInterpreter::ExecuteFunction(UScriptContextPtr context, const std::string &name, + ScriptParams *params) +{ + ScriptFunction *function = FindFunction(name); + if (function == nullptr) { + USCRIPT_LOGI("Fail to find function %s", name.c_str()); + return std::make_shared(USCRIPT_NOTEXIST_INSTRUCTION); + } else { + return function->Execute(*this, context, params); + } +} + +UScriptValuePtr ScriptInterpreter::FindVariable(UScriptContextPtr local, std::string id) +{ + for (auto context = contextStack_.rbegin(); context != contextStack_.rend(); context++) { + UScriptValuePtr variable = (*context)->FindVariable(*this, id); + if (variable != nullptr) { + return variable; + } + if ((*context)->IsTop()) { + break; + } + } + return nullptr; +} + +UScriptValuePtr ScriptInterpreter::UpdateVariable(UScriptContextPtr local, std::string id, UScriptValuePtr var) +{ + for (auto context = contextStack_.rbegin(); context != contextStack_.rend(); context++) { + UScriptValuePtr variable = (*context)->FindVariable(*this, id); + if (variable != nullptr) { + (*context)->UpdateVariable(*this, id, var); + } + if ((*context)->IsTop()) { + break; + } + } + return nullptr; +} + +void ScriptInterpreter::AddStatement(UScriptStatement *statement) +{ + if (statements_ == nullptr) { + statements_ = UScriptStatementList::CreateInstance(statement); + } else { + statements_->AddScriptStatement(statement); + } +} + +bool ScriptInterpreter::IsNativeFunction(std::string name) +{ + return scriptManager_->FindInstruction(name) != nullptr; +} + +UScriptValuePtr ScriptInterpreter::ExecuteNativeFunc(UScriptContextPtr context, + const std::string &name, ScriptParams *params) +{ + std::shared_ptr error = std::make_shared(USCRIPT_ERROR_INTERPRET); + std::shared_ptr retValue = std::make_shared(); + INTERPRETER_LOGI(*this, context, "ExecuteNativeFunc::Execute %s ", name.c_str()); + UScriptInstruction* instruction = scriptManager_->FindInstruction(name); + USCRIPT_CHECK(instruction != nullptr, return error, "Fail to find instruction %s", name.c_str()); + + std::shared_ptr funcContext = std::make_shared(); + USCRIPT_CHECK(funcContext != nullptr, return error, "Fail to create context %s", name.c_str()); + if (params == nullptr) { + int32_t ret = instruction->Execute(*scriptManager_->GetScriptEnv(name), *funcContext.get()); + retValue->AddValues(funcContext->GetOutVar()); + INTERPRETER_LOGI(*this, context, "ExecuteNativeFunc::Execute %s result: %d", name.c_str(), ret); + return retValue; + } + + for (auto id : params->GetParams()) { + UScriptValuePtr result = id->Execute(*this, context); + if (result == nullptr || result->GetValueType() == UScriptValue::VALUE_TYPE_ERROR) { + INTERPRETER_LOGI(*this, context, "ExecuteNativeFunc::Execute %s ", name.c_str()); + return error; + } + + if (result->GetValueType() != UScriptValue::VALUE_TYPE_LIST) { + funcContext->AddInputParam(result); + } else { + ReturnValue* values = (ReturnValue*)(result.get()); + for (auto out : values->GetValues()) { + funcContext->AddInputParam(out); + } + } + } + + int32_t ret = instruction->Execute(*scriptManager_->GetScriptEnv(name), *funcContext.get()); + INTERPRETER_LOGI(*this, context, "ExecuteNativeFunc::Execute %s result: %d", name.c_str(), ret); + if (ret != USCRIPT_SUCCESS) { + error->SetValue(ret); + return error; + } + retValue->AddValues(funcContext->GetOutVar()); + return retValue; +} +} // namespace uscript diff --git a/services/script/script_interpreter.h b/services/script/script_interpreter.h new file mode 100644 index 00000000..adced81b --- /dev/null +++ b/services/script/script_interpreter.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef USCRIPT_INTERPRETER_H +#define USCRIPT_INTERPRETER_H + +#include "script_context.h" +#include "script_expression.h" +#include "script_function.h" +#include "script_manager_impl.h" +#include "script_param.h" +#include "script_statement.h" + +#define INTERPRETER_LOGE(inter, context, format, ...) \ + Logger(updater::INFO, (__FILE_NAME__), (__LINE__), \ + "[INTERPRETER %d-%d]"#format, (inter).GetInstanceId(), (context)->GetContextId(), ##__VA_ARGS__) +#define INTERPRETER_LOGI(inter, context, format, ...) \ + Logger(updater::INFO, (__FILE_NAME__), (__LINE__), \ + "[INTERPRETER %d-%d]"#format, (inter).GetInstanceId(), (context)->GetContextId(), ##__VA_ARGS__) + +#define INTERPRETER_CHECK(inter, context, ret, statement, ...) \ + if (!(ret)) { \ + INTERPRETER_LOGE(inter, context, __VA_ARGS__); \ + statement; \ + } + +namespace uscript { +class Parser; +class Scanner; +class ScriptManagerImpl; + +class ScriptInterpreter { +public: + static int32_t ExecuteScript(ScriptManagerImpl *manager, hpackage::PkgManager::StreamPtr pkgStream); + + explicit ScriptInterpreter(ScriptManagerImpl *manager); + ~ScriptInterpreter(); + + void AddStatement(UScriptStatement *statement); + int32_t AddFunction(ScriptFunction *function); + bool IsNativeFunction(std::string name); + UScriptValuePtr ExecuteNativeFunc(UScriptContextPtr upContext, const std::string &name, + ScriptParams *params); + UScriptValuePtr ExecuteFunction(UScriptContextPtr context, const std::string &name, + ScriptParams *params); + UScriptValuePtr FindVariable(UScriptContextPtr local, std::string id); + UScriptValuePtr UpdateVariable(UScriptContextPtr local, std::string id, UScriptValuePtr var); + int32_t GetInstanceId() const + { + return instanceId_; + } + + void ContextPush(UScriptContextPtr context) + { + contextStack_.push_back(context); + } + void ContextPop() + { + contextStack_.pop_back(); + } + +private: + int32_t LoadScript(hpackage::PkgManager::StreamPtr pkgStream); + int32_t Execute(); + +private: + ScriptFunction* FindFunction(const std::string &name); + UScriptStatementList* statements_ = nullptr; + std::map functions_; + std::vector contextStack_; + ScriptManagerImpl* scriptManager_ = nullptr; + Parser* parser_ = nullptr; + Scanner* scanner_ = nullptr; + int32_t instanceId_ = 0; +}; +} // namespace uscript +#endif diff --git a/services/script/script_interpreter/script_expression.cpp b/services/script/script_interpreter/script_expression.cpp index d3f6293b..048d1b38 100644 --- a/services/script/script_interpreter/script_expression.cpp +++ b/services/script/script_interpreter/script_expression.cpp @@ -154,16 +154,7 @@ UScriptValuePtr FunctionCallExpression::Execute(ScriptInterpreter &inter, UScrip if (inter.IsNativeFunction(functionName_)) { return inter.ExecuteNativeFunc(local, functionName_, params_); } - - ScriptFunction* function = function_; - if (function_ == nullptr) { - function = inter.FindFunction(functionName_); - } - if (function == nullptr) { - INTERPRETER_LOGI(inter, local, "Can not find function %s", functionName_.c_str()); - return std::make_shared(USCRIPT_NOTEXIST_INSTRUCTION); - } - return function->Execute(inter, local, params_); + return inter.ExecuteFunction(local, functionName_, params_); } BinaryExpression::~BinaryExpression() @@ -177,7 +168,6 @@ AssignExpression::~AssignExpression() } FunctionCallExpression::~FunctionCallExpression() { - delete function_; delete params_; } } // namespace uscript diff --git a/services/script/script_interpreter/script_expression.h b/services/script/script_interpreter/script_expression.h index c864969c..1d4e163f 100644 --- a/services/script/script_interpreter/script_expression.h +++ b/services/script/script_interpreter/script_expression.h @@ -200,7 +200,6 @@ public: static UScriptExpression* CreateExpression(std::string identifier, ScriptParams *params); private: std::string functionName_; - ScriptFunction* function_ = nullptr; ScriptParams* params_ = nullptr; }; } // namespace uscript diff --git a/services/script/script_interpreter/script_interpreter.h b/services/script/script_interpreter/script_interpreter.h index 7a30b0a1..adced81b 100644 --- a/services/script/script_interpreter/script_interpreter.h +++ b/services/script/script_interpreter/script_interpreter.h @@ -49,10 +49,11 @@ public: void AddStatement(UScriptStatement *statement); int32_t AddFunction(ScriptFunction *function); - ScriptFunction* FindFunction(const std::string &name); bool IsNativeFunction(std::string name); UScriptValuePtr ExecuteNativeFunc(UScriptContextPtr upContext, const std::string &name, ScriptParams *params); + UScriptValuePtr ExecuteFunction(UScriptContextPtr context, const std::string &name, + ScriptParams *params); UScriptValuePtr FindVariable(UScriptContextPtr local, std::string id); UScriptValuePtr UpdateVariable(UScriptContextPtr local, std::string id, UScriptValuePtr var); int32_t GetInstanceId() const @@ -74,6 +75,7 @@ private: int32_t Execute(); private: + ScriptFunction* FindFunction(const std::string &name); UScriptStatementList* statements_ = nullptr; std::map functions_; std::vector contextStack_; @@ -83,4 +85,4 @@ private: int32_t instanceId_ = 0; }; } // namespace uscript -#endif \ No newline at end of file +#endif -- Gitee