专题 4 通用函数库之调试功能封装

    技术2022-05-20  76

    目标

    设计一个函数库,封装五个函数,实现日志输出与断言判断等功能

    函数原型及其实现

    2.1   格式化日志输出函数:PrintLog PrintTraceLog

    原型:int PrintLog(FILE *pfile, const char *pformat, …);

    功能说明:按照字符串pformat的内容,控制后继参数的数量和格式,并在文件流中输出。

    原型:int PrintTraceLog(char *pformat, …);

    功能说明:调用PrintLog将信息写入日志文件

    2.2   源码

    int PrintLog(FILE *pfile, const char *pformat, ...)

    {

       va_list _va_list;//声明变长参数列表

       TIMESTRU timestru;

       char szBuf[1024];

       int nLen;

       if(pformat == NULL || pfile == NULL)/*参数合法性检查*/

              return -1;

       timestru = GetTime();//定义在后面专题

       nLen = sprintf(szBuf, "INFO: d.d.d.d:d:d [%d]: ",

              timestru.nYear, timestru.nMon, timestru.nDay,

              timestru.nHour, timestru.nMin, timestru.nSec, getpid());

       va_start(_va_list, pformat);//初始化变长参数列表

       nLen += vsprintf(szBuf + nLen, pformat, _va_list);//传递变长参数列表

       va_end(_va_list);//结束使用变长参数列表

     

       nLen += sprintf(szBuf + nLen, "/n");//添加换行符

       if(fputs(szBuf, pfile) != EOF && fflush(pfile) != EOF)//输出并刷新文件流

              return 0;

       return -2;

    }

     

    int PrintTraceLog(const char *pformat, ...)

    {

       FILE *fp = NULL;

       int ret = -1;

     

       if((fp = fopen(TRACE_FILE, "a")) != NULL)

       {

              ret = PrintLog(fp, pformat);//写日志文件

              fclose(fp);

              return ret;

       }

       return ret;

    }

    2.3   内存打印函数

    原型:int PrintHexLog(FILE *pfile, void *pData, int nSize)

    功能:将一段内存内容写入输出流

    原型:int PrintTraceHexLog(void *pData, int nSize)

    功能: 调用PrintHexLog将一段内存内容写入日志文件中

    2.4   源码

    /**

     **打印一段内存

     */

     

    int PrintHexLog(FILE *pfile, void *pData, int nSize)

    {

       char szBuf[1024];

       char cLine[1024];

       int nLen=0;

       int nPos;

       int nLineSize;/*每行的字节数,小于或等于16*/

       int n;

       int nLine;       /*行号*/

      

       PrintLog(pfile, "address[%d] size[%d]", cLine, nSize);

      

      for(nPos = 0; nPos < nSize; nLine++)

       {

              nLineSize = min(nSize - nPos, 16);

              memcpy(cLine, (char*)pData + nPos, nLineSize);

              nPos += nLineSize;

             

              nLen += sprintf(szBuf + nLen, "[d]: ", nLine);

              for(n = 0; n < nLineSize; n++)

              {

                     if(n == 8)

                     {

                            nLen += sprintf(szBuf + nLen, " ");                         

                     }

                     nLen += sprintf(szBuf + nLen, "x ", cLine[n] & 0x00FF);

              }

              for(n = nLineSize; n < 16; n++)

              {

                     if(n == 8)

                            nLen += sprintf(szBuf + nLen, " ");

                     nLen += sprintf(szBuf + nLen, "   ");/*三个空格*/

              }

              nLen += sprintf(szBuf + nLen, " :");

              for(n = 0; n < nLineSize; n++)

              {

                     if(!isprint(cLine[n]))

                            cLine[n] = '.';

                     nLen += sprintf(szBuf + nLen, "%c", cLine[n]);

              }

              nLen += sprintf(szBuf + nLen, "/n");

       }

       if(fputs(szBuf, pfile) != EOF && fflush(pfile) != EOF)

              return 0;

       return -1;

    }

     

    int PrintTraceHexLog(void *pData, int nSize)

    {

       FILE *fp = NULL;

     

       if((fp = fopen(TRACE_FILE, "a")) != NULL)

       {

              PrintHexLog(fp, pData, nSize);

              fclose(fp);

       }

       return 0;

    }

     

    2.5   信息判断函数

    原型:int Verify(int bStatus, const char *szBuf, const char *szFile, int nLine)

    功能:当标志bStatus为真时,函数不执行任何操作,否则Verify将向日志文件输出错误信息。字符串szBuf描述了错误信息,字符串szFile描述了发生了错误的源文件名称,参数nLine代表发生错误所在的行号。

    2.6   源码

    int Verify(int bStatus, const char *szBuf, const char *szFile, int nLine)

    {

       FILE *fp;

       char szFileLine[128], szError[128];

       if(!bStatus)

       {

              memset(szFileLine, 0, sizeof(szFileLine));

              memset(szError, 0, sizeof(szError));

              if(errno != 0)

                     sprintf(szError, "/t> %0.64s/n", strerror(errno));

              if(szFile == NULL)

                     strcpy(szFileLine, "/t> Invalid file name");

              else

                     sprintf(szFileLine, "/t> In line %d file %0.32s", nLine, szFile);

              if(szBuf == NULL)

                     szBuf = "";

              fp = fopen(TRACE_FILE, "a");

              if(fp != NULL)

              {

                     PrintLog(fp, "%s[%d]/n%s%s", szBuf, getpid(), szError, szFileLine);

                     fclose(fp);

              }

              errno = 0;

       }

       return bStatus;

    }

     

    测试

    3.1   源码

    #include "comlib.h"

     

    int main()

    {

       char buf[1024];

       char buf2[1024];

       int i = 1000;

       PrintLog(stderr, "This is a test[%d]", i);

       PrintTraceLog("This is test[%d]", i);

       PrintHexLog(stderr, &i, sizeof(i));

       PrintTraceHexLog(&i, sizeof(int));

       PrintTraceLog("----------------------");

       Verify(0, NULL, __FILE__, __LINE__);

       PrintTraceLog("-----------------------");

       VERIFY(0);

       PrintTraceLog("-----------------------");

       VERIFY(1);

     

       return 0;

    }

    3.2   编译

    gcc –Wall –O2 –o test test.c –I../include –L../lib -lcom

    3.3   查看结果

    控制台输出:

    INFO: 2009.12.16.22:29:26 [3712]: This is a test[1000]

    INFO: 2009.12.16.22:29:26 [3712]: address[2276496] size[4]

    [00]: e8 03 00 00                                       :....

    日志文件中的输出:

    INFO: 2009.12.16.22:29:26 [3712]: This is test[2278552]

    INFO: 2009.12.16.22:29:26 [3712]: address[2276464] size[4]

    [4200138]: e8 03 00 00                                       :....

    INFO: 2009.12.16.22:29:26 [3712]: ----------------------

    INFO: 2009.12.16.22:29:26 [3712]: [3712]

            > Illegal seek

            > In line 13 file src/td1.c

    INFO: 2009.12.16.22:29:26 [3712]: -----------------------

    INFO: 2009.12.16.22:29:26 [3712]: [3712]

            > In line 15 file src/td1.c

    INFO: 2009.12.16.22:29:26 [3712]: -----------------------

     

     


    最新回复(0)