Merge branch 'master' of gitee.com:openharmony/developtools_syscap_codec into master

Signed-off-by: 创达 <fangwanning@huawei.com>
This commit is contained in:
创达
2022-11-29 08:34:41 +00:00
committed by Gitee
10 changed files with 486 additions and 604 deletions
+23 -60
View File
@@ -59,6 +59,9 @@ ohos_executable("syscap_tool_bin") {
if (is_mingw) {
defines += [ "_POSIX_" ]
}
if (defined(ohos_lite) && ohos_kernel_type == "liteos_m") {
cflags = [ "-DPATH_MAX=1024" ]
}
sources = [ "./src/main.c" ]
sources += sources_platform_common
@@ -74,71 +77,32 @@ ohos_executable("syscap_tool_bin") {
part_name = "syscap_codec"
}
ohos_executable("syscap_tool_test") {
install_enable = true
include_dirs = [ "src" ]
public_configs = [ ":pubilc" ]
defines = []
if (is_mingw) {
defines += [ "_POSIX_" ]
}
sources = [ "./test/syscap_tool_test.c" ]
sources += sources_platform_common
deps = [ "//third_party/bounds_checking_function:libsec_static" ]
if (defined(ohos_lite)) {
deps += [ "//build/lite/config/component/cJSON:cjson_static" ]
} else {
deps += [ "//third_party/cJSON:cjson_static" ]
}
subsystem_name = "developtools"
part_name = "syscap_codec"
}
ohos_shared_library("syscap_tool_shared") {
output_name = "syscap_codec"
include_dirs = [ "src" ]
public_configs = [ ":pubilc" ]
sources = sources_platform_common
deps = [ "//third_party/bounds_checking_function:libsec_static" ]
if (defined(ohos_lite)) {
deps += [ "//build/lite/config/component/cJSON:cjson_static" ]
} else {
deps += [ "//third_party/cJSON:cjson_static" ]
}
subsystem_name = "developtools"
part_name = "syscap_codec"
}
config("syscap_interface_public_config") {
include_dirs = [ "./interfaces/inner_api/" ]
}
if (defined(ohos_lite)) {
shared_library("syscap_interface_shared") {
include_dirs = [
"include",
"src",
]
public_configs = [ ":syscap_interface_public_config" ]
sources = [
"./interfaces/inner_api/syscap_interface.c",
"./src/endian_internal.c",
"./src/syscap_tool.c",
]
if (ohos_kernel_type == "liteos_m") {
group("syscap_interface_shared") {
}
} else {
shared_library("syscap_interface_shared") {
include_dirs = [
"include",
"src",
]
public_configs = [ ":syscap_interface_public_config" ]
sources = [
"./interfaces/inner_api/syscap_interface.c",
"./src/endian_internal.c",
"./src/syscap_tool.c",
]
deps = [
"//build/lite/config/component/cJSON:cjson_static",
"//third_party/bounds_checking_function:libsec_static",
]
deps = [
"//build/lite/config/component/cJSON:cjson_static",
"//third_party/bounds_checking_function:libsec_static",
]
}
}
} else {
ohos_shared_library("syscap_interface_shared") {
@@ -199,7 +163,6 @@ group("syscap_codec") {
":pcid_sc",
":syscap_define_check",
":syscap_interface_shared",
":syscap_tool_shared",
]
if (support_jsapi && is_standard_system) {
deps += [ "napi:systemcapability" ]
+27
View File
@@ -248,6 +248,19 @@ typedef enum SystemCapabilityNum {
// Add here
MULTIMODALINPUT_INPUT_COOPERATOR,
ABILITY_ABILITYRUNTIME_QUICKFIX,
SECURITY_DLPCREDENTIALSERVICE,
BUNDLEMANAGER_BUNDLEFRAMEWORK_APPCONTROL,
BUNDLEMANAGER_BUNDLEFRAMEWORK_CORE,
BUNDLEMANAGER_BUNDLEFRAMEWORK_FREEINSTALL,
BUNDLEMANAGER_BUNDLEFRAMEWORK_LAUNCHER,
BUNDLEMANAGER_BUNDLEFRAMEWORK_DEFAULTAPP,
BUNDLEMANAGER_BUNDLEFRAMEWORK_RESOURCE,
MULTIMEDIA_AVSESSION_CORE,
MULTIMEDIA_AVSESSION_MANAGER,
MULTIMEDIA_AUDIO_TONE,
MULTIMEDIA_AUDIO_INTERRUPT,
CLOUD_AAID,
MSDP_DEVICESTATUS_STATIONARY,
SYSCAP_NUM_MAX = 960
} SyscapNum;
@@ -473,6 +486,20 @@ const static SyscapWithNum g_arraySyscap[] = {
{"SystemCapability.Security.CryptoFramework", SECURITY_CRYPTOFRAMEWORK},
{"SystemCapability.MultimodalInput.Input.Cooperator", MULTIMODALINPUT_INPUT_COOPERATOR},
{"SystemCapability.Ability.AbilityRuntime.QuickFix", ABILITY_ABILITYRUNTIME_QUICKFIX},
{"SystemCapability.Security.DlpCredentialService", SECURITY_DLPCREDENTIALSERVICE},
{"SystemCapability.BundleManager.BundleFramework.AppControl", BUNDLEMANAGER_BUNDLEFRAMEWORK_APPCONTROL},
{"SystemCapability.BundleManager.BundleFramework.Core", BUNDLEMANAGER_BUNDLEFRAMEWORK_CORE},
{"SystemCapability.BundleManager.BundleFramework.FreeInstall", BUNDLEMANAGER_BUNDLEFRAMEWORK_FREEINSTALL},
{"SystemCapability.BundleManager.BundleFramework.Launcher", BUNDLEMANAGER_BUNDLEFRAMEWORK_LAUNCHER},
{"SystemCapability.BundleManager.BundleFramework.DefaultApp",
BUNDLEMANAGER_BUNDLEFRAMEWORK_DEFAULTAPP},
{"SystemCapability.BundleManager.BundleFramework.Resource", BUNDLEMANAGER_BUNDLEFRAMEWORK_RESOURCE},
{"SystemCapability.Multimedia.AVSession.Core", MULTIMEDIA_AVSESSION_CORE},
{"SystemCapability.Multimedia.AVSession.Manager", MULTIMEDIA_AVSESSION_MANAGER},
{"SystemCapability.Multimedia.Audio.Tone", MULTIMEDIA_AUDIO_TONE},
{"SystemCapability.Multimedia.Audio.Interrupt", MULTIMEDIA_AUDIO_INTERRUPT},
{"SystemCapability.Cloud.AAID", CLOUD_AAID},
{"SystemCapability.Msdp.DeviceStatus.Stationary", MSDP_DEVICESTATUS_STATIONARY},
};
#ifdef __cplusplus
+1 -1
View File
@@ -298,7 +298,7 @@ bool DecodePrivateSyscap(char *input, char (**output)[SINGLE_SYSCAP_LEN], int *o
return true;
}
static int SetOsSysCapBitMap(uint8_t *out, uint16_t outLen, uint16_t *index, uint16_t indexLen)
static int SetOsSysCapBitMap(uint8_t *out, uint16_t outLen, const uint16_t *index, uint16_t indexLen)
{
uint16_t sector, pos;
+24 -24
View File
@@ -42,7 +42,7 @@ constexpr size_t KEY_BUFFER_SIZE = 32;
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)
// Async Function Set
struct systemCapabilityAsyncContext {
struct SystemCapabilityAsyncContext {
napi_env env = nullptr;
napi_async_work work = nullptr;
char key[KEY_BUFFER_SIZE] = { 0 };
@@ -64,7 +64,7 @@ static char* getSystemCapability()
uint32_t *osCapU32 = nullptr;
char *priOutput = nullptr;
char *temp = nullptr;
char *allSyscapBUffer = nullptr;
char *allSyscapBuffer = nullptr;
char osCapArray[PCID_MAIN_U32][U32_TO_STR_MAX_LEN] = {};
char (*priCapArray)[SINGLE_SYSCAP_LEN] = nullptr;
@@ -105,39 +105,39 @@ static char* getSystemCapability()
sumLen += (PCID_MAIN_U32 + priCapArrayCnt + 1); // split with ','
// splicing string
allSyscapBUffer = (char *)malloc(sumLen);
if (allSyscapBUffer == nullptr) {
allSyscapBuffer = (char *)malloc(sumLen);
if (allSyscapBuffer == nullptr) {
PRINT_ERR("malloc failed!");
goto FREE_PRICAP_ARRAY;
}
err = memset_s(allSyscapBUffer, sumLen, 0, sumLen);
err = memset_s(allSyscapBuffer, sumLen, 0, sumLen);
if (err != EOK) {
PRINT_ERR("memset failed!");
free(allSyscapBUffer);
allSyscapBUffer = nullptr;
free(allSyscapBuffer);
allSyscapBuffer = nullptr;
goto FREE_PRICAP_ARRAY;
}
temp = *osCapArray;
for (size_t i = 1; i < PCID_MAIN_U32; i++) {
retError = sprintf_s(allSyscapBUffer, sumLen, "%s,%s", temp, osCapArray[i]);
retError = sprintf_s(allSyscapBuffer, sumLen, "%s,%s", temp, osCapArray[i]);
if (retError == -1) {
PRINT_ERR("splicing os syscap string failed.");
free(allSyscapBUffer);
allSyscapBUffer = nullptr;
free(allSyscapBuffer);
allSyscapBuffer = nullptr;
goto FREE_PRICAP_ARRAY;
}
temp = allSyscapBUffer;
temp = allSyscapBuffer;
}
for (int i = 0; i < priCapArrayCnt; i++) {
retError = sprintf_s(allSyscapBUffer, sumLen, "%s,%s", temp, *(priCapArray + i));
retError = sprintf_s(allSyscapBuffer, sumLen, "%s,%s", temp, *(priCapArray + i));
if (retError == -1) {
PRINT_ERR("splicing pri syscap string failed.");
free(allSyscapBUffer);
allSyscapBUffer = nullptr;
free(allSyscapBuffer);
allSyscapBuffer = nullptr;
goto FREE_PRICAP_ARRAY;
}
temp = allSyscapBUffer;
temp = allSyscapBuffer;
}
FREE_PRICAP_ARRAY:
@@ -145,7 +145,7 @@ FREE_PRICAP_ARRAY:
FREE_PRIOUTPUT:
free(priOutput);
return allSyscapBUffer;
return allSyscapBuffer;
}
napi_value QuerySystemCapability(napi_env env, napi_callback_info info)
@@ -154,7 +154,7 @@ napi_value QuerySystemCapability(napi_env env, napi_callback_info info)
NAPI_ASSERT(env, argc <= 1, "too many parameters");
napi_value result = nullptr;
systemCapabilityAsyncContext* asyncContext = new systemCapabilityAsyncContext();
SystemCapabilityAsyncContext* asyncContext = new SystemCapabilityAsyncContext();
asyncContext->env = env;
@@ -178,7 +178,7 @@ napi_value QuerySystemCapability(napi_env env, napi_callback_info info)
napi_create_async_work(
env, nullptr, resource,
[](napi_env env, void* data) {
systemCapabilityAsyncContext *asyncContext = (systemCapabilityAsyncContext *)data;
SystemCapabilityAsyncContext *asyncContext = (SystemCapabilityAsyncContext *)data;
char *syscapStr = getSystemCapability();
if (syscapStr != nullptr) {
asyncContext->value = syscapStr;
@@ -188,8 +188,8 @@ napi_value QuerySystemCapability(napi_env env, napi_callback_info info)
}
},
[](napi_env env, napi_status status, void* data) {
systemCapabilityAsyncContext *asyncContext = (systemCapabilityAsyncContext *)data;
napi_value result[2] = {0};
SystemCapabilityAsyncContext *asyncContext = (SystemCapabilityAsyncContext *)data;
napi_value result[2] = {nullptr, nullptr};
if (!asyncContext->status) {
napi_get_undefined(env, &result[0]);
napi_create_string_utf8(env, asyncContext->value, strlen(asyncContext->value), &result[1]); // ?
@@ -235,14 +235,14 @@ EXTERN_C_END
/*
* Module define
*/
static napi_module systemCapabilityModule = {
static napi_module g_systemCapabilityModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = QuerryExport,
.nm_modname = "systemCapability",
.nm_priv = ((void*)0),
.reserved = {0},
.nm_priv = nullptr,
.reserved = {nullptr},
};
/*
@@ -250,6 +250,6 @@ static napi_module systemCapabilityModule = {
*/
extern "C" __attribute__((constructor)) void systemCapabilityRegisterModule(void)
{
napi_module_register(&systemCapabilityModule);
napi_module_register(&g_systemCapabilityModule);
}
}
+22 -22
View File
@@ -231,8 +231,8 @@ int32_t CreatePCID(char *inputFile, char *outDirPath)
uint16_t allPriSyscapStrLen = 0;
for (i = 0; i < privateCapSize; i++) {
jsonArrayItem = cJSON_GetArrayItem(jsonPriSyscapObj, i);
allPriSyscapStrLen += strlen(strchr(jsonArrayItem->valuestring, '.') + 1);
jsonArrayItem = cJSON_GetArrayItem(jsonPriSyscapObj, (int)i);
allPriSyscapStrLen += (uint16_t)strlen(strchr(jsonArrayItem->valuestring, '.') + 1);
allPriSyscapStrLen++; // for separator ','
}
if ((allPriSyscapStrLen + 1) > PRIVATE_SYSCAP_SIZE) {
@@ -241,18 +241,18 @@ int32_t CreatePCID(char *inputFile, char *outDirPath)
goto FREE_CONVERT_OUT;
}
uint16_t PCIDLength = sizeof(PCIDMain) + allPriSyscapStrLen + 1;
PCIDMain *PCIDBuffer = (PCIDMain *)malloc(PCIDLength);
if (PCIDBuffer == NULL) {
uint16_t pcidLength = sizeof(PCIDMain) + allPriSyscapStrLen + 1;
PCIDMain *pcidBuffer = (PCIDMain *)malloc(pcidLength);
if (pcidBuffer == NULL) {
PRINT_ERR("malloc for pcid buffer failed\n");
ret = -1;
goto FREE_CONVERT_OUT;
}
(void)memset_s(PCIDBuffer, PCIDLength, 0, PCIDLength);
(void)memset_s(pcidBuffer, pcidLength, 0, pcidLength);
// process os syscap
for (i = 0; i < osCapSize; i++) {
jsonArrayItem = cJSON_GetArrayItem(jsonOsSyscapObj, i);
jsonArrayItem = cJSON_GetArrayItem(jsonOsSyscapObj, (int)i);
osCapIndex = cJSON_GetObjectItem(allOsSyscapObj, jsonArrayItem->valuestring);
if (osCapIndex == NULL) {
PRINT_ERR("can't find the syscap: %s, please add it in syscap_define.h.\n", jsonArrayItem->valuestring);
@@ -266,14 +266,14 @@ int32_t CreatePCID(char *inputFile, char *outDirPath)
ret = -1;
goto FREE_PCID_BUFFER_OUT;
}
PCIDBuffer->osSyscap[sectorOfBits] |= 1 << (posOfBits);
pcidBuffer->osSyscap[sectorOfBits] |= 1 << (posOfBits);
}
// process private syscap
char *priSyscapHead = (char *)(PCIDBuffer + 1);
char *priSyscapHead = (char *)(pcidBuffer + 1);
char *priSyscapStr = NULL;
for (i = 0; i < privateCapSize; i++) {
jsonArrayItem = cJSON_GetArrayItem(jsonPriSyscapObj, i);
jsonArrayItem = cJSON_GetArrayItem(jsonPriSyscapObj, (int)i);
priSyscapStr = strchr(jsonArrayItem->valuestring, '.') + 1;
nRet = strcat_s(priSyscapHead, allPriSyscapStrLen + 1, priSyscapStr);
nRet += strcat_s(priSyscapHead, allPriSyscapStrLen + 1, ",");
@@ -290,8 +290,8 @@ int32_t CreatePCID(char *inputFile, char *outDirPath)
ret = -1;
goto FREE_PCID_BUFFER_OUT;
}
PCIDBuffer->apiVersion = HtonsInter((uint16_t)jsonSyscapObj->valueint);
PCIDBuffer->apiVersionType = 0;
pcidBuffer->apiVersion = HtonsInter((uint16_t)jsonSyscapObj->valueint);
pcidBuffer->apiVersionType = 0;
jsonSyscapObj = cJSON_GetObjectItem(jsonRootObj, "system_type");
if (jsonSyscapObj == NULL || !cJSON_IsString(jsonSyscapObj)) {
@@ -300,10 +300,10 @@ int32_t CreatePCID(char *inputFile, char *outDirPath)
goto FREE_PCID_BUFFER_OUT;
}
systemType = jsonSyscapObj->valuestring;
PCIDBuffer->systemType = !strcmp(systemType, "mini") ? 0b001 :
pcidBuffer->systemType = !strcmp(systemType, "mini") ? 0b001 :
(!strcmp(systemType, "small") ? 0b010 :
(!strcmp(systemType, "standard") ? 0b100 : 0));
if (PCIDBuffer->systemType == 0) {
if (pcidBuffer->systemType == 0) {
PRINT_ERR("\"system_type\" is invaild, systemType = \"%s\"\n", systemType);
ret = -1;
goto FREE_PCID_BUFFER_OUT;
@@ -315,10 +315,10 @@ int32_t CreatePCID(char *inputFile, char *outDirPath)
ret = -1;
goto FREE_PCID_BUFFER_OUT;
}
PCIDBuffer->manufacturerID = HtonlInter((uint32_t)jsonSyscapObj->valueint);
pcidBuffer->manufacturerID = HtonlInter((uint32_t)jsonSyscapObj->valueint);
const char pcidFileName[] = "PCID.sc";
ret = ConvertedContextSaveAsFile(outDirPath, pcidFileName, (char *)PCIDBuffer, PCIDLength);
ret = ConvertedContextSaveAsFile(outDirPath, pcidFileName, (char *)pcidBuffer, pcidLength);
if (ret != 0) {
PRINT_ERR("ConvertedContextSaveAsFile failed, outDirPath:%s, filename:%s\n", outDirPath, pcidFileName);
ret = -1;
@@ -326,7 +326,7 @@ int32_t CreatePCID(char *inputFile, char *outDirPath)
}
FREE_PCID_BUFFER_OUT:
free(PCIDBuffer);
free(pcidBuffer);
FREE_CONVERT_OUT:
free(allOsSyscapObj);
FreeContextBuffer(contextBuffer);
@@ -376,7 +376,7 @@ int32_t DecodePCID(char *inputFile, char *outDirPath)
}
nRet = memcpy_s(osSyscap, OS_SYSCAP_BYTES, (uint8_t *)pcidMain + 8, OS_SYSCAP_BYTES); // 8, bytes of pcid header
if (EOK != nRet) {
if (nRet != EOK) {
PRINT_ERR("memcpy_s failed.");
ret = -1;
goto FREE_VECTOR_OUT;
@@ -420,7 +420,7 @@ int32_t DecodePCID(char *inputFile, char *outDirPath)
}
char *ptrPrivateSyscap = (char *)(pcidMain + 1);
uint16_t privateSyscapLen = contextBufLen - sizeof(PCIDMain) - 1;
int privateSyscapLen = (int)(contextBufLen - sizeof(PCIDMain) - 1);
char priSyscapStr[SINGLE_SYSCAP_LEN] = {0};
char *tempPriSyscapStr = priSyscapStr;
char fullPriSyscapStr[SINGLE_SYSCAP_LEN] = {0};
@@ -694,15 +694,15 @@ int32_t DecodeStringPCIDToJson(char *input, char *outDirPath)
PRINT_ERR("Add syscap to json failed.\n");
goto ADD_JSON_FAILED;
}
if (AddHeaderToJsonObj(pcidHeader, PCID_HEADER, rootObj)) {
if (AddHeaderToJsonObj(pcidHeader, PCID_HEADER, rootObj) != 0) {
PRINT_ERR("Add header to json object failed.\n");
goto ADD_JSON_FAILED;
}
if (AddOsSyscapToJsonObj(osSyscapUintArray, OS_SYSCAP_NUM, sysCapObj)) {
if (AddOsSyscapToJsonObj(osSyscapUintArray, OS_SYSCAP_NUM, sysCapObj) != 0) {
PRINT_ERR("Add os syscap json object failed.\n");
goto ADD_JSON_FAILED;
}
if (AddPriSyscapToJsonObj(priSyscapStr, strlen(priSyscapStr), sysCapObj)) {
if (AddPriSyscapToJsonObj(priSyscapStr, (uint32_t)strlen(priSyscapStr), sysCapObj) != 0) {
PRINT_ERR("Add private syscap json object failed.\n");
goto ADD_JSON_FAILED;
}
+44 -33
View File
@@ -27,14 +27,6 @@
#include "create_pcid.h"
#include "syscap_tool.h"
typedef struct ProductCompatibilityIDHead {
uint16_t apiVersion : 15;
uint16_t apiVersionType : 1;
uint16_t systemType : 3;
uint16_t reserved : 13;
uint32_t manufacturerID;
} PCIDHead;
typedef struct RequiredProductCompatibilityIDHead {
uint16_t apiVersion : 15;
uint16_t apiVersionType : 1;
@@ -48,6 +40,7 @@ typedef struct RequiredProductCompatibilityIDHead {
#define PCID_OUT_BUFFER RPCID_OUT_BUFFER
#define BYTES_OF_OS_SYSCAP 120
#define U32_TO_STR_MAX_LEN 11
#define STRING_FORMAT_LEN_MAX 1024
#define PRINT_ERR(...) \
do { \
@@ -123,12 +116,12 @@ static int32_t ConvertedContextSaveAsFile(char *outDirPath, const char *filename
char path[PATH_MAX + 1] = {0x00};
#ifdef _POSIX_
if (strlen(outDirPath) > PATH_MAX || strncpy_s(path, PATH_MAX, outDirPath, strlen(outDirPath)) != EOK) {
if (strlen(outDirPath) >= PATH_MAX || strncpy_s(path, PATH_MAX, outDirPath, strlen(outDirPath)) != EOK) {
PRINT_ERR("get path(%s) failed\n", outDirPath);
return -1;
}
#else
if (strlen(outDirPath) > PATH_MAX || realpath(outDirPath, path) == NULL) {
if (strlen(outDirPath) >= PATH_MAX || realpath(outDirPath, path) == NULL) {
PRINT_ERR("get file(%s) real path failed\n", outDirPath);
return -1;
}
@@ -170,15 +163,15 @@ static int32_t ConvertedContextSaveAsFile(char *outDirPath, const char *filename
static cJSON *CreateWholeSyscapJsonObj(void)
{
size_t numOfSyscapAll = sizeof(g_arraySyscap) / sizeof(SyscapWithNum);
size_t allSyscapNum = sizeof(g_arraySyscap) / sizeof(SyscapWithNum);
cJSON *root = cJSON_CreateObject();
for (size_t i = 0; i < numOfSyscapAll; i++) {
for (size_t i = 0; i < allSyscapNum; i++) {
cJSON_AddItemToObject(root, g_arraySyscap[i].str, cJSON_CreateNumber(g_arraySyscap[i].num));
}
return root;
}
int32_t RPCIDEncode(char *inputFile, char *outDirPath)
int32_t RPCIDEncode(char *inputFile, char *outputPath)
{
int32_t ret;
char *contextBuffer = NULL;
@@ -248,7 +241,7 @@ int32_t RPCIDEncode(char *inputFile, char *outDirPath)
*(uint16_t *)fillTmpPtr = HtonsInter((uint16_t)(sysCapSize * SINGLE_FEAT_LEN));
fillTmpPtr += sizeof(uint16_t);
for (uint32_t i = 0; i < sysCapSize; i++) {
arrayItemPtr = cJSON_GetArrayItem(sysCapPtr, i);
arrayItemPtr = cJSON_GetArrayItem(sysCapPtr, (int)i);
char *pointPos = strchr(arrayItemPtr->valuestring, '.');
if (pointPos == NULL) {
PRINT_ERR("context of \"syscap\" array is invalid\n");
@@ -271,9 +264,9 @@ int32_t RPCIDEncode(char *inputFile, char *outDirPath)
fillTmpPtr += SINGLE_FEAT_LEN;
}
ret = ConvertedContextSaveAsFile(outDirPath, "RPCID.sc", convertedBuffer, convertedBufLen);
ret = ConvertedContextSaveAsFile(outputPath, "RPCID.sc", convertedBuffer, convertedBufLen);
if (ret != 0) {
PRINT_ERR("ConvertedContextSaveAsFile failed, outDirPath:%s, filename:rpcid.sc\n", outDirPath);
PRINT_ERR("ConvertedContextSaveAsFile failed, outputPath:%s, filename:rpcid.sc\n", outputPath);
goto FREE_CONVERT_OUT;
}
@@ -289,6 +282,10 @@ static int32_t ParseRpcidToJson(char *input, uint32_t inputLen, cJSON *rpcidJson
uint32_t i;
int32_t ret = 0;
uint16_t sysCapLength = NtohsInter(*(uint16_t *)(input + sizeof(uint32_t)));
if (sysCapLength > inputLen - sizeof(uint32_t)) {
PRINT_ERR("Get sysCapLength(%u) error, inputLen = %u\n", sysCapLength, inputLen);
return -1;
}
uint16_t sysCapCount = sysCapLength / SINGLE_FEAT_LEN;
char *sysCapBegin = input + sizeof(RPCIDHead) + sizeof(uint32_t);
RPCIDHead *rpcidHeader = (RPCIDHead *)input;
@@ -368,7 +365,7 @@ static int32_t CheckRpcidFormat(char *inputFile, char **Buffer, uint32_t *Len)
return 0;
}
int32_t RPCIDDecode(char *inputFile, char *outDirPath)
int32_t RPCIDDecode(char *inputFile, char *outputPath)
{
int32_t ret = 0;
char *contextBuffer = NULL;
@@ -383,16 +380,16 @@ int32_t RPCIDDecode(char *inputFile, char *outDirPath)
// parse rpcid to json
cJSON *rpcidRoot = cJSON_CreateObject();
if (ParseRpcidToJson(contextBuffer, bufferLen, rpcidRoot)) {
if (ParseRpcidToJson(contextBuffer, bufferLen, rpcidRoot) != 0) {
PRINT_ERR("Prase rpcid to json failed. Input failed: %s\n", inputFile);
goto FREE_RPCID_ROOT;
}
// save to json file
convertedBuffer = cJSON_Print(rpcidRoot);
ret = ConvertedContextSaveAsFile(outDirPath, "RPCID.json", convertedBuffer, strlen(convertedBuffer));
ret = ConvertedContextSaveAsFile(outputPath, "RPCID.json", convertedBuffer, strlen(convertedBuffer));
if (ret != 0) {
PRINT_ERR("ConvertedContextSaveAsFile failed, outDirPath:%s, filename:rpcid.json\n", outDirPath);
PRINT_ERR("ConvertedContextSaveAsFile failed, outputPath:%s, filename:rpcid.json\n", outputPath);
goto FREE_RPCID_ROOT;
}
@@ -403,7 +400,7 @@ FREE_CONTEXT_OUT:
return ret;
}
static int SetOsSysCapBitMap(uint8_t *out, uint16_t outLen, uint16_t *index, uint16_t indexLen)
static int SetOsSysCapBitMap(uint8_t *out, uint16_t outLen, const uint16_t *index, uint16_t indexLen)
{
uint16_t sector, pos;
@@ -429,7 +426,6 @@ int32_t EncodeRpcidscToString(char *inputFile, char *outDirPath)
int32_t ret = 0;
int32_t sysCapArraySize;
uint32_t bufferLen, i;
uint16_t indexOs = 0;
uint16_t indexPri = 0;
uint16_t *osSysCapIndex;
char *contextBuffer = NULL;
@@ -448,7 +444,7 @@ int32_t EncodeRpcidscToString(char *inputFile, char *outDirPath)
// parse rpcid to json
rpcidRoot = cJSON_CreateObject();
if (ParseRpcidToJson(contextBuffer, bufferLen, rpcidRoot)) {
if (ParseRpcidToJson(contextBuffer, bufferLen, rpcidRoot) != 0) {
PRINT_ERR("Prase rpcid to json failed. Input file: %s\n", inputFile);
goto FREE_RPCID_ROOT;
}
@@ -474,16 +470,17 @@ int32_t EncodeRpcidscToString(char *inputFile, char *outDirPath)
(void)memset_s(osSysCapIndex, sizeof(uint16_t) * sysCapArraySize,
0, sizeof(uint16_t) * sysCapArraySize);
// malloc for save private syscap string
priSyscapArray = (char *)malloc(sysCapArraySize * SINGLE_SYSCAP_LEN);
priSyscapArray = (char *)malloc((uint32_t)sysCapArraySize * SINGLE_SYSCAP_LEN);
if (priSyscapArray == NULL) {
PRINT_ERR("malloc(%d) failed.\n", sysCapArraySize * SINGLE_SYSCAP_LEN);
goto FREE_MALLOC_OSSYSCAP;
}
(void)memset_s(priSyscapArray, sysCapArraySize * SINGLE_SYSCAP_LEN,
0, sysCapArraySize * SINGLE_SYSCAP_LEN);
(void)memset_s(priSyscapArray, (size_t)(sysCapArraySize * SINGLE_SYSCAP_LEN),
0, (size_t)(sysCapArraySize * SINGLE_SYSCAP_LEN));
priSyscap = priSyscapArray;
// part os syscap and ptivate syscap
for (i = 0; i < (uint32_t)sysCapArraySize; i++) {
uint16_t indexOs = 0;
for (int i = 0; i < sysCapArraySize; i++) {
cJSON *cJsonItem = cJSON_GetArrayItem(sysCapArray, i);
cJsonTemp = cJSON_GetObjectItem(sysCapDefine, cJsonItem->valuestring);
if (cJsonTemp != NULL) {
@@ -565,7 +562,7 @@ int32_t SeparateSyscapFromString(const char *inputString, uint32_t *osArray, uin
{
int32_t ret = 0;
uint32_t i;
size_t inputLen = strlen(inputString);
uint32_t count = 0;
char *temp = NULL;
char *tok = NULL;
@@ -576,7 +573,16 @@ int32_t SeparateSyscapFromString(const char *inputString, uint32_t *osArray, uin
}
// copy to temp string input
char *input = (char *)malloc(strlen(inputString) + 1);
if (inputString == NULL) {
PRINT_ERR("inputString is null.\n");
return -1;
}
size_t inputLen = strlen(inputString);
if (inputLen > STRING_FORMAT_LEN_MAX) {
PRINT_ERR("input string too long(%zu).\n", inputLen);
return -1;
}
char *input = (char *)malloc(inputLen + 1);
if (input == NULL) {
PRINT_ERR("malloc failed.\n");
return -1;
@@ -658,6 +664,7 @@ int32_t ComparePcidWithRpcidString(char *pcidFile, char *rpcidFile, uint32_t typ
bool priSysFound;
uint32_t pcidOsAarry[PCID_OUT_BUFFER] = {0};
uint32_t rpcidOsAarry[PCID_OUT_BUFFER] = {0};
const size_t allSyscapNum = sizeof(g_arraySyscap) / sizeof(SyscapWithNum);
if (type == TYPE_FILE) {
if (GetFileContext(pcidFile, &pcidContent, &pcidContentLen)) {
@@ -700,9 +707,13 @@ int32_t ComparePcidWithRpcidString(char *pcidFile, char *rpcidFile, uint32_t typ
continue;
}
for (uint8_t k = 0; k < INT_BIT; k++) {
if (temp2 & (0x1 << k)) {
// 2, header of pcid & rpcid
printf("Missing: %s\n", g_arraySyscap[(i - 2) * INT_BIT + k].str);
if (!(temp2 & (0x1 << k))) {
continue;
}
// 2, header of pcid & rpcid
size_t pos = (size_t)((i - 2) * INT_BIT + k);
if (pos < allSyscapNum) {
printf("Missing: %s\n", g_arraySyscap[pos].str);
ossyscapFlag += 1;
}
}
@@ -730,4 +741,4 @@ int32_t ComparePcidWithRpcidString(char *pcidFile, char *rpcidFile, uint32_t typ
printf("Fail! The pcid does not meet the rpcid\n");
}
return 0;
}
}
+1 -1
View File
@@ -25,7 +25,7 @@ int main(void)
for (size_t i = 0; i < size; i++) {
if (g_arraySyscap[i].num != i) {
printf("[Error][syscap_define.h]: %s -> num(%u) should be %lu.\n",
printf("[Error][syscap_define.h]: %s -> num(%u) should be %zu.\n",
g_arraySyscap[i].str, g_arraySyscap[i].num, i);
flag++;
}
-143
View File
@@ -1,143 +0,0 @@
/*
* Copyright (C) 2022 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 <string.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <limits.h>
#include <sys/types.h>
#include <wait.h>
#include "syscap_tool.h"
#include "create_pcid.h"
char *g_testFilePcid = "{\n \"api_version\": 0,\n \"manufacturer_id\": 0,\n \"product\": \"rk3568\",\n" \
" \"syscap\": {\n \"os\": [\n \"SystemCapability.Account.AppAccount\",\n" \
" \"SystemCapability.Account.OsAccount\"\n ]\n },\n" \
" \"system_type\": \"standard\"\n}";
char *g_testFileRpcid = "{\n \"api_version\": 7,\n \"syscap\": [\n \"SystemCapability.hiviewdfx.hilog\",\n" \
" \"SystemCapability.communication.softbus\",\n \"SystemCapability.hisicon.flashlight\"\n ]\n}";
int32_t PrepareTestFile(char *fileName, char *fileContext)
{
int32_t ret;
FILE *fp = fopen(fileName, "wb");
if (fp == NULL) {
return -1;
}
size_t len = fwrite(fileContext, 1, strlen(fileContext), fp);
if (len != strlen(fileContext)) {
(void)fclose(fp);
return -1;
}
ret = fclose(fp);
if (ret != 0) {
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
int32_t status;
char *pcidFileName = "SystemCapability.json";
char *rpcidFileName = "rpcid.json";
printf("###start syscap tool test###\n");
(void)unlink(pcidFileName);
(void)unlink(rpcidFileName);
(void)unlink("./rk3568.sc");
(void)unlink("./newPCID.sc");
(void)unlink("./rpcid.sc");
(void)unlink("./rk3568.json");
pid_t pid = fork();
if (pid == 0) {
printf("prepare test file...\n");
int32_t passCnt = 0;
int32_t ret = PrepareTestFile(pcidFileName, g_testFilePcid);
if (ret != 0) {
printf(" error: prepare pcid file failed\n");
exit(passCnt);
}
ret = PrepareTestFile(rpcidFileName, g_testFileRpcid);
if (ret != 0) {
printf(" error: prepare rpcid file failed\n");
exit(passCnt);
}
printf("1.test rpcid.json encode to rpcid.sc\n");
ret = RPCIDEncode(rpcidFileName, "./");
if (ret != 0) {
printf(" error: rpcid.json encode failed\n");
exit(passCnt);
}
passCnt++;
printf("pass\n");
printf("2.test rpcid.sc decode to rpcid.json\n");
ret = RPCIDDecode("rpcid.sc", "./");
if (ret != 0) {
printf(" error: rpcid.sc decode failed\n");
exit(passCnt);
}
passCnt++;
printf("pass\n");
printf("3.test pcid.json encode to pcid.sc\n");
ret = PCIDEncode(pcidFileName, "./");
if (ret != 0) {
printf(" error: pcid.json encode failed\n");
exit(passCnt);
}
passCnt++;
printf("pass\n");
printf("4.test pcid.sc decode to pcid.json\n");
ret = PCIDDecode("./rk3568.sc", "./");
if (ret != 0) {
printf(" error: pcid.sc decode failed\n");
exit(passCnt);
}
passCnt++;
printf("pass\n");
printf("5.test pcid.json encode to new PCID.sc\n");
ret = CreatePCID("./newPCID.sc", "./");
if (ret != 0) {
printf(" error: new pcid.sc encode failed\n");
exit(passCnt);
}
passCnt++;
printf("pass\n");
printf("6.test new pcid.sc decode to pcid.json\n");
ret = PCIDDecode("./newPCID.sc", "./");
if (ret != 0) {
printf(" error: new pcid.sc decode failed\n");
exit(passCnt);
}
passCnt++;
printf("pass\n");
exit(passCnt);
}
(void)wait(&status);
printf("summary: total 4 passed %d\n", WEXITSTATUS(status));
(void)unlink(pcidFileName);
(void)unlink(rpcidFileName);
(void)unlink("./rk3568.sc");
(void)unlink("./newPCID.sc");
(void)unlink("./rpcid.sc");
(void)unlink("./rk3568.json");
return 0;
}
+35 -31
View File
@@ -11,51 +11,55 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
if (defined(ohos_lite)) {
import("//build/lite/config/component/lite_component.gni")
import("//build/lite/config/test.gni")
test_output_root = "$root_out_dir/test/unittest/syscap_codec"
executable("test_syscap_napi_unittest") {
output_extension = "bin"
output_dir = test_output_root
if (ohos_kernel_type != "liteos_m") {
test_output_root = "$root_out_dir/test/unittest/syscap_codec"
include_dirs = [
"//commonlibrary/c_utils/base/include",
"//third_party/node/src",
"//third_party/googletest/include",
"//developtools/syscap_codec/src/",
"//developtools/syscap_codec/include/",
"//developtools/syscap_codec/interfaces/inner_api/",
"//developtools/syscap_codec/test/unittest/common/include/",
]
executable("test_syscap_napi_unittest") {
output_extension = "bin"
output_dir = test_output_root
cflags = [ "-g3" ]
include_dirs = [
"//commonlibrary/c_utils/base/include",
"//third_party/node/src",
"//third_party/googletest/include",
"//developtools/syscap_codec/src/",
"//developtools/syscap_codec/include/",
"//developtools/syscap_codec/interfaces/inner_api/",
"//developtools/syscap_codec/test/unittest/common/include/",
]
sources = [
"//developtools/syscap_codec/interfaces/inner_api/syscap_interface.c",
"//developtools/syscap_codec/src/create_pcid.c",
"//developtools/syscap_codec/src/endian_internal.c",
"//developtools/syscap_codec/src/syscap_tool.c",
"syscap_codec_test.cpp",
]
cflags = [ "-g3" ]
defines = [ "NAPI_TEST" ]
sources = [
"//developtools/syscap_codec/interfaces/inner_api/syscap_interface.c",
"//developtools/syscap_codec/src/create_pcid.c",
"//developtools/syscap_codec/src/endian_internal.c",
"//developtools/syscap_codec/src/syscap_tool.c",
"syscap_codec_test.cpp",
]
deps = [
"//base//hiviewdfx/hilog_lite/frameworks/featured:hilog_shared",
"//test/developertest/third_party/lib/cpp:gtest_main",
"//third_party/bounds_checking_function:libsec_static",
]
defines = [ "NAPI_TEST" ]
deps += [ "//build/lite/config/component/cJSON:cjson_static" ]
deps = [
"//base//hiviewdfx/hilog_lite/frameworks/featured:hilog_shared",
"//test/testfwk/developer_test/third_party/lib/cpp:gtest_main",
"//third_party/bounds_checking_function:libsec_static",
]
deps += [ "//build/lite/config/component/cJSON:cjson_static" ]
}
}
group("unittest") {
deps = [ ":test_syscap_napi_unittest" ]
if (ohos_kernel_type != "liteos_m") {
deps = [ ":test_syscap_napi_unittest" ]
}
}
} else {
import("//build/lite/config/component/lite_component.gni")
import("//build/ohos.gni")
import("//build/test.gni")
Executable → Regular
+309 -289
View File
@@ -1,289 +1,309 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2022 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.
import os
import json
import re
import argparse
from prettytable import PrettyTable, ALL
table = PrettyTable()
table.hrules = ALL
def get_args():
parser = argparse.ArgumentParser(add_help=True)
parser.add_argument(
"-p",
"--project_path",
default=r"./",
type=str,
help="root path of project. default: ./",
)
parser.add_argument(
"-t",
"--check_target",
type=str,
choices=["component_codec", "component_sdk", "sdk_codec"],
required=True,
help="the target to be compared",
)
parser.add_argument(
"-b",
"--bundles",
nargs="*",
type=str,
help="option take effect only when the check_target is component_codec. allow multiple json file. "
"default: all bundle.json file",
)
args = parser.parse_args()
return args
def list_to_multiline(target_list):
return str(target_list).lstrip("[").rstrip("]").replace(", ", "\n")
def add_dict_as_table_row(f_table, d_dict):
s_keys = sorted(list(d_dict.keys()))
for k in s_keys:
f_table.add_row([k, list_to_multiline(sorted(list(d_dict.get(k))))])
def read_value_from_json(filepath, key_hierarchy, result_dict):
if os.path.exists(filepath) is False:
print('error: file "{}" not exists.'.format(filepath))
return result_dict
if os.path.isfile(filepath) is False:
print('error: "{}" is not a file.')
return result_dict
with open(filepath, "r") as f:
data = json.load(f)
for key in key_hierarchy:
try:
data = data[key]
except KeyError:
print(
'warning: can\'t find the key:"{}" in file "{}"'.format(
key, filepath
)
)
return result_dict
finally:
f.close()
data = [x.split("=")[0].strip() for x in data if len(x) != 0 and x.isspace() is False]
if len(data) != 0:
result_dict[filepath] = data
return result_dict
def collect_syscap_from_codec(filepath):
array_syscap_set = set()
pattern = r'{"(.*)"'
with open(filepath, "r") as f:
for line in f:
syscap = re.search(pattern, line.strip())
if syscap is not None:
array_syscap_set.add(syscap.group(0).lstrip("{").strip('"'))
return array_syscap_set
def collect_syscap_from_component(project_path, bundles=None):
result_dict = dict()
key_heirarchy = ["component", "syscap"]
if bundles is None:
subsystem_list = [
x
for x in os.listdir(project_path)
if os.path.isdir(os.path.join(project_path, x)) and x != "out"
]
for ss in subsystem_list:
output = os.popen(
"find {} -name bundle.json".format(os.path.join(project_path, ss))
)
for line in output:
read_value_from_json(line.strip(), key_heirarchy, result_dict)
else:
for b in bundles:
result_dict = read_value_from_json(b, key_heirarchy, result_dict)
result_set = set()
for v in result_dict.values():
result_set.update(v)
return result_set, result_dict
def collect_syscap_from_sdk(project_path):
full_path = os.path.join(project_path, "interface", "sdk-js", "api")
ts_list = [
os.path.join(full_path, x) for x in os.listdir(full_path) if x.endswith(".d.ts")
]
syscap_dict = dict()
pattern = r"\* *@syscap +(.*)"
syscap_set = set()
for ts in ts_list:
with open(ts, "r") as f:
sub_set = set()
for line in f:
syscap = re.search(pattern, line)
if syscap is not None:
ss = syscap.group(0).strip().lstrip(r"\* @syscap ").strip()
sub_set.add(ss)
syscap_dict[ts] = sub_set
for v in syscap_dict.values():
syscap_set.update(v)
return syscap_set, syscap_dict
def find_files_containes_value(value_set, file_values_dict):
value_files_dict = dict()
for v in value_set:
filename_set = set()
for file in file_values_dict.keys():
if v in file_values_dict[file]:
filename_set.add(file)
if 0 != len(filename_set):
value_files_dict[v] = filename_set
return value_files_dict
def check_component_and_codec(project_path, bundles=None):
if bundles is not None and len(bundles) > 0:
component_syscap_set, component_syscap_dict = collect_syscap_from_component(
project_path, bundles
)
else:
component_syscap_set, component_syscap_dict = collect_syscap_from_component(
project_path
)
array_syscap_set = collect_syscap_from_codec(
os.path.join(
project_path, "developtools", "syscap_codec", "include", "syscap_define.h"
)
)
component_diff_array = component_syscap_set.difference(array_syscap_set)
value_files_dict = find_files_containes_value(
component_diff_array, component_syscap_dict
)
array_diff_component = array_syscap_set.difference(component_syscap_set)
if 0 == len(component_diff_array) and 0 == len(array_diff_component):
table.clear()
table.field_names = ["Component and Codec are Consistent"]
print(table)
return
if 0 != len(component_diff_array):
table.field_names = ["Syscap Only in Component", "Files"]
add_dict_as_table_row(table, value_files_dict)
elif 0 == len(component_diff_array):
table.field_names = ["All Syscap in Component have been Covered by Codec"]
print("\n")
print(table)
table.clear()
if 0 != len(array_diff_component):
table.field_names = ["SysCap Only in Codec"]
table.add_row([list_to_multiline(sorted(list(array_diff_component)))])
elif 0 == len(array_diff_component):
table.field_names = ["All SysCap in Codec have been Covered by Component"]
print("\n")
print(table)
def check_component_and_sdk(project_path):
component_syscap_set, component_syscap_dict = collect_syscap_from_component(
project_path
)
ts_syscap_set, ts_syscap_dict = collect_syscap_from_sdk(project_path)
ts_diff_component = ts_syscap_set.difference(component_syscap_set)
value_ts_dict = find_files_containes_value(ts_diff_component, ts_syscap_dict)
component_diff_ts = component_syscap_set.difference(ts_syscap_set)
value_component_dict = find_files_containes_value(
component_diff_ts, component_syscap_dict
)
if 0 == len(ts_diff_component) and 0 == len(component_diff_ts):
table.clear()
table.field_names = ["SDK and Component are Consistent"]
print(table)
return
table.clear()
if 0 != len(component_diff_ts):
table.field_names = ["SysCap Only in Component", "Files"]
add_dict_as_table_row(table, value_component_dict)
elif 0 == len(component_diff_ts):
table.field_names = ["SysCap in Component have been Covered by SDK"]
print("\n")
print(table)
table.clear()
if 0 != len(ts_diff_component):
table.field_names = ["SysCap Only in SDK", "Files"]
add_dict_as_table_row(table, value_ts_dict)
elif 0 == len(ts_diff_component):
table.field_names = ["All SysCap in SDK have been Covered by Component"]
print("\n")
print(table)
def check_sdk_and_codec(project_path):
ts_syscap_set, ts_syscap_dict = collect_syscap_from_sdk(project_path)
array_syscap_set = collect_syscap_from_codec(
os.path.join(
project_path, "developtools", "syscap_codec", "include", "syscap_define.h"
)
)
ts_diff_array = ts_syscap_set.difference(array_syscap_set)
value_ts_dict = find_files_containes_value(ts_diff_array, ts_syscap_dict)
array_diff_ts = array_syscap_set.difference(ts_syscap_set)
if 0 == len(ts_diff_array) and 0 == len(array_diff_ts):
table.clear()
table.field_names = ["SDK and Codec are Consistent"]
print(table)
return
table.clear()
if 0 != len(ts_diff_array):
table.field_names = ["SysCap Only in SDK", "Files"]
add_dict_as_table_row(table, value_ts_dict)
elif 0 == len(ts_diff_array):
table.field_names = ["SysCap in SDK have been Covered by Codec"]
print("\n")
print(table)
table.clear()
if 0 != len(array_diff_ts):
table.field_names = ["SysCap Only in Codec"]
table.add_row([list_to_multiline(sorted(list(array_diff_ts)))])
elif 0 == len(array_diff_ts):
table.field_names = ["SysCap in Codec have been Covered by SDK"]
print("\n")
print(table)
def main():
args = get_args()
project_path = args.project_path
check_target = args.check_target
bundles = args.bundles
if "component_codec" == check_target:
if bundles is None:
check_component_and_codec(project_path)
else:
if 0 == len(bundles):
print(r"error: '--bundles' parameter is specified, but has no value")
else:
check_component_and_codec(project_path, bundles)
elif "component_sdk" == check_target:
check_component_and_sdk(project_path)
elif "sdk_codec" == check_target:
check_sdk_and_codec(project_path)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) 2022 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.
import os
import json
import re
import argparse
from prettytable import PrettyTable, ALL
def get_args():
parser = argparse.ArgumentParser(add_help=True)
parser.add_argument(
"-p",
"--project_path",
default=r"./",
type=str,
help="root path of project. default: ./",
)
parser.add_argument(
"-t",
"--check_target",
type=str,
choices=["component_codec", "component_sdk", "sdk_codec"],
required=True,
help="the target to be compared",
)
parser.add_argument(
"-b",
"--bundles",
nargs="*",
type=str,
help="option take effect only when the check_target is component_codec. allow multiple json file. "
"default: all bundle.json file",
)
args = parser.parse_args()
return args
def list_to_multiline(target_list: list):
return str(target_list).lstrip("[").rstrip("]").replace(", ", "\n")
def convert_set_to_sorted_list(target_set) -> list:
return sorted(list(target_set))
def add_dict_as_table_row(f_table: PrettyTable, d_dict: dict, out_converter=list_to_multiline) -> None:
s_keys = convert_set_to_sorted_list(d_dict.keys())
for i, k in enumerate(s_keys):
f_table.add_row([i + 1, k, out_converter(convert_set_to_sorted_list(d_dict.get(k)))])
def bundle_syscap_post_handler(syscap: str) -> str:
return syscap.split('=')[0].strip()
def read_value_from_json(filepath: str,
key_hierarchy: tuple,
result_dict: dict,
post_handler=None
) -> None:
if os.path.exists(filepath) is False:
print('error: file "{}" not exist.'.format(filepath))
return
if not os.path.isfile(filepath):
print('error: "{}" is not a file.')
return
with open(filepath, 'r', encoding='utf-8') as f:
data = json.load(f)
for key in key_hierarchy:
try:
data = data[key]
except KeyError:
return
finally:
pass
data = [post_handler(x) for x in data if len(x) != 0 and not x.isspace()]
if len(data) != 0:
result_dict[filepath] = data
def collect_syscap_from_codec(filepath: str, pattern: str = r'{"(.*)"') -> tuple:
"""
从syscap_define.h收集syscap
:param filepath: 文件的路径
:param pattern: 匹配syscap的规则
:return: syscap_define.h中声明的syscap集合
"""
array_syscap_set = set()
array_syscap_dict = dict()
ptrn = re.compile(pattern)
with open(filepath, "r") as f:
content = f.read()
array_syscap_set.update(re.findall(ptrn, content))
array_syscap_dict[filepath] = list()
for v in array_syscap_set:
array_syscap_dict.get(filepath).append(v)
return array_syscap_set, array_syscap_dict
def collect_syscap_from_component(project_path: str,
black_dirs: tuple,
key_heirarchy: tuple,
bundles: list = None,
) -> tuple:
"""
从部件的bundle.json中收集syscap
:param project_path: 项目根路径
:param black_dirs: 根路径下的一级目录的黑名单,不扫描这些bundle.json下面的内容
:param key_heirarchy: bundle.json中syscap所在的key的元组
:param bundles: 指定的bundle.json
:return: syscap_set,文件名和其syscap list组成的dict
"""
result_dict = dict()
if bundles is None:
search_dir_list = [
os.path.join(project_path, x)
for x in os.listdir(project_path)
if os.path.isdir(os.path.join(project_path, x)) and x not in black_dirs
]
for folder in search_dir_list:
output = os.popen("find {} -name bundle.json".format(folder))
for line in output:
line = line.strip()
read_value_from_json(line, key_heirarchy, result_dict, post_handler=bundle_syscap_post_handler)
else:
for bundle in bundles:
read_value_from_json(bundle, key_heirarchy, result_dict, post_handler=bundle_syscap_post_handler)
result_set = set()
for v in result_dict.values():
result_set.update(v)
return result_set, result_dict
def sdk_syscap_post_handler(syscap: str) -> str:
return syscap.strip().lstrip("*").lstrip().lstrip("*@syscap").strip()
def collect_syscap_from_sdk(ts_path: str,
pattern: str = r"\* *@syscap +((?i)SystemCapability\..*)",
post_handler=None
) -> tuple:
"""
从sdk下的*.d.ts中收集syscap
:param ts_path: ts文件的所在路径
:param pattern: 匹配syscap的pattern
:param post_handler: 对匹配到的syscap进行后置处理
:return: syscap_set,和由文件名、syscap list组成的dict
"""
ts_list = list()
for item in os.listdir(ts_path):
file_path = os.path.join(ts_path, item)
if file_path.endswith(".d.ts") and os.path.isfile(file_path):
ts_list.append(file_path)
syscap_dict = dict()
ptrn = re.compile(pattern)
for ts in ts_list:
with open(ts, 'r') as f:
content = f.read()
sub_syscap_list = re.findall(ptrn, content)
sub_syscap_set = set()
for syscap in sub_syscap_list:
sub_syscap_set.add(post_handler(syscap))
syscap_dict[ts] = sub_syscap_set
syscap_set = set()
for v in syscap_dict.values():
syscap_set.update(v)
return syscap_set, syscap_dict
def find_files_containes_value(value_set: set, file_values_dict: dict) -> dict:
"""
查看包含指定值的文件
:param value_set: 指定值
:param file_values_dict: 文件和值组成的dict
:return: 值和文件组成的dict
"""
value_files_dict = dict()
for v in value_set:
filename_set = set()
for file in file_values_dict.keys():
if v in file_values_dict[file]:
filename_set.add(file)
if 0 != len(filename_set):
value_files_dict[v] = filename_set
return value_files_dict
def mutual_diff(a_set: set, b_set: set) -> tuple:
return a_set.difference(b_set), b_set.difference(a_set)
def print_inconsistent(diff_set: set, a_name: str, b_name: str, table: PrettyTable,
value_file_dict: dict) -> None:
table.clear()
if len(diff_set) != 0:
table.field_names = ["index", "SysCap only in {}".format(a_name), "Files"]
add_dict_as_table_row(table, value_file_dict)
elif len(diff_set) == 0:
table.field_names = ["All SysCap in {} have been Covered by {}".format(a_name, b_name)]
print(table)
print()
def print_consistent(a_diff_b_set: set, b_diff_a_set: set, table: PrettyTable, a_name: str, b_name: str) -> bool:
if len(a_diff_b_set) == 0 and len(b_diff_a_set) == 0:
table.field_names = ["{} and {} are Consistent".format(a_name, b_name)]
print(table)
print()
return True
return False
def print_check_result(a_diff_b_set: set,
b_diff_a_set: set,
a_name: str,
b_name: str,
a_value_file_dict: dict,
b_value_file_dict: dict,
) -> None:
f_table = PrettyTable()
f_table.hrules = ALL
consistent_flag = print_consistent(a_diff_b_set, b_diff_a_set, f_table, a_name, b_name)
if not consistent_flag:
print_inconsistent(a_diff_b_set, a_name, b_name, f_table, a_value_file_dict)
print_inconsistent(b_diff_a_set, b_name, a_name, f_table, b_value_file_dict)
def check_component_and_codec(project_path, syscap_define_path: str, component_black_dirs: tuple,
bundle_key_heirarchy: tuple, bundles=None):
component_syscap_set, component_syscap_dict = collect_syscap_from_component(
project_path, black_dirs=component_black_dirs, key_heirarchy=bundle_key_heirarchy, bundles=bundles
)
array_syscap_set, array_syscap_dict = collect_syscap_from_codec(syscap_define_path)
component_diff_array, array_diff_component = mutual_diff(component_syscap_set, array_syscap_set)
value_component_dict = find_files_containes_value(
component_diff_array, component_syscap_dict
)
value_h_dict = find_files_containes_value(array_diff_component, array_syscap_dict)
print_check_result(component_diff_array, array_diff_component, a_name="Component", b_name="Codec",
a_value_file_dict=value_component_dict, b_value_file_dict=value_h_dict)
def check_component_and_sdk(project_path, component_black_dirs: tuple, component_key_heirarchy: tuple, sdk_path: str):
component_syscap_set, component_syscap_dict = collect_syscap_from_component(
project_path, black_dirs=component_black_dirs, key_heirarchy=component_key_heirarchy
)
ts_syscap_set, ts_syscap_dict = collect_syscap_from_sdk(ts_path=sdk_path,
post_handler=sdk_syscap_post_handler)
component_diff_ts, ts_diff_component = mutual_diff(component_syscap_set, ts_syscap_set)
value_ts_dict = find_files_containes_value(ts_diff_component, ts_syscap_dict)
value_component_dict = find_files_containes_value(
component_diff_ts, component_syscap_dict
)
print_check_result(component_diff_ts, ts_diff_component, a_name="Component", b_name="SDK",
a_value_file_dict=value_component_dict, b_value_file_dict=value_ts_dict)
def check_sdk_and_codec(syscap_define_path: str, sdk_path: str) -> None:
ts_syscap_set, ts_syscap_dict = collect_syscap_from_sdk(ts_path=sdk_path,
post_handler=sdk_syscap_post_handler)
array_syscap_set, array_syscap_dict = collect_syscap_from_codec(syscap_define_path)
ts_diff_array, array_diff_ts = mutual_diff(ts_syscap_set, array_syscap_set)
value_ts_dict = find_files_containes_value(ts_diff_array, ts_syscap_dict)
value_h_dict = find_files_containes_value(array_diff_ts, array_syscap_dict)
print_check_result(ts_diff_array, array_diff_ts, a_name="SDK", b_name="Codec", a_value_file_dict=value_ts_dict,
b_value_file_dict=value_h_dict)
def main():
args = get_args()
project_path = args.project_path
check_target = args.check_target
bundles = args.bundles
syscap_define_path = os.path.join(project_path, "developtools", "syscap_codec", "include", "syscap_define.h")
ts_path = os.path.join(project_path, "interface", "sdk-js", "api")
component_black_dirs = ("out",)
bundle_syscap_heirarchy = ("component", "syscap")
if (bundles is not None or (bundles is not None and len(bundles) != 0)) and check_target != "component_codec":
print("error: --bundles could only be used with -t component_codec")
return
if "component_sdk" == check_target:
check_component_and_sdk(project_path, component_black_dirs, bundle_syscap_heirarchy, sdk_path=ts_path)
elif "sdk_codec" == check_target:
check_sdk_and_codec(syscap_define_path=syscap_define_path, sdk_path=ts_path)
elif "component_codec" == check_target:
if bundles is not None and len(bundles) == 0:
print(r"error: '--bundles' parameter is specified, but has no value")
else:
check_component_and_codec(project_path, syscap_define_path, component_black_dirs=component_black_dirs,
bundle_key_heirarchy=bundle_syscap_heirarchy, bundles=bundles)
if __name__ == "__main__":
main()