Android:kw_is(kw, type) (keyword_info[kw].flags & (type))分析

代码结构://以init.rc 的第一个有效命令为例分析—>import /init.environ.rc

init_parse_config_file("/init.rc");
    parse_config(path, data);
        next_token(&state);
            lookup_keyword //将传入的参数添加K_前缀
            parse_new_section(&state, kw, nargs, args);/*section:import,service,on*/
            kw_is(kw, type) (keyword_info[kw].flags & (type))
            //K_import情况下
            parse_import(state, nargs, args);

参考代码:
参考代码
kw_is(K_import, SECTION)分析:
第一次包含keyword.h的文件内容:

#ifndef KEYWORD
int do_bootchart_init(int nargs, char **args);
...
#define __MAKE_KEYWORD_ENUM__
#define KEYWORD(symbol, flags, nargs, func) K_##symbol,
enum {
    K_UNKNOWN,
#endif
    KEYWORD(bootchart_init,        COMMAND, 0, do_bootchart_init)
…
#ifdef __MAKE_KEYWORD_ENUM__
    KEYWORD_COUNT,
};
#undef __MAKE_KEYWORD_ENUM__
#undef KEYWORD
#endif

① 首次包含肯定没定义KEYWORD,等几个宏,so,相当于添加几个函数声明,以及一个K_大头的枚举.

#define KEYWORD(symbol, flags, nargs, func) K_##symbol,
    KEYWORD(bootchart_init, COMMAND, 0, do_bootchart_init)

展开:
K_##symbol—>K_ bootchart_init
综上,第一次包含想当于添加几个函数声明和一个枚举。
去除宏定义
第二次包含在结构体中:
第一次包含的最后又用undef关键字去除KEYWORD关键字定义(其他几个宏也一样只不过没有二次再定义所以其中间的内容也不被包含),紧接着就在此定义KEYWORD,但是已经今非昔比了。
这里写图片描述
再次包含keywords.h时就全然不同了:
这里写图片描述
再看上述通过宏定义精简的keyword.h代码:

#ifndef KEYWORD
int do_bootchart_init(int nargs, char **args);
…
enum {
    K_UNKNOWN,
#endif
…
 KEYWORD(writepid,    OPTION,  0, 0)
#ifdef __MAKE_KEYWORD_ENUM__
    KEYWORD_COUNT,
};
#undef __MAKE_KEYWORD_ENUM__
#undef KEYWORD
#endif

函数以及杂七杂八的都不被包含仅仅剩下等KEYWORD:

…
  KEYWORD(bootchart_init,        COMMAND, 0, do_bootchart_init)
  KEYWORD(chmod,       COMMAND, 2, do_chmod)
…

展开:

#define KEYWORD(symbol, flags, nargs, func) [ K_##symbol ] = { #symbol, func, nargs + 1, flags, },
KEYWORD(bootchart_init,COMMAND, 0, do_bootchart_init)
[ K_ bootchart ] = { bootchart, do_bootchart_init, 0 + 1, COMMAND, },
//熟悉的结构体成员定义是不是回来了?
//带入结构体:
static struct {
    const char *name;
    int (*func)(int nargs, char **args);
    unsigned char nargs;
    unsigned char flags;
} keyword_info[KEYWORD_COUNT] = {
    [ K_UNKNOWN ] = { "unknown", 0, 0, 0 },
[ K_ bootchart ] = { bootchart, do_bootchart_init, 0 + 1, COMMAND, },
…
};

看到这应该能感受到代码的巧妙了吧。
现在来好好看下为什么能判断是否为SECTION,COMMAND等关键字了,走了这么一大段路也只不过是为了定义一个结构体罢了:

#define kw_is(kw, type) (keyword_info[kw].flags & (type))

这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值