C語(yǔ)言自動(dòng)生成enum值和名字映射代碼
這年頭好像繼續(xù)做C語(yǔ)言的人不多了,年輕人大多去互聯(lián)網(wǎng)和移動(dòng)應(yīng)用。確實(shí),那兩個(gè)領(lǐng)域現(xiàn)在來(lái)錢(qián)快,且總是供不應(yīng)求。就說(shuō)剛剛在一個(gè)舊同事的微信群里,有人剛放出自己有團(tuán)隊(duì)可以做App幾分鐘,哇塞,好幾個(gè)人說(shuō)有項(xiàng)目,要求加好友私聊。我也想過(guò)轉(zhuǎn)行,可惜人老珠黃,沒(méi)有互聯(lián)網(wǎng)或是應(yīng)用團(tuán)隊(duì)愿意接收。估計(jì)再過(guò)些年,C程序世界里就只有我這樣的小老頭們繼續(xù)自?shī)首詷?lè)了,羨慕死年輕人了!
平常工作中,經(jīng)常要做一些打印,或是日志。而這里面,enum類(lèi)型的數(shù)據(jù)就很多,如果只是打印出它的整數(shù)值,顯然會(huì)讓測(cè)試人員很惱火,鬼知道那數(shù)字說(shuō)的是什么。就算你給他個(gè)文檔對(duì)著看,也絲毫不能得到原諒。最后,都得乖乖的把這個(gè)enum對(duì)應(yīng)的名字打印出來(lái)才能平息。
今天說(shuō)的這個(gè),就是幫忙搞定這個(gè)轉(zhuǎn)換問(wèn)題的。
比如,有這么個(gè)example.h文件:
enum InfoStateE{ eInfoStateIdle, eInfoStateIniting, eInfoStateInited, eInfoStateReady, eInfoStateActive, eInfoStateStandby, eInfoStateRelease, };
我們需要個(gè)函數(shù),把enum值翻譯成字符串;另外也要個(gè)函數(shù),能查找字符串對(duì)應(yīng)的enum值;可以提供名字的一部分。p_enum.pl就是做這個(gè)的,只需要執(zhí)行:
perl p_enum.pl example.h -o:example_map
p_enum.pl接受目錄,通配符,或是多個(gè)文件。-o:example_map是指定輸出的文件名。這里我們得到了example_map.h和example_map.c兩個(gè)文件:
/* FILE: example_map.h This file was created at Fri Dec 11 16:40:56 CST 2015 Auto-generated source. Don't change it manually. Contact with hhao020@gmail.com for bug reporting and supporting. */ #ifndef EXAMPLE_MAP #define EXAMPLE_MAP #ifdef __cplusplus extern "C" { #endif #include "zType_Def.h" extern const char* InfoStateE2Name(dword_t e); extern dword_t InfoStateE2Value(char* name, int bAppro); extern int InfoStateEMapShow(); #ifdef __cplusplus } #endif #endif /*EXAMPLE_MAP*/
/* FILE: example_map.c This file was created at Fri Dec 11 16:40:56 CST 2015 Auto-generated source. Don't change it manually. Contact with hhao020@gmail.com for bug reporting and supporting. */ #define _GNU_SOURCE #include <string.h> #include <stdio.h> #include <stdlib.h> #include "zAutoCodeApi.h" #ifndef ENUM_PRIMARY_FUNCTIONS static char *zEnum2Name(dword_t e, zEnum2NameMap_t arr[], int nSize) { int i; for(i=0; i<nSize; i++) { if(arr[i].e == e) return arr[i].name; } return 0; } static int zName2Enum(char* name, zEnum2NameMap_t arr[], int nSize, int bAppro) { int i; for(i=0; i<nSize; i++) { if(bAppro) { if(strcasestr(arr[i].name, name)) return arr[i].e; } else { if(!strcmp(arr[i].name, name)) return arr[i].e; } } return -1; } static int zEnumMapShow(zEnum2NameMap_t arr[], int nSize) { int i; for(i=0; i<nSize; i++) { printf("%3d %d-> %s \n", i, arr[i].e, arr[i].name); } return 0; } #endif /*ENUM_PRIMARY_FUNCTIONS*/
#include "example_map.h" #include "example.h" zEnum2NameMap_t InfoStateE_map_t[]= { {eInfoStateIdle, "eInfoStateIdle"}, {eInfoStateIniting, "eInfoStateIniting"}, {eInfoStateInited, "eInfoStateInited"}, {eInfoStateReady, "eInfoStateReady"}, {eInfoStateActive, "eInfoStateActive"}, {eInfoStateStandby, "eInfoStateStandby"}, {eInfoStateRelease, "eInfoStateRelease"}, }; /*InfoStateE_map_t*/ const char* InfoStateE2Name(dword_t e) { char* pName = zEnum2Name(e, InfoStateE_map_t, TBL_SIZE(InfoStateE_map_t)); if(pName) return pName; return "*NA*"; } dword_t InfoStateE2Value(char* name, int bAppro) { return zName2Enum(name, InfoStateE_map_t, TBL_SIZE(InfoStateE_map_t), bAppro); }; int InfoStateEMapShow() { return zEnumMapShow(InfoStateE_map_t, TBL_SIZE(InfoStateE_map_t)); };
p_enum.pl是用了我自己做的lex和yacc庫(kù)。本來(lái)是學(xué)習(xí)編譯原理時(shí)的一些實(shí)驗(yàn)代碼,后來(lái)發(fā)現(xiàn)它對(duì)于文本提取還是很強(qiáng)大,于是有了enum相關(guān)的自動(dòng)生成工具。有興趣的,可以參考,或者有問(wèn)題留言。
嗯,還有一點(diǎn),p_enum.pl不支持enum定義里包含編譯控制宏。如果你有這個(gè)需求,需要自己修改enum.lex和enum.yacc文件來(lái)支持。我非常厭惡編譯宏,因此不會(huì)做這個(gè)更新。
如何設(shè)置使用環(huán)境的補(bǔ)充說(shuō)明:
linux環(huán)境,perl_zlib建議解壓在你的home目錄下。然后在你的用戶配置文件.bashrc(或是.profile,不同linux略有差別)里面添加zlib的路徑。我的配置里是這樣的:
export PATH="$HOME/perl/Debug:$PATH" export PERL5LIB="$HOME/perl/zLib:$HOME/perl5/lib/perl5" PERL_MB_OPT="--install_base \"$HOME/perl5\""; export PERL_MB_OPT; PERL_MM_OPT="INSTALL_BASE=$HOME/perl5"; export PERL_MM_OPT;
這當(dāng)中只有PERL5LIB里的zLib路徑是必須的。perl5是我用來(lái)裝額外的perl庫(kù)用的,一起貼出來(lái)供參考。
windows環(huán)境,需要先運(yùn)行zlib.bat來(lái)設(shè)置環(huán)境變量,然后才能運(yùn)行p_enum.pl。當(dāng)然,你還要確認(rèn)安裝了activeperl。
欄 目:C語(yǔ)言
下一篇:深入解析C++編程中__alignof 與__uuidof運(yùn)算符的使用
本文標(biāo)題:C語(yǔ)言自動(dòng)生成enum值和名字映射代碼
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2590.html
您可能感興趣的文章
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用函數(shù)刪除字符
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)式函數(shù)庫(kù)
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)數(shù)怎么表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段函數(shù)
- 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排序法函數(shù)
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段函數(shù)
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎么打出三角函數(shù)的值
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求階乘


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10delphi制作wav文件的方法
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 04-02jquery與jsp,用jquery
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10C#中split用法實(shí)例總結(jié)