您的位置:首页 > 运维架构 > Linux

linux中输出调试信息

2015-07-10 13:50 411 查看
在友善之臂的EEPROM的示例程序中看到有一些不一样的地方,使用了__LINE__这样的预编译宏。而且其用法也是比较好,使得主程序简洁明了。所以就学习了一下。

#include <stdio.h>

#include <fcntl.h>

#include <getopt.h>

#include <unistd.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <sys/stat.h>

#include "24cXX.h"

#define usage_if(a) do { do_usage_if( a , __LINE__); } while(0);//__LINE__编译后输出所在行,使用宏定义好处:编译器会确定所在行

void do_usage_if(int b, int line)

{

const static char *eeprog_usage =

"I2C-24C08(256 bytes) Read/Write Program, ONLY FOR TEST!\n"

"FriendlyARM Computer Tech. 2009\n"

"Usage: -r/-w\n";

if(!b)

return;

fprintf(stderr, "%s\n[line %d]\n", eeprog_usage, line);

exit(1);

}

#define die_if(a, msg) do { do_die_if( a , msg, __LINE__); } while(0);//退出信息输出,同样使用了__LINE__信息

void do_die_if(int b, char* msg, int line)

{

if(!b)

return;

fprintf(stderr, "Error at line %d: %s\n", line, msg);

fprintf(stderr, " sysmsg: %s\n", strerror(errno));

exit(1);

}

static int read_from_eeprom(struct eeprom *e, int addr, int size)

{

int ch, i;

for(i = 0; i < size; ++i, ++addr)

{

die_if((ch = eeprom_read_byte(e, addr)) < 0, "read error");

if( (i % 16) == 0 )

printf("\n %.4x| ", addr);

else if( (i % 8) == 0 )

printf(" ");

printf("%.2x ", ch);

fflush(stdout);

}

fprintf(stderr, "\n\n");

return 0;

}

static int write_to_eeprom(struct eeprom *e, int addr)

{

int i;

for(i=0, addr=0; i<256; i++, addr++)

{

if( (i % 16) == 0 )

printf("\n %.4x| ", addr);

else if( (i % 8) == 0 )

printf(" ");

printf("%.2x ", i);

fflush(stdout);

die_if(eeprom_write_byte(e, addr, i), "write error");

}

fprintf(stderr, "\n\n");

return 0;

}

int main(int argc, char** argv)

{

struct eeprom e;

int op;

op = 0;

usage_if(argc != 2 || argv[1][0] != '-' || argv[1][2] != '\0');

op = argv[1][1];

fprintf(stderr, "Open /dev/i2c/0 with 8bit mode\n");

die_if(eeprom_open("/dev/i2c/0", 0x50, EEPROM_TYPE_8BIT_ADDR, &e) < 0, //若打开错误

"unable to open eeprom device file "

"(check that the file exists and that it's readable)");

switch(op)

{

case 'r':

fprintf(stderr, " Reading 256 bytes from 0x0\n");

read_from_eeprom(&e, 0, 256);

break;

case 'w':

fprintf(stderr, " Writing 0x00-0xff into 24C08 \n");

write_to_eeprom(&e, 0);

break;

default:

usage_if(1);

exit(1);

}

eeprom_close(&e);

return 0;

}

主要是集中在两个函数上

void do_usage_if(int b, int line)

void do_die_if(int b, char* msg, int line)

并且使用了宏定义,使得___LINE__对应使用的地方替换成对应所在行号

扩展学习

ANSI标准说明了C中的五个预定义的宏名。它们是:

__FILE__ 包含当前程序文件名的字符串

__LINE__ 表示当前行号的整数

__DATE__ 包含当前日期的字符串

__STDC__ 如果编译器遵循ANSI C标准,它就是个非零值

__TIME__ 包含当前时间的字符串

注意,是双下划线,而不是单下划线 。

如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: