我写程序有个习惯,就是给那些独立于任何接口的常用宏放在一个全局头文件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