web-dev-qa-db-ja.com

貼り付けたトークンをマクロで大文字にできますか?

Cマクロで、貼り付けたトークンを大文字にすることはできますか?たとえば、現在、次のマクロがあります。

#define TEST(name, keyword) \
    test_##name:
        TEST_##keyword##_KEYWORD

私はこれを次のように呼び出します:

TEST(test1, TEST1)

これにより、次のようになります。

test_test1:
    TEST_TEST1_KEYWORD

さて、同じ名前を2回入力する代わりに(1回はすべて小文字で、もう1回はすべて大文字で)、次のいずれかを実行して、トークンをすべて大文字に変更する方法はありますか?またはすべて小文字?

TEST(test1) or TEST(TEST1)

ありがとう、ライアン

34
DuneBug

私の知る限り、Cプリプロセッサ(少なくともISO/ANSI規格)のトークンに対して実行できる操作は、トークンを置き換える、「文字列化する」、または連結することだけです。私はまた、あなたがやりたいことをできるようにするGCCまたはMSVC拡張機能を知りません。

しかし、人々はマクロを使って魔法の(または恐ろしい)ことをする巧妙な(または奇妙な)方法を考え出しているので、誰かが私を驚かせても驚かないでしょう。

13
Michael Burr

次のようなことができます(テストされていない、おそらくタイプミス...)

#define NORMALIZE(TOK) NORMALIZE_ ## TOK

そして、発生する可能性のある書き込みのそれぞれについて、

#define NORMALIZE_test1 test1
#define NORMALIZE_TEST1 test1

次に、実際のマクロ内でNORMALIZEマクロを次のように使用します。

#define TEST(name, keyword)                    \
    test_ ## NORMALIZE(name):                  \
        TEST_ ## NORMALIZE(keyword) ##_KEYWORD

(ただし、すべての連結が正しく行われるまで、いくつかの中間ヘルパーマクロを実行する必要があるかもしれません)

10
Jens Gustedt

プリプロセッサはpp-tokenの入力ストリームで動作し、これらを意味のある方法で分解できる構造がないため、これは不可能です。

プリプロセッサには、pp-tokensをマクロ展開に置き換えたり、連結したり、(完全に)削除したりするための構造があります。

つまり、大文字にする唯一の希望は、個々の文字から始めて大文字にしてから、すべてを接着することです。使用できるセットは有限であるため、個々の文字を大文字にするのは非常に簡単です。一方、少なくとも固定された最大長に制限している場合は、それらを接着することが可能です。最終的には、次のように使用されるマクロになります。

TEST(t,e,s,t,1)
4
skyking