我寫程序有個習慣,就是給那些獨立于任何接口的常用宏放在一個全局頭文件c.h中,然后不論在每個.c文件中都包含該頭文件,這樣可以方便調用,貌似是從
postgreSQL中學到的.c.h中還有調試宏,可以很快定位程序異常,并打印異常原因及調用層次,另外,還可以用宏開關的形式定義調試級別,以控制
輸出何種調試信息,一共有4級,最高級是給程序員看的,給出最詳盡的異常信息;下一級是用戶可以看的,不會輸出接口內部的異常信息,實現接口內部隱藏等
等。該頭文件在不斷完善中 ,先給出部分代碼如下 :
/* c.h */
#ifndef _C_H
#define _C_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#define Delay(n) do { int i,j,k; /
for(k=0;k<n;k++) for(i=0;i<8999;i++) for(j=0;j<8999;j++); }while(0)
#define MAKE_RAND(M,N) ((M)+rand()/(RAND_MAX/((N)-(M)+1)+1))
#define NELEMS(x) ((sizeof(x))/(sizeof((x)[0])))
//n是2的冪次,如4,8,16
#define Round_Up(x,n) (((x)+((n)-1))&(~((n)-1)))
#define offsetof(ptype, MEMBER) ((size_t) &((ptype)0)->MEMBER)
#define container_of(ptr,ptype, member) /
(ptype)((char *)ptr-offsetof(ptype,member))
#define show_software_edition() do{/
printf("/nLast Compiled on %s at %s/n/n",__DATE__,__TIME__);/
}while(0)
//注意以下宏在使用時,如果__VA_ARGS__中消息過長可以分行,但是
//注意分行時不要在中間插入逗號,否則就會當作參數了
//字符串分行時會自動進行合并,如
/*
return_val_if_fail(
pp != 0 && *pp != 0,
0,
"In %s %s Line %d , "
"Memory Find Failed",
file , func , line
);
若在"In %s %s Line %d , "后面加逗號,"Memory Find Failed"將被當作第一個參數
*/
/*
if(x>0)
return_if_fail(x>5);
else ...
可能會出錯,等價形式為
if(x>0)
if(!(x>5)){
};
else ...
因為return_if_fail尾部的分號截斷了上一個if,所以else會提示找不到
上一個if。
解決辦法為將return_if_fail用大括號括起來
if(x>0) {
return_if_fail(x>5);
}
else
*/
#define myassert(exp) ((void)((exp)||(fprintf(stderr,/
"/n/nAssert !! In %s -> %s -> %d :: %s/n"/
,__FILE__,__FUNCTION__,__LINE__,#exp),abort(),0)))
#if defined(DEBUG0)
#define return_val_if_fail(p,ret,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
char error_msg[128]; /
fprintf(stdout,"/nWarning !! In %s %s Line %d , "#p" Failed ./n", /
__FILE__,__FUNCTION__,__LINE__); /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
if(*error_msg)fprintf(stdout,"Error Message : %s",error_msg); /
return ret ; /
} /
} while(0)
#define return_if_fail(p,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
char error_msg[128]; /
fprintf(stdout,"/nWarning !! In %s %s Line %d , "#p" Failed ./n", /
__FILE__,__FUNCTION__,__LINE__); /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
if(*error_msg)fprintf(stdout,"Error Message : %s",error_msg); /
return ; /
} /
} while(0)
#define err_if_fail(p,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
char error_msg[128]; /
fprintf(stdout,"/nWarning !! In %s %s Line %d , "#p" Failed ./n", /
__FILE__,__FUNCTION__,__LINE__); /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
if(*error_msg)fprintf(stdout,"Error Message : %s",error_msg); /
} /
} while(0)
#ifndef DISABLE_SHOW
#define Show_Value(x,u) fprintf(stdout,"/nIn %s %s Line : %d , The Value of "#x" is %"#u" .",/
__FILE__,__FUNCTION__,__LINE__,x)
#else
#define Show_Value(x,u) ((void)(x))
#endif
#elif defined(DEBUG1)
#define return_val_if_fail(p,ret,...) do { /
int val = (p) ? 1:0 ; /
if(val==0) { /
char error_msg[128]; /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
return ret ; /
} /
} while(0)
#define return_if_fail(p,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
char error_msg[128]; /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
if(*error_msg)fprintf(stdout,"/nError Message : %s",error_msg); /
return ; /
} /
} while(0)
#define err_if_fail(p,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
char error_msg[128]; /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
if(*error_msg)fprintf(stdout,"/nError Message : %s",error_msg); /
} /
} while(0)
#ifndef DISABLE_SHOW
#define Show_Value(x,u) fprintf(stdout,"/nThe Value of "#x" is %"#u" .",x)
#else
#define Show_Value(x,u) ((void)(x))
#endif
#elif defined(DEBUG2)
#define return_val_if_fail(p,ret,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
return ret ; /
} /
} while(0)
#define return_if_fail(p,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
return ; /
} /
} while(0)
#define err_if_fail(p,...) do { /
int val = (p) ? 1:0; /
} while(0)
#ifndef DISABLE_SHOW
#define Show_Value(x,u) fprintf(stdout,"%"#u"",x)
#else
#define Show_Value(x,u) ((void)(x))
#endif
#elif defined(DISABLE_RETURN_DEBUG)
#define return_val_if_fail(p,ret,...) ((void)0)
#define return_if_fail(p,...) ((void)0)
#define err_if_fail(p,...) ((void)0)
#else
#define return_val_if_fail(p,ret,...) do { /
int val = (p) ? 1:0; /
} while(0)
#define return_if_fail(p,...) do { /
int val = (p) ? 1:0; /
} while(0)
#define err_if_fail(p,...) do { /
int val = (p) ? 1:0; /
} while(0)
#define Show_Value(x,u) ((void)(x))
#endif
#if defined(DEBUG0) || defined(DEBUG1) || defined(DEBUG2)
#ifndef DISABLE_D
#define D__ fprintf(stdout,"/nRunning Over %s %s Line %d .", /
__FILE__,__FUNCTION__,__LINE__);
#else
#define D__ ((void)0);
#endif
#ifndef DISABLE_MSG
#define err_msg(std,...) fprintf(std , __VA_ARGS__)
#else
#define err_msg(std,...) ((void)0)
#endif
#endif
#define Abs(a) ((a)>0 ? (a) : -(a))
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)>(b)?(b):(a))
#define Bzero(ptr,size) memset((ptr),0,(size))
#define Zero_Memory(ptr) Bzero(ptr,sizeof *(ptr))
#define Str_Macro(p) _Str_Macro(p)
#define _Str_Macro(p) #p
#define Strcmp(a,R,b) (strcmp(a,b) R 0)
#endif