2010-08-03 10 views
25

En una macro C, ¿es posible capitalizar una ficha pegada? Por ejemplo, tengo actualmente la macro siguiente:¿Puedes capitalizar un token pegado en una macro?

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

I habría invocar esto como sigue:

TEST(test1, TEST1) 

lo cual produciría lo siguiente:

test_test1: 
    TEST_TEST1_KEYWORD 

Ahora, en lugar de tener que escriba el mismo nombre dos veces (una vez con todos los caracteres en minúscula y otra vez con todos los caracteres en mayúscula), ¿hay alguna manera de que yo pueda hacer cualquiera de las siguientes acciones y cambie el token a mayúscula l? etters o todas las letras minúsculas?

TEST(test1) or TEST(TEST1) 

Gracias, Ryan

+0

He visto códigos muy grandes y antiguos que repiten muchas palabras en mayúsculas y minúsculas para lograr lo que desea. Supongo que esto no es posible. –

Respuesta

8

Por lo que yo sé, las únicas operaciones que se pueden hacer en fichas en el preprocesador C (al menos la norma ISO/ANSI) es reemplazar, 'stringify o concatenarlos. Tampoco estoy enterado de ninguna extensión de GCC o MSVC que te permita hacer lo que quieras.

Sin embargo, la gente ha inventado maneras ingeniosas (o extrañas) de hacer cosas mágicas (u horribles) con macros, por lo que no me sorprendería que alguien me sorprendiera.

+0

Gracias, Michael. Esto es más o menos lo que esperaba, pero esperaba que alguien pudiera sorprenderme también. =) – DuneBug

7

Se podría hacer algo como lo siguiente (no probado, probablemente errores tipográficos ...)

#define NORMALIZE(TOK) NORMALIZE_ ## TOK 

y luego para cada uno de los escritos que puedan producirse

#define NORMALIZE_test1 test1 
#define NORMALIZE_TEST1 test1 

continuación, utilizar la macro NORMALIZE dentro de su macro real algo así como

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

(pero tal vez tendrías que hacer un poco macros auxiliares intermedios hasta que obtener todas las concatenaciones derecha)

+0

¡Ja! ¡Decir ah! Lo hiciste de la manera incorrecta ...él quiere 'TEST (nombre)' por lo que tendría '#define NORMALIZE_TEST1_UPPER TEST1' y luego' #define NORMALIZE_TEST1_LOWER test1' luego usa TEST con la versión en mayúsculas: 'TEST (TEST1)'. (Por supuesto, podría hacer lo mismo con la letra minúscula, depende de cómo quiera llamar a su macro 'TEST()'.) –

1

no es posible debido a que el preprocesador trabaja en un flujo de entrada de pp-token y no tiene un constructo que permite descomponer estas de una manera significativa.

Qué tiene el preprocesador es constructos para reemplazar pp-token s con expansiones de macro, concatenar, eliminarlos (en su totalidad), etc.

Esto significa que su única esperanza de uppercasing es comenzar con los caracteres individuales y mayúsculas estos y luego pegue todo junto. La duplicación de caracteres individuales es bastante sencilla ya que solo tiene un conjunto finito para trabajar. Por otro lado, sería posible unirlos, al menos si se limita a una longitud máxima fija. Usted terminaría en una macro que se usaría así:

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