diff --git a/Kconfig b/Kconfig index 3d51204c0c..ff874c3eff 100644 --- a/Kconfig +++ b/Kconfig @@ -745,6 +745,9 @@ menu "LVGL configuration" When enabled, LV_CHECK_ARG checks validate function arguments at runtime. Failed checks log a warning and execute the specified action. When disabled, all LV_CHECK_ARG checks compile to nothing. + Disabling this is not recommended unless extreme care is taken and only + in very resource constrained environments where it can be absolutely + ensured that invariants are never violated. config LV_CHECK_ARG_ASSERT_ON_FAIL bool "Call assert handler on LV_CHECK_ARG failure" @@ -753,6 +756,36 @@ menu "LVGL configuration" help When enabled, LV_ASSERT_HANDLER is also invoked when an LV_CHECK_ARG check fails, before the action is executed. + + choice + prompt "Log behavior on LV_CHECK_ARG failure" + depends on LV_USE_CHECK_ARG + default LV_CHECK_ARG_LOG_MODE_VERBOSE if LV_USE_LOG + default LV_CHECK_ARG_LOG_MODE_NONE if !LV_USE_LOG + help + Controls what is logged when an LV_CHECK_ARG check fails. + MINIMAL and VERBOSE modes require LV_USE_LOG to be enabled; + selecting either when LV_USE_LOG is disabled will cause a + compile-time error. + + config LV_CHECK_ARG_LOG_MODE_NONE + bool "None: no log output on failure" + + config LV_CHECK_ARG_LOG_MODE_MINIMAL + bool "Minimal: log 'Check failed' only (file/line from LV_LOG_WARN)" + depends on LV_USE_LOG + + config LV_CHECK_ARG_LOG_MODE_VERBOSE + bool "Verbose: log 'Check failed: ' plus caller-supplied message" + depends on LV_USE_LOG + endchoice + + config LV_CHECK_ARG_LOG_MODE + int + depends on LV_USE_CHECK_ARG + default 0 if LV_CHECK_ARG_LOG_MODE_NONE + default 1 if LV_CHECK_ARG_LOG_MODE_MINIMAL + default 2 if LV_CHECK_ARG_LOG_MODE_VERBOSE endmenu menu "Debug" diff --git a/include/lvgl/config/lv_conf_internal.h b/include/lvgl/config/lv_conf_internal.h index aa91a00472..ac99809baa 100644 --- a/include/lvgl/config/lv_conf_internal.h +++ b/include/lvgl/config/lv_conf_internal.h @@ -45,6 +45,10 @@ #define LV_NANOVG_BACKEND_GLES2 3 #define LV_NANOVG_BACKEND_GLES3 4 +#define LV_CHECK_ARG_LOG_MODE_NONE 0 +#define LV_CHECK_ARG_LOG_MODE_MINIMAL 1 +#define LV_CHECK_ARG_LOG_MODE_VERBOSE 2 + /** Handle special Kconfig options. */ #ifndef LV_KCONFIG_IGNORE #include "lv_conf_kconfig.h" @@ -424,7 +428,7 @@ #define LV_USE_DRAW_SW 1 #endif #endif -#if LV_USE_DRAW_SW == 1 +#if LV_USE_DRAW_SW /* * Selectively disable color format support in order to reduce code size. * NOTE: some features use certain color formats internally, e.g. @@ -1500,8 +1504,13 @@ * Check arg *-----------*/ -/** Enable LV_CHECK_ARG macro to validate function arguments at runtime. - * When enabled, failed checks log a warning and execute the specified action. +/** When enabled, LV_CHECK_ARG checks validate function arguments + * at runtime. Failed checks log a warning and execute the specified + * action. When disabled, all LV_CHECK_ARG checks compile to nothing. + * Disabling this is not recommended unless extreme care is taken and only + * in very resource constrained environments where it can be absolutely + * ensured that invariants are never violated. + * * 0: Disable all LV_CHECK_ARG checks (checks compile to nothing) * 1: Enable LV_CHECK_ARG checks */ #ifndef LV_USE_CHECK_ARG @@ -1516,13 +1525,32 @@ #endif #endif -/** If enabled, also call LV_ASSERT_HANDLER when an LV_CHECK_ARG check fails. - * Requires LV_USE_CHECK_ARG to be enabled. */ -#ifndef LV_CHECK_ARG_ASSERT_ON_FAIL - #ifdef CONFIG_LV_CHECK_ARG_ASSERT_ON_FAIL - #define LV_CHECK_ARG_ASSERT_ON_FAIL CONFIG_LV_CHECK_ARG_ASSERT_ON_FAIL - #else - #define LV_CHECK_ARG_ASSERT_ON_FAIL 0 +#if LV_USE_CHECK_ARG + /** If enabled, also call LV_ASSERT_HANDLER when an LV_CHECK_ARG check fails. + * Requires LV_USE_CHECK_ARG to be enabled. */ + #ifndef LV_CHECK_ARG_ASSERT_ON_FAIL + #ifdef CONFIG_LV_CHECK_ARG_ASSERT_ON_FAIL + #define LV_CHECK_ARG_ASSERT_ON_FAIL CONFIG_LV_CHECK_ARG_ASSERT_ON_FAIL + #else + #define LV_CHECK_ARG_ASSERT_ON_FAIL 0 + #endif + #endif + + #if LV_USE_LOG + /** Controls what is logged when an LV_CHECK_ARG check fails. + * Any mode other than NONE also requires LV_USE_LOG; if LV_USE_LOG is 0 + * no output is produced regardless of this setting. + * + * LV_CHECK_ARG_LOG_MODE_NONE (0): No log output. + * LV_CHECK_ARG_LOG_MODE_MINIMAL (1): Log "Check failed" only (file/line from LV_LOG_WARN). + * LV_CHECK_ARG_LOG_MODE_VERBOSE (2): Log "Check failed: " plus caller-supplied message. */ + #ifndef LV_CHECK_ARG_LOG_MODE + #ifdef CONFIG_LV_CHECK_ARG_LOG_MODE + #define LV_CHECK_ARG_LOG_MODE CONFIG_LV_CHECK_ARG_LOG_MODE + #else + #define LV_CHECK_ARG_LOG_MODE LV_CHECK_ARG_LOG_MODE_VERBOSE + #endif + #endif #endif #endif @@ -5026,4 +5054,8 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #endif #endif /*defined(LV_CONF_SKIP)*/ +#ifndef LV_CHECK_ARG_LOG_MODE + #define LV_CHECK_ARG_LOG_MODE 0 +#endif + #endif /*LV_CONF_INTERNAL_H*/ diff --git a/include/lvgl/core/lv_obj_class.h b/include/lvgl/core/lv_obj_class.h index 6073578dc7..7c6e52dee1 100644 --- a/include/lvgl/core/lv_obj_class.h +++ b/include/lvgl/core/lv_obj_class.h @@ -57,9 +57,9 @@ lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * pa void lv_obj_class_init_obj(lv_obj_t * obj); -bool lv_obj_is_editable(lv_obj_t * obj); +bool lv_obj_is_editable(const lv_obj_t * obj); -bool lv_obj_is_group_def(lv_obj_t * obj); +bool lv_obj_is_group_def(const lv_obj_t * obj); #if LV_USE_EXT_DATA /** diff --git a/include/lvgl/core/lv_obj_tree.h b/include/lvgl/core/lv_obj_tree.h index 8f5457684a..a9a7c6905a 100644 --- a/include/lvgl/core/lv_obj_tree.h +++ b/include/lvgl/core/lv_obj_tree.h @@ -151,20 +151,20 @@ lv_obj_t * lv_obj_get_child_by_type(const lv_obj_t * obj, int32_t idx, /** * Return a sibling of an object - * @param obj pointer to an object whose sibling should be get + * @param obj pointer to an object whose sibling should be get. The object needs to be registered as a child of its parent. * @param idx 0: `obj` itself * -1: the first older sibling * -2: the next older sibling * 1: the first younger sibling * 2: the next younger sibling * etc - * @return pointer to the requested sibling or NULL if there is no such sibling +* @return pointer to the requested sibling or NULL if there is no such sibling - would navigate outside the array of children using the index (get the -3rd sibling of the second child of the parent) */ lv_obj_t * lv_obj_get_sibling(const lv_obj_t * obj, int32_t idx); /** * Return a sibling of an object. Consider the siblings only with a given type. - * @param obj pointer to an object whose sibling should be get + * @param obj pointer to an object whose sibling should be get. The object needs to be registered as a child of its parent. * @param idx 0: `obj` itself * -1: the first older sibling * -2: the next older sibling @@ -172,7 +172,7 @@ lv_obj_t * lv_obj_get_sibling(const lv_obj_t * obj, int32_t idx); * 2: the next younger sibling * etc * @param class_p the type of the children to check - * @return pointer to the requested sibling or NULL if there is no such sibling + * @return pointer to the requested sibling or NULL if there is no such sibling or would navigate outside the array of children using the index (get the -3rd sibling of the second child of the parent) */ lv_obj_t * lv_obj_get_sibling_by_type(const lv_obj_t * obj, int32_t idx, const lv_obj_class_t * class_p); diff --git a/include/lvgl/core/lv_observer.h b/include/lvgl/core/lv_observer.h index 9ba89b7be5..fbc9e2d14e 100644 --- a/include/lvgl/core/lv_observer.h +++ b/include/lvgl/core/lv_observer.h @@ -231,7 +231,7 @@ const char * lv_subject_get_string(lv_subject_t * subject); * @param subject pointer to Subject * @return pointer to buffer containing previous value * @note NULL will be returned if NULL was passed in `lv_subject_init_string()` - * as `prev_buf`. + * as `prev_buf` or if `subject` is NULL or not of string type. */ const char * lv_subject_get_previous_string(lv_subject_t * subject); diff --git a/include/lvgl/debugging/lv_check_arg.h b/include/lvgl/debugging/lv_check_arg.h index c63a7b6fbd..ad14b1e492 100644 --- a/include/lvgl/debugging/lv_check_arg.h +++ b/include/lvgl/debugging/lv_check_arg.h @@ -43,50 +43,60 @@ extern "C" { #if LV_USE_CHECK_ARG -#if LV_CHECK_ARG_ASSERT_ON_FAIL +/*---------------------------------------------------------------------- + * Internal helper: assert handler + * Expands to LV_ASSERT_HANDLER when LV_CHECK_ARG_ASSERT_ON_FAIL is set, + * otherwise to a no-op. + *---------------------------------------------------------------------*/ +# if LV_CHECK_ARG_ASSERT_ON_FAIL +# define LV_CHECK_ARG_ASSERT_HANDLER_ LV_ASSERT_HANDLER +# else +# define LV_CHECK_ARG_ASSERT_HANDLER_ do {} while(0) +# endif -/** - * Internal macro: checks a condition, logs a warning, calls the assert handler, - * and then executes the specified action on failure. +/*---------------------------------------------------------------------- + * Internal helper: log output + * Controlled by LV_CHECK_ARG_LOG_MODE. + * In all modes the macro accepts (cond_str, ...) so that + * LV_CHECK_ARG_INTERNAL_ can call it uniformly. + *---------------------------------------------------------------------*/ +# if LV_CHECK_ARG_LOG_MODE == LV_CHECK_ARG_LOG_MODE_VERBOSE +# define LV_CHECK_ARG_LOG_(cond_str, ...) LV_LOG_WARN("Check failed: " cond_str " " __VA_ARGS__) +# elif LV_CHECK_ARG_LOG_MODE == LV_CHECK_ARG_LOG_MODE_MINIMAL +# define LV_CHECK_ARG_LOG_(cond_str, ...) LV_LOG_WARN("Check failed") +# else /* LV_CHECK_ARG_LOG_MODE_NONE */ +# define LV_CHECK_ARG_LOG_(cond_str, ...) do {} while(0) +# endif + +/*---------------------------------------------------------------------- + * Internal macro: single definition, behaviour driven by the helpers above. * Do not use directly; use LV_CHECK_ARG instead. - */ -#define LV_CHECK_ARG_INTERNAL_(cond, cond_str, action_on_fail, ...) \ - if(LV_UNLIKELY(!(cond))) { \ - LV_LOG_WARN("Check failed: " cond_str " " __VA_ARGS__); \ - LV_ASSERT_HANDLER \ - action_on_fail; \ + *---------------------------------------------------------------------*/ +# define LV_CHECK_ARG_INTERNAL_(cond, cond_str, action_on_fail, ...) \ + if(LV_UNLIKELY(!(cond))) { \ + LV_CHECK_ARG_LOG_(cond_str, __VA_ARGS__); \ + LV_CHECK_ARG_ASSERT_HANDLER_; \ + action_on_fail; \ } else {} #else -/** - * Internal macro: checks a condition, logs a warning, and executes the - * specified action on failure. - * Do not use directly; use LV_CHECK_ARG instead. - */ -#define LV_CHECK_ARG_INTERNAL_(cond, cond_str, action_on_fail, ...) \ - if(LV_UNLIKELY(!(cond))) { \ - LV_LOG_WARN("Check failed: " cond_str " " __VA_ARGS__); \ - action_on_fail; \ - } else {} - -#endif /*LV_CHECK_ARG_ASSERT_ON_FAIL*/ - -#else - /** LV_CHECK_ARG is disabled; all checks compile to nothing. */ -#define LV_CHECK_ARG_INTERNAL_(cond, cond_str, action_on_fail, ...) ((void)0) +# define LV_CHECK_ARG_INTERNAL_(cond, cond_str, action_on_fail, ...) ((void)0) #endif /*LV_USE_CHECK_ARG*/ /** * Check that a condition is true. If the condition is false, log a warning * and execute `action_on_fail` (e.g. `return`, `return val`, `break`). - * Additional printf-style arguments are appended to the log message. + * Additional printf-style arguments are appended to the log message when + * LV_CHECK_ARG_LOG_MODE is set to VERBOSE. * * Can be disabled entirely by setting LV_USE_CHECK_ARG to 0 in lv_conf.h. * If LV_CHECK_ARG_ASSERT_ON_FAIL is 1, LV_ASSERT_HANDLER is also invoked * before the action. + * Log output requires LV_USE_LOG to be enabled; if LV_USE_LOG is 0 no + * output is produced regardless of LV_CHECK_ARG_LOG_MODE. * * Example: * @code @@ -97,6 +107,7 @@ extern "C" { * @param cond condition to check * @param action_on_fail statement to execute on failure (e.g. `return`, `return 0`, `break`) * @param ... optional printf-style format string and arguments appended to the log + * (only used when LV_CHECK_ARG_LOG_MODE == LV_CHECK_ARG_LOG_MODE_VERBOSE) */ #define LV_CHECK_ARG(cond, action_on_fail, ...) \ LV_CHECK_ARG_INTERNAL_(cond, #cond, action_on_fail, __VA_ARGS__) diff --git a/include/lvgl/logging/lv_log.h b/include/lvgl/logging/lv_log.h index 37f0473e0b..8975cddaa3 100644 --- a/include/lvgl/logging/lv_log.h +++ b/include/lvgl/logging/lv_log.h @@ -144,7 +144,9 @@ void lv_log_add(lv_log_level_t level, const char * file, int line, #else /*LV_USE_LOG*/ -/*Do nothing if `LV_USE_LOG 0`*/ +/* When LV_USE_LOG is 0 all logging macros expand to no-ops. + * This also suppresses any log output from LV_CHECK_ARG (and similar check + * macros such as LV_CHECK_OBJ) regardless of LV_CHECK_ARG_LOG_MODE. */ #define lv_log_add(level, file, line, ...) #define LV_LOG_TRACE(...) do {}while(0) #define LV_LOG_INFO(...) do {}while(0) diff --git a/lv_conf_template.h b/lv_conf_template.h index 1a6ca8d4b6..ceaa5427b7 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -169,7 +169,7 @@ #define LV_DRAW_THREAD_PRIO LV_THREAD_PRIO_HIGH #define LV_USE_DRAW_SW 1 -#if LV_USE_DRAW_SW == 1 +#if LV_USE_DRAW_SW /* * Selectively disable color format support in order to reduce code size. * NOTE: some features use certain color formats internally, e.g. @@ -517,15 +517,33 @@ * Check arg *-----------*/ -/** Enable LV_CHECK_ARG macro to validate function arguments at runtime. - * When enabled, failed checks log a warning and execute the specified action. +/** When enabled, LV_CHECK_ARG checks validate function arguments + * at runtime. Failed checks log a warning and execute the specified + * action. When disabled, all LV_CHECK_ARG checks compile to nothing. + * Disabling this is not recommended unless extreme care is taken and only + * in very resource constrained environments where it can be absolutely + * ensured that invariants are never violated. + * * 0: Disable all LV_CHECK_ARG checks (checks compile to nothing) * 1: Enable LV_CHECK_ARG checks */ #define LV_USE_CHECK_ARG 1 -/** If enabled, also call LV_ASSERT_HANDLER when an LV_CHECK_ARG check fails. - * Requires LV_USE_CHECK_ARG to be enabled. */ -#define LV_CHECK_ARG_ASSERT_ON_FAIL 0 +#if LV_USE_CHECK_ARG + /** If enabled, also call LV_ASSERT_HANDLER when an LV_CHECK_ARG check fails. + * Requires LV_USE_CHECK_ARG to be enabled. */ + #define LV_CHECK_ARG_ASSERT_ON_FAIL 0 + + #if LV_USE_LOG + /** Controls what is logged when an LV_CHECK_ARG check fails. + * Any mode other than NONE also requires LV_USE_LOG; if LV_USE_LOG is 0 + * no output is produced regardless of this setting. + * + * LV_CHECK_ARG_LOG_MODE_NONE (0): No log output. + * LV_CHECK_ARG_LOG_MODE_MINIMAL (1): Log "Check failed" only (file/line from LV_LOG_WARN). + * LV_CHECK_ARG_LOG_MODE_VERBOSE (2): Log "Check failed: " plus caller-supplied message. */ + #define LV_CHECK_ARG_LOG_MODE LV_CHECK_ARG_LOG_MODE_VERBOSE + #endif +#endif /*------------- * Debug diff --git a/scripts/check_gcov_coverage.py b/scripts/check_gcov_coverage.py index a04bc299ad..f9ba77b1dd 100755 --- a/scripts/check_gcov_coverage.py +++ b/scripts/check_gcov_coverage.py @@ -59,7 +59,12 @@ def create_argument_parser() -> argparse.ArgumentParser: def run_git_command(args: List[str], cwd: str = ".") -> str: """Run git command and return output""" result = subprocess.run( - ["git"] + args, capture_output=True, text=True, cwd=cwd, check=True + ["git"] + args, + capture_output=True, + cwd=cwd, + check=True, + encoding="utf-8", + errors="replace", ) return result.stdout diff --git a/scripts/lv_conf_internal_gen.py b/scripts/lv_conf_internal_gen.py index 88a9e4be94..9fa8328e48 100755 --- a/scripts/lv_conf_internal_gen.py +++ b/scripts/lv_conf_internal_gen.py @@ -83,6 +83,10 @@ fout.write( #define LV_NANOVG_BACKEND_GLES2 3 #define LV_NANOVG_BACKEND_GLES3 4 +#define LV_CHECK_ARG_LOG_MODE_NONE 0 +#define LV_CHECK_ARG_LOG_MODE_MINIMAL 1 +#define LV_CHECK_ARG_LOG_MODE_VERBOSE 2 + /** Handle special Kconfig options. */ #ifndef LV_KCONFIG_IGNORE #include "lv_conf_kconfig.h" @@ -339,6 +343,10 @@ LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN); #endif #endif /*defined(LV_CONF_SKIP)*/ +#ifndef LV_CHECK_ARG_LOG_MODE + #define LV_CHECK_ARG_LOG_MODE 0 +#endif + #endif /*LV_CONF_INTERNAL_H*/ ''' ) diff --git a/src/core/lv_group.c b/src/core/lv_group.c index 15bdcfafbc..5d7e8b46c7 100644 --- a/src/core/lv_group.c +++ b/src/core/lv_group.c @@ -9,6 +9,7 @@ #include "lv_group_private.h" #include "../core/lv_obj_private.h" #include "../core/lv_global.h" +#include "../lv_public_api.h" /********************* * DEFINES @@ -75,8 +76,9 @@ lv_group_t * lv_group_create(void) void lv_group_delete(lv_group_t * group) { + if(group == NULL) return; + /*Defocus the currently focused object*/ - LV_ASSERT_NULL(group); if(group->obj_focus != NULL) { lv_obj_send_event(*group->obj_focus, LV_EVENT_DEFOCUSED, get_indev(group)); lv_obj_invalidate(*group->obj_focus); @@ -123,7 +125,8 @@ lv_group_t * lv_group_get_default(void) void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj) { - if(group == NULL) return; + LV_CHECK_ARG(group != NULL, return); + LV_CHECK_ARG(obj != NULL, return); LV_LOG_TRACE("begin"); @@ -131,6 +134,8 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj) return; } + LV_ASSERT_NULL(obj->spec_attr); + /*Be sure the object is removed from its current group*/ lv_group_remove_obj(obj); obj->spec_attr->group_p = group; @@ -151,8 +156,12 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj) void lv_group_swap_obj(lv_obj_t * obj1, lv_obj_t * obj2) { + LV_CHECK_ARG(obj1 != NULL, return); + LV_CHECK_ARG(obj2 != NULL, return); + lv_group_t * g1 = lv_obj_get_group(obj1); lv_group_t * g2 = lv_obj_get_group(obj2); + if(g1 != g2) return; if(g1 == NULL) return; @@ -163,10 +172,10 @@ void lv_group_swap_obj(lv_obj_t * obj1, lv_obj_t * obj2) else if((*obj_i) == obj2)(*obj_i) = obj1; } + // Swap the focus as well. lv_obj_t * focused = lv_group_get_focused(g1); if(focused == obj1) lv_group_focus_obj(obj2); else if(focused == obj2) lv_group_focus_obj(obj1); - } void lv_group_remove_obj(lv_obj_t * obj) @@ -176,7 +185,7 @@ void lv_group_remove_obj(lv_obj_t * obj) LV_LOG_TRACE("begin"); - /*Focus on the next object*/ + /* If we are removing the focused object */ if(g->obj_focus && *g->obj_focus == obj) { if(g->frozen) g->frozen = 0; @@ -212,7 +221,7 @@ void lv_group_remove_obj(lv_obj_t * obj) void lv_group_remove_all_objs(lv_group_t * group) { - LV_ASSERT_NULL(group); + LV_CHECK_ARG(group != NULL, return); /*Defocus the currently focused object*/ if(group->obj_focus != NULL) { @@ -232,11 +241,12 @@ void lv_group_remove_all_objs(lv_group_t * group) void lv_group_focus_obj(lv_obj_t * obj) { - if(obj == NULL) return; - lv_group_t * g = lv_obj_get_group(obj); - if(g == NULL) return; + LV_CHECK_ARG(obj != NULL, return); - if(g->frozen != 0) return; + lv_group_t * g = lv_obj_get_group(obj); + + if(g == NULL) return; + if(g->frozen) return; /*On defocus edit mode must be leaved*/ lv_group_set_editing(g, false); @@ -265,29 +275,29 @@ void lv_group_focus_obj(lv_obj_t * obj) void lv_group_focus_next(lv_group_t * group) { - LV_ASSERT_NULL(group); + LV_CHECK_ARG(group != NULL, return); bool focus_changed = focus_next_core(group, lv_ll_get_head, lv_ll_get_next); - if(group->edge_cb) { - if(!focus_changed) - group->edge_cb(group, true); + + if(!focus_changed && group->edge_cb) { + group->edge_cb(group, true); } } void lv_group_focus_prev(lv_group_t * group) { - LV_ASSERT_NULL(group); + LV_CHECK_ARG(group != NULL, return); bool focus_changed = focus_next_core(group, lv_ll_get_tail, lv_ll_get_prev); - if(group->edge_cb) { - if(!focus_changed) - group->edge_cb(group, false); + + if(!focus_changed && group->edge_cb) { + group->edge_cb(group, false); } } void lv_group_focus_freeze(lv_group_t * group, bool en) { - LV_ASSERT_NULL(group); + LV_CHECK_ARG(group != NULL, return); if(en == false) group->frozen = 0; else group->frozen = 1; @@ -295,7 +305,7 @@ void lv_group_focus_freeze(lv_group_t * group, bool en) lv_result_t lv_group_send_data(lv_group_t * group, uint32_t c) { - LV_ASSERT_NULL(group); + LV_CHECK_ARG(group != NULL, return LV_RESULT_INVALID); lv_obj_t * act = lv_group_get_focused(group); if(act == NULL) return LV_RESULT_OK; @@ -307,21 +317,21 @@ lv_result_t lv_group_send_data(lv_group_t * group, uint32_t c) void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb) { - if(group == NULL) return; + LV_CHECK_ARG(group != NULL, return); group->focus_cb = focus_cb; } void lv_group_set_edge_cb(lv_group_t * group, lv_group_edge_cb_t edge_cb) { - LV_ASSERT_NULL(group); + LV_CHECK_ARG(group != NULL, return); group->edge_cb = edge_cb; } void lv_group_set_editing(lv_group_t * group, bool edit) { - LV_ASSERT_NULL(group); + LV_CHECK_ARG(group != NULL, return); uint8_t en_val = edit ? 1 : 0; if(en_val == group->editing) return; /*Do not set the same mode again*/ @@ -339,19 +349,19 @@ void lv_group_set_editing(lv_group_t * group, bool edit) void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy) { - LV_ASSERT_NULL(group); + LV_CHECK_ARG(group != NULL, return); group->refocus_policy = policy & 0x01; } void lv_group_set_wrap(lv_group_t * group, bool en) { - LV_ASSERT_NULL(group); + LV_CHECK_ARG(group != NULL, return); group->wrap = en ? 1 : 0; } lv_obj_t * lv_group_get_focused(const lv_group_t * group) { - if(!group) return NULL; + LV_CHECK_ARG(group != NULL, return NULL); if(group->obj_focus == NULL) return NULL; return *group->obj_focus; @@ -359,36 +369,37 @@ lv_obj_t * lv_group_get_focused(const lv_group_t * group) lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group) { - if(!group) return NULL; + LV_CHECK_ARG(group != NULL, return NULL); return group->focus_cb; } lv_group_edge_cb_t lv_group_get_edge_cb(const lv_group_t * group) { - if(!group) return NULL; + LV_CHECK_ARG(group != NULL, return NULL); return group->edge_cb; } bool lv_group_get_editing(const lv_group_t * group) { - if(!group) return false; + LV_CHECK_ARG(group != NULL, return false); return group->editing; } bool lv_group_get_wrap(lv_group_t * group) { - if(!group) return false; + LV_CHECK_ARG(group != NULL, return false); return group->wrap; } uint32_t lv_group_get_obj_count(lv_group_t * group) { - LV_ASSERT_NULL(group); + LV_CHECK_ARG(group != NULL, return 0); return lv_ll_get_len(&group->obj_ll); } lv_obj_t * lv_group_get_obj_by_index(lv_group_t * group, uint32_t index) { + LV_CHECK_ARG(group != NULL, return NULL); uint32_t len = 0; lv_obj_t ** obj; @@ -424,10 +435,7 @@ lv_group_t * lv_group_by_index(uint32_t index) #if LV_USE_EXT_DATA void lv_group_set_external_data(lv_group_t * group, void * data, void (* free_cb)(void * data)) { - if(!group) { - LV_LOG_WARN("Can't attach external user data and destructor callback to a NULL group"); - return; - } + LV_CHECK_ARG(group != NULL, return); group->ext_data.data = data; group->ext_data.free_cb = free_cb; @@ -436,13 +444,13 @@ void lv_group_set_external_data(lv_group_t * group, void * data, void (* free_cb void lv_group_set_user_data(lv_group_t * group, void * user_data) { - if(group == NULL) return; + LV_CHECK_ARG(group != NULL, return); group->user_data = user_data; } void * lv_group_get_user_data(const lv_group_t * group) { - if(group == NULL) return NULL; + LV_CHECK_ARG(group != NULL, return NULL); return group->user_data; } @@ -467,8 +475,9 @@ static void lv_group_refocus(lv_group_t * g) static bool focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *), void * (*move)(const lv_ll_t *, const void *)) { + if(group->frozen) return false; + bool focus_changed = false; - if(group->frozen) return focus_changed; lv_obj_t ** obj_next = group->obj_focus; lv_obj_t ** obj_sentinel = NULL; diff --git a/src/core/lv_obj.c b/src/core/lv_obj.c index 091037ad73..6cf722a6df 100644 --- a/src/core/lv_obj.c +++ b/src/core/lv_obj.c @@ -7,6 +7,7 @@ * INCLUDES *********************/ #include "lv_obj_private.h" +#include "../lv_public_api.h" #include "../misc/lv_event_private.h" #include "../misc/lv_area_private.h" #include "lv_obj_style_private.h" @@ -223,10 +224,15 @@ const lv_obj_class_t lv_obj_class = { lv_obj_t * lv_obj_create(lv_obj_t * parent) { LV_LOG_INFO("begin"); + lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent); - LV_ASSERT_NULL(obj); + if(obj == NULL) return NULL; + lv_obj_class_init_obj(obj); + + LV_LOG_TRACE("finished"); + return obj; } @@ -241,6 +247,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent) void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f) { LV_ASSERT_OBJ(obj, MY_CLASS); + if(lv_obj_has_flag(obj, f)) /*Check if all flags are set*/ return; @@ -280,6 +287,7 @@ void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f) void lv_obj_remove_flag(lv_obj_t * obj, lv_obj_flag_t f) { LV_ASSERT_OBJ(obj, MY_CLASS); + if(!lv_obj_has_flag_any(obj, f)) return; @@ -402,6 +410,7 @@ lv_group_t * lv_obj_get_group(const lv_obj_t * obj) lv_result_t lv_obj_add_child(lv_obj_t * parent, lv_obj_t * child) { LV_ASSERT_OBJ(parent, MY_CLASS); + LV_CHECK_ARG(child != NULL, return LV_RESULT_INVALID); uint16_t new_child_cnt = parent->spec_attr->child_cnt + 1; @@ -421,6 +430,7 @@ void lv_obj_remove_child(lv_obj_t * parent, lv_obj_t * child) { LV_ASSERT_OBJ(parent, MY_CLASS); LV_ASSERT_OBJ(child, MY_CLASS); + for(int32_t i = lv_obj_get_index(child); i < (int32_t)parent->spec_attr->child_cnt - 1; i++) { parent->spec_attr->children[i] = parent->spec_attr->children[i + 1]; } @@ -443,6 +453,7 @@ void lv_obj_remove_child(lv_obj_t * parent, lv_obj_t * child) lv_obj_spec_attr_t * lv_obj_allocate_spec_attr(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, MY_CLASS); + if(obj->spec_attr) { return obj->spec_attr; } @@ -462,12 +473,14 @@ lv_obj_spec_attr_t * lv_obj_allocate_spec_attr(lv_obj_t * obj) bool lv_obj_check_type(const lv_obj_t * obj, const lv_obj_class_t * class_p) { - if(obj == NULL) return false; + LV_CHECK_ARG(obj != NULL, return false); return obj->class_p == class_p; } bool lv_obj_has_class(const lv_obj_t * obj, const lv_obj_class_t * class_p) { + LV_CHECK_ARG(obj != NULL, return false); + const lv_obj_class_t * obj_class = obj->class_p; while(obj_class) { if(obj_class == class_p) return true; @@ -479,11 +492,14 @@ bool lv_obj_has_class(const lv_obj_t * obj, const lv_obj_class_t * class_p) const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return NULL); return obj->class_p; } bool lv_obj_is_valid(const lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return false); + lv_display_t * disp = lv_display_get_next(NULL); while(disp) { uint32_t i; @@ -501,18 +517,23 @@ bool lv_obj_is_valid(const lv_obj_t * obj) void lv_obj_null_on_delete(lv_obj_t ** obj_ptr) { + LV_CHECK_ARG(obj_ptr != NULL, return); + LV_CHECK_ARG(*obj_ptr != NULL, return); + lv_obj_add_event_cb(*obj_ptr, null_on_delete_cb, LV_EVENT_DELETE, obj_ptr); } #if LV_USE_OBJ_ID void * lv_obj_get_id(const lv_obj_t * obj) { - LV_ASSERT_NULL(obj); + LV_CHECK_ARG(obj != NULL, return NULL); return obj->id; } lv_obj_t * lv_obj_find_by_id(const lv_obj_t * obj, const void * id) { + LV_CHECK_ARG(id != NULL, return NULL); + LV_LOG_WARN("DEPRECATED: IDs are used only to print the widget trees. To find a widget use obj_name"); if(obj == NULL) obj = lv_display_get_screen_active(NULL); @@ -520,15 +541,13 @@ lv_obj_t * lv_obj_find_by_id(const lv_obj_t * obj, const void * id) uint32_t i; uint32_t child_cnt = lv_obj_get_child_count(obj); - for(i = 0; i < child_cnt; i++) { - lv_obj_t * child = obj->spec_attr->children[i]; - if(lv_obj_id_compare(child->id, id) == 0) return child; - } - /*Search children*/ for(i = 0; i < child_cnt; i++) { lv_obj_t * child = obj->spec_attr->children[i]; + + if(lv_obj_id_compare(child->id, id) == 0) return child; lv_obj_t * found = lv_obj_find_by_id(child, id); + if(found != NULL) return found; } @@ -539,10 +558,8 @@ lv_obj_t * lv_obj_find_by_id(const lv_obj_t * obj, const void * id) void lv_obj_add_screen_load_event(lv_obj_t * obj, lv_event_code_t trigger, lv_obj_t * screen, lv_screen_load_anim_t anim_type, uint32_t duration, uint32_t delay) { - if(screen == NULL) { - LV_LOG_WARN("`screen` is NULL, can't load a non existing screens"); - return; - } + LV_CHECK_ARG(screen != NULL, return, "can't load a non-existing screen"); + LV_CHECK_ARG(duration > 0 || anim_type == LV_SCREEN_LOAD_ANIM_NONE, return); screen_load_anim_dsc_t * dsc = lv_malloc(sizeof(screen_load_anim_dsc_t)); LV_ASSERT_MALLOC(dsc); @@ -559,6 +576,8 @@ void lv_obj_add_screen_load_event(lv_obj_t * obj, lv_event_code_t trigger, lv_ob void lv_obj_add_screen_create_event(lv_obj_t * obj, lv_event_code_t trigger, lv_screen_create_cb_t screen_create_cb, lv_screen_load_anim_t anim_type, uint32_t duration, uint32_t delay) { + LV_CHECK_ARG(duration > 0 || anim_type == LV_SCREEN_LOAD_ANIM_NONE, return); + screen_load_anim_dsc_t * dsc = lv_malloc(sizeof(screen_load_anim_dsc_t)); LV_ASSERT_MALLOC(dsc); lv_memzero(dsc, sizeof(screen_load_anim_dsc_t)); @@ -574,6 +593,9 @@ void lv_obj_add_screen_create_event(lv_obj_t * obj, lv_event_code_t trigger, lv_ void lv_obj_add_play_timeline_event(lv_obj_t * obj, lv_event_code_t trigger, lv_anim_timeline_t * at, uint32_t delay, bool reverse) { + LV_CHECK_ARG(obj != NULL, return); + LV_CHECK_ARG(at != NULL, return); + timeline_play_dsc_t * dsc = lv_malloc(sizeof(timeline_play_dsc_t)); LV_ASSERT_MALLOC(dsc); lv_memzero(dsc, sizeof(timeline_play_dsc_t)); @@ -587,11 +609,14 @@ void lv_obj_add_play_timeline_event(lv_obj_t * obj, lv_event_code_t trigger, lv_ void lv_obj_set_user_data(lv_obj_t * obj, void * user_data) { + LV_CHECK_ARG(obj != NULL, return); obj->user_data = user_data; } void * lv_obj_get_user_data(lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return NULL); + return obj->user_data; } @@ -601,6 +626,8 @@ void * lv_obj_get_user_data(lv_obj_t * obj) static void lv_obj_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return); + LV_UNUSED(class_p); LV_TRACE_OBJ_CREATE("begin"); @@ -636,6 +663,8 @@ static void lv_obj_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj) static void lv_obj_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return); + LV_UNUSED(class_p); lv_event_mark_deleted(obj); diff --git a/src/core/lv_obj_class.c b/src/core/lv_obj_class.c index 49209c3a17..f61eede269 100644 --- a/src/core/lv_obj_class.c +++ b/src/core/lv_obj_class.c @@ -9,6 +9,7 @@ #include "lv_obj_class_private.h" #include "lv_obj_private.h" #include "../display/lv_display_private.h" +#include "../lv_public_api.h" /********************* * DEFINES @@ -43,9 +44,12 @@ static uint32_t get_instance_size(const lv_obj_class_t * class_p); lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * parent) { + LV_CHECK_ARG(class_p != NULL, return NULL); + LV_TRACE_OBJ_CREATE("Creating object with %p class on %p parent", (void *)class_p, (void *)parent); uint32_t s = get_instance_size(class_p); lv_obj_t * obj = lv_malloc_zeroed(s); + LV_ASSERT_MALLOC(obj); if(obj == NULL) return NULL; obj->class_p = class_p; obj->parent = parent; @@ -67,6 +71,7 @@ lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * pa lv_obj_t ** screens = lv_realloc(disp->screens, sizeof(lv_obj_t *) * (disp->screen_cnt + 1)); LV_ASSERT_MALLOC(screens); if(screens == NULL) { + LV_LOG_WARN("Failed to expand memory for screen array"); lv_free(obj); return NULL; } @@ -101,7 +106,7 @@ lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * pa void lv_obj_class_init_obj(lv_obj_t * obj) { - if(obj == NULL) return; + LV_CHECK_ARG(obj != NULL, return); lv_obj_mark_layout_as_dirty(obj); lv_obj_enable_style_refresh(false); @@ -133,6 +138,9 @@ void lv_obj_class_init_obj(lv_obj_t * obj) void lv_obj_destruct(lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return); + LV_CHECK_ARG(obj->class_p != NULL, return); + #if LV_USE_EXT_DATA if(obj->ext_data.free_cb) { obj->ext_data.free_cb(obj->ext_data.data); @@ -151,8 +159,10 @@ void lv_obj_destruct(lv_obj_t * obj) } } -bool lv_obj_is_editable(lv_obj_t * obj) +bool lv_obj_is_editable(const lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return false); + const lv_obj_class_t * class_p = obj->class_p; /*Find a base in which editable is set*/ @@ -163,8 +173,10 @@ bool lv_obj_is_editable(lv_obj_t * obj) return class_p->editable == LV_OBJ_CLASS_EDITABLE_TRUE; } -bool lv_obj_is_group_def(lv_obj_t * obj) +bool lv_obj_is_group_def(const lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return false); + const lv_obj_class_t * class_p = obj->class_p; /*Find a base in which group_def is set*/ @@ -178,10 +190,7 @@ bool lv_obj_is_group_def(lv_obj_t * obj) #if LV_USE_EXT_DATA void lv_obj_set_external_data(lv_obj_t * obj, void * data, void (* free_cb)(void * data)) { - if(!obj) { - LV_LOG_WARN("Can't attach external user data and destructor callback to a NULL object"); - return; - } + LV_CHECK_ARG(obj != NULL, return, "Can't attach external user data and destructor callback to a NULL object"); obj->ext_data.data = data; obj->ext_data.free_cb = free_cb; @@ -194,9 +203,13 @@ void lv_obj_set_external_data(lv_obj_t * obj, void * data, void (* free_cb)(void static void lv_obj_construct(const lv_obj_class_t * class_p, lv_obj_t * obj) { - if(LV_USE_OBJ_NAME) { - LV_ASSERT_NULL(class_p->name); - } + LV_ASSERT_NULL(class_p); + LV_ASSERT_NULL(obj); + LV_ASSERT_NULL(obj->class_p); + +#if LV_USE_OBJ_NAME + LV_ASSERT_NULL(class_p->name); +#endif #if LV_USE_EXT_DATA obj->ext_data.free_cb = NULL; @@ -222,10 +235,9 @@ static void lv_obj_construct(const lv_obj_class_t * class_p, lv_obj_t * obj) static uint32_t get_instance_size(const lv_obj_class_t * class_p) { /*Find a base in which instance size is set*/ - const lv_obj_class_t * base = class_p; - while(base && base->instance_size == 0) base = base->base_class; + while(class_p && class_p->instance_size == 0) class_p = class_p->base_class; - if(base == NULL) return 0; /*Never happens: set at least in `lv_obj` class*/ + LV_ASSERT(class_p != NULL); /*Never happens: set at least in `lv_obj` class*/ - return base->instance_size; + return class_p->instance_size; } diff --git a/src/core/lv_obj_draw.c b/src/core/lv_obj_draw.c index b40b585bba..62beb55315 100644 --- a/src/core/lv_obj_draw.c +++ b/src/core/lv_obj_draw.c @@ -8,6 +8,7 @@ *********************/ #include "lv_obj_draw_private.h" #include "lv_obj_private.h" +#include "../lv_public_api.h" /********************* * DEFINES @@ -44,6 +45,8 @@ static void drop_shadow_init(const lv_obj_t * obj, lv_part_t part, lv_draw_dsc_b void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_t * draw_dsc) { + LV_CHECK_ARG(draw_dsc != NULL, return); + LV_PROFILER_DRAW_BEGIN; draw_dsc->base.obj = obj; draw_dsc->base.part = part; @@ -166,6 +169,8 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_ void lv_obj_init_draw_label_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_label_dsc_t * draw_dsc) { + LV_CHECK_ARG(draw_dsc != NULL, return); + LV_PROFILER_DRAW_BEGIN; draw_dsc->base.obj = obj; draw_dsc->base.part = part; @@ -207,6 +212,8 @@ void lv_obj_init_draw_label_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_label_ds void lv_obj_init_draw_image_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_image_dsc_t * draw_dsc) { + LV_CHECK_ARG(draw_dsc != NULL, return); + LV_PROFILER_DRAW_BEGIN; draw_dsc->base.obj = obj; draw_dsc->base.part = part; @@ -249,6 +256,8 @@ void lv_obj_init_draw_image_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_image_ds void lv_obj_init_draw_line_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_line_dsc_t * draw_dsc) { + LV_CHECK_ARG(draw_dsc != NULL, return); + LV_PROFILER_DRAW_BEGIN; draw_dsc->base.obj = obj; draw_dsc->base.part = part; @@ -292,6 +301,8 @@ void lv_obj_init_draw_line_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_line_dsc_ void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_arc_dsc_t * draw_dsc) { + LV_CHECK_ARG(draw_dsc != NULL, return); + LV_PROFILER_DRAW_BEGIN; draw_dsc->base.obj = obj; draw_dsc->base.part = part; @@ -330,6 +341,8 @@ void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_arc_dsc_t void lv_obj_init_draw_blur_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_blur_dsc_t * draw_dsc) { + LV_CHECK_ARG(draw_dsc != NULL, return); + LV_PROFILER_DRAW_BEGIN; draw_dsc->base.obj = obj; draw_dsc->base.part = part; @@ -420,12 +433,15 @@ void lv_obj_refresh_ext_draw_size(lv_obj_t * obj) int32_t lv_obj_get_ext_draw_size(const lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return 0); + if(obj->spec_attr) return obj->spec_attr->ext_draw_size; else return 0; } lv_layer_type_t lv_obj_get_layer_type(const lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return LV_LAYER_TYPE_NONE); if(obj->spec_attr) return (lv_layer_type_t)obj->spec_attr->layer_type; else return LV_LAYER_TYPE_NONE; diff --git a/src/core/lv_obj_event.c b/src/core/lv_obj_event.c index a9edaf4921..2767549c1a 100644 --- a/src/core/lv_obj_event.c +++ b/src/core/lv_obj_event.c @@ -11,6 +11,7 @@ #include "lv_obj_class_private.h" #include "lv_obj_private.h" #include "../indev/lv_indev_private.h" +#include "../lv_public_api.h" /********************* * DEFINES @@ -27,6 +28,7 @@ static lv_result_t event_send_core(lv_event_t * e); static bool event_is_bubbled(lv_event_t * e); static bool event_is_trickled(lv_event_t * e); +static bool event_code_in_array(lv_event_code_t code, const lv_event_code_t * arr, uint32_t len); /********************** * STATIC VARIABLES @@ -47,7 +49,7 @@ static bool event_is_trickled(lv_event_t * e); lv_result_t lv_obj_send_event(lv_obj_t * obj, lv_event_code_t event_code, void * param) { - if(obj == NULL) return LV_RESULT_OK; + LV_CHECK_ARG(obj != NULL, return LV_RESULT_OK); LV_ASSERT_OBJ(obj, MY_CLASS); @@ -75,6 +77,9 @@ lv_result_t lv_obj_send_event(lv_obj_t * obj, lv_event_code_t event_code, void * lv_result_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e) { + LV_CHECK_ARG(e != NULL, return LV_RESULT_INVALID); + LV_CHECK_ARG(e->current_target != NULL, return LV_RESULT_INVALID); + const lv_obj_class_t * base; if(class_p == NULL) base = ((lv_obj_t *)e->current_target)->class_p; else base = class_p->base_class; @@ -100,7 +105,9 @@ lv_result_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e) lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data) { + LV_CHECK_ARG(event_cb != NULL, return NULL); LV_ASSERT_OBJ(obj, MY_CLASS); + if(!lv_obj_allocate_spec_attr(obj)) { return NULL; } @@ -110,36 +117,38 @@ lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_ uint32_t lv_obj_get_event_count(lv_obj_t * obj) { - LV_ASSERT_NULL(obj); + LV_CHECK_ARG(obj != NULL, return 0); if(obj->spec_attr == NULL) return 0; return lv_event_get_count(&obj->spec_attr->event_list); } lv_event_dsc_t * lv_obj_get_event_dsc(lv_obj_t * obj, uint32_t index) { - LV_ASSERT_NULL(obj); + LV_CHECK_ARG(obj != NULL, return NULL); if(obj->spec_attr == NULL) return NULL; return lv_event_get_dsc(&obj->spec_attr->event_list, index); } bool lv_obj_remove_event(lv_obj_t * obj, uint32_t index) { - LV_ASSERT_NULL(obj); + LV_CHECK_ARG(obj != NULL, return false); if(obj->spec_attr == NULL) return false; return lv_event_remove(&obj->spec_attr->event_list, index); } bool lv_obj_remove_event_dsc(lv_obj_t * obj, lv_event_dsc_t * dsc) { - LV_ASSERT_NULL(obj); - LV_ASSERT_NULL(dsc); + LV_CHECK_ARG(obj != NULL, return false); + LV_CHECK_ARG(dsc != NULL, return false); + if(obj->spec_attr == NULL) return false; return lv_event_remove_dsc(&obj->spec_attr->event_list, dsc); } uint32_t lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb) { - LV_ASSERT_NULL(obj); + LV_CHECK_ARG(obj != NULL, return 0); + LV_CHECK_ARG(event_cb != NULL, return 0); uint32_t event_cnt = lv_obj_get_event_count(obj); uint32_t removed_count = 0; @@ -160,7 +169,8 @@ uint32_t lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb) uint32_t lv_obj_remove_event_cb_with_user_data(lv_obj_t * obj, lv_event_cb_t event_cb, void * user_data) { - LV_ASSERT_NULL(obj); + LV_CHECK_ARG(obj != NULL, return 0); + LV_CHECK_ARG(event_cb != NULL, return 0); uint32_t event_cnt = lv_obj_get_event_count(obj); uint32_t removed_count = 0; @@ -191,174 +201,112 @@ lv_obj_t * lv_event_get_target_obj(lv_event_t * e) lv_indev_t * lv_event_get_indev(lv_event_t * e) { - - if(e->code == LV_EVENT_PRESSED || - e->code == LV_EVENT_PRESSING || - e->code == LV_EVENT_PRESS_LOST || - e->code == LV_EVENT_SHORT_CLICKED || - e->code == LV_EVENT_LONG_PRESSED || - e->code == LV_EVENT_LONG_PRESSED_REPEAT || - e->code == LV_EVENT_CLICKED || - e->code == LV_EVENT_RELEASED || - e->code == LV_EVENT_SCROLL_BEGIN || - e->code == LV_EVENT_SCROLL_END || - e->code == LV_EVENT_SCROLL || - e->code == LV_EVENT_GESTURE || - e->code == LV_EVENT_KEY || - e->code == LV_EVENT_FOCUSED || - e->code == LV_EVENT_DEFOCUSED || - e->code == LV_EVENT_LEAVE || - e->code == LV_EVENT_HOVER_OVER || - e->code == LV_EVENT_HOVER_LEAVE) { - return lv_event_get_param(e); - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - return NULL; - } + static const lv_event_code_t indev_codes[] = { + LV_EVENT_PRESSED, LV_EVENT_PRESSING, LV_EVENT_PRESS_LOST, + LV_EVENT_SHORT_CLICKED, LV_EVENT_LONG_PRESSED, LV_EVENT_LONG_PRESSED_REPEAT, + LV_EVENT_CLICKED, LV_EVENT_RELEASED, + LV_EVENT_SCROLL_BEGIN, LV_EVENT_SCROLL_END, LV_EVENT_SCROLL, + LV_EVENT_GESTURE, LV_EVENT_KEY, + LV_EVENT_FOCUSED, LV_EVENT_DEFOCUSED, LV_EVENT_LEAVE, + LV_EVENT_HOVER_OVER, LV_EVENT_HOVER_LEAVE, + }; + LV_CHECK_ARG(event_code_in_array(e->code, indev_codes, sizeof(indev_codes) / sizeof(indev_codes[0])), + return NULL, "invalid event code %" LV_PRId32, (int32_t)e->code); + return lv_event_get_param(e); } lv_layer_t * lv_event_get_layer(lv_event_t * e) { - if(e->code == LV_EVENT_DRAW_MAIN || - e->code == LV_EVENT_DRAW_MAIN_BEGIN || - e->code == LV_EVENT_DRAW_MAIN_END || - e->code == LV_EVENT_DRAW_POST || - e->code == LV_EVENT_DRAW_POST_BEGIN || - e->code == LV_EVENT_DRAW_POST_END) { - return lv_event_get_param(e); - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - return NULL; - } + static const lv_event_code_t draw_codes[] = { + LV_EVENT_DRAW_MAIN, LV_EVENT_DRAW_MAIN_BEGIN, LV_EVENT_DRAW_MAIN_END, + LV_EVENT_DRAW_POST, LV_EVENT_DRAW_POST_BEGIN, LV_EVENT_DRAW_POST_END, + }; + LV_CHECK_ARG(event_code_in_array(e->code, draw_codes, sizeof(draw_codes) / sizeof(draw_codes[0])), + return NULL, "invalid event code %" LV_PRId32, (int32_t)e->code); + return lv_event_get_param(e); } const lv_area_t * lv_event_get_old_size(lv_event_t * e) { - if(e->code == LV_EVENT_SIZE_CHANGED) { - return lv_event_get_param(e); - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - return NULL; - } + LV_CHECK_ARG(e->code == LV_EVENT_SIZE_CHANGED, return NULL, + "invalid event code %" LV_PRId32, (int32_t)e->code); + return lv_event_get_param(e); } uint32_t lv_event_get_key(lv_event_t * e) { - if(e->code == LV_EVENT_KEY) { - uint32_t * k = lv_event_get_param(e); - if(k) return *k; - else return 0; - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - return 0; - } + LV_CHECK_ARG(e->code == LV_EVENT_KEY, return 0, + "invalid event code %" LV_PRId32, (int32_t)e->code); + uint32_t * k = lv_event_get_param(e); + return k ? *k : 0; } int32_t lv_event_get_rotary_diff(lv_event_t * e) { - if(e->code == LV_EVENT_ROTARY) { - int32_t * r = lv_event_get_param(e); - if(r) return *r; - else return 0; - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - return 0; - } + LV_CHECK_ARG(e->code == LV_EVENT_ROTARY, return 0, + "invalid event code %" LV_PRId32, (int32_t)e->code); + int32_t * r = lv_event_get_param(e); + return r ? *r : 0; } lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e) { - if(e->code == LV_EVENT_SCROLL_BEGIN) { - return lv_event_get_param(e); - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - return NULL; - } + LV_CHECK_ARG(e->code == LV_EVENT_SCROLL_BEGIN, return NULL, + "invalid event code %" LV_PRId32, (int32_t)e->code); + return lv_event_get_param(e); } void lv_event_set_ext_draw_size(lv_event_t * e, int32_t size) { - if(e->code == LV_EVENT_REFR_EXT_DRAW_SIZE) { - int32_t * cur_size = lv_event_get_param(e); - *cur_size = LV_MAX(*cur_size, size); - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - } + LV_CHECK_ARG(e->code == LV_EVENT_REFR_EXT_DRAW_SIZE, return, + "invalid event code %" LV_PRId32, (int32_t)e->code); + int32_t * cur_size = lv_event_get_param(e); + *cur_size = LV_MAX(*cur_size, size); } lv_point_t * lv_event_get_self_size_info(lv_event_t * e) { - if(e->code == LV_EVENT_GET_SELF_SIZE) { - return lv_event_get_param(e); - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - return 0; - } + LV_CHECK_ARG(e->code == LV_EVENT_GET_SELF_SIZE, return NULL, + "invalid event code %" LV_PRId32, (int32_t)e->code); + return lv_event_get_param(e); } lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e) { - if(e->code == LV_EVENT_HIT_TEST) { - return lv_event_get_param(e); - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - return 0; - } + LV_CHECK_ARG(e->code == LV_EVENT_HIT_TEST, return NULL, + "invalid event code %" LV_PRId32, (int32_t)e->code); + return lv_event_get_param(e); } const lv_area_t * lv_event_get_cover_area(lv_event_t * e) { - if(e->code == LV_EVENT_COVER_CHECK) { - lv_cover_check_info_t * p = lv_event_get_param(e); - return p->area; - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - return NULL; - } + LV_CHECK_ARG(e->code == LV_EVENT_COVER_CHECK, return NULL, + "invalid event code %" LV_PRId32, (int32_t)e->code); + lv_cover_check_info_t * p = lv_event_get_param(e); + return p->area; } void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res) { - if(e->code == LV_EVENT_COVER_CHECK) { - lv_cover_check_info_t * p = lv_event_get_param(e); - if(res > p->res) p->res = res; /*Save only "stronger" results*/ - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - } + LV_CHECK_ARG(e->code == LV_EVENT_COVER_CHECK, return, + "invalid event code %" LV_PRId32, (int32_t)e->code); + lv_cover_check_info_t * p = lv_event_get_param(e); + if(res > p->res) p->res = res; /*Save only "stronger" results*/ } lv_draw_task_t * lv_event_get_draw_task(lv_event_t * e) { - if(e->code == LV_EVENT_DRAW_TASK_ADDED) { - return lv_event_get_param(e); - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - return NULL; - } + LV_CHECK_ARG(e->code == LV_EVENT_DRAW_TASK_ADDED, return NULL, + "invalid event code %" LV_PRId32, (int32_t)e->code); + return lv_event_get_param(e); } lv_state_t lv_event_get_prev_state(lv_event_t * e) { - if(e->code == LV_EVENT_STATE_CHANGED) { - lv_state_t * state = lv_event_get_param(e); - return state ? *state : 0; - } - else { - LV_LOG_WARN("Not interpreted with this event code"); - return 0; - } + LV_CHECK_ARG(e->code == LV_EVENT_STATE_CHANGED, return 0, + "invalid event code %" LV_PRId32, (int32_t)e->code); + lv_state_t * state = lv_event_get_param(e); + return state ? *state : 0; } /********************** @@ -490,3 +438,12 @@ static bool event_is_trickled(lv_event_t * e) return true; } } + +static bool event_code_in_array(lv_event_code_t code, const lv_event_code_t * arr, uint32_t len) +{ + uint32_t i; + for(i = 0; i < len; i++) { + if(code == arr[i]) return true; + } + return false; +} diff --git a/src/core/lv_obj_id_builtin.c b/src/core/lv_obj_id_builtin.c index 7732262d47..7d41e96f64 100644 --- a/src/core/lv_obj_id_builtin.c +++ b/src/core/lv_obj_id_builtin.c @@ -9,6 +9,7 @@ #include "lv_obj_class_private.h" #include "lv_obj_private.h" #include "lv_global.h" +#include "../lv_public_api.h" #include "../osal/lv_os_private.h" /********************* @@ -44,15 +45,15 @@ typedef struct _class_info_t { void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj) { - LV_ASSERT(obj && class_p); + LV_CHECK_ARG(obj != NULL, return); + LV_CHECK_ARG(class_p != NULL, return); uint32_t i; uint32_t id = 0; lv_global_t * global = LV_GLOBAL_DEFAULT(); class_info_t * info = NULL; - if(obj == NULL || class_p == NULL) return; - if(global == NULL) return; + LV_ASSERT_NULL(global); obj->id = NULL; @@ -80,20 +81,22 @@ void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj) void lv_obj_set_id(lv_obj_t * obj, void * id) { - LV_ASSERT_NULL(obj); + LV_CHECK_ARG(obj != NULL, return); if(obj->id) lv_obj_free_id(obj); obj->id = id; } void lv_obj_free_id(lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return); obj->id = NULL; } const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len) { - if(obj == NULL || obj->class_p == NULL) return NULL; - if(buf == NULL) return NULL; + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(obj->class_p != NULL, return NULL); + LV_CHECK_ARG(buf != NULL, return NULL); const char * name = obj->class_p->name; if(name == NULL) name = "nameless"; diff --git a/src/core/lv_obj_pos.c b/src/core/lv_obj_pos.c index e2168719af..2f4f382361 100644 --- a/src/core/lv_obj_pos.c +++ b/src/core/lv_obj_pos.c @@ -15,6 +15,7 @@ #include "../display/lv_display_private.h" #include "lv_refr_private.h" #include "../core/lv_global.h" +#include "../lv_public_api.h" /********************* * DEFINES @@ -127,6 +128,9 @@ static int32_t calc_dynamic_width(lv_obj_t * obj, lv_style_prop_t prop, int32_t int32_t lv_obj_calc_dynamic_width(lv_obj_t * obj, lv_style_prop_t prop) { + LV_CHECK_ARG(obj != NULL, return 0); + LV_CHECK_ARG(prop == LV_STYLE_WIDTH || prop == LV_STYLE_MIN_WIDTH || prop == LV_STYLE_MAX_WIDTH, return 0); + return calc_dynamic_width(obj, prop, NULL); } @@ -170,6 +174,9 @@ static int32_t calc_dynamic_height(lv_obj_t * obj, lv_style_prop_t prop, int32_t int32_t lv_obj_calc_dynamic_height(lv_obj_t * obj, lv_style_prop_t prop) { + LV_CHECK_ARG(obj != NULL, return 0); + LV_CHECK_ARG(prop == LV_STYLE_HEIGHT || prop == LV_STYLE_MIN_HEIGHT || prop == LV_STYLE_MAX_HEIGHT, return 0); + return calc_dynamic_height(obj, prop, NULL); } @@ -333,6 +340,8 @@ void lv_obj_set_height(lv_obj_t * obj, int32_t h) void lv_obj_set_content_width(lv_obj_t * obj, int32_t w) { + LV_ASSERT_OBJ(obj, MY_CLASS); + int32_t left = lv_obj_get_style_space_left(obj, LV_PART_MAIN); int32_t right = lv_obj_get_style_space_right(obj, LV_PART_MAIN); lv_obj_set_width(obj, w + left + right); @@ -340,6 +349,8 @@ void lv_obj_set_content_width(lv_obj_t * obj, int32_t w) void lv_obj_set_content_height(lv_obj_t * obj, int32_t h) { + LV_ASSERT_OBJ(obj, MY_CLASS); + int32_t top = lv_obj_get_style_space_top(obj, LV_PART_MAIN); int32_t bottom = lv_obj_get_style_space_bottom(obj, LV_PART_MAIN); lv_obj_set_height(obj, h + top + bottom); @@ -356,6 +367,8 @@ void lv_obj_set_layout(lv_obj_t * obj, uint32_t layout) bool lv_obj_is_layout_positioned(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(lv_obj_has_flag_any(obj, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_IGNORE_LAYOUT | LV_OBJ_FLAG_FLOATING)) return false; lv_obj_t * parent = lv_obj_get_parent(obj); @@ -368,6 +381,8 @@ bool lv_obj_is_layout_positioned(const lv_obj_t * obj) void lv_obj_mark_layout_as_dirty(lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + obj->layout_inv = 1; /*Mark the screen as dirty too to mark that there is something to do on this screen*/ @@ -381,6 +396,8 @@ void lv_obj_mark_layout_as_dirty(lv_obj_t * obj) void lv_obj_update_layout(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(update_layout_mutex) { LV_LOG_TRACE("Already running, returning"); return; @@ -410,6 +427,7 @@ void lv_obj_set_align(lv_obj_t * obj, lv_align_t align) void lv_obj_align(lv_obj_t * obj, lv_align_t align, int32_t x_ofs, int32_t y_ofs) { + LV_ASSERT_OBJ(obj, MY_CLASS); lv_obj_set_style_align(obj, align, 0); lv_obj_set_pos(obj, x_ofs, y_ofs); } @@ -566,6 +584,7 @@ void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, in void lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * coords) { + LV_CHECK_ARG(coords != NULL, return); LV_ASSERT_OBJ(obj, MY_CLASS); lv_area_copy(coords, &obj->coords); @@ -621,11 +640,15 @@ int32_t lv_obj_get_y2(const lv_obj_t * obj) int32_t lv_obj_get_x_aligned(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + return lv_obj_get_style_x(obj, LV_PART_MAIN); } int32_t lv_obj_get_y_aligned(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + return lv_obj_get_style_y(obj, LV_PART_MAIN); } @@ -677,6 +700,8 @@ void lv_obj_get_content_coords(const lv_obj_t * obj, lv_area_t * area) int32_t lv_obj_get_self_width(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_point_t p = {0, LV_COORD_MIN}; lv_obj_send_event((lv_obj_t *)obj, LV_EVENT_GET_SELF_SIZE, &p); return p.x; @@ -684,6 +709,8 @@ int32_t lv_obj_get_self_width(const lv_obj_t * obj) int32_t lv_obj_get_self_height(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_point_t p = {LV_COORD_MIN, 0}; lv_obj_send_event((lv_obj_t *)obj, LV_EVENT_GET_SELF_SIZE, &p); return p.y; @@ -787,6 +814,8 @@ bool lv_obj_is_height_max(lv_obj_t * obj) bool lv_obj_refresh_self_size(lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(!lv_obj_is_style_any_width_content(obj) && !lv_obj_is_style_any_height_content(obj)) return false; @@ -806,6 +835,8 @@ bool lv_obj_refresh_self_size(lv_obj_t * obj) void lv_obj_refr_pos(lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(lv_obj_is_layout_positioned(obj)) return; lv_obj_t * parent = lv_obj_get_parent(obj); @@ -915,6 +946,8 @@ void lv_obj_refr_pos(lv_obj_t * obj) void lv_obj_move_to(lv_obj_t * obj, int32_t x, int32_t y) { + LV_ASSERT_OBJ(obj, MY_CLASS); + /*Convert x and y to absolute coordinates*/ lv_obj_t * parent = obj->parent; @@ -984,6 +1017,8 @@ void lv_obj_move_to(lv_obj_t * obj, int32_t x, int32_t y) void lv_obj_move_children_by(lv_obj_t * obj, int32_t x_diff, int32_t y_diff, bool ignore_floating) { + LV_ASSERT_OBJ(obj, MY_CLASS); + uint32_t i; uint32_t child_cnt = lv_obj_get_child_count(obj); for(i = 0; i < child_cnt; i++) { @@ -1000,30 +1035,36 @@ void lv_obj_move_children_by(lv_obj_t * obj, int32_t x_diff, int32_t y_diff, boo void lv_obj_transform_point(const lv_obj_t * obj, lv_point_t * p, lv_obj_point_transform_flag_t flags) { + LV_ASSERT_OBJ(obj, MY_CLASS); + LV_CHECK_ARG(p != NULL, return); + lv_obj_transform_point_array(obj, p, 1, flags); } void lv_obj_transform_point_array(const lv_obj_t * obj, lv_point_t points[], size_t count, lv_obj_point_transform_flag_t flags) { - if(obj) { - lv_layer_type_t layer_type = lv_obj_get_layer_type(obj); - bool do_tranf = layer_type == LV_LAYER_TYPE_TRANSFORM; - bool recursive = flags & LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE; - bool inverse = flags & LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE; - if(inverse) { - if(recursive) lv_obj_transform_point_array(lv_obj_get_parent(obj), points, count, flags); - if(do_tranf) transform_point_array(obj, points, count, inverse); - } - else { - if(do_tranf) transform_point_array(obj, points, count, inverse); - if(recursive) lv_obj_transform_point_array(lv_obj_get_parent(obj), points, count, flags); - } + LV_CHECK_ARG(obj != NULL, return); + + lv_layer_type_t layer_type = lv_obj_get_layer_type(obj); + bool do_tranf = layer_type == LV_LAYER_TYPE_TRANSFORM; + bool recursive = flags & LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE; + bool inverse = flags & LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE; + if(inverse) { + if(recursive) lv_obj_transform_point_array(lv_obj_get_parent(obj), points, count, flags); + if(do_tranf) transform_point_array(obj, points, count, inverse); + } + else { + if(do_tranf) transform_point_array(obj, points, count, inverse); + if(recursive) lv_obj_transform_point_array(lv_obj_get_parent(obj), points, count, flags); } } void lv_obj_get_transformed_area(const lv_obj_t * obj, lv_area_t * area, lv_obj_point_transform_flag_t flags) { + LV_CHECK_ARG(area != NULL, return); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_point_t p[4] = { {area->x1, area->y1}, {area->x1, area->y2 + 1}, @@ -1089,6 +1130,7 @@ static lv_obj_tree_walk_res_t blur_walk_cb(lv_obj_t * obj, void * user_data) lv_result_t lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area) { + LV_CHECK_ARG(area != NULL, return LV_RESULT_INVALID); LV_ASSERT_OBJ(obj, MY_CLASS); lv_display_t * disp = lv_obj_get_display(obj); @@ -1124,6 +1166,9 @@ lv_result_t lv_obj_invalidate(const lv_obj_t * obj) bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area) { + LV_CHECK_ARG(area != NULL, return false); + LV_ASSERT_OBJ(obj, MY_CLASS); + if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return false; /*Invalidate the object only if it belongs to the current or previous or one of the layers'*/ @@ -1201,6 +1246,9 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, int32_t size) void lv_obj_get_click_area(const lv_obj_t * obj, lv_area_t * area) { + LV_CHECK_ARG(area != NULL, return); + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_area_copy(area, &obj->coords); if(obj->spec_attr) { lv_area_increase(area, obj->spec_attr->ext_click_pad, obj->spec_attr->ext_click_pad); @@ -1209,6 +1257,9 @@ void lv_obj_get_click_area(const lv_obj_t * obj, lv_area_t * area) bool lv_obj_hit_test(lv_obj_t * obj, const lv_point_t * point) { + LV_CHECK_ARG(point != NULL, return false); + LV_ASSERT_OBJ(obj, MY_CLASS); + if(!lv_obj_has_flag(obj, LV_OBJ_FLAG_CLICKABLE)) return false; lv_area_t a; diff --git a/src/core/lv_obj_property.c b/src/core/lv_obj_property.c index c4785ac976..4c0a5fc505 100644 --- a/src/core/lv_obj_property.c +++ b/src/core/lv_obj_property.c @@ -9,6 +9,7 @@ #include "lv_obj_private.h" #include "../misc/lv_utils.h" #include "lv_obj_class_private.h" +#include "../lv_public_api.h" #if LV_USE_OBJ_PROPERTY @@ -105,7 +106,8 @@ static int property_name_compare(const void * ref, const void * element); lv_result_t lv_obj_set_property(lv_obj_t * obj, const lv_property_t * value) { - LV_ASSERT(obj && value); + LV_CHECK_ARG(obj != NULL, return LV_RESULT_INVALID); + LV_CHECK_ARG(value != NULL, return LV_RESULT_INVALID); uint32_t index = LV_PROPERTY_ID_INDEX(value->id); if(value->id == LV_PROPERTY_ID_INVALID || index > LV_PROPERTY_ID_ANY) { @@ -123,6 +125,9 @@ lv_result_t lv_obj_set_property(lv_obj_t * obj, const lv_property_t * value) lv_result_t lv_obj_set_properties(lv_obj_t * obj, const lv_property_t * value, uint32_t count) { + LV_CHECK_ARG(obj != NULL, return LV_RESULT_INVALID); + LV_CHECK_ARG(value != NULL, return LV_RESULT_INVALID); + for(uint32_t i = 0; i < count; i++) { lv_result_t result = lv_obj_set_property(obj, &value[i]); if(result != LV_RESULT_OK) { @@ -135,6 +140,10 @@ lv_result_t lv_obj_set_properties(lv_obj_t * obj, const lv_property_t * value, u lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id) { + LV_CHECK_ARG(obj != NULL, return (lv_property_t) { + .id = LV_PROPERTY_ID_INVALID + }); + lv_result_t result; lv_property_t value = { 0 }; @@ -162,6 +171,10 @@ lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id) lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, lv_part_t part) { + LV_CHECK_ARG(obj != NULL, return (lv_property_t) { + .id = LV_PROPERTY_ID_INVALID + }); + lv_property_t value; uint32_t index = LV_PROPERTY_ID_INDEX(id); @@ -217,6 +230,8 @@ lv_prop_id_t lv_obj_class_property_get_id(const lv_obj_class_t * clz, const char lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name) { #if LV_USE_OBJ_PROPERTY_NAME + LV_CHECK_ARG(obj != NULL, return LV_PROPERTY_ID_INVALID); + const lv_obj_class_t * clz; lv_prop_id_t id; diff --git a/src/core/lv_obj_scroll.c b/src/core/lv_obj_scroll.c index 7b5e28cc8c..0a19a7bd17 100644 --- a/src/core/lv_obj_scroll.c +++ b/src/core/lv_obj_scroll.c @@ -10,6 +10,7 @@ #include "../misc/lv_anim_private.h" #include "lv_obj_private.h" #include "../indev/lv_indev_scroll.h" +#include "../lv_public_api.h" /********************* * DEFINES @@ -71,6 +72,8 @@ void lv_obj_set_scrollbar_mode(lv_obj_t * obj, lv_scrollbar_mode_t mode) void lv_obj_set_scroll_dir(lv_obj_t * obj, lv_dir_t dir) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(!lv_obj_allocate_spec_attr(obj)) { return; } @@ -82,6 +85,8 @@ void lv_obj_set_scroll_dir(lv_obj_t * obj, lv_dir_t dir) void lv_obj_set_scroll_snap_x(lv_obj_t * obj, lv_scroll_snap_t align) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(!lv_obj_allocate_spec_attr(obj)) { return; } @@ -90,6 +95,8 @@ void lv_obj_set_scroll_snap_x(lv_obj_t * obj, lv_scroll_snap_t align) void lv_obj_set_scroll_snap_y(lv_obj_t * obj, lv_scroll_snap_t align) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(!lv_obj_allocate_spec_attr(obj)) { return; } @@ -102,42 +109,56 @@ void lv_obj_set_scroll_snap_y(lv_obj_t * obj, lv_scroll_snap_t align) lv_scrollbar_mode_t lv_obj_get_scrollbar_mode(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(obj->spec_attr) return (lv_scrollbar_mode_t) obj->spec_attr->scrollbar_mode; else return LV_SCROLLBAR_MODE_AUTO; } lv_dir_t lv_obj_get_scroll_dir(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(obj->spec_attr) return (lv_dir_t) obj->spec_attr->scroll_dir; else return LV_DIR_ALL; } lv_scroll_snap_t lv_obj_get_scroll_snap_x(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(obj->spec_attr) return (lv_scroll_snap_t) obj->spec_attr->scroll_snap_x; else return LV_SCROLL_SNAP_NONE; } lv_scroll_snap_t lv_obj_get_scroll_snap_y(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(obj->spec_attr) return (lv_scroll_snap_t) obj->spec_attr->scroll_snap_y; else return LV_SCROLL_SNAP_NONE; } int32_t lv_obj_get_scroll_x(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(obj->spec_attr == NULL) return 0; return -obj->spec_attr->scroll.x; } int32_t lv_obj_get_scroll_y(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(obj->spec_attr == NULL) return 0; return -obj->spec_attr->scroll.y; } int32_t lv_obj_get_scroll_top(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(obj->spec_attr == NULL) return 0; return -obj->spec_attr->scroll.y; } @@ -252,6 +273,9 @@ int32_t lv_obj_get_scroll_right(const lv_obj_t * obj) void lv_obj_get_scroll_end(lv_obj_t * obj, lv_point_t * end) { + LV_ASSERT_OBJ(obj, MY_CLASS); + LV_CHECK_ARG(end != NULL, return); + lv_anim_t * a; a = lv_anim_get(obj, scroll_x_anim); end->x = a ? -a->end_value : lv_obj_get_scroll_x(obj); @@ -266,6 +290,8 @@ void lv_obj_get_scroll_end(lv_obj_t * obj, lv_point_t * end) void lv_obj_scroll_by_bounded(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t anim_en) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(dx == 0 && dy == 0) return; /*We need to know the final sizes for bound check*/ @@ -314,6 +340,8 @@ void lv_obj_scroll_by_bounded(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_en void lv_obj_scroll_by(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t anim_en) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(dx == 0 && dy == 0) return; if(anim_en) { lv_display_t * d = lv_obj_get_display(obj); @@ -371,12 +399,16 @@ void lv_obj_scroll_by(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t a void lv_obj_scroll_to(lv_obj_t * obj, int32_t x, int32_t y, lv_anim_enable_t anim_en) { + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_obj_scroll_to_x(obj, x, anim_en); lv_obj_scroll_to_y(obj, y, anim_en); } void lv_obj_scroll_to_x(lv_obj_t * obj, int32_t x, lv_anim_enable_t anim_en) { + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_anim_delete(obj, scroll_x_anim); int32_t scroll_x = lv_obj_get_scroll_x(obj); @@ -387,6 +419,8 @@ void lv_obj_scroll_to_x(lv_obj_t * obj, int32_t x, lv_anim_enable_t anim_en) void lv_obj_scroll_to_y(lv_obj_t * obj, int32_t y, lv_anim_enable_t anim_en) { + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_anim_delete(obj, scroll_y_anim); int32_t scroll_y = lv_obj_get_scroll_y(obj); @@ -397,6 +431,8 @@ void lv_obj_scroll_to_y(lv_obj_t * obj, int32_t y, lv_anim_enable_t anim_en) void lv_obj_scroll_to_view(lv_obj_t * obj, lv_anim_enable_t anim_en) { + LV_ASSERT_OBJ(obj, MY_CLASS); + /*Be sure the screens layout is correct*/ lv_obj_update_layout(obj); @@ -406,6 +442,8 @@ void lv_obj_scroll_to_view(lv_obj_t * obj, lv_anim_enable_t anim_en) void lv_obj_scroll_to_view_recursive(lv_obj_t * obj, lv_anim_enable_t anim_en) { + LV_ASSERT_OBJ(obj, MY_CLASS); + /*Be sure the screens layout is correct*/ lv_obj_update_layout(obj); @@ -421,6 +459,8 @@ void lv_obj_scroll_to_view_recursive(lv_obj_t * obj, lv_anim_enable_t anim_en) lv_result_t lv_obj_scroll_by_raw(lv_obj_t * obj, int32_t x, int32_t y) { + LV_ASSERT_OBJ(obj, MY_CLASS); + if(x == 0 && y == 0) return LV_RESULT_OK; if(!lv_obj_allocate_spec_attr(obj)) { @@ -439,6 +479,8 @@ lv_result_t lv_obj_scroll_by_raw(lv_obj_t * obj, int32_t x, int32_t y) bool lv_obj_is_scrolling(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_indev_t * indev = lv_indev_get_next(NULL); while(indev) { if(lv_indev_get_scroll_obj(indev) == obj) return true; @@ -455,12 +497,16 @@ bool lv_obj_is_scrolling(const lv_obj_t * obj) void lv_obj_stop_scroll_anim(const lv_obj_t * obj) { + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_anim_delete((lv_obj_t *)obj, scroll_y_anim); lv_anim_delete((lv_obj_t *)obj, scroll_x_anim); } void lv_obj_update_snap(lv_obj_t * obj, lv_anim_enable_t anim_en) { + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_obj_update_layout(obj); lv_point_t p; lv_indev_scroll_get_snap_dist(obj, &p); @@ -471,6 +517,10 @@ void lv_obj_update_snap(lv_obj_t * obj, lv_anim_enable_t anim_en) void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor_area, lv_area_t * ver_area) { + LV_ASSERT_OBJ(obj, MY_CLASS); + LV_CHECK_ARG(hor_area != NULL, return); + LV_CHECK_ARG(ver_area != NULL, return); + lv_area_set(hor_area, 0, 0, -1, -1); lv_area_set(ver_area, 0, 0, -1, -1); @@ -647,6 +697,8 @@ void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor_area, lv_area_t * void lv_obj_scrollbar_invalidate(lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return); + lv_area_t hor_area; lv_area_t ver_area; lv_obj_get_scrollbar_area(obj, &hor_area, &ver_area); @@ -659,6 +711,8 @@ void lv_obj_scrollbar_invalidate(lv_obj_t * obj) void lv_obj_readjust_scroll(lv_obj_t * obj, lv_anim_enable_t anim_en) { + LV_CHECK_ARG(obj != NULL, return); + /*Be sure the bottom side is not remains scrolled in*/ /*With snapping the content can't be scrolled in*/ if(lv_obj_get_scroll_snap_y(obj) == LV_SCROLL_SNAP_NONE) { diff --git a/src/core/lv_obj_style.c b/src/core/lv_obj_style.c index 5f58572007..f795481b51 100644 --- a/src/core/lv_obj_style.c +++ b/src/core/lv_obj_style.c @@ -13,6 +13,7 @@ #include "../display/lv_display_private.h" #include "../core/lv_global.h" #include "lv_observer_private.h" +#include "../lv_public_api.h" /********************* * DEFINES @@ -104,7 +105,9 @@ void lv_obj_style_deinit(void) void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector) { - LV_ASSERT(obj->style_cnt < 63); + LV_CHECK_ARG(obj != NULL, return); + LV_CHECK_ARG(obj->style_cnt < 63, return, + "obj->style_cnt is restricted to 6 bits, so we can't store more than 63 styles"); trans_delete(obj, selector, LV_STYLE_PROP_ANY, NULL); @@ -164,14 +167,14 @@ void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selecto bool lv_obj_replace_style(lv_obj_t * obj, const lv_style_t * old_style, const lv_style_t * new_style, lv_style_selector_t selector) { + LV_CHECK_ARG(obj != NULL, return false); + LV_CHECK_ARG(old_style != NULL, return false); + LV_CHECK_ARG(new_style != NULL, return false); + LV_CHECK_ARG(old_style != new_style, return false); + lv_state_t state = lv_obj_style_get_selector_state(selector); lv_part_t part = lv_obj_style_get_selector_part(selector); - /*All objects must exist*/ - if(!obj || !old_style || !new_style || (old_style == new_style)) { - return false; - } - /*Similar to lv_obj_add_style, delete transition*/ trans_delete(obj, selector, LV_STYLE_PROP_ANY, NULL); @@ -209,17 +212,23 @@ bool lv_obj_replace_style(lv_obj_t * obj, const lv_style_t * old_style, const lv void lv_obj_remove_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector) { + LV_CHECK_ARG(obj != NULL, return); + remove_style_core(obj, style, selector, false); } void lv_obj_remove_theme(lv_obj_t * obj, lv_style_selector_t selector) { + LV_CHECK_ARG(obj != NULL, return); + remove_style_core(obj, NULL, selector, true); } void lv_obj_remove_style_all(lv_obj_t * obj) { - lv_obj_remove_style(obj, NULL, LV_PART_ANY | LV_STATE_ANY); + LV_CHECK_ARG(obj != NULL, return); + + remove_style_core(obj, NULL, LV_PART_ANY | LV_STATE_ANY, false); } void lv_obj_report_style_change(lv_style_t * style) @@ -286,6 +295,9 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop) void lv_obj_style_set_disabled(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector, bool dis) { + LV_CHECK_ARG(obj != NULL, return); + LV_CHECK_ARG(style != NULL, return); + uint32_t i; for(i = 0; i < obj->style_cnt; i++) { if(obj->styles[i].style == style && obj->styles[i].selector == selector) { @@ -303,6 +315,9 @@ void lv_obj_style_set_disabled(lv_obj_t * obj, const lv_style_t * style, lv_styl bool lv_obj_style_get_disabled(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector) { + LV_CHECK_ARG(obj != NULL, return false); + LV_CHECK_ARG(style != NULL, return false); + uint32_t i; for(i = 0; i < obj->style_cnt; i++) { if(obj->styles[i].style == style && obj->styles[i].selector == selector) { @@ -322,7 +337,7 @@ void lv_obj_enable_style_refresh(bool en) lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop) { - LV_ASSERT_NULL(obj) + LV_CHECK_ARG(obj != NULL, return lv_style_prop_get_default(prop)); lv_style_selector_t selector = part | obj->state; lv_style_value_t value_act = { .ptr = NULL }; @@ -336,7 +351,7 @@ lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_ bool lv_obj_has_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop) { - LV_ASSERT_NULL(obj) + LV_CHECK_ARG(obj != NULL, return false); lv_style_value_t value_act = { .ptr = NULL }; lv_style_res_t found; @@ -350,6 +365,8 @@ bool lv_obj_has_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, l void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value, lv_style_selector_t selector) { + LV_CHECK_ARG(obj != NULL, return); + LV_PROFILER_STYLE_BEGIN; /*Stop running transitions with this property */ @@ -379,6 +396,9 @@ void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_ lv_style_res_t lv_obj_get_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value, lv_style_selector_t selector) { + LV_CHECK_ARG(obj != NULL, return LV_STYLE_RES_NOT_FOUND); + LV_CHECK_ARG(value != NULL, return LV_STYLE_RES_NOT_FOUND); + uint32_t i; for(i = 0; i < obj->style_cnt; i++) { if(obj->styles[i].is_local && @@ -418,6 +438,9 @@ bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_sty void lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t prev_state, lv_state_t new_state, const lv_obj_style_transition_dsc_t * tr_dsc) { + LV_CHECK_ARG(obj != NULL, return); + LV_CHECK_ARG(tr_dsc != NULL, return); + trans_t * tr; /*Get the previous and current values*/ @@ -473,7 +496,8 @@ void lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t p lv_style_value_t lv_obj_style_apply_color_filter(const lv_obj_t * obj, lv_part_t part, lv_style_value_t v) { #if LV_USE_COLOR_FILTER - if(obj == NULL) return v; + LV_CHECK_ARG(obj != NULL, return v); + const lv_color_filter_dsc_t * f = lv_obj_get_style_color_filter_dsc(obj, part); if(f && f->filter_cb) { lv_opa_t f_opa = lv_obj_get_style_color_filter_opa(obj, part); @@ -489,6 +513,8 @@ lv_style_value_t lv_obj_style_apply_color_filter(const lv_obj_t * obj, lv_part_t lv_style_state_cmp_t lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state1, lv_state_t state2) { + LV_CHECK_ARG(obj != NULL, return LV_STYLE_STATE_CMP_SAME); + lv_style_state_cmp_t res = LV_STYLE_STATE_CMP_SAME; /*Are there any new styles for the new state?*/ @@ -550,6 +576,8 @@ lv_style_state_cmp_t lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state void lv_obj_fade_in(lv_obj_t * obj, uint32_t time, uint32_t delay) { + LV_CHECK_ARG(obj != NULL, return); + lv_anim_t a; lv_anim_init(&a); lv_anim_set_var(&a, obj); @@ -563,6 +591,8 @@ void lv_obj_fade_in(lv_obj_t * obj, uint32_t time, uint32_t delay) void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay) { + LV_CHECK_ARG(obj != NULL, return); + lv_anim_t a; lv_anim_init(&a); lv_anim_set_var(&a, obj); @@ -575,6 +605,8 @@ void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay) lv_text_align_t lv_obj_calculate_style_text_align(const lv_obj_t * obj, lv_part_t part, const char * txt) { + LV_CHECK_ARG(obj != NULL, return LV_TEXT_ALIGN_AUTO); + lv_text_align_t align = lv_obj_get_style_text_align(obj, part); lv_base_dir_t base_dir = lv_obj_get_style_base_dir(obj, part); lv_bidi_calculate_align(&align, &base_dir, txt); @@ -583,6 +615,8 @@ lv_text_align_t lv_obj_calculate_style_text_align(const lv_obj_t * obj, lv_part_ lv_opa_t lv_obj_get_style_opa_recursive(const lv_obj_t * obj, lv_part_t part) { + LV_CHECK_ARG(obj != NULL, return LV_OPA_TRANSP); + LV_PROFILER_STYLE_BEGIN; lv_opa_t opa_obj = lv_obj_get_style_opa(obj, part); if(opa_obj <= LV_OPA_MIN) { @@ -631,6 +665,8 @@ lv_opa_t lv_obj_get_style_opa_recursive(const lv_obj_t * obj, lv_part_t part) void lv_obj_update_layer_type(lv_obj_t * obj) { + LV_CHECK_ARG(obj != NULL, return); + lv_layer_type_t layer_type = calculate_layer_type(obj); if(obj->spec_attr) obj->spec_attr->layer_type = layer_type; else if(layer_type != LV_LAYER_TYPE_NONE) { @@ -643,6 +679,10 @@ void lv_obj_update_layer_type(lv_obj_t * obj) lv_color32_t lv_obj_style_apply_recolor(const lv_obj_t * obj, lv_part_t part, lv_color32_t color) { + LV_CHECK_ARG(obj != NULL, return (lv_color32_t) { + 0 + }); + lv_opa_t opa = lv_obj_get_style_recolor_opa(obj, part); if(opa > LV_OPA_TRANSP) { lv_color_t recolor = lv_obj_get_style_recolor(obj, part); @@ -654,6 +694,10 @@ lv_color32_t lv_obj_style_apply_recolor(const lv_obj_t * obj, lv_part_t part, lv lv_color32_t lv_obj_get_style_recolor_recursive(const lv_obj_t * obj, lv_part_t part) { + LV_CHECK_ARG(obj != NULL, return (lv_color32_t) { + 0 + }); + lv_color32_t result; lv_color_t color = lv_obj_get_style_recolor(obj, part); @@ -681,8 +725,9 @@ lv_color32_t lv_obj_get_style_recolor_recursive(const lv_obj_t * obj, lv_part_t lv_observer_t * lv_obj_bind_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector, lv_subject_t * subject, int32_t ref_value) { - LV_ASSERT_NULL(subject); - LV_ASSERT_NULL(obj); + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(style != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); if(subject->type != LV_SUBJECT_TYPE_INT) { LV_LOG_WARN("Subject type must be `int` (was %d)", subject->type); @@ -710,8 +755,8 @@ lv_observer_t * lv_obj_bind_style(lv_obj_t * obj, const lv_style_t * style, lv_s lv_observer_t * lv_obj_bind_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_selector_t selector, lv_subject_t * subject) { - LV_ASSERT_NULL(subject); - LV_ASSERT_NULL(obj); + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); if(subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_COLOR && subject->type != LV_SUBJECT_TYPE_POINTER) { diff --git a/src/core/lv_obj_tree.c b/src/core/lv_obj_tree.c index 9016b29c4e..f2f87c5242 100644 --- a/src/core/lv_obj_tree.c +++ b/src/core/lv_obj_tree.c @@ -12,6 +12,7 @@ #include "../display/lv_display_private.h" #include "../misc/lv_anim_private.h" #include "../core/lv_global.h" +#include "../lv_public_api.h" /********************* * DEFINES @@ -52,11 +53,10 @@ static lv_obj_t * lv_obj_get_first_not_deleting_child(lv_obj_t * obj); void lv_obj_delete(lv_obj_t * obj) { - if(obj->is_deleting) - return; + if(!obj) return; + if(obj->is_deleting) return; LV_LOG_TRACE("begin (delete %p)", (void *)obj); - LV_ASSERT_OBJ(obj, MY_CLASS); lv_obj_invalidate(obj); lv_obj_t * par = lv_obj_get_parent(obj); @@ -120,6 +120,8 @@ void lv_obj_clean(lv_obj_t * obj) void lv_obj_delete_delayed(lv_obj_t * obj, uint32_t delay_ms) { + LV_ASSERT_OBJ(obj, MY_CLASS); + lv_anim_t a; lv_anim_init(&a); lv_anim_set_var(&a, obj); @@ -132,6 +134,8 @@ void lv_obj_delete_delayed(lv_obj_t * obj, uint32_t delay_ms) void lv_obj_delete_anim_completed_cb(lv_anim_t * a) { + LV_CHECK_ARG(a != NULL, return); + lv_obj_delete(a->var); } @@ -339,6 +343,7 @@ lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, int32_t idx) lv_obj_t * lv_obj_get_child_by_type(const lv_obj_t * obj, int32_t idx, const lv_obj_class_t * class_p) { LV_ASSERT_OBJ(obj, MY_CLASS); + LV_CHECK_ARG(class_p != NULL, return NULL); if(obj->spec_attr == NULL) return NULL; @@ -366,6 +371,9 @@ lv_obj_t * lv_obj_get_child_by_type(const lv_obj_t * obj, int32_t idx, const lv_ lv_obj_t * lv_obj_get_sibling(const lv_obj_t * obj, int32_t idx) { + LV_ASSERT_OBJ(obj, MY_CLASS); + LV_CHECK_ARG(obj->parent != NULL, return NULL); + lv_obj_t * parent = lv_obj_get_parent(obj); int32_t sibling_idx = (int32_t)lv_obj_get_index(obj) + idx; if(sibling_idx < 0) return NULL; @@ -376,6 +384,8 @@ lv_obj_t * lv_obj_get_sibling(const lv_obj_t * obj, int32_t idx) lv_obj_t * lv_obj_get_sibling_by_type(const lv_obj_t * obj, int32_t idx, const lv_obj_class_t * class_p) { LV_ASSERT_OBJ(obj, MY_CLASS); + LV_CHECK_ARG(obj->parent != NULL, return NULL); + LV_CHECK_ARG(class_p != NULL, return NULL); lv_obj_t * parent = lv_obj_get_parent(obj); int32_t sibling_idx = (int32_t)lv_obj_get_index_by_type(obj, class_p) + idx; @@ -394,6 +404,8 @@ uint32_t lv_obj_get_child_count(const lv_obj_t * obj) uint32_t lv_obj_get_child_count_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p) { LV_ASSERT_OBJ(obj, MY_CLASS); + LV_CHECK_ARG(class_p != NULL, return 0); + if(obj->spec_attr == NULL) return 0; uint32_t i; @@ -429,6 +441,7 @@ void lv_obj_set_name(lv_obj_t * obj, const char * name) void lv_obj_set_name_static(lv_obj_t * obj, const char * name) { LV_ASSERT_OBJ(obj, MY_CLASS); + LV_CHECK_ARG(name != NULL, return); if(!lv_obj_allocate_spec_attr(obj)) { return; @@ -450,6 +463,7 @@ const char * lv_obj_get_name(const lv_obj_t * obj) void lv_obj_get_name_resolved(const lv_obj_t * obj, char buf[], size_t buf_size) { LV_ASSERT_OBJ(obj, MY_CLASS); + LV_CHECK_ARG(buf != NULL && buf_size > 0, return); const char * name = lv_obj_get_name(obj); /*Use a default name which auto-indexing*/ @@ -516,8 +530,8 @@ void lv_obj_get_name_resolved(const lv_obj_t * obj, char buf[], size_t buf_size) lv_obj_t * lv_obj_get_child_by_name(const lv_obj_t * parent, const char * path) { LV_ASSERT_OBJ(parent, MY_CLASS); - - if(parent == NULL || parent->spec_attr == NULL || path == NULL) return NULL; + LV_CHECK_ARG(path != NULL, return NULL); + LV_CHECK_ARG(parent->spec_attr != NULL, return NULL); while(*path) { const char * segment = path; @@ -547,6 +561,8 @@ lv_obj_t * lv_obj_get_child_by_name(const lv_obj_t * parent, const char * path) lv_obj_t * lv_obj_find_by_name(const lv_obj_t * parent, const char * name) { + LV_CHECK_ARG(name != NULL, return NULL); + if(parent == NULL) parent = lv_display_get_screen_active(NULL); if(parent == NULL) return NULL; @@ -587,6 +603,7 @@ int32_t lv_obj_get_index(const lv_obj_t * obj) int32_t lv_obj_get_index_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p) { LV_ASSERT_OBJ(obj, MY_CLASS); + LV_CHECK_ARG(class_p != NULL, return 0); lv_obj_t * parent = lv_obj_get_parent(obj); if(parent == NULL) return 0xFFFFFFFF; diff --git a/src/core/lv_observer.c b/src/core/lv_observer.c index 5c13ef17c7..6f08cf1258 100644 --- a/src/core/lv_observer.c +++ b/src/core/lv_observer.c @@ -13,7 +13,6 @@ #include "../lv_public_api.h" #include "../core/lv_obj_private.h" #include "../misc/lv_event_private.h" - /********************* * DEFINES *********************/ @@ -94,10 +93,7 @@ static void subject_set_string_free_user_data_event_cb(lv_event_t * e); #if LV_USE_EXT_DATA void lv_subject_set_external_data(lv_subject_t * subject, void * data, void (* free_cb)(void * data)) { - if(!subject) { - LV_LOG_WARN("Can't attach external user data and destructor callback to a NULL subject"); - return; - } + LV_CHECK_ARG(subject != NULL, return, "Can't attach external user data and destructor callback to a NULL subject"); subject->ext_data.data = data; subject->ext_data.free_cb = free_cb; @@ -106,6 +102,8 @@ void lv_subject_set_external_data(lv_subject_t * subject, void * data, void (* f void lv_subject_init_int(lv_subject_t * subject, int32_t value) { + LV_CHECK_ARG(subject != NULL, return); + lv_memzero(subject, sizeof(lv_subject_t)); subject->type = LV_SUBJECT_TYPE_INT; subject->value.num = value; @@ -117,10 +115,8 @@ void lv_subject_init_int(lv_subject_t * subject, int32_t value) void lv_subject_set_int(lv_subject_t * subject, int32_t value) { - if(subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT"); - return; - } + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_INT, return); value = LV_CLAMP(subject->min_value.num, value, subject->max_value.num); @@ -131,40 +127,32 @@ void lv_subject_set_int(lv_subject_t * subject, int32_t value) int32_t lv_subject_get_int(lv_subject_t * subject) { - if(subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT"); - return 0; - } + LV_CHECK_ARG(subject != NULL, return 0); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_INT, return 0); return subject->value.num; } int32_t lv_subject_get_previous_int(lv_subject_t * subject) { - if(subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT"); - return 0; - } + LV_CHECK_ARG(subject != NULL, return 0); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_INT, return 0); return subject->prev_value.num; } void lv_subject_set_min_value_int(lv_subject_t * subject, int32_t min_value) { - if(subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT"); - return; - } + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_INT, return); subject->min_value.num = min_value; } void lv_subject_set_max_value_int(lv_subject_t * subject, int32_t max_value) { - if(subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_INT"); - return; - } + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_INT, return); subject->max_value.num = max_value; } @@ -173,6 +161,8 @@ void lv_subject_set_max_value_int(lv_subject_t * subject, int32_t max_value) void lv_subject_init_float(lv_subject_t * subject, float value) { + LV_CHECK_ARG(subject != NULL, return); + lv_memzero(subject, sizeof(lv_subject_t)); subject->type = LV_SUBJECT_TYPE_FLOAT; subject->value.float_v = value; @@ -184,10 +174,8 @@ void lv_subject_init_float(lv_subject_t * subject, float value) void lv_subject_set_float(lv_subject_t * subject, float value) { - if(subject->type != LV_SUBJECT_TYPE_FLOAT) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_FLOAT"); - return; - } + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_FLOAT, return); value = LV_CLAMP(subject->min_value.float_v, value, subject->max_value.float_v); @@ -198,40 +186,32 @@ void lv_subject_set_float(lv_subject_t * subject, float value) float lv_subject_get_float(lv_subject_t * subject) { - if(subject->type != LV_SUBJECT_TYPE_FLOAT) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_FLOAT"); - return 0; - } + LV_CHECK_ARG(subject != NULL, return 0.0); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_FLOAT, return 0.0); return subject->value.float_v; } float lv_subject_get_previous_float(lv_subject_t * subject) { - if(subject->type != LV_SUBJECT_TYPE_FLOAT) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_FLOAT"); - return 0; - } + LV_CHECK_ARG(subject != NULL, return 0.0); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_FLOAT, return 0.0); return subject->prev_value.float_v; } void lv_subject_set_min_value_float(lv_subject_t * subject, float min_value) { - if(subject->type != LV_SUBJECT_TYPE_FLOAT) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_FLOAT"); - return; - } + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_FLOAT, return); subject->min_value.float_v = min_value; } void lv_subject_set_max_value_float(lv_subject_t * subject, float max_value) { - if(subject->type != LV_SUBJECT_TYPE_FLOAT) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_FLOAT"); - return; - } + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_FLOAT, return); subject->max_value.float_v = max_value; } @@ -241,6 +221,8 @@ void lv_subject_set_max_value_float(lv_subject_t * subject, float max_value) void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, size_t size, const char * value) { + LV_CHECK_ARG(subject != NULL, return); + lv_memzero(subject, sizeof(lv_subject_t)); lv_strlcpy(buf, value, size); if(prev_buf) lv_strlcpy(prev_buf, value, size); @@ -255,12 +237,10 @@ void lv_subject_init_string(lv_subject_t * subject, char * buf, char * prev_buf, void lv_subject_copy_string(lv_subject_t * subject, const char * buf) { - if(subject->type != LV_SUBJECT_TYPE_STRING) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_STRING"); - return; - } + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_STRING, return); - if(subject->size < 1) return; + if(subject->size == 0) return; if(subject->prev_value.pointer) { lv_strlcpy((char *)subject->prev_value.pointer, subject->value.pointer, subject->size); } @@ -272,10 +252,8 @@ void lv_subject_copy_string(lv_subject_t * subject, const char * buf) void lv_subject_snprintf(lv_subject_t * subject, const char * format, ...) { - if(subject->type != LV_SUBJECT_TYPE_STRING) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_STRING"); - return; - } + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_STRING, return); if(subject->size < 1U) return; @@ -294,26 +272,24 @@ void lv_subject_snprintf(lv_subject_t * subject, const char * format, ...) const char * lv_subject_get_string(lv_subject_t * subject) { - if(subject->type != LV_SUBJECT_TYPE_STRING) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_STRING"); - return ""; - } + LV_CHECK_ARG(subject != NULL, return NULL); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_STRING, return NULL); return subject->value.pointer; } const char * lv_subject_get_previous_string(lv_subject_t * subject) { - if(subject->type != LV_SUBJECT_TYPE_STRING) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_STRING"); - return NULL; - } + LV_CHECK_ARG(subject != NULL, return NULL); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_STRING, return NULL); return subject->prev_value.pointer; } void lv_subject_init_pointer(lv_subject_t * subject, void * value) { + LV_CHECK_ARG(subject != NULL, return); + lv_memzero(subject, sizeof(lv_subject_t)); subject->type = LV_SUBJECT_TYPE_POINTER; subject->value.pointer = value; @@ -323,10 +299,8 @@ void lv_subject_init_pointer(lv_subject_t * subject, void * value) void lv_subject_set_pointer(lv_subject_t * subject, void * ptr) { - if(subject->type != LV_SUBJECT_TYPE_POINTER) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_POINTER"); - return; - } + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_POINTER, return); subject->prev_value.pointer = subject->value.pointer; subject->value.pointer = ptr; @@ -335,26 +309,25 @@ void lv_subject_set_pointer(lv_subject_t * subject, void * ptr) const void * lv_subject_get_pointer(lv_subject_t * subject) { - if(subject->type != LV_SUBJECT_TYPE_POINTER) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_POINTER"); - return NULL; - } + LV_CHECK_ARG(subject != NULL, return NULL); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_POINTER, return NULL); + return subject->value.pointer; } const void * lv_subject_get_previous_pointer(lv_subject_t * subject) { - if(subject->type != LV_SUBJECT_TYPE_POINTER) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_POINTER"); - return NULL; - } + LV_CHECK_ARG(subject != NULL, return NULL); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_POINTER, return NULL); return subject->prev_value.pointer; } void lv_subject_init_color(lv_subject_t * subject, lv_color_t color) { + LV_CHECK_ARG(subject != NULL, return); + lv_memzero(subject, sizeof(lv_subject_t)); subject->type = LV_SUBJECT_TYPE_COLOR; subject->value.color = color; @@ -364,10 +337,8 @@ void lv_subject_init_color(lv_subject_t * subject, lv_color_t color) void lv_subject_set_color(lv_subject_t * subject, lv_color_t color) { - if(subject->type != LV_SUBJECT_TYPE_COLOR) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_COLOR"); - return; - } + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_COLOR, return); subject->prev_value.color = subject->value.color; subject->value.color = color; @@ -376,26 +347,25 @@ void lv_subject_set_color(lv_subject_t * subject, lv_color_t color) lv_color_t lv_subject_get_color(lv_subject_t * subject) { - if(subject->type != LV_SUBJECT_TYPE_COLOR) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_COLOR"); - return lv_color_black(); - } + LV_CHECK_ARG(subject != NULL, return lv_color_black()); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_COLOR, return lv_color_black()); return subject->value.color; } lv_color_t lv_subject_get_previous_color(lv_subject_t * subject) { - if(subject->type != LV_SUBJECT_TYPE_COLOR) { - LV_LOG_WARN("Subject type is not LV_SUBJECT_TYPE_COLOR"); - return lv_color_black(); - } + LV_CHECK_ARG(subject != NULL, return lv_color_black()); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_COLOR, return lv_color_black()); return subject->prev_value.color; } void lv_subject_init_group(lv_subject_t * group_subject, lv_subject_t * list[], uint32_t list_len) { + LV_CHECK_ARG(group_subject != NULL, return); + LV_CHECK_ARG(list != NULL, return); + group_subject->type = LV_SUBJECT_TYPE_GROUP; group_subject->size = list_len; lv_ll_init(&(group_subject->subs_ll), sizeof(lv_observer_t)); @@ -409,19 +379,6 @@ void lv_subject_init_group(lv_subject_t * group_subject, lv_subject_t * list[], } } -void lv_subject_deinit(lv_subject_t * subject) -{ - lv_observer_t * observer = lv_ll_get_head(&subject->subs_ll); - while(observer) { - lv_observer_t * observer_next = lv_ll_get_next(&subject->subs_ll, observer); - - lv_observer_remove(observer); - observer = observer_next; - } - - lv_ll_clear(&subject->subs_ll); -} - lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t index) { if(subject->type != LV_SUBJECT_TYPE_GROUP) { @@ -435,8 +392,26 @@ lv_subject_t * lv_subject_get_group_element(lv_subject_t * subject, int32_t inde return ((lv_subject_t **)(subject->value.pointer))[index]; } +void lv_subject_deinit(lv_subject_t * subject) +{ + if(!subject) return; + + lv_observer_t * observer = lv_ll_get_head(&subject->subs_ll); + while(observer) { + lv_observer_t * observer_next = lv_ll_get_next(&subject->subs_ll, observer); + + lv_observer_remove(observer); + observer = observer_next; + } + + lv_ll_clear(&subject->subs_ll); +} + lv_observer_t * lv_subject_add_observer(lv_subject_t * subject, lv_observer_cb_t cb, void * user_data) { + LV_CHECK_ARG(subject != NULL, return NULL); + LV_CHECK_ARG(cb != NULL, return NULL); + lv_observer_t * observer = lv_subject_add_observer_obj(subject, cb, NULL, user_data); if(observer == NULL) return NULL; @@ -447,11 +422,10 @@ lv_observer_t * lv_subject_add_observer(lv_subject_t * subject, lv_observer_cb_t lv_observer_t * lv_subject_add_observer_obj(lv_subject_t * subject, lv_observer_cb_t cb, lv_obj_t * obj, void * user_data) { - LV_ASSERT_NULL(subject); - if(subject->type == LV_SUBJECT_TYPE_INVALID) { - LV_LOG_WARN("Subject not initialized yet"); - return NULL; - } + LV_CHECK_ARG(subject != NULL, return NULL); + LV_CHECK_ARG(cb != NULL, return NULL); + LV_CHECK_ARG(subject->type != LV_SUBJECT_TYPE_INVALID, return NULL); + lv_observer_t * observer = lv_ll_ins_tail(&(subject->subs_ll)); LV_ASSERT_MALLOC(observer); if(observer == NULL) return NULL; @@ -477,11 +451,10 @@ lv_observer_t * lv_subject_add_observer_obj(lv_subject_t * subject, lv_observer_ lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_observer_cb_t cb, void * target, void * user_data) { - LV_ASSERT_NULL(subject); - if(subject->type == LV_SUBJECT_TYPE_INVALID) { - LV_LOG_WARN("Subject not initialized yet"); - return NULL; - } + LV_CHECK_ARG(subject != NULL, return NULL); + LV_CHECK_ARG(cb != NULL, return NULL); + LV_CHECK_ARG(subject->type != LV_SUBJECT_TYPE_INVALID, return NULL); + lv_observer_t * observer = lv_ll_ins_tail(&(subject->subs_ll)); LV_ASSERT_MALLOC(observer); if(observer == NULL) return NULL; @@ -502,7 +475,7 @@ lv_observer_t * lv_subject_add_observer_with_target(lv_subject_t * subject, lv_o void lv_observer_remove(lv_observer_t * observer) { - LV_ASSERT_NULL(observer); + LV_CHECK_ARG(observer != NULL, return); if(observer->for_obj && observer->target) { lv_obj_remove_event_cb_with_user_data(observer->target, unsubscribe_on_delete_cb, observer); @@ -528,7 +501,8 @@ void lv_observer_remove(lv_observer_t * observer) void lv_obj_remove_from_subject(lv_obj_t * obj, lv_subject_t * subject) { - LV_ASSERT_NULL(obj); + LV_CHECK_ARG(obj != NULL, return); + LV_CHECK_ARG(subject != NULL, return); /* * Look for the `observer` that connects `obj` and `subject` * Since the obj is associated with the subject, @@ -557,14 +531,14 @@ void lv_obj_remove_from_subject(lv_obj_t * obj, lv_subject_t * subject) void * lv_observer_get_target(lv_observer_t * observer) { - LV_ASSERT_NULL(observer); + LV_CHECK_ARG(observer != NULL, return NULL); return observer->target; } void lv_subject_notify(lv_subject_t * subject) { - LV_ASSERT_NULL(subject); + LV_CHECK_ARG(subject != NULL, return); lv_observer_t * observer; LV_LL_READ(&(subject->subs_ll), observer) { @@ -586,10 +560,9 @@ void lv_subject_notify(lv_subject_t * subject) lv_subject_increment_dsc_t * lv_obj_add_subject_increment_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, int32_t step) { - if(subject->type != LV_SUBJECT_TYPE_INT && subject->type != LV_SUBJECT_TYPE_FLOAT) { - LV_LOG_WARN("Subject type must be `int` or `float` (was %d)", subject->type); - return NULL; - } + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_INT || subject->type == LV_SUBJECT_TYPE_FLOAT, return NULL); lv_subject_increment_dsc_t * user_data = lv_malloc(sizeof(lv_subject_increment_dsc_t)); if(user_data == NULL) { @@ -612,11 +585,7 @@ lv_subject_increment_dsc_t * lv_obj_add_subject_increment_event(lv_obj_t * obj, void lv_obj_set_subject_increment_event_min_value(lv_obj_t * obj, lv_subject_increment_dsc_t * dsc, int32_t min_value) { LV_UNUSED(obj); - LV_ASSERT_NULL(dsc); - if(dsc == NULL) { - LV_LOG_WARN("Invalid parameters"); - return; - } + LV_CHECK_ARG(dsc != NULL, return); dsc->min_value = min_value; if(dsc->subject->type == LV_SUBJECT_TYPE_INT) { @@ -636,12 +605,7 @@ void lv_obj_set_subject_increment_event_min_value(lv_obj_t * obj, lv_subject_inc void lv_obj_set_subject_increment_event_max_value(lv_obj_t * obj, lv_subject_increment_dsc_t * dsc, int32_t max_value) { LV_UNUSED(obj); - LV_ASSERT_NULL(dsc); - if(dsc == NULL) { - LV_LOG_WARN("Invalid parameters"); - return; - } - + LV_CHECK_ARG(dsc != NULL, return); dsc->max_value = max_value; if(dsc->subject->type == LV_SUBJECT_TYPE_INT) { @@ -661,30 +625,25 @@ void lv_obj_set_subject_increment_event_max_value(lv_obj_t * obj, lv_subject_inc void lv_obj_set_subject_increment_event_rollover(lv_obj_t * obj, lv_subject_increment_dsc_t * dsc, bool rollover) { LV_UNUSED(obj); - LV_ASSERT_NULL(dsc); - if(dsc == NULL) { - LV_LOG_WARN("Invalid parameters"); - return; - } + LV_CHECK_ARG(dsc != NULL, return); dsc->rollover = rollover; } void lv_obj_add_subject_toggle_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger) { - if(subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Subject type must be `int` (was %d)", subject->type); - return; - } + LV_CHECK_ARG(obj != NULL, return); + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_INT, return); + lv_obj_add_event_cb(obj, subject_toggle_cb, trigger, subject); } void lv_obj_add_subject_set_int_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, int32_t value) { - if(subject->type != LV_SUBJECT_TYPE_INT) { - LV_LOG_WARN("Subject type must be `int` (was %d)", subject->type); - return; - } + LV_CHECK_ARG(obj != NULL, return); + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_INT, return); subject_set_int_user_data_t * user_data = lv_malloc(sizeof(subject_set_int_user_data_t)); if(user_data == NULL) { @@ -703,10 +662,9 @@ void lv_obj_add_subject_set_int_event(lv_obj_t * obj, lv_subject_t * subject, lv #if LV_USE_FLOAT void lv_obj_add_subject_set_float_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, float value) { - if(subject->type != LV_SUBJECT_TYPE_FLOAT) { - LV_LOG_WARN("Subject type must be `float` (was %d)", subject->type); - return; - } + LV_CHECK_ARG(obj != NULL, return); + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_FLOAT, return); subject_set_float_user_data_t * user_data = lv_malloc(sizeof(subject_set_float_user_data_t)); if(user_data == NULL) { @@ -726,11 +684,9 @@ void lv_obj_add_subject_set_float_event(lv_obj_t * obj, lv_subject_t * subject, void lv_obj_add_subject_set_string_event(lv_obj_t * obj, lv_subject_t * subject, lv_event_code_t trigger, const char * value) { - - if(subject->type != LV_SUBJECT_TYPE_STRING) { - LV_LOG_WARN("Subject type must be `string` (was %d)", subject->type); - return; - } + LV_CHECK_ARG(obj != NULL, return); + LV_CHECK_ARG(subject != NULL, return); + LV_CHECK_ARG(subject->type == LV_SUBJECT_TYPE_STRING, return); subject_set_string_user_data_t * user_data = lv_malloc(sizeof(subject_set_string_user_data_t)); if(user_data == NULL) { @@ -755,6 +711,9 @@ void lv_obj_add_subject_set_string_event(lv_obj_t * obj, lv_subject_t * subject, lv_observer_t * lv_obj_bind_flag_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, false, FLAG_COND_EQ); return observable; } @@ -762,11 +721,16 @@ lv_observer_t * lv_obj_bind_flag_if_eq(lv_obj_t * obj, lv_subject_t * subject, l lv_observer_t * lv_obj_bind_flag_if_not_eq(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, true, FLAG_COND_EQ); return observable; } lv_observer_t * lv_obj_bind_flag_if_gt(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, false, FLAG_COND_GT); return observable; @@ -774,6 +738,8 @@ lv_observer_t * lv_obj_bind_flag_if_gt(lv_obj_t * obj, lv_subject_t * subject, l lv_observer_t * lv_obj_bind_flag_if_ge(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, false, FLAG_COND_GE); return observable; @@ -781,6 +747,9 @@ lv_observer_t * lv_obj_bind_flag_if_ge(lv_obj_t * obj, lv_subject_t * subject, l lv_observer_t * lv_obj_bind_flag_if_lt(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); + /* a < b == !(a >= b) */ lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, true, FLAG_COND_GE); return observable; @@ -788,6 +757,9 @@ lv_observer_t * lv_obj_bind_flag_if_lt(lv_obj_t * obj, lv_subject_t * subject, l lv_observer_t * lv_obj_bind_flag_if_le(lv_obj_t * obj, lv_subject_t * subject, lv_obj_flag_t flag, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); + /* a <= b == !(a > b) */ lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_flag_observer_cb, flag, ref_value, true, FLAG_COND_GT); return observable; @@ -796,6 +768,9 @@ lv_observer_t * lv_obj_bind_flag_if_le(lv_obj_t * obj, lv_subject_t * subject, l lv_observer_t * lv_obj_bind_state_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, false, FLAG_COND_EQ); return observable; @@ -803,6 +778,9 @@ lv_observer_t * lv_obj_bind_state_if_eq(lv_obj_t * obj, lv_subject_t * subject, lv_observer_t * lv_obj_bind_state_if_not_eq(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, true, FLAG_COND_EQ); return observable; @@ -810,6 +788,8 @@ lv_observer_t * lv_obj_bind_state_if_not_eq(lv_obj_t * obj, lv_subject_t * subje lv_observer_t * lv_obj_bind_state_if_gt(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, false, FLAG_COND_GT); @@ -818,6 +798,9 @@ lv_observer_t * lv_obj_bind_state_if_gt(lv_obj_t * obj, lv_subject_t * subject, lv_observer_t * lv_obj_bind_state_if_ge(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, false, FLAG_COND_GE); return observable; @@ -825,6 +808,9 @@ lv_observer_t * lv_obj_bind_state_if_ge(lv_obj_t * obj, lv_subject_t * subject, lv_observer_t * lv_obj_bind_state_if_lt(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); + /* a < b == !(a >= b) */ lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, true, FLAG_COND_GE); @@ -834,6 +820,8 @@ lv_observer_t * lv_obj_bind_state_if_lt(lv_obj_t * obj, lv_subject_t * subject, lv_observer_t * lv_obj_bind_state_if_le(lv_obj_t * obj, lv_subject_t * subject, lv_state_t state, int32_t ref_value) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); /* a <= b == !(a > b) */ lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, state, ref_value, true, @@ -844,6 +832,9 @@ lv_observer_t * lv_obj_bind_state_if_le(lv_obj_t * obj, lv_subject_t * subject, lv_observer_t * lv_obj_bind_checked(lv_obj_t * obj, lv_subject_t * subject) { + LV_CHECK_ARG(obj != NULL, return NULL); + LV_CHECK_ARG(subject != NULL, return NULL); + lv_observer_t * observable = bind_to_bitfield(subject, obj, obj_state_observer_cb, LV_STATE_CHECKED, 0, true, FLAG_COND_EQ); @@ -855,12 +846,15 @@ lv_observer_t * lv_obj_bind_checked(lv_obj_t * obj, lv_subject_t * subject) lv_obj_t * lv_observer_get_target_obj(lv_observer_t * observer) { + LV_CHECK_ARG(observer != NULL, return NULL); + return (lv_obj_t *)lv_observer_get_target(observer); } void * lv_observer_get_user_data(const lv_observer_t * observer) { - LV_ASSERT_NULL(observer); + LV_CHECK_ARG(observer != NULL, return NULL); + return observer->user_data; } diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c index 12789e3fcb..eb5dbbc0ef 100644 --- a/src/core/lv_refr.c +++ b/src/core/lv_refr.c @@ -17,6 +17,7 @@ #include "../draw/lv_draw_private.h" #include "../draw/opengles/lv_draw_opengles.h" #include "lv_global.h" +#include "../lv_public_api.h" /********************* * DEFINES @@ -99,6 +100,9 @@ void lv_refr_now(lv_display_t * disp) void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj) { + LV_CHECK_ARG(layer != NULL, return); + LV_CHECK_ARG(obj != NULL, return); + LV_PROFILER_REFR_BEGIN; lv_area_t clip_area_ori = layer->_clip_area; lv_area_t clip_coords_for_obj; @@ -453,6 +457,9 @@ refr_finish: */ lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) { + LV_CHECK_ARG(area_p != NULL, return NULL); + LV_CHECK_ARG(obj != NULL, return NULL); + lv_obj_t * found_p = NULL; if(lv_area_is_in(area_p, &obj->coords, 0) == false) return NULL; @@ -490,8 +497,9 @@ lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj) void lv_obj_refr(lv_layer_t * layer, lv_obj_t * obj) { - LV_ASSERT_NULL(layer); - LV_ASSERT_NULL(obj); + LV_CHECK_ARG(layer != NULL, return); + LV_CHECK_ARG(obj != NULL, return); + if(lv_obj_has_flag(obj, LV_OBJ_FLAG_HIDDEN)) return; /*If `opa_layered != LV_OPA_COVER` draw the widget on a new layer and blend that layer with the given opacity.*/ diff --git a/src/libs/gltf/gltf_data/lv_gltf_data_injest.cpp b/src/libs/gltf/gltf_data/lv_gltf_data_injest.cpp index 944ea60668..520ee8c094 100644 --- a/src/libs/gltf/gltf_data/lv_gltf_data_injest.cpp +++ b/src/libs/gltf/gltf_data/lv_gltf_data_injest.cpp @@ -89,7 +89,7 @@ static void make_small_magenta_texture(uint32_t new_magenta_tex); template static size_t injest_vec_attribute(uint8_t vec_size, int32_t current_attrib_index, lv_gltf_model_t * data, const fastgltf::Primitive * prim, const char * attrib_id, GLuint primitive_vertex_buffer, - size_t offset, Func &&functor); + size_t offset, Func && functor); static int32_t injest_get_any_image_index(fastgltf::Optional tex); static bool injest_check_any_image_index_valid(fastgltf::Optional tex); @@ -829,7 +829,7 @@ static bool injest_mesh(lv_gltf_model_t * data, fastgltf::Mesh & mesh) template static size_t injest_vec_attribute(uint8_t vec_size, int32_t current_attrib_index, lv_gltf_model_t * data, const fastgltf::Primitive * prim, const char * attrib_id, GLuint primitive_vertex_buffer, - size_t offset, Func &&functor + size_t offset, Func && functor ) { diff --git a/src/misc/lv_event.c b/src/misc/lv_event.c index ee9409302c..d4b0e03334 100644 --- a/src/misc/lv_event.c +++ b/src/misc/lv_event.c @@ -484,3 +484,4 @@ static lv_event_dsc_t ** event_array_at(lv_event_list_t * list, uint32_t index) { return lv_array_at(&list->array, index); } + diff --git a/src/misc/lv_ll.c b/src/misc/lv_ll.c index 59f08babab..67f5f58829 100644 --- a/src/misc/lv_ll.c +++ b/src/misc/lv_ll.c @@ -41,6 +41,8 @@ static void node_set_next(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * nex void lv_ll_init(lv_ll_t * ll_p, uint32_t node_size) { + LV_CHECK_ARG(ll_p != NULL, return); + LV_CHECK_ARG(node_size > 0, return, "cannot initialize a linked list with empty nodes"); ll_p->head = NULL; ll_p->tail = NULL; #ifdef LV_ARCH_64 diff --git a/tests/src/test_cases/test_check_arg.c b/tests/src/test_cases/test_check_arg.c index 0815c3bf0a..58d7d03aa7 100644 --- a/tests/src/test_cases/test_check_arg.c +++ b/tests/src/test_cases/test_check_arg.c @@ -63,12 +63,14 @@ static void log_cb(lv_log_level_t level, const char * buf) static int helper_return_val_on_null(void * ptr) { LV_CHECK_ARG(ptr != NULL, return -1, "ptr is NULL"); + LV_UNUSED(ptr); return 42; } static void helper_return_void_on_null(void * ptr, bool * was_reached) { LV_CHECK_ARG(ptr != NULL, return, "ptr is NULL"); + LV_UNUSED(ptr); *was_reached = true; } @@ -108,6 +110,7 @@ void test_check_arg_printf_args(void) { int x = 0; int val = 7; + LV_UNUSED(val); LV_CHECK_ARG(val > 10, x = -1, ": val=%d", val); TEST_ASSERT_EQUAL_INT(-1, x); TEST_ASSERT_TRUE(log_warned); @@ -195,6 +198,7 @@ void test_check_arg_multiple_in_sequence(void) static int helper_return_val_complex_expr(void * ptr) { LV_CHECK_ARG(ptr != NULL, return (1 > 0 ? -100 : -200), "complex expr"); + LV_UNUSED(ptr); return 42; } @@ -210,6 +214,7 @@ void test_check_arg_return_val_complex_expr(void) static int helper_return_val_zero(void * ptr) { LV_CHECK_ARG(ptr != NULL, return 0, "returns zero"); + LV_UNUSED(ptr); return 42; } diff --git a/tests/src/test_cases/widgets/test_objid.c b/tests/src/test_cases/widgets/test_objid.c index 50637c3c3f..643465638d 100644 --- a/tests/src/test_cases/widgets/test_objid.c +++ b/tests/src/test_cases/widgets/test_objid.c @@ -34,11 +34,11 @@ void test_obj_id_get_child(void) lv_obj_t * child = lv_label_create(parent); lv_obj_t * grandchild = lv_label_create(child); - lv_obj_set_id(child, (void *)(lv_uintptr_t)1); - lv_obj_set_id(grandchild, (void *)(lv_uintptr_t)2); + lv_obj_set_id(child, (void *)(lv_uintptr_t)42); + lv_obj_set_id(grandchild, (void *)(lv_uintptr_t)43); - TEST_ASSERT_EQUAL_PTR(child, lv_obj_find_by_id(NULL, (void *)(lv_uintptr_t)1)); - TEST_ASSERT_EQUAL_PTR(grandchild, lv_obj_find_by_id(NULL, (void *)(lv_uintptr_t)2)); + TEST_ASSERT_EQUAL_PTR(child, lv_obj_find_by_id(NULL, (void *)(lv_uintptr_t)42)); + TEST_ASSERT_EQUAL_PTR(grandchild, lv_obj_find_by_id(NULL, (void *)(lv_uintptr_t)43)); } #endif