這年頭好像繼續做C語言的人不多了,年輕人大多去互聯網和移動應用。確實,那兩個領域現在來錢快,且總是供不應求。就說剛剛在一個舊同事的微信群里,有人剛放出自己有團隊可以做App幾分鐘,哇塞,好幾個人說有項目,要求加好友私聊。我也想過轉行,可惜人老珠黃,沒有互聯網或是應用團隊愿意接收。估計再過些年,C程序世界里就只有我這樣的小老頭們繼續自娛自樂了,羨慕死年輕人了!
平常工作中,經常要做一些打印,或是日志。而這里面,enum類型的數據就很多,如果只是打印出它的整數值,顯然會讓測試人員很惱火,鬼知道那數字說的是什么。就算你給他個文檔對著看,也絲毫不能得到原諒。最后,都得乖乖的把這個enum對應的名字打印出來才能平息。
今天說的這個,就是幫忙搞定這個轉換問題的。
比如,有這么個example.h文件:
enum InfoStateE{ eInfoStateIdle, eInfoStateIniting, eInfoStateInited, eInfoStateReady, eInfoStateActive, eInfoStateStandby, eInfoStateRelease,};
我們需要個函數,把enum值翻譯成字符串;另外也要個函數,能查找字符串對應的enum值;可以提供名字的一部分。p_enum.pl就是做這個的,只需要執行:
perl p_enum.pl example.h -o:example_map
p_enum.pl接受目錄,通配符,或是多個文件。-o:example_map是指定輸出的文件名。這里我們得到了example_map.h和example_map.c兩個文件:
/*FILE: example_map.hThis file was created at Fri Dec 11 16:40:56 CST 2015Auto-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.cThis file was created at Fri Dec 11 16:40:56 CST 2015Auto-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_FUNCTIONSstatic 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庫。本來是學習編譯原理時的一些實驗代碼,后來發現它對于文本提取還是很強大,于是有了enum相關的自動生成工具。有興趣的,可以參考,或者有問題留言。
嗯,還有一點,p_enum.pl不支持enum定義里包含編譯控制宏。如果你有這個需求,需要自己修改enum.lex和enum.yacc文件來支持。我非常厭惡編譯宏,因此不會做這個更新。
如何設置使用環境的補充說明:
linux環境,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;
這當中只有PERL5LIB里的zLib路徑是必須的。perl5是我用來裝額外的perl庫用的,一起貼出來供參考。
windows環境,需要先運行zlib.bat來設置環境變量,然后才能運行p_enum.pl。當然,你還要確認安裝了activeperl。
|
新聞熱點
疑難解答
圖片精選