神奇的xx宏

来源:互联网 发布:能年玲奈 知乎 编辑:程序博客网 时间:2024/04/29 08:49

转载时请注明出处和作者联系方式
作者联系方式:李先静 <xianjimli at hotmail dot com>


前段时间研究lcc,看见token.h里有这样一些代码:

xx(FLOAT,     1, 0,  0,    0,      CHAR,   "float")

xx(DOUBLE,    2, 0,  0,    0,      CHAR,   "double")

xx(CHAR,      3, 0,  0,    0,      CHAR,   "char")

xx(SHORT,     4, 0,  0,    0,      CHAR,   "short")

yy(0,           94,     7,      BXOR,   bittree,'^',    "^")

yy(0,           95,     0,      0,      0,      0,      0)

yy(0,           96,     0,      0,      0,      0,      0)

yy(0,           97,     0,      0,      0,      0,      0)


#undef yy

#undef xx

初看有点不解,xx到底是个什么东西呢?但从这些信息很容易想到,其中每一行描述一个token的信息。把代码大概看了一下,主要有以下几个地方引用到token.h:

在enode.c中:

Tree (*optree[])(int, Tree, Tree) = {

#define xx(a,b,c,d,e,f,g) e,

#define yy(a,b,c,d,e,f,g) e,

#include "token.h"

};
 

在expr.c中:

static int oper[] = {

#define xx(a,b,c,d,e,f,g) d,

#define yy(a,b,c,d,e,f,g) d,

#include "token.h"

};

在output.c中:

static char *tokens[] = {

#define xx(a,b,c,d,e,f,g) g,

#define yy(a,b,c,d,e,f,g) g,

#include "token.h"

};
 

看了这些代码,一下明了了作者的意图:把每个token相关的信息放在一起,便于集中管理,而在不同的地方,通过把xx/yy定义成不同功能的宏,以提取所需要的信息。称它为xx/yy,正是因为这两个宏在使用时还有没定义,在不同的上下文中,其功能是不同的。

我们做的是一个智能手机,在项目早期总会不断有新的AP加入进来,一个APP都很多描述信息,每次加入新AP时,总会遗漏某些信息没有加入,导致Autobuild失败,搞得我很烦,检查了一下相关的代码。发现AP具有下信息:

1.主窗口类

2.主窗口名

3.ID

4.名称

5.INF文件名

6.入口函数

7.资源

8.APP的说明

每一项的定义都在不同的地方,更麻烦的是,增加一个APP竟要4个人配合修改:模块负责人本人,负责修改PC和硬件的工程文件的人,负责加入APP的ID的人,负责加APP的入口函数及其它信息的人。尽管增加APP时用邮件通知了大家,但总有人忘了修改自己的负责的地方,所以常常让Autobuild编译失败。


看了lcc里的xx/yy的方式后,我想在一个地方统一管理这些信息可以避免不必要的麻烦,于用了这种方式去声明APP的信息,如:

#define ALL_APPS_LIST /

  xx("桌面",                 STATUSBAR_CLASS,         STATUSBAR_NAME,         DESKTOP_APPID,       DESKTOPAPPNAME,          DESKTOPWINMAININF,       DesktopWin,               desktop_res)/

  xx("名片",                 CARDCLASS,               CARDNAME,               CARD_APPID,          CARDAPPNAME,             CARDWINMAININF,          Card_WinMain,             card_res)/

  xx("电话",                 TELCLASS,                TELNAME,                TELEPHONE_APPID,     TELAPPNAME,              TELWINMAININF,           Telephone_WinMain,        tel_res)/

使用方式如下:

#undef  xx

#define xx(APP_NAME_COMMENT, WIN_CLASS, WIN_NAME, APP_ID, APP_NAME, APP_INF, APP_WINMAIN, APP_RES)  {(WIN_CLASS), (WIN_NAME)},

const AppClassWindow AppClassDefine[]=

{

       ALL_APPS_LIST

       {NULL,NULL},

};
 

#undef  xx

#define xx(APP_NAME_COMMENT, WIN_CLASS, WIN_NAME, APP_ID, APP_NAME, APP_INF, APP_WINMAIN, APP_RES)  APP_ID,

typedef enum tagAPPID_E

{

    ALL_APPS_LIST

    MAX_APPID

}APPID_E;

现在只要一个人维护这张表和工程文件,其它地方都不需要修改,至此之后一切平安无事。

最近研究ZX的手机开发平台,里面用了IMAGE_DEF/TEXT_DEF等实现了类似的功能,xx换成了更具明显意义的宏,给人感觉更直观一些。