用于将枚举元素名称和值保存到文件的c ++宏

时间:2013-09-14 01:35:00

标签: c++ macros enums

通常我会尽量避免使用宏,所以我实际上不知道如何使用它们超出最基本的值,但我正在尝试进行一些元操作,因此我认为需要使用宏。 / p>

我有一个枚举列出了各种日志条目及其各自的ID,例如

enum LogID
{
  LOG_ID_ITEM1=0,
  LOG_ID_ITEM2,
  LOG_ID_ITEM3=10,
  ...
}

在将数据写入日志文件时在我的程序中使用。请注意,它们通常不会按任何顺序排列。

我在Matlab中执行大部分日志文件后处理,因此我想将相同的变量名称和值写入文件以供Matlab加载。例如,文件看起来像

LOG_ID_ITEM1=0;
LOG_ID_ITEM2=1;
LOG_ID_ITEM3=10;
...

我不知道如何去做,但似乎不应该太复杂。如果有帮助,我使用的是c ++ 11。

编辑: 为了澄清,我不是在寻找宏本身来编写文件。我想要一种方法将枚举元素名称和值以某种方式存储为字符串和整数,这样我就可以使用常规的c ++函数将所有内容写入文件。我认为宏可能会用于将字符串和值构建到向量中?那样有用吗?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:1)

我同意Adam Burry的观点,单独的脚本可能是最好的。不确定您熟悉哪种语言,但这是一个快速的Python脚本,可以完成这项工作:

#!/usr/bin/python

'''Makes a .m file from an enum in a C++ source file.'''


from __future__ import print_function
import sys
import re


def parse_cmd_line():

    '''Gets a filename from the first command line argument.'''

    if len(sys.argv) != 2:
        sys.stderr.write('Usage: enummaker [cppfilename]\n')
        sys.exit(1)
    return sys.argv[1]


def make_m_file(cpp_file, m_file):

    '''Makes an .m file from enumerations in a .cpp file.'''

    in_enum = False
    enum_val = 0
    lines = cpp_file.readlines()

    for line in lines:
        if in_enum:

            # Currently processing an enumeration

            if '}' in line:

                # Encountered a closing brace, so stop
                # processing and reset value counter

                in_enum = False
                enum_val = 0
            else:

                # No closing brace, so process line

                if '=' in line:

                    # If a value is supplied, use it

                    ev_string = re.match(r'[^=]*=(\d+)', line)
                    enum_val = int(ev_string.group(1))

                # Write output line to file

                e_out = re.match(r'[^=\n,]+', line)
                m_file.write(e_out.group(0).strip() + '=' +
                        str(enum_val) + ';\n')
                enum_val += 1
        else:

            # Not currently processing an enum,
            # so check for an enum definition

            enumstart = re.match(r'enum \w+ {', line)
            if enumstart:
                in_enum = True


def main():

    '''Main function.'''

    # Get file names

    cpp_name = parse_cmd_line()
    m_name = cpp_name.replace('cpp', 'm')
    print('Converting ' + cpp_name + ' to ' + m_name + '...')

    # Open the files

    try:
        cpp_file = open(cpp_name, 'r')
    except IOError:
        print("Couldn't open " + cpp_name + ' for reading.')
        sys.exit(1)

    try:
        m_file = open(m_name, 'w')
    except IOError:
        print("Couldn't open " + m_name + ' for writing.')
        sys.exit(1)

    # Translate the cpp file

    make_m_file(cpp_file, m_file)

    # Finish

    print("Done.")

    cpp_file.close()
    m_file.close()


if __name__ == '__main__':
    main()

在该名称的以下文件上运行./enummaker.py testenum.cpp

/* Random code here */

enum LogID {
    LOG_ID_ITEM1=0,
    LOG_ID_ITEM2,
    LOG_ID_ITEM3=10,
    LOG_ID_ITEM4
};

/* More random code here */

enum Stuff {
    STUFF_ONE,
    STUFF_TWO,
    STUFF_THREE=99,
    STUFF_FOUR,
    STUFF_FIVE
};

/*  Yet more random code here */

生成包含以下内容的文件testenum.m

LOG_ID_ITEM1=0;
LOG_ID_ITEM2=1;
LOG_ID_ITEM3=10;
LOG_ID_ITEM4=11;
STUFF_ONE=0;
STUFF_TWO=1;
STUFF_THREE=99;
STUFF_FOUR=100;
STUFF_FIVE=101;

此脚本假定enum块的右括号始终在一个单独的行上,第一个标识符在开括号后面的行上定义,大括号之间没有空行, enum出现在一行的开头,=和数字后面没有空格。很容易修改脚本以克服这些限制。您可以让makefile自动运行。

答案 1 :(得分:0)

您是否考虑过“走另一条路”?在(文本)文件中维护数据定义通常更有意义,然后作为构建过程的一部分,您可以生成C ++标头并包含它。 Python和mako是一个很好的工具。