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を使用しています。

編集:明確にするために、ファイルを書き込むマクロ自体を探しているわけではありません。enum 要素の名前と値を何らかの形で文字列と int として格納する方法が必要なので、通常の 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先頭にあることを前提としています。と の後にスペースを入れないで=ください。これらの制限を克服するためにスクリプトを変更するのは簡単です。これを自動的に実行するメイクファイルを作成できます。

于 2013-09-14T03:39:16.230 に答える
0

「別の道」を考えたことはありますか?通常は、データ定義を (テキスト) ファイルに保持する方が理にかなっています。その後、ビルド プロセスの一部として、C++ ヘッダーを生成してインクルードできます。Python と mako は、これを行うための優れたツールです。

于 2013-09-14T03:46:13.930 に答える