summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2013-12-13 16:28:22 +0100
committerHaru <haru@dotalux.com>2013-12-17 01:02:32 +0100
commit853c5a3141d1f431af95aed55d991334a2b995f6 (patch)
tree09ce65b20320045954be0b3582e38fb7d01fef0b /src
parentefe4174e59dc462130fde872365e891a7c73654a (diff)
downloadhercules-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.c82
-rw-r--r--src/common/nullpo.h253
-rw-r--r--src/map/battle.c22
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;