linux中输出调试信息

来源:互联网 发布:淘宝货到付款商城 编辑:程序博客网 时间:2024/05/08 20:12
在友善之臂的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__ 包含当前时间的字符串
 注意,是双下划线,而不是单下划线 。

如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩睡觉老想着军训怎么办 1岁宝宝太老实了怎么办 上课小孩很调皮不听话怎么办 初中学生上课爱说话调皮怎么办 8个月婴儿疝气怎么办 头部疤痕不长发怎么办呢 有纹身想去当兵怎么办 在部队干活的钱怎么办 新兵5公里超过标准时间怎么办 17个月婴儿裹手怎么办 7个月婴儿裹手怎么办 俩月孩子裹手怎么办 婴儿 3个月 裹手怎么办 一岁宝宝裹手怎么办 5个月宝宝裹手怎么办 不想让孩子裹手怎么办 四个月宝宝裹手怎么办 开车撞狗了跑了怎么办 母螃蟹抱卵了怎么办 我能怎么办我也想睡觉 一个人的微信群找不到了怎么办 一个人的微信被删了找不到了怎么办 不想回对方微信怎么办 喜欢我的人太多怎么办 假如战争今夜打响我们该怎么办 约客户客户说忙怎么办 第一天来姨妈痛怎么办 痛经痛的很厉害怎么办 工作第一天被辞怎么办 第一天练车紧张怎么办 到新公司第一天怎么办 我妈上班别人欺负怎么办 欺负别人他妈来找了怎么办 家人都欺负我妈怎么办 人老了日不动了怎么办? 日照职业技术学院公租房怎么办留宿 眼镜上沾了胶水怎么办 近视镜片刮花了怎么办 墨镜镜片磨花了怎么办 邻居养狗味道大怎么办 邻居不让养狗了怎么办