From 68ef7daad12ae2c46302d671e4e3121bd3ba135c Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Tue, 2 Jan 2024 20:14:35 +0900 Subject: [PATCH] tools: Add hal-compatibility-checker Provide tool for executing compatibility checker of libhalcc by command. See 'hal-compatibility-checker --help'. Change-Id: I3bfd46496997471dcd41d790cc702cc57664a01b Signed-off-by: Youngjae Cho --- CMakeLists.txt | 1 + packaging/hal-api-common.spec | 1 + .../hal-compatibility-checker/CMakeLists.txt | 9 + tools/hal-compatibility-checker/main.c | 249 ++++++++++++++++++ 4 files changed, 260 insertions(+) create mode 100644 tools/hal-compatibility-checker/CMakeLists.txt create mode 100644 tools/hal-compatibility-checker/main.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c1e84a..7b0d070 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,3 +66,4 @@ ADD_SUBDIRECTORY(halcc) ADD_SUBDIRECTORY(tests) ADD_SUBDIRECTORY(tools/lshal) +ADD_SUBDIRECTORY(tools/hal-compatibility-checker) diff --git a/packaging/hal-api-common.spec b/packaging/hal-api-common.spec index e728d5f..73f8e89 100644 --- a/packaging/hal-api-common.spec +++ b/packaging/hal-api-common.spec @@ -107,6 +107,7 @@ systemd-tmpfiles /usr/lib/tmpfiles.d/hal-rpmdb-checker.conf --create %dir /hal %{_libdir}/hal/*.so* %{_bindir}/lshal +%{_bindir}/hal-compatibility-checker %{_sysconfdir}/ld.so.conf.d/libhal-api.conf %{_systemdgeneratordir}/systemd-hal-firmware-generator diff --git a/tools/hal-compatibility-checker/CMakeLists.txt b/tools/hal-compatibility-checker/CMakeLists.txt new file mode 100644 index 0000000..c3b6c13 --- /dev/null +++ b/tools/hal-compatibility-checker/CMakeLists.txt @@ -0,0 +1,9 @@ +PROJECT(hal-compatibility-checker C) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/halcc/include) + +ADD_EXECUTABLE(${PROJECT_NAME} main.c) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES INSTALL_RPATH ${LIBDIR}/hal) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE libhalcc) +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin/) diff --git a/tools/hal-compatibility-checker/main.c b/tools/hal-compatibility-checker/main.c new file mode 100644 index 0000000..1bf188a --- /dev/null +++ b/tools/hal-compatibility-checker/main.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DEFAULT_PLATFORM_MANIFEST_DIR "/etc/hal" +#define DEFAULT_HAL_INFO_INI "/hal/etc/hal-info.ini" + +#define HCC_BUF_MAX (256) +#define BOLD(STR) "\e[1m"STR"\e[m" + +enum { + OPT_START = 0, + OPT_HELP = OPT_START, + OPT_PLATFORM, + OPT_SKIP_IF_RESULT_EXIST, + OPT_REDIRECT_ALL, + OPT_REDIRECT_STDOUT, + OPT_REDIRECT_STDERR, + OPT_END, +}; + +static const struct option long_option[] = { + [OPT_HELP] + = { "help", no_argument, NULL, 'h' }, + + [OPT_PLATFORM] + = { "platform", required_argument, NULL, 'p' }, + + [OPT_SKIP_IF_RESULT_EXIST] + = { "skip-if-result-exist", optional_argument, NULL, 0 }, + + [OPT_REDIRECT_ALL] + = { "redirect-all", required_argument, NULL, 0 }, + + [OPT_REDIRECT_STDOUT] + = { "redirect-stdout", required_argument, NULL, 0 }, + + [OPT_REDIRECT_STDERR] + = { "redirect-stderr", required_argument, NULL, 0 }, + + { 0, }, +}; + +static int get_tizen_hal_version(int *major, int *minor) +{ + FILE *fp = NULL; + char *line = NULL; + size_t len = 0; + int found = 0; + int ret; + + assert(major); + assert(minor); + + fp = fopen(DEFAULT_HAL_INFO_INI, "r"); + if (!fp) + return -errno; + + while (getline(&line, &len, fp) != EOF) { + if (fscanf(fp, "Model=Tizen%d.%d", major, minor) == 2) { + found = 1; + break; + } + } + + fclose(fp); + fp = NULL; + free(line); + line = NULL; + + return found ? 0 : -EINVAL; +} + +static const char* default_platform_manifest_dir(void) +{ + static char dirpath[HCC_BUF_MAX] = { 0 , }; + int major; + int minor; + int ret; + + ret = get_tizen_hal_version(&major, &minor); + if (ret != 0) + return NULL; + + snprintf(dirpath, sizeof(dirpath), DEFAULT_PLATFORM_MANIFEST_DIR"/%d.%d", major, minor); + + return dirpath; +} + +// check result is exist, return true on exist. +static bool result_exist(const char *dir) +{ + // check result exists based on the directory 'dir'. + return false; +} + +static int redirect_output(const char *file, int stdfd) +{ + int fd = open(file, O_WRONLY | O_APPEND | O_CREAT, 0644); + int newfd; + + if (fd == -1) { + printf("hal-compatibility-checker: Failed to redirect output: %m\n"); + return -1; + } + + newfd = dup2(fd, stdfd); + close(fd); + + return newfd; +} + +static void show_help(void) +{ + printf( + "hal-compatibility-checker - check compatibility between hal-api and hal-backend\n" + "\n" + BOLD("USAGE\n") + "\thal-compatibility-checker [OPTION]...\n" + "\n" + BOLD("OPTION\n") + "\t-h, --help\n" + "\t\tshow this help.\n" + "\n" + "\t-p, --platform=DIRECTORY\n" + "\t\tspecify directory that holds platform manifest xml\n" + "\t\twhen it is not specified, use default path: %s\n" + "\n" + "\t--skip-if-result-exist[=DIRECTORY]\n" + "\t\tskip compatibility check if there exists a result of compatibility.\n" + "\t\tif DIRECTORY is given, locate a result based on the given DIRECTORY.\n" + "\n" + "\t--redirect-all=FILE\n" + "\t\tredirect stdout/stderr to FILE.\n" + "\n" + "\t--redirect-stdout=FILE\n" + "\t\tredirect stdout to FILE.\n" + "\n" + "\t--redirect-stderr=FILE\n" + "\t\tredirect stderr to FILE.\n" + , default_platform_manifest_dir() + ); +} + +static void compatibility_cb(enum hal_module module, + halcc_compatibility_e is_compatible, void *user_data) +{ + // do something +} + +int main(int argc, char *argv[]) +{ + int opt; + int help = 0; + int index; + bool skip_if_result_exist = false; + const char *skip_if_result_exist_dir = NULL; + const char *platform_manifest_dir = NULL; + const char *outfile = NULL; + const char *errfile = NULL; + + for (;;) { + opt = getopt_long(argc, argv, "hp:", long_option, &index); + if (opt == -1) + break; + + switch (opt) { + case 'h': + help = 1; + break; + case 'p': + platform_manifest_dir = optarg; + break; + case 0: // long-only options + { + switch (index) { + case OPT_SKIP_IF_RESULT_EXIST: + skip_if_result_exist = true; + skip_if_result_exist_dir = optarg; + break; + case OPT_REDIRECT_ALL: + outfile = optarg; + errfile = optarg; + break; + case OPT_REDIRECT_STDOUT: + outfile = optarg; + break; + case OPT_REDIRECT_STDERR: + errfile = optarg; + break; + default: + break; + } + + break; + } + default: + break; + } + } + + if (help) { + show_help(); + return 0; + } + + if (outfile) + redirect_output(outfile, STDOUT_FILENO); + + if (errfile) + redirect_output(errfile, STDERR_FILENO); + + if (skip_if_result_exist && result_exist(skip_if_result_exist_dir)) { + printf("hal-compatibility-checker: skip checking\n"); + return 0; + } + + if (!platform_manifest_dir) + platform_manifest_dir = default_platform_manifest_dir(); + + halcc_check_compatibility(platform_manifest_dir, compatibility_cb, NULL); + + return 0; +} -- 2.34.1