azure-c-shared-utility

azure-edgeのソース見てると、マクロ関連がいろいろ使われていたので、その定義先を調べてみた。

基本的にはazure-c-shared-utilityに定義が固まっているようだ。

 

github.com

 

一つ例を取り上げると、Lock_Init()だと、

azure_c_shared_utility/lock.hに以下の定義がある。

/**
 * @brief	This API creates and returns a valid lock handle.
 *
 * @return	A valid @c LOCK_HANDLE when successful or @c NULL otherwise.
 */
MOCKABLE_FUNCTION(, LOCK_HANDLE, Lock_Init);

また、新しいマクロか。。。ということで、結論だけでいくと、MOCKABLE_FUNCTIONの動作は置いておいて(マクロが長すぎて、読むのがつらい)

LOCK_HANDLE Lock_Init()に展開されています。※正確にはUnitテストができるように値を外から流し込めるように実装が展開されますが割愛。

2017/8/12追記 マクロで展開してみましたが、行数が多いため解析を断念。時間あるときに試すことにする。

ENABLE_MOCKSが無効な時は単に、プロトタイプ宣言として、マクロを展開するだけのようです。

また、Lock_Init()の説明は、azure-c-shared-utility/porting_guide.md at master · Azure/azure-c-shared-utility · GitHubにある。

C言語でテストを書いたことがないので、これ以降は、勉強のために追跡する。※修正予定

テスト関連はmock_cというライブラリを使っている。※目で追うのはさすがにつらいので、-Eオプションでプリプロセッサを展開させようかな。

#ifdef ENABLE_MOCKS

/* Codes_SRS_UMOCK_C_LIB_01_001: [MOCKABLE_FUNCTION shall be used to wrap function definition allowing the user to declare a function that can be mocked.]*/
#define MOCKABLE_FUNCTION(modifiers, result, function, ...) \
    MOCKABLE_FUNCTION_UMOCK_INTERNAL_WITH_MOCK(modifiers, result, function, __VA_ARGS__)

#include "umock_c.h"

#else

#include "azure_c_shared_utility/macro_utils.h"

#define UMOCK_C_PROD_ARG_IN_SIGNATURE(count, arg_type, arg_name) arg_type arg_name IFCOMMA(count)

/* Codes_SRS_UMOCK_C_LIB_01_002: [The macro shall generate a function signature in case ENABLE_MOCKS is not defined.] */
/* Codes_SRS_UMOCK_C_LIB_01_005: [**If ENABLE_MOCKS is not defined, MOCKABLE_FUNCTION shall only generate a declaration for the function.] */
/* Codes_SRS_UMOCK_C_LIB_01_001: [MOCKABLE_FUNCTION shall be used to wrap function definition allowing the user to declare a function that can be mocked.]*/
#define MOCKABLE_FUNCTION(modifiers, result, function, ...) \
    result modifiers function(IF(COUNT_ARG(__VA_ARGS__),,void) FOR_EACH_2_COUNTED(UMOCK_C_PROD_ARG_IN_SIGNATURE, __VA_ARGS__));

#endif

ENABLE_MOCKSが有効だと、MOCKABLE_FUNCTION_UMOCK_INTERNAL_WITH_MOCKが呼ばれ、無効だと FOR_EACH_2_COUNTEDが呼ばれる。

MOCKABLE_FUNCTION_UMOCK_INTERNAL_WITH_MOCKは以下のソースに定義がある。
 
github.com


FOR_EACH_2_COUNTEDは以下のソースに定義がある。

github.com