// https://qiita.com/Wander_nyanko/questions/dfc4ff1dc20be5710745
// gcc main.c -o a.out
#include <stdio.h>
#include <stdbool.h>
#define MAX 100
static bool is_hoge_called = false;
#define SET_HOGE_CALLED(v) { is_hoge_called = v; }
#define GET_HOGE_CALLED() (is_hoge_called)
void hoge()
{
SET_HOGE_CALLED( true );
}
void callHoge( int A, int B, int C, int D, int E, int F, int G, void* XYZ )
{
#if 0
// 従来方法1
if ( ( 0 < A ) && ( A < MAX) ) {
if ( ( 0 < B ) && ( B < MAX) ) {
if ( ( 0 < C ) && ( C < MAX) ) {
if ( ( 0 < D ) && ( D < MAX) ) {
if ( ( 0 < E ) && ( E < MAX) ) {
if ( ( 0 < F ) && ( F < MAX) ) {
if ( ( 0 < G ) && ( G < MAX) ) {
if ( XYZ != NULL ) {
hoge();
}
}
}
}
}
}
}
}
#elif 0
// 従来方法2
if ( ! (( 0 < A ) && ( A < MAX )) ) { return; }
if ( ! (( 0 < B ) && ( B < MAX )) ) { return; }
if ( ! (( 0 < C ) && ( C < MAX )) ) { return; }
if ( ! (( 0 < D ) && ( D < MAX )) ) { return; }
if ( ! (( 0 < E ) && ( E < MAX )) ) { return; }
if ( ! (( 0 < F ) && ( F < MAX )) ) { return; }
if ( ! (( 0 < G ) && ( G < MAX )) ) { return; }
if ( XYZ == NULL ) { return ;}
hoge();
#elif 0
// 改善案1
bool ret = true;
ret = (( 0 < A ) && ( A < MAX ));
ret &= (( 0 < B ) && ( B < MAX ));
ret &= (( 0 < C ) && ( C < MAX ));
ret &= (( 0 < D ) && ( D < MAX ));
ret &= (( 0 < E ) && ( E < MAX ));
ret &= (( 0 < F ) && ( F < MAX ));
ret &= (( 0 < G ) && ( G < MAX ));
ret &= ( XYZ != NULL );
if ( ret == false )
{
// fprintf(stderr, "[TRACE][%d], A=%d, B=%d, C=%d, D=%d, E=%d, F=%d, G=%d, XYZ=%p\n", __LINE__, A,B,C,D,E,F,G,XYZ);
return;
}
hoge();
#else
// 改善案2
const bool ret =
(( 0 < A ) && ( A < MAX )) &&
(( 0 < B ) && ( B < MAX )) &&
(( 0 < C ) && ( C < MAX )) &&
(( 0 < D ) && ( D < MAX )) &&
(( 0 < E ) && ( E < MAX )) &&
(( 0 < F ) && ( F < MAX )) &&
(( 0 < G ) && ( G < MAX )) &&
( XYZ != NULL );
if ( ret == false )
{
// fprintf(stderr, "[TRACE][%d], A=%d, B=%d, C=%d, D=%d, E=%d, F=%d, G=%d, XYZ=%p\n", __LINE__, A,B,C,D,E,F,G,XYZ);
return;
}
hoge();
#endif
}
typedef struct testcase{
bool expectedResult;
int val[7];
void* xyz;
} testcase_t;
bool unitTest( testcase_t *_testcase )
{
SET_HOGE_CALLED( false );
callHoge(
_testcase->val[0], // A
_testcase->val[1], // B
_testcase->val[2], // C
_testcase->val[3], // D
_testcase->val[4], // E
_testcase->val[5], // F
_testcase->val[6], // G
_testcase->xyz // XYZ
);
return GET_HOGE_CALLED() == _testcase->expectedResult;
}
int main(void)
{
int dmy_xyz;
testcase_t TestCase[] = {
// Common
{ true, { 1, 1, 1, 1, 1, 1, 1}, &dmy_xyz },
// Test for A
{ false, { 0, 1, 1, 1, 1, 1, 1}, &dmy_xyz },
{ true, { 99, 1, 1, 1, 1, 1, 1}, &dmy_xyz },
{ false, {100, 1, 1, 1, 1, 1, 1}, &dmy_xyz },
// Test for B
{ false, { 1, 0, 1, 1, 1, 1, 1}, &dmy_xyz },
{ true, { 1, 99, 1, 1, 1, 1, 1}, &dmy_xyz },
{ false, { 1,100, 1, 1, 1, 1, 1}, &dmy_xyz },
// Test for C
{ false, { 1, 1, 0, 1, 1, 1, 1}, &dmy_xyz },
{ true, { 1, 1, 99, 1, 1, 1, 1}, &dmy_xyz },
{ false, { 1, 1,100, 1, 1, 1, 1}, &dmy_xyz },
// Test for D
{ false, { 1, 1, 1, 0, 1, 1, 1}, &dmy_xyz },
{ true, { 1, 1, 1, 99, 1, 1, 1}, &dmy_xyz },
{ false, { 1, 1, 1,100, 1, 1, 1}, &dmy_xyz },
// Test for E
{ false, { 1, 1, 1, 1, 0, 1, 1}, &dmy_xyz },
{ true, { 1, 1, 1, 1, 99, 1, 1}, &dmy_xyz },
{ false, { 1, 1, 1, 1,100, 1, 1}, &dmy_xyz },
// Test for F
{ false, { 1, 1, 1, 1, 1, 0, 1}, &dmy_xyz },
{ true, { 1, 1, 1, 1, 1, 99, 1}, &dmy_xyz },
{ false, { 1, 1, 1, 1, 1,100, 1}, &dmy_xyz },
// Test for G
{ false, { 1, 1, 1, 1, 1, 1, 0}, &dmy_xyz },
{ true, { 1, 1, 1, 1, 1, 1, 99}, &dmy_xyz },
{ false, { 1, 1, 1, 1, 1, 1,100}, &dmy_xyz },
// Test for XYZ
{ false, { 1, 1, 1, 1, 1, 1, 1}, NULL }
};
for ( int i = 0 ; i < sizeof(TestCase) / sizeof(TestCase[0]); i++ )
{
bool ret = unitTest( &(TestCase[i]) );
printf("[%-6s] Expected %c : %4d %4d %4d %4d %4d %4d %4d %p \n",
( ret?"OK":"FAILED" ),
( TestCase[i].expectedResult?'T':'F'),
TestCase[i].val[0], TestCase[i].val[1], TestCase[i].val[2], TestCase[i].val[3],
TestCase[i].val[4], TestCase[i].val[5], TestCase[i].val[6],
( TestCase[i].xyz )
);
}
return 0;
}