0

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

我有一个枚举列出各种日志条目及其各自的 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++ 函数将所有内容写入文件。我在想这个宏可能会被用来将字符串和值构建成向量?那样有用吗?如果是这样,怎么做?

4

2 回答 2

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自动运行它。

于 2013-09-14T03:39:16.230 回答
0

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

于 2013-09-14T03:46:13.930 回答