mirror of
https://github.com/zlgopen/awtk.git
synced 2025-05-09 12:01:19 +08:00
refactor and fix memory leaks found by valgrind
This commit is contained in:
parent
0f799305d4
commit
16e992c20b
1138
demos/assets.c
1138
demos/assets.c
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,9 @@
|
||||
# 最新动态
|
||||
* 2019/04/08
|
||||
* 增加assets\_manager\_preload
|
||||
* 重构
|
||||
* 修改valgrind发现的内存泄露。
|
||||
|
||||
* 2019/04/07
|
||||
* 为适配AWTK-WEB做了写小的修改。
|
||||
* 修改资源脚本,生成文件列表,用于awtk-web。
|
||||
|
@ -14,6 +14,8 @@ ASSET_C=common.joinPath(APP_ROOT, 'demos/assets.c')
|
||||
common.init(AWTK_ROOT, ASSETS_ROOT, ASSET_C);
|
||||
|
||||
def buildTools():
|
||||
os.system('scons '+common.toExe('bsvggen'))
|
||||
os.system('scons '+common.toExe('strgen'))
|
||||
os.system('scons '+common.toExe('resgen'))
|
||||
os.system('scons '+common.toExe('themegen'))
|
||||
os.system('scons '+common.toExe('imagegen'))
|
||||
|
@ -237,6 +237,7 @@ def gen_res_all_script():
|
||||
|
||||
|
||||
def gen_res_all_string():
|
||||
print('gen_res_all_string');
|
||||
strgen('strings/strings.xml', 'strings')
|
||||
strgen_bin('strings/strings.xml', 'strings')
|
||||
|
||||
@ -355,11 +356,11 @@ def gen_res_c():
|
||||
|
||||
result += '#ifdef WITH_FS_RES\n'
|
||||
result += "#if defined(WITH_MINI_FONT)\n"
|
||||
result += ' assets_manager_load(rm, ASSET_TYPE_FONT, "default_mini");\n'
|
||||
result += ' assets_manager_preload(rm, ASSET_TYPE_FONT, "default_mini");\n'
|
||||
result += "#else/*WITH_MINI_FONT*/\n"
|
||||
result += ' assets_manager_load(rm, ASSET_TYPE_FONT, "default");\n'
|
||||
result += ' assets_manager_preload(rm, ASSET_TYPE_FONT, "default");\n'
|
||||
result += '#endif/*WITH_MINI_FONT*/\n'
|
||||
result += ' assets_manager_load(rm, ASSET_TYPE_STYLE, "default");\n'
|
||||
result += ' assets_manager_preload(rm, ASSET_TYPE_STYLE, "default");\n'
|
||||
result += '#else\n'
|
||||
|
||||
files = glob.glob(joinPath(OUTPUT_DIR, '**/*.data'))
|
||||
|
@ -465,6 +465,14 @@ ret_t assets_manager_clear_cache(assets_manager_t* am, asset_type_t type) {
|
||||
return darray_remove_all(&(am->assets), &info);
|
||||
}
|
||||
|
||||
ret_t assets_manager_preload(assets_manager_t* am, asset_type_t type, const char* name) {
|
||||
asset_info_t* info = assets_manager_load(am, type, name);
|
||||
return_value_if_fail(info != NULL, RET_FAIL);
|
||||
assets_manager_unref(am, info);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t assets_manager_deinit(assets_manager_t* am) {
|
||||
return_value_if_fail(am != NULL, RET_BAD_PARAMS);
|
||||
|
||||
|
@ -344,6 +344,17 @@ const asset_info_t* assets_manager_find_in_cache(assets_manager_t* am, asset_typ
|
||||
*/
|
||||
asset_info_t* assets_manager_load(assets_manager_t* am, asset_type_t type, const char* name);
|
||||
|
||||
/**
|
||||
* @method assets_manager_preload
|
||||
* 从文件系统中加载指定的资源,并缓存到内存中。在定义了宏WITH\_FS\_RES时才生效。
|
||||
* @param {assets_manager_t*} am asset manager对象。
|
||||
* @param {asset_type_t} type 资源的类型。
|
||||
* @param {char*} name 资源的名称。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t assets_manager_preload(assets_manager_t* am, asset_type_t type, const char* name);
|
||||
|
||||
/**
|
||||
* @method assets_manager_clear_cache
|
||||
* 清除指定类型的缓存。
|
||||
|
@ -78,3 +78,55 @@ ret_t pointer_event_rotate(pointer_event_t* evt, system_info_t* info) {
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
event_t* wheel_event_init(wheel_event_t* event, uint32_t type, void* target, int32_t dy) {
|
||||
return_value_if_fail(event != NULL, NULL);
|
||||
memset(event, 0x00, sizeof(wheel_event_t));
|
||||
|
||||
event->e = event_init(type, target);
|
||||
event->dy = dy;
|
||||
|
||||
return (event_t*)event;
|
||||
}
|
||||
|
||||
event_t* pointer_event_init(pointer_event_t* event, uint32_t type, void* target, int32_t x,
|
||||
int32_t y) {
|
||||
return_value_if_fail(event != NULL, NULL);
|
||||
memset(event, 0x00, sizeof(pointer_event_t));
|
||||
|
||||
event->e = event_init(type, target);
|
||||
event->x = x;
|
||||
event->y = y;
|
||||
|
||||
return (event_t*)event;
|
||||
}
|
||||
|
||||
event_t* key_event_init(key_event_t* event, uint32_t type, void* target, int32_t key) {
|
||||
return_value_if_fail(event != NULL, NULL);
|
||||
memset(event, 0x00, sizeof(key_event_t));
|
||||
|
||||
event->e = event_init(type, target);
|
||||
event->key = key;
|
||||
|
||||
return (event_t*)event;
|
||||
}
|
||||
|
||||
event_t* paint_event_init(paint_event_t* event, uint32_t type, void* target, canvas_t* c) {
|
||||
return_value_if_fail(event != NULL, NULL);
|
||||
memset(event, 0x00, sizeof(paint_event_t));
|
||||
|
||||
event->e = event_init(type, target);
|
||||
event->c = c;
|
||||
|
||||
return (event_t*)event;
|
||||
}
|
||||
|
||||
event_t* window_event_init(window_event_t* event, uint32_t type, void* target, widget_t* window) {
|
||||
return_value_if_fail(event != NULL, NULL);
|
||||
memset(event, 0x00, sizeof(window_event_t));
|
||||
|
||||
event->e = event_init(type, target);
|
||||
event->window = window;
|
||||
|
||||
return (event_t*)event;
|
||||
}
|
||||
|
@ -298,16 +298,10 @@ typedef enum _event_type_t {
|
||||
*/
|
||||
typedef struct _wheel_event_t {
|
||||
event_t e;
|
||||
/**
|
||||
* @property {int32_t} dx
|
||||
* @annotation ["readable", "scriptable"]
|
||||
* 滚轮的x值。
|
||||
*/
|
||||
int32_t dx;
|
||||
/**
|
||||
* @property {int32_t} dy
|
||||
* @annotation ["readable", "scriptable"]
|
||||
* 滚轮的x值。
|
||||
* 滚轮的y值。
|
||||
*/
|
||||
int32_t dy;
|
||||
/**
|
||||
@ -336,10 +330,22 @@ typedef struct _wheel_event_t {
|
||||
* 把event对象转wheel_event_t对象,主要给脚本语言使用。
|
||||
* @param {event_t*} event event对象。
|
||||
*
|
||||
* @return {wheel_event_t*} 对象。
|
||||
* @return {wheel_event_t*} event对象。
|
||||
*/
|
||||
wheel_event_t* wheel_event_cast(event_t* event);
|
||||
|
||||
/**
|
||||
* @method wheel_event_init
|
||||
* 初始化事件。
|
||||
* @param {wheel_event_t*} event event对象。
|
||||
* @param {void*} target 事件目标。
|
||||
* @param {uint32_t} type 事件类型。
|
||||
* @param {int32_t} dy 滚轮的y值。
|
||||
*
|
||||
* @return {event_t*} event对象。
|
||||
*/
|
||||
event_t* wheel_event_init(wheel_event_t* event, uint32_t type, void* target, int32_t dy);
|
||||
|
||||
/**
|
||||
* @class pointer_event_t
|
||||
* @annotation ["scriptable"]
|
||||
@ -403,6 +409,20 @@ typedef struct _pointer_event_t {
|
||||
*/
|
||||
pointer_event_t* pointer_event_cast(event_t* event);
|
||||
|
||||
/**
|
||||
* @method pointer_event_init
|
||||
* 初始化事件。
|
||||
* @param {pointer_event_t*} event event对象。
|
||||
* @param {void*} target 事件目标。
|
||||
* @param {uint32_t} type 事件类型。
|
||||
* @param {int32_t} x x的值。
|
||||
* @param {int32_t} y y的值。
|
||||
*
|
||||
* @return {event_t*} event对象。
|
||||
*/
|
||||
event_t* pointer_event_init(pointer_event_t* event, uint32_t type, void* target, int32_t x,
|
||||
int32_t y);
|
||||
|
||||
/**
|
||||
* @class key_event_t
|
||||
* @annotation ["scriptable"]
|
||||
@ -453,6 +473,18 @@ typedef struct _key_event_t {
|
||||
*/
|
||||
key_event_t* key_event_cast(event_t* event);
|
||||
|
||||
/**
|
||||
* @method key_event_init
|
||||
* 初始化事件。
|
||||
* @param {key_event_t*} event event对象。
|
||||
* @param {void*} target 事件目标。
|
||||
* @param {uint32_t} type 事件类型。
|
||||
* @param {int32_t} key key的值。
|
||||
*
|
||||
* @return {event_t*} event对象。
|
||||
*/
|
||||
event_t* key_event_init(key_event_t* event, uint32_t type, void* target, int32_t key);
|
||||
|
||||
/**
|
||||
* @class paint_event_t
|
||||
* @annotation ["scriptable"]
|
||||
@ -475,10 +507,22 @@ typedef struct _paint_event_t {
|
||||
* 把event对象转paint_event_t对象。主要给脚本语言使用。
|
||||
* @param {event_t*} event event对象。
|
||||
*
|
||||
* @return {paint_event_t*} 对象。
|
||||
* @return {paint_event_t*} event 对象。
|
||||
*/
|
||||
paint_event_t* paint_event_cast(event_t* event);
|
||||
|
||||
/**
|
||||
* @method paint_event_init
|
||||
* 初始化事件。
|
||||
* @param {paint_event_t*} event event对象。
|
||||
* @param {void*} target 事件目标。
|
||||
* @param {uint32_t} type 事件类型。
|
||||
* @param {canvas_t*} c canvas对象。
|
||||
*
|
||||
* @return {event_t*} event对象。
|
||||
*/
|
||||
event_t* paint_event_init(paint_event_t* event, uint32_t type, void* target, canvas_t* c);
|
||||
|
||||
/**
|
||||
* @class window_event_t
|
||||
* @annotation ["scriptable"]
|
||||
@ -505,6 +549,18 @@ typedef struct _window_event_t {
|
||||
*/
|
||||
window_event_t* window_event_cast(event_t* event);
|
||||
|
||||
/**
|
||||
* @method window_event_init
|
||||
* 初始化事件。
|
||||
* @param {window_event_t*} event event对象。
|
||||
* @param {void*} target 事件目标。
|
||||
* @param {uint32_t} type 事件类型。
|
||||
* @param {widget_t*} widget window对象。
|
||||
*
|
||||
* @return {event_t*} event对象。
|
||||
*/
|
||||
event_t* window_event_init(window_event_t* event, uint32_t type, void* target, widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method pointer_event_rotate
|
||||
* 根据屏幕旋转方向修正pointer_event中的坐标。
|
||||
|
@ -91,9 +91,8 @@ font_t* font_manager_load(font_manager_t* fm, const char* name, uint32_t size) {
|
||||
if (info != NULL) {
|
||||
if (info->subtype == fm->loader->type) {
|
||||
font = font_loader_load(fm->loader, name, info->data, info->size);
|
||||
} else {
|
||||
assets_manager_unref(assets_manager(), info);
|
||||
}
|
||||
assets_manager_unref(assets_manager(), info);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1168,12 +1168,8 @@ ret_t widget_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
if (widget->vt->on_paint_self) {
|
||||
ret = widget->vt->on_paint_self(widget, c);
|
||||
} else {
|
||||
paint_event_t paint;
|
||||
paint.c = c;
|
||||
paint.e.type = EVT_PAINT;
|
||||
paint.e.target = widget;
|
||||
|
||||
widget_dispatch(widget, (event_t*)&paint);
|
||||
paint_event_t e;
|
||||
widget_dispatch(widget, paint_event_init(&e, EVT_BEFORE_PAINT, widget, c));
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1219,9 +1215,7 @@ ret_t widget_on_paint_begin(widget_t* widget, canvas_t* c) {
|
||||
ret = widget->vt->on_paint_begin(widget, c);
|
||||
}
|
||||
|
||||
e.c = c;
|
||||
e.e = event_init(EVT_BEFORE_PAINT, widget);
|
||||
widget_dispatch(widget, (event_t*)(&e));
|
||||
widget_dispatch(widget, paint_event_init(&e, EVT_BEFORE_PAINT, widget, c));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1232,9 +1226,7 @@ static ret_t widget_on_paint_done(widget_t* widget, canvas_t* c) {
|
||||
return_value_if_fail(widget != NULL && c != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(widget->vt != NULL, RET_BAD_PARAMS);
|
||||
|
||||
e.c = c;
|
||||
e.e = event_init(EVT_PAINT_DONE, widget);
|
||||
widget_dispatch(widget, (event_t*)(&e));
|
||||
widget_dispatch(widget, paint_event_init(&e, EVT_PAINT_DONE, widget, c));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1249,9 +1241,7 @@ ret_t widget_on_paint_end(widget_t* widget, canvas_t* c) {
|
||||
ret = widget->vt->on_paint_end(widget, c);
|
||||
}
|
||||
|
||||
e.c = c;
|
||||
e.e = event_init(EVT_AFTER_PAINT, widget);
|
||||
widget_dispatch(widget, (event_t*)(&e));
|
||||
widget_dispatch(widget, paint_event_init(&e, EVT_AFTER_PAINT, widget, c));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1614,7 +1604,11 @@ ret_t widget_destroy(widget_t* widget) {
|
||||
if (parent != NULL) {
|
||||
if (parent->target == widget || parent->key_target == widget) {
|
||||
widget_remove_child(parent, widget);
|
||||
return widget_destroy_async(widget);
|
||||
if (parent->parent == NULL) {
|
||||
return widget_do_destroy(widget);
|
||||
} else {
|
||||
return widget_destroy_async(widget);
|
||||
}
|
||||
}
|
||||
|
||||
widget_remove_child(widget->parent, widget);
|
||||
|
@ -149,7 +149,10 @@ ret_t mutable_image_set_framebuffer(widget_t* widget, uint32_t w, uint32_t h,
|
||||
mutable_image->fb = bitmap_create();
|
||||
return_value_if_fail(mutable_image->fb != NULL, RET_OOM);
|
||||
|
||||
return bitmap_init(mutable_image->fb, w, h, format, buff);
|
||||
bitmap_init(mutable_image->fb, w, h, format, buff);
|
||||
mutable_image->fb->should_free_handle = TRUE;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
widget_t* mutable_image_cast(widget_t* widget) {
|
||||
|
@ -22,17 +22,14 @@ static ret_t main_loop_sdl2_dispatch_key_event(main_loop_simple_t* loop, SDL_Eve
|
||||
int type = sdl_event->type;
|
||||
widget_t* widget = loop->base.wm;
|
||||
|
||||
memset(&event, 0x00, sizeof(event));
|
||||
event.e.time = time_now_ms();
|
||||
event.key = sdl_event->key.keysym.sym;
|
||||
switch (type) {
|
||||
case SDL_KEYDOWN: {
|
||||
event.e.type = EVT_KEY_DOWN;
|
||||
key_event_init(&event, EVT_KEY_DOWN, widget, sdl_event->key.keysym.sym);
|
||||
window_manager_dispatch_input_event(widget, (event_t*)&event);
|
||||
break;
|
||||
}
|
||||
case SDL_KEYUP: {
|
||||
event.e.type = EVT_KEY_UP;
|
||||
key_event_init(&event, EVT_KEY_UP, widget, sdl_event->key.keysym.sym);
|
||||
window_manager_dispatch_input_event(widget, (event_t*)&event);
|
||||
break;
|
||||
}
|
||||
@ -47,18 +44,14 @@ static ret_t main_loop_sdl2_dispatch_key_event(main_loop_simple_t* loop, SDL_Eve
|
||||
static ret_t main_loop_sdl2_dispatch_wheel_event(main_loop_simple_t* loop, SDL_Event* sdl_event) {
|
||||
wheel_event_t event;
|
||||
widget_t* widget = loop->base.wm;
|
||||
|
||||
memset(&event, 0x00, sizeof(event));
|
||||
event.e = event_init(EVT_WHEEL, widget);
|
||||
event.dx = sdl_event->wheel.x;
|
||||
event.dy = sdl_event->wheel.y;
|
||||
event_t* e = wheel_event_init(&event, EVT_WHEEL, widget, sdl_event->wheel.y);
|
||||
|
||||
if (event.dy > 0) {
|
||||
event.dy = tk_max(MIN_WHEEL_DELTA, event.dy);
|
||||
} else if (event.dy < 0) {
|
||||
event.dy = tk_min(-MIN_WHEEL_DELTA, event.dy);
|
||||
}
|
||||
window_manager_dispatch_input_event(widget, (event_t*)&event);
|
||||
window_manager_dispatch_input_event(widget, e);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
@ -69,13 +62,11 @@ static ret_t main_loop_sdl2_dispatch_mouse_event(main_loop_simple_t* loop, SDL_E
|
||||
widget_t* widget = loop->base.wm;
|
||||
|
||||
memset(&event, 0x00, sizeof(event));
|
||||
event.e.time = time_now_ms();
|
||||
switch (type) {
|
||||
case SDL_MOUSEBUTTONDOWN: {
|
||||
loop->pressed = 1;
|
||||
event.e.type = EVT_POINTER_DOWN;
|
||||
event.x = sdl_event->button.x;
|
||||
event.y = sdl_event->button.y;
|
||||
pointer_event_init(&event, EVT_POINTER_DOWN, widget, sdl_event->button.x,
|
||||
sdl_event->button.y);
|
||||
event.button = sdl_event->button.button;
|
||||
event.pressed = loop->pressed;
|
||||
|
||||
@ -84,9 +75,7 @@ static ret_t main_loop_sdl2_dispatch_mouse_event(main_loop_simple_t* loop, SDL_E
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEBUTTONUP: {
|
||||
event.e.type = EVT_POINTER_UP;
|
||||
event.x = sdl_event->button.x;
|
||||
event.y = sdl_event->button.y;
|
||||
pointer_event_init(&event, EVT_POINTER_UP, widget, sdl_event->button.x, sdl_event->button.y);
|
||||
event.button = sdl_event->button.button;
|
||||
event.pressed = loop->pressed;
|
||||
|
||||
@ -96,9 +85,8 @@ static ret_t main_loop_sdl2_dispatch_mouse_event(main_loop_simple_t* loop, SDL_E
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEMOTION: {
|
||||
event.e.type = EVT_POINTER_MOVE;
|
||||
event.x = sdl_event->motion.x;
|
||||
event.y = sdl_event->motion.y;
|
||||
pointer_event_init(&event, EVT_POINTER_MOVE, widget, sdl_event->button.x,
|
||||
sdl_event->button.y);
|
||||
event.button = 0;
|
||||
event.pressed = loop->pressed;
|
||||
|
||||
|
@ -870,10 +870,16 @@ EvalResult eval_execute(const char* expression, const EvalHooks* hooks, void* us
|
||||
ctx.stack_level = 0;
|
||||
|
||||
result = get_token(&ctx);
|
||||
if (result != EVAL_RESULT_OK) return result;
|
||||
if (result != EVAL_RESULT_OK) {
|
||||
expr_str_clear(&ctx.str);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = parse_expr(&ctx, output);
|
||||
if (result != EVAL_RESULT_OK) return result;
|
||||
if (result != EVAL_RESULT_OK) {
|
||||
expr_str_clear(&ctx.str);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = (ctx.token.type == EVAL_TOKEN_TYPE_END) ? EVAL_RESULT_OK : EVAL_RESULT_UNEXPECTED_CHAR;
|
||||
expr_str_clear(&ctx.str);
|
||||
|
@ -513,7 +513,11 @@ static const char* expand_var(str_t* str, const char* p, const object_t* obj) {
|
||||
return_value_if_fail(len <= TK_NAME_LEN, end + 1);
|
||||
|
||||
tk_strncpy(name, p, len);
|
||||
return_value_if_fail(object_eval((object_t*)obj, name, &v) == RET_OK, end + 1);
|
||||
if (object_eval((object_t*)obj, name, &v) != RET_OK) {
|
||||
value_reset(&v);
|
||||
|
||||
return end + 1;
|
||||
}
|
||||
|
||||
if (v.type == VALUE_TYPE_STRING) {
|
||||
str_append(str, value_str(&v));
|
||||
@ -522,6 +526,7 @@ static const char* expand_var(str_t* str, const char* p, const object_t* obj) {
|
||||
tk_snprintf(num, TK_NUM_MAX_LEN, "%d", value_int(&v));
|
||||
str_append(str, num);
|
||||
}
|
||||
value_reset(&v);
|
||||
|
||||
return end + 1;
|
||||
}
|
||||
|
@ -72,6 +72,13 @@ static ret_t dialog_get_prop(widget_t* widget, const char* name, value_t* v) {
|
||||
return window_base_get_prop(widget, name, v);
|
||||
}
|
||||
|
||||
static ret_t dialog_on_destroy(widget_t* widget) {
|
||||
dialog_t* dialog = DIALOG(widget);
|
||||
TKMEM_FREE(dialog->highlight);
|
||||
|
||||
return window_base_on_destroy(widget);
|
||||
}
|
||||
|
||||
TK_DECL_VTABLE(dialog) = {.size = sizeof(dialog_t),
|
||||
.type = WIDGET_TYPE_DIALOG,
|
||||
.is_window = TRUE,
|
||||
@ -86,7 +93,7 @@ TK_DECL_VTABLE(dialog) = {.size = sizeof(dialog_t),
|
||||
.on_paint_end = window_base_on_paint_end,
|
||||
.set_prop = dialog_set_prop,
|
||||
.get_prop = dialog_get_prop,
|
||||
.on_destroy = window_base_on_destroy};
|
||||
.on_destroy = dialog_on_destroy};
|
||||
|
||||
widget_t* dialog_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
return window_base_create(parent, TK_REF_VTABLE(dialog), x, y, w, h);
|
||||
|
@ -290,6 +290,7 @@ TEST(ObejectDefault, copy_prop) {
|
||||
|
||||
ASSERT_NE(object_copy_prop(obj, src, "not exist"), RET_OK);
|
||||
|
||||
object_unref(src);
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
@ -345,6 +346,7 @@ TEST(ObejectDefault, expr_str) {
|
||||
ASSERT_EQ(object_eval(obj, "$a+$b", &v), RET_OK);
|
||||
ASSERT_EQ(string(value_str(&v)), string("123abc"));
|
||||
|
||||
value_reset(&v);
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
@ -360,6 +362,7 @@ TEST(ObejectDefault, clone) {
|
||||
ASSERT_EQ(object_eval(clone, "$a+$b", &v), RET_OK);
|
||||
ASSERT_EQ(string(value_str(&v)), string("123abc"));
|
||||
|
||||
value_reset(&v);
|
||||
object_unref(obj);
|
||||
object_unref(clone);
|
||||
}
|
||||
|
@ -250,5 +250,6 @@ TEST(Str, expand_vars) {
|
||||
ASSERT_EQ(str_expand_vars(s, "123${abc+$x}456", vars), RET_OK);
|
||||
ASSERT_STREQ(s->str, "123456");
|
||||
|
||||
object_unref(vars);
|
||||
str_reset(s);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user