diff options
author | Haru <haru@dotalux.com> | 2013-12-13 16:28:22 +0100 |
---|---|---|
committer | Haru <haru@dotalux.com> | 2013-12-17 01:02:32 +0100 |
commit | 853c5a3141d1f431af95aed55d991334a2b995f6 (patch) | |
tree | 09ce65b20320045954be0b3582e38fb7d01fef0b /src | |
parent | efe4174e59dc462130fde872365e891a7c73654a (diff) | |
download | hercules-853c5a3141d1f431af95aed55d991334a2b995f6.tar.gz hercules-853c5a3141d1f431af95aed55d991334a2b995f6.tar.bz2 hercules-853c5a3141d1f431af95aed55d991334a2b995f6.tar.xz hercules-853c5a3141d1f431af95aed55d991334a2b995f6.zip |
Nullpo cleanup
- Removed unused, nonportable nullpo checks with formatted message
(related: eAthena r15245)
- Converted nullpo_chk to a macro, to make it easier on the llvm static
analyzer.
- Added more details to the nullpo_info reports (related: eAthena
r15246)
- Ensured that the nullpo check macros evaluate their pointer argument
once and only once, so that it's safe to use with expressions that
assign values or have side-effects.
Signed-off-by: Haru <haru@dotalux.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/common/nullpo.c | 82 | ||||
-rw-r--r-- | src/common/nullpo.h | 253 | ||||
-rw-r--r-- | src/map/battle.c | 22 |
3 files changed, 72 insertions, 285 deletions
diff --git a/src/common/nullpo.c b/src/common/nullpo.c index 4383109a7..f0fc2c7ab 100644 --- a/src/common/nullpo.c +++ b/src/common/nullpo.c @@ -6,86 +6,18 @@ #include <string.h> #include "nullpo.h" #include "../common/showmsg.h" -// #include "logs.h" // 布石してみる -static void nullpo_info_core(const char *file, int line, const char *func, - const char *fmt, va_list ap); - -/*====================================== - * Nullチェック 及び 情報出力 - *--------------------------------------*/ -int nullpo_chk_f(const char *file, int line, const char *func, const void *target, - const char *fmt, ...) -{ - va_list ap; - - if (target != NULL) - return 0; - - va_start(ap, fmt); - nullpo_info_core(file, line, func, fmt, ap); - va_end(ap); - return 1; -} - -int nullpo_chk(const char *file, int line, const char *func, const void *target) -{ - if (target != NULL) - return 0; - - nullpo_info_core(file, line, func, NULL, NULL); - return 1; -} - - -/*====================================== - * nullpo情報出力(外部呼出し向けラッパ) - *--------------------------------------*/ -void nullpo_info_f(const char *file, int line, const char *func, - const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - nullpo_info_core(file, line, func, fmt, ap); - va_end(ap); -} - -void nullpo_info(const char *file, int line, const char *func) -{ - nullpo_info_core(file, line, func, NULL, NULL); -} - - -/*====================================== - * nullpo情報出力(Main) - *--------------------------------------*/ -static void nullpo_info_core(const char *file, int line, const char *func, - const char *fmt, va_list ap) -{ +/** + * Reports NULL pointer information + */ +void nullpo_info(const char *file, int line, const char *func, const char *targetname) { if (file == NULL) file = "??"; - func = - func == NULL ? "unknown": - func[0] == '\0' ? "unknown": - func; + if (func == NULL || *func == '\0') + func = "unknown"; ShowMessage("--- nullpo info --------------------------------------------\n"); - ShowMessage("%s:%d: in func `%s'\n", file, line, func); - if (fmt != NULL) - { - if (fmt[0] != '\0') - { - vprintf(fmt, ap); - - // 最後に改行したか確認 - if (fmt[strlen(fmt)-1] != '\n') - ShowMessage("\n"); - } - } + ShowMessage("%s:%d: target '%s' in func `%s'\n", file, line, targetname, func); ShowMessage("--- end nullpo info ----------------------------------------\n"); - - // ここらでnullpoログをファイルに書き出せたら - // まとめて提出できるなと思っていたり。 } diff --git a/src/common/nullpo.h b/src/common/nullpo.h index 8ee86a782..5400acaa1 100644 --- a/src/common/nullpo.h +++ b/src/common/nullpo.h @@ -14,212 +14,73 @@ #define NULLPO_CHECK #endif -/*---------------------------------------------------------------------------- - * Macros - *---------------------------------------------------------------------------- +#if defined(NULLPO_CHECK) +/** + * Reports NULL pointer information if the passed pointer is NULL + * + * @param t pointer to check + * @return true if the passed pointer is NULL, false otherwise */ -/*====================================== - * Nullチェック 及び 情報出力後 return - *・展開するとifとかreturn等が出るので - * 一行単体で使ってください。 - *・nullpo_ret(x = func()); - * のような使用法も想定しています。 - *-------------------------------------- - * nullpo_ret(t) - * 戻り値 0固定 - * [引数] - * t チェック対象 - *-------------------------------------- - * nullpo_retv(t) - * 戻り値 なし - * [引数] - * t チェック対象 - *-------------------------------------- - * nullpo_retr(ret, t) - * 戻り値 指定 - * [引数] - * ret return(ret); - * t チェック対象 - *-------------------------------------- - * nullpo_ret_f(t, fmt, ...) - * 詳細情報出力用 - * 戻り値 0 - * [引数] - * t チェック対象 - * fmt ... vprintfに渡される - * 備考や関係変数の書き出しなどに - *-------------------------------------- - * nullpo_retv_f(t, fmt, ...) - * 詳細情報出力用 - * 戻り値 なし - * [引数] - * t チェック対象 - * fmt ... vprintfに渡される - * 備考や関係変数の書き出しなどに - *-------------------------------------- - * nullpo_retr_f(ret, t, fmt, ...) - * 詳細情報出力用 - * 戻り値 指定 - * [引数] - * ret return(ret); - * t チェック対象 - * fmt ... vprintfに渡される - * 備考や関係変数の書き出しなどに - *-------------------------------------- +#define nullpo_chk(t) ( (t) != NULL ? false : (nullpo_info(NLP_MARK, #t), true) ) +#else // ! NULLPO_CHECK +#define nullpo_chk(t) ((t), false) +#endif // NULLPO_CHECK + +/** + * The following macros check for NULL pointers and return from the current + * function or block in case one is found. + * + * It is guaranteed that the argument is evaluated once and only once, so it + * is safe to call them as: + * nullpo_ret(x = func()); + * The macros can be used safely in any context, as they expand to a do/while + * construct, except nullpo_retb, which expands to an if/else construct. */ -#if defined(NULLPO_CHECK) - +/** + * Returns 0 if a NULL pointer is found. + * + * @param t pointer to check + */ #define nullpo_ret(t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {return(0);} - -#define nullpo_retv(t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {return;} - -#define nullpo_retr(ret, t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {return(ret);} - -#define nullpo_retb(t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {break;} - -// 可変引数マクロに関する条件コンパイル -#if __STDC_VERSION__ >= 199901L -/* C99に対応 */ -#define nullpo_ret_f(t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return(0);} - -#define nullpo_retv_f(t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return;} - -#define nullpo_retr_f(ret, t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return(ret);} - -#define nullpo_retb_f(t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {break;} - -#elif __GNUC__ >= 2 -/* GCC用 */ -#define nullpo_ret_f(t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return(0);} - -#define nullpo_retv_f(t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return;} - -#define nullpo_retr_f(ret, t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return(ret);} - -#define nullpo_retb_f(t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {break;} - -#else - -/* その他の場合・・・ orz */ + do { if (nullpo_chk(t)) return(0); } while(0) -#endif - -#else /* NULLPO_CHECK */ -/* No Nullpo check */ - -// if((t)){;} -// 良い方法が思いつかなかったので・・・苦肉の策です。 -// 一応ワーニングは出ないはず - -#define nullpo_ret(t) (void)(t) -#define nullpo_retv(t) (void)(t) -#define nullpo_retr(ret, t) (void)(t) -#define nullpo_retb(t) (void)(t) - -// 可変引数マクロに関する条件コンパイル -#if __STDC_VERSION__ >= 199901L -/* C99に対応 */ -#define nullpo_ret_f(t, fmt, ...) (void)(t) -#define nullpo_retv_f(t, fmt, ...) (void)(t) -#define nullpo_retr_f(ret, t, fmt, ...) (void)(t) -#define nullpo_retb_f(t, fmt, ...) (void)(t) - -#elif __GNUC__ >= 2 -/* GCC用 */ -#define nullpo_ret_f(t, fmt, args...) (void)(t) -#define nullpo_retv_f(t, fmt, args...) (void)(t) -#define nullpo_retr_f(ret, t, fmt, args...) (void)(t) -#define nullpo_retb_f(t, fmt, args...) (void)(t) - -#else -/* その他の場合・・・ orz */ -#endif - -#endif /* NULLPO_CHECK */ - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------- +/** + * Returns void if a NULL pointer is found. + * + * @param t pointer to check */ -/*====================================== - * nullpo_chk - * Nullチェック 及び 情報出力 - * [引数] - * file __FILE__ - * line __LINE__ - * func __func__ (関数名) - * これらには NLP_MARK を使うとよい - * target チェック対象 - * [返り値] - * 0 OK - * 1 NULL - *-------------------------------------- - */ -int nullpo_chk(const char *file, int line, const char *func, const void *target); - +#define nullpo_retv(t) \ + do { if (nullpo_chk(t)) return; } while(0) -/*====================================== - * nullpo_chk_f - * Nullチェック 及び 詳細な情報出力 - * [引数] - * file __FILE__ - * line __LINE__ - * func __func__ (関数名) - * これらには NLP_MARK を使うとよい - * target チェック対象 - * fmt ... vprintfに渡される - * 備考や関係変数の書き出しなどに - * [返り値] - * 0 OK - * 1 NULL - *-------------------------------------- +/** + * Returns the given value if a NULL pointer is found. + * + * @param ret value to return + * @param t pointer to check */ -int nullpo_chk_f(const char *file, int line, const char *func, const void *target, - const char *fmt, ...) - __attribute__((format(printf,5,6))); - +#define nullpo_retr(ret, t) \ + do { if (nullpo_chk(t)) return(ret); } while(0) -/*====================================== - * nullpo_info - * nullpo情報出力 - * [引数] - * file __FILE__ - * line __LINE__ - * func __func__ (関数名) - * これらには NLP_MARK を使うとよい - *-------------------------------------- +/** + * Breaks fromt he current loop/switch if a NULL pointer is found. + * + * @param t pointer to check */ -void nullpo_info(const char *file, int line, const char *func); - - -/*====================================== - * nullpo_info_f - * nullpo詳細情報出力 - * [引数] - * file __FILE__ - * line __LINE__ - * func __func__ (関数名) - * これらには NLP_MARK を使うとよい - * fmt ... vprintfに渡される - * 備考や関係変数の書き出しなどに - *-------------------------------------- +#define nullpo_retb(t) \ + if (nullpo_chk(t)) break; else (void)0 + +/** + * Reports NULL pointer information + * + * @param file Source file where the error was detected + * @param line Line + * @param func Function + * @param targetname Name of the checked symbol + * + * It is possible to use the NLP_MARK macro that expands to: + * __FILE__, __LINE__, __func__ */ -void nullpo_info_f(const char *file, int line, const char *func, - const char *fmt, ...) - __attribute__((format(printf,4,5))); - +void nullpo_info(const char *file, int line, const char *func, const char *targetname); #endif /* _NULLPO_H_ */ diff --git a/src/map/battle.c b/src/map/battle.c index b3e7e6dc2..94c8fe581 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -3209,11 +3209,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list memset(&ad,0,sizeof(ad)); memset(&flag,0,sizeof(flag)); - if(src==NULL || target==NULL) - { - nullpo_info(NLP_MARK); - return ad; - } + nullpo_retr(ad, src); + nullpo_retr(ad, target); + //Initial Values ad.damage = 1; ad.div_=skill->get_num(skill_id,skill_lv); @@ -3521,10 +3519,8 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * memset(&md,0,sizeof(md)); - if( src == NULL || target == NULL ){ - nullpo_info(NLP_MARK); - return md; - } + nullpo_retr(md, src); + nullpo_retr(md, target); //Some initial values md.amotion=skill->get_inf(skill_id)&INF_GROUND_SKILL?0:sstatus->amotion; @@ -3947,11 +3943,9 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list memset(&wd,0,sizeof(wd)); memset(&flag,0,sizeof(flag)); - if(src==NULL || target==NULL) - { - nullpo_info(NLP_MARK); - return wd; - } + nullpo_retr(wd, src); + nullpo_retr(wd, target); + //Initial flag flag.rh=1; flag.weapon=1; |