C语言自动生成enum值和名字映射代码

所属分类: 软件编程 / C 语言 阅读数: 67
收藏 0 赞 0 分享

这年头好像继续做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.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库。本来是学习编译原理时的一些实验代码,后来发现它对于文本提取还是很强大,于是有了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。

更多精彩内容其他人还在看

C++中四种对象生存期和作用域以及static的用法总结分析

以下是对C++中四种对象生存期和作用域以及static的用法进行了详细的介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C++嵌套类与局部类详细解析

从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类之外的作用域使用该类名时,需要加名字限定
收藏 0 赞 0 分享

C++空类详解

以下是对C++中的空类进行了详细的介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C++之友元:友元函数和友元类详解

友元是一种允许非类成员函数访问类的非公有成员的一种机制。可以把一个函数指定为类的友元,也可以把整个类指定为另一个类的友元
收藏 0 赞 0 分享

C++中返回指向函数的指针示例

int (*ff(int)) (int *,int);表示:ff(int)是一个函数,带有一个int型的形参,该函数返回int (*) (int *,int),它是一个指向函数的指针,所指向的函数返回int型并带有两个分别是Int*和int型的形参
收藏 0 赞 0 分享

C数据结构之单链表详细示例分析

以下是对C语言中的单链表进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C数据结构之双链表详细示例分析

以下是对c语言中的双链表进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

浅析如何在c语言中调用Linux脚本

如何在c语言中调用Linux脚本呢?下面小编就为大家详细的介绍一下吧!需要的朋友可以过来参考下
收藏 0 赞 0 分享

深入解析unsigned int 和 int

以下是对unsigned int和int进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

浅谈C++中的string 类型占几个字节

本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节
收藏 0 赞 0 分享
查看更多