C语言自动生成enum值和名字映射代码
这年头好像继续做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 /* 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,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,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文件来支持。我非常厌恶编译宏,因此不会做这个更新。 如何设置使用环境的补充说明: 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。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |