2018-02-21 19:36:38 +08:00
|
|
|
/**
|
|
|
|
* File: utils.c
|
2018-05-15 09:31:58 +08:00
|
|
|
* Author: AWTK Develop Team
|
2018-02-21 19:36:38 +08:00
|
|
|
* Brief: utils function
|
|
|
|
*
|
2020-01-01 11:27:36 +08:00
|
|
|
* Copyright (c) 2018 - 2020 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
2018-02-21 19:36:38 +08:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* License file for more details.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* History:
|
|
|
|
* ================================================================
|
|
|
|
* 2018-01-21 Li XianJing <xianjimli@hotmail.com> created
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "utils.h"
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
2018-12-15 17:22:05 +08:00
|
|
|
#include "tkc/fs.h"
|
|
|
|
#include "tkc/mem.h"
|
2019-12-25 17:36:14 +08:00
|
|
|
#include "tkc/wstr.h"
|
2018-03-09 21:54:46 +08:00
|
|
|
#include "base/enums.h"
|
2018-12-15 17:22:05 +08:00
|
|
|
#include "tkc/path.h"
|
2018-08-24 07:45:37 +08:00
|
|
|
#include "base/assets_manager.h"
|
2018-02-21 19:36:38 +08:00
|
|
|
|
2020-03-23 12:16:07 +08:00
|
|
|
bool_t exit_if_need_not_update(const char* in, const char* out) {
|
2018-11-02 11:51:14 +08:00
|
|
|
if (in == NULL || out == NULL) {
|
|
|
|
log_debug("invalid params: %s %s\n", in, out);
|
2020-03-23 12:16:07 +08:00
|
|
|
return TRUE;
|
2018-11-02 11:51:14 +08:00
|
|
|
}
|
|
|
|
|
2019-12-25 17:36:14 +08:00
|
|
|
if (!fs_file_exist(os_fs(), in)) {
|
2018-11-02 11:51:14 +08:00
|
|
|
log_debug("%s not exist\n", in);
|
2020-03-23 12:16:07 +08:00
|
|
|
return TRUE;
|
2018-11-02 11:51:14 +08:00
|
|
|
}
|
|
|
|
|
2022-06-14 10:41:04 +08:00
|
|
|
if (file_get_size(in) == 0) {
|
|
|
|
log_debug("%s is empty\n", in);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2019-12-25 17:36:14 +08:00
|
|
|
if (!fs_file_exist(os_fs(), out)) {
|
2020-03-23 12:16:07 +08:00
|
|
|
return FALSE;
|
2018-11-02 11:51:14 +08:00
|
|
|
}
|
|
|
|
|
2019-12-25 17:36:14 +08:00
|
|
|
ret_t rt = RET_OK;
|
2020-01-06 08:16:52 +08:00
|
|
|
fs_stat_info_t fst_in;
|
|
|
|
fs_stat_info_t fst_out;
|
2019-12-25 17:36:14 +08:00
|
|
|
|
2020-01-06 08:16:52 +08:00
|
|
|
rt = fs_stat(os_fs(), in, &fst_in);
|
2019-12-25 17:36:14 +08:00
|
|
|
if (rt != RET_OK) {
|
|
|
|
log_debug("get \"%s\" filetime failed\n", in);
|
2020-03-23 12:16:07 +08:00
|
|
|
return TRUE;
|
2019-12-25 17:36:14 +08:00
|
|
|
}
|
2020-01-06 08:16:52 +08:00
|
|
|
rt = fs_stat(os_fs(), out, &fst_out);
|
2019-12-25 17:36:14 +08:00
|
|
|
if (rt != RET_OK) {
|
|
|
|
log_debug("get \"%s\" filetime failed\n", out);
|
2020-03-23 12:16:07 +08:00
|
|
|
return TRUE;
|
2019-12-25 17:36:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fst_in.mtime < fst_out.mtime) {
|
2018-11-02 11:51:14 +08:00
|
|
|
log_debug("Skip because: %s is newer than %s\n", out, in);
|
2020-03-23 12:16:07 +08:00
|
|
|
return TRUE;
|
2018-11-02 11:51:14 +08:00
|
|
|
}
|
2020-03-23 12:16:07 +08:00
|
|
|
return FALSE;
|
2018-11-02 11:51:14 +08:00
|
|
|
}
|
|
|
|
|
2019-09-05 10:05:29 +08:00
|
|
|
void exit_if_need_not_update_for_infiles(const char* out, int infiles_number, ...) {
|
|
|
|
int i = 0;
|
|
|
|
va_list va;
|
2019-12-25 17:36:14 +08:00
|
|
|
ret_t rt = RET_OK;
|
2020-01-06 08:16:52 +08:00
|
|
|
fs_stat_info_t st_in;
|
|
|
|
fs_stat_info_t st_out;
|
2019-09-05 10:05:29 +08:00
|
|
|
bool_t is_not_need_update = TRUE;
|
|
|
|
|
|
|
|
if (out == NULL) {
|
2021-12-02 18:23:28 +08:00
|
|
|
log_debug("invalid params\n");
|
2019-09-05 16:33:05 +08:00
|
|
|
exit(-1);
|
2019-09-05 10:05:29 +08:00
|
|
|
}
|
|
|
|
|
2019-12-25 17:36:14 +08:00
|
|
|
if (!fs_file_exist(os_fs(), out)) {
|
2019-09-05 16:33:05 +08:00
|
|
|
return;
|
2019-09-05 10:05:29 +08:00
|
|
|
}
|
|
|
|
|
2020-01-06 08:16:52 +08:00
|
|
|
rt = fs_stat(os_fs(), out, &st_out);
|
2019-12-25 17:36:14 +08:00
|
|
|
if (rt != RET_OK) {
|
|
|
|
log_debug("get \"%s\" filetime failed\n", out);
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
2019-09-05 10:05:29 +08:00
|
|
|
va_start(va, infiles_number);
|
2019-09-05 16:33:05 +08:00
|
|
|
|
|
|
|
for (i = 0; i < infiles_number; i++) {
|
2019-09-05 10:05:29 +08:00
|
|
|
char* in = va_arg(va, char*);
|
2019-09-05 16:33:05 +08:00
|
|
|
|
|
|
|
if (in == NULL) {
|
2019-09-05 10:05:29 +08:00
|
|
|
continue;
|
|
|
|
}
|
2019-12-25 17:36:14 +08:00
|
|
|
|
|
|
|
if (!fs_file_exist(os_fs(), in)) {
|
2019-09-05 10:05:29 +08:00
|
|
|
log_debug("%s not exist\n", in);
|
|
|
|
is_not_need_update = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
2019-12-25 17:36:14 +08:00
|
|
|
|
2020-01-06 08:16:52 +08:00
|
|
|
rt = fs_stat(os_fs(), in, &st_in);
|
2019-12-25 17:36:14 +08:00
|
|
|
if (rt != RET_OK) {
|
|
|
|
log_debug("get \"%s\" filetime failed\n", in);
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (st_in.mtime > st_out.mtime) {
|
2019-09-05 10:05:29 +08:00
|
|
|
is_not_need_update = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end(va);
|
|
|
|
|
|
|
|
if (is_not_need_update) {
|
|
|
|
log_debug("Skip because: %s is new \n", out);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-03 10:19:34 +08:00
|
|
|
char* read_file(const char* file_name, uint32_t* length) {
|
2019-07-04 08:53:58 +08:00
|
|
|
return (char*)file_read(file_name, length);
|
2018-06-03 10:19:34 +08:00
|
|
|
}
|
2018-02-21 19:36:38 +08:00
|
|
|
|
2018-04-27 18:12:12 +08:00
|
|
|
ret_t write_file(const char* file_name, const void* buff, uint32_t length) {
|
2018-08-26 07:14:32 +08:00
|
|
|
return file_write(file_name, buff, length);
|
2018-02-21 19:36:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int unique(wchar_t* str, int size) {
|
|
|
|
int i = 0;
|
|
|
|
wchar_t* d = str + 1;
|
|
|
|
|
|
|
|
for (i = 1; i < size; i++) {
|
|
|
|
wchar_t c = str[i];
|
|
|
|
if (c != d[-1]) {
|
|
|
|
d[0] = c;
|
|
|
|
d++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return d - str;
|
|
|
|
}
|
|
|
|
|
2020-03-23 12:16:07 +08:00
|
|
|
static const char* to_var_name(char var_name[2 * TK_NAME_LEN + 1], const char* theme,
|
|
|
|
const char* prefix, const char* name) {
|
|
|
|
if (tk_str_eq(theme, "default") || theme == NULL) {
|
|
|
|
tk_snprintf(var_name, 2 * TK_NAME_LEN, "%s_%s", prefix ? prefix : "", name);
|
|
|
|
} else {
|
|
|
|
tk_snprintf(var_name, 2 * TK_NAME_LEN, "%s_%s_%s", prefix ? prefix : "", name, theme);
|
|
|
|
}
|
2019-03-20 11:16:26 +08:00
|
|
|
|
2020-03-23 16:34:45 +08:00
|
|
|
return filter_name(var_name);
|
2019-03-20 11:16:26 +08:00
|
|
|
}
|
|
|
|
|
2020-03-23 12:16:07 +08:00
|
|
|
ret_t output_c_source(const char* filename, const char* theme, const char* prefix, const char* name,
|
|
|
|
uint8_t* buff, uint32_t size) {
|
2018-02-21 19:36:38 +08:00
|
|
|
uint32_t i = 0;
|
2019-12-25 17:36:14 +08:00
|
|
|
fs_file_t* ft = NULL;
|
2018-12-26 09:14:02 +08:00
|
|
|
char str[TK_NAME_LEN + 1];
|
2019-03-20 11:16:26 +08:00
|
|
|
char var_name[2 * TK_NAME_LEN + 1];
|
2018-02-21 19:36:38 +08:00
|
|
|
return_value_if_fail(filename != NULL && buff != NULL, RET_BAD_PARAMS);
|
|
|
|
|
|
|
|
if (name == NULL) {
|
|
|
|
filename_to_name(filename, str, sizeof(str));
|
|
|
|
name = str;
|
|
|
|
}
|
|
|
|
|
2019-03-20 11:16:26 +08:00
|
|
|
log_debug("filename=%s prefix=%s name=%s size=%u\n", filename, prefix, name, size);
|
|
|
|
|
2019-12-25 17:36:14 +08:00
|
|
|
ft = fs_open_file(os_fs(), filename, "wb+");
|
|
|
|
if (ft != NULL) {
|
|
|
|
fs_file_printf(ft, "TK_CONST_DATA_ALIGN(const unsigned char %s[]) = {",
|
2020-03-23 12:16:07 +08:00
|
|
|
to_var_name(var_name, theme, prefix, name));
|
2018-02-21 19:36:38 +08:00
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
if ((i % 20) == 0) {
|
2019-12-25 17:36:14 +08:00
|
|
|
fs_file_printf(ft, "\n");
|
2018-02-21 19:36:38 +08:00
|
|
|
}
|
2019-12-25 17:36:14 +08:00
|
|
|
fs_file_printf(ft, "0x%02x,", (int)(buff[i]));
|
2018-02-21 19:36:38 +08:00
|
|
|
}
|
|
|
|
|
2019-12-25 17:36:14 +08:00
|
|
|
fs_file_printf(ft, "};/*%u*/\n", size);
|
|
|
|
fs_file_close(ft);
|
2018-02-21 19:36:38 +08:00
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return RET_FAIL;
|
|
|
|
}
|
2018-03-09 21:54:46 +08:00
|
|
|
|
2020-03-23 12:16:07 +08:00
|
|
|
ret_t output_res_c_source_ex(const char* filename, const char* theme, uint16_t type,
|
|
|
|
uint16_t subtype, uint8_t* buff, uint32_t size, const char* name) {
|
2018-08-24 07:45:37 +08:00
|
|
|
asset_info_t* res = NULL;
|
2020-11-04 15:00:39 +08:00
|
|
|
const char* array_name = NULL;
|
|
|
|
const char* asset_name = NULL;
|
2018-08-24 07:45:37 +08:00
|
|
|
uint32_t total_size = sizeof(asset_info_t) + size;
|
|
|
|
const key_type_value_t* kv = asset_type_find_by_value(type);
|
2018-03-09 21:54:46 +08:00
|
|
|
return_value_if_fail(kv != NULL, RET_BAD_PARAMS);
|
|
|
|
return_value_if_fail(filename != NULL && buff != NULL, RET_BAD_PARAMS);
|
|
|
|
|
2018-08-24 07:45:37 +08:00
|
|
|
res = (asset_info_t*)malloc(total_size);
|
2018-11-14 18:07:42 +08:00
|
|
|
memset(res, 0x00, total_size);
|
2018-03-09 21:54:46 +08:00
|
|
|
res->size = size;
|
|
|
|
res->type = type;
|
2018-04-27 18:12:12 +08:00
|
|
|
res->is_in_rom = TRUE;
|
2018-05-04 11:46:31 +08:00
|
|
|
res->refcount = 0;
|
2018-03-18 11:29:31 +08:00
|
|
|
res->subtype = subtype;
|
2018-03-09 21:54:46 +08:00
|
|
|
memcpy(res->data, buff, size);
|
2019-03-20 11:16:26 +08:00
|
|
|
if (name != NULL) {
|
2020-11-04 15:00:39 +08:00
|
|
|
array_name = name;
|
|
|
|
asset_name = asset_info_get_formatted_name(name);
|
2019-03-20 11:16:26 +08:00
|
|
|
} else {
|
2020-11-04 15:00:39 +08:00
|
|
|
char full_name[MAX_PATH] = {0};
|
2019-03-20 11:16:26 +08:00
|
|
|
if (type == ASSET_TYPE_DATA) {
|
2020-11-04 15:00:39 +08:00
|
|
|
filename_to_name_ex(filename, full_name, MAX_PATH, FALSE);
|
2019-03-20 11:16:26 +08:00
|
|
|
} else {
|
2020-11-04 15:00:39 +08:00
|
|
|
filename_to_name(filename, full_name, MAX_PATH);
|
2019-03-20 11:16:26 +08:00
|
|
|
}
|
2020-11-04 15:00:39 +08:00
|
|
|
array_name = (const char*)full_name;
|
|
|
|
asset_name = asset_info_get_formatted_name(full_name);
|
2019-03-20 11:16:26 +08:00
|
|
|
}
|
2020-11-04 15:00:39 +08:00
|
|
|
tk_strncpy(res->name, asset_name, sizeof(res->name) - 1);
|
|
|
|
|
|
|
|
output_c_source(filename, theme, kv->name, array_name, (uint8_t*)res, total_size);
|
2018-03-09 21:54:46 +08:00
|
|
|
free(res);
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
}
|
2018-03-16 18:27:27 +08:00
|
|
|
|
2020-03-23 12:16:07 +08:00
|
|
|
ret_t output_res_c_source(const char* filename, const char* theme, uint16_t type, uint16_t subtype,
|
|
|
|
uint8_t* buff, uint32_t size) {
|
|
|
|
return output_res_c_source_ex(filename, theme, type, subtype, buff, size, NULL);
|
2019-03-20 11:16:26 +08:00
|
|
|
}
|
|
|
|
|
2018-03-16 18:27:27 +08:00
|
|
|
const char* skip_to(const char* p, char c) {
|
2018-03-18 17:02:10 +08:00
|
|
|
while (*p && *p != c) p++;
|
2018-03-16 18:27:27 +08:00
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* skip_char(const char* p, char c) {
|
2018-03-18 17:02:10 +08:00
|
|
|
while (*p && *p == c) p++;
|
2018-03-16 18:27:27 +08:00
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* skip_to_next(const char* p, char c) {
|
|
|
|
return skip_char(skip_to(skip_char(p, c), c), c);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* get_next_token(const char* p, char* token, char c) {
|
|
|
|
const char* start = skip_char(p, c);
|
|
|
|
const char* end = skip_to(start, c);
|
|
|
|
uint32_t size = end - start;
|
|
|
|
strncpy(token, start, size);
|
|
|
|
token[size] = '\0';
|
|
|
|
|
|
|
|
return token;
|
|
|
|
}
|
|
|
|
|
2018-04-01 19:44:39 +08:00
|
|
|
bool_t start_with(const char* p, const char* str) {
|
2018-04-01 08:12:52 +08:00
|
|
|
return_value_if_fail(p != NULL && str != NULL && strlen(p) >= strlen(str), FALSE);
|
|
|
|
|
2018-04-01 19:44:39 +08:00
|
|
|
return strncmp(p, str, strlen(str)) == 0;
|
2018-04-01 08:12:52 +08:00
|
|
|
}
|
|
|
|
|
2018-04-01 19:44:39 +08:00
|
|
|
bool_t end_with(const char* p, const char* str) {
|
2018-04-01 08:12:52 +08:00
|
|
|
return_value_if_fail(p != NULL && str != NULL && strlen(p) >= strlen(str), FALSE);
|
|
|
|
|
2018-04-01 19:44:39 +08:00
|
|
|
return strncmp(p + strlen(p) - strlen(str), str, strlen(str)) == 0;
|
2018-04-01 08:12:52 +08:00
|
|
|
}
|
2018-03-16 18:27:27 +08:00
|
|
|
|
2020-11-27 16:24:49 +08:00
|
|
|
bool_t case_end_with(const char* p, const char* str) {
|
|
|
|
return_value_if_fail(p != NULL && str != NULL && strlen(p) >= strlen(str), FALSE);
|
|
|
|
|
|
|
|
return tk_str_ieq(p + strlen(p) - strlen(str), str);
|
|
|
|
}
|
|
|
|
|
2018-03-16 18:27:27 +08:00
|
|
|
const char* to_lower(char* str) {
|
|
|
|
char* p = str;
|
|
|
|
|
2018-03-18 17:02:10 +08:00
|
|
|
while (*p) {
|
2018-03-16 18:27:27 +08:00
|
|
|
*p = tolower(*p);
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
2019-12-25 17:36:14 +08:00
|
|
|
|
2020-03-23 16:36:06 +08:00
|
|
|
const char* filter_name(char* name) {
|
2020-03-23 16:34:45 +08:00
|
|
|
char* p = name;
|
|
|
|
while (*p) {
|
|
|
|
if (!(isdigit(*p) || isalpha(*p) || *p == '_')) {
|
|
|
|
*p = '_';
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2019-12-25 17:36:14 +08:00
|
|
|
wchar_t** argvw_create(int argc, char* argv[]) {
|
|
|
|
int i = 0;
|
|
|
|
wstr_t str;
|
|
|
|
wchar_t** argvw = TKMEM_ALLOC((argc + 1) * sizeof(wchar_t*));
|
|
|
|
return_value_if_fail(argvw != NULL, NULL);
|
|
|
|
wstr_init(&str, 100);
|
|
|
|
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
|
|
wstr_set_utf8(&str, argv[i]);
|
2021-09-16 16:10:54 +08:00
|
|
|
argvw[i] = wcs_dup(str.str);
|
2019-12-25 17:36:14 +08:00
|
|
|
}
|
|
|
|
argvw[i] = NULL;
|
|
|
|
|
|
|
|
return argvw;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret_t argvw_destroy(wchar_t** argvw) {
|
|
|
|
uint32_t i = 0;
|
|
|
|
return_value_if_fail(argvw != NULL, RET_BAD_PARAMS);
|
|
|
|
|
|
|
|
for (i = 0; argvw[i] != NULL; i++) {
|
|
|
|
TKMEM_FREE(argvw[i]);
|
|
|
|
}
|
|
|
|
TKMEM_FREE(argvw);
|
|
|
|
|
|
|
|
return RET_OK;
|
|
|
|
}
|