【轉】神奇的xx宏

轉載時請註明出處和作者聯繫方式
作者聯繫方式:李先靜 <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換成了更具明顯意義的宏,給人感覺更直觀一些。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章