Existe un preprocesador C que elimine los bloques #ifdef basados en valores definidos / indefinidos?

Pregunta original

Lo que me gustaría no es un preprocesador C estándar, sino una variación que aceptaría desde algún lugar, probablemente la línea de comando a través de las opciones -DNAME1 y -UNAME2, una especificación de las macros que se definen y luego eliminaría código muerto.

Puede ser más fácil entender lo que busco con algunos ejemplos:

#ifdef NAME1
#define ALBUQUERQUE "ambidextrous"
#else
#define PHANTASMAGORIA "ghostly"
#endif

Si el comando se ejecutara con '-DNAME1', el resultado sería:

#define ALBUQUERQUE "ambidextrous"

Si el comando se ejecutara con '-UNAME1', el resultado sería:

#define PHANTASMAGORIA "ghostly"

Si el comando se ejecutara sin ninguna opción, la salida sería la misma que la entrada.

Este es un caso simple: espero que el código también pueda manejar casos más complejos.

Para ilustrar con un ejemplo del mundo real pero aún simple:

#ifdef USE_VOID
#ifdef PLATFORM1
#define VOID void
#else
#undef VOID
typedef void    VOID;
#endif /* PLATFORM1 */
typedef void *  VOIDPTR;
#else
typedef mint     VOID;
typedef char *  VOIDPTR;
#endif /* USE_VOID */

Me gustaría ejecutar el comando con-DUSE_VOID -UPLATFORM1 y obtenga la salida:

#undef VOID
typedef void    VOID;
typedef void *  VOIDPTR;

Otro ejemplo

#ifndef DOUBLEPAD
#if (defined NT) || (defined OLDUNIX)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */

Idealmente, me gustaría correr con-UOLDUNIX y obtenga la salida:

#ifndef DOUBLEPAD
#if (defined NT)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */

Esto puede estar empujando mi suert

Motivación: base de código grande y antigua con mucho código condicional. Muchas de las condiciones ya no se aplican: la plataforma OLDUNIX, por ejemplo, ya no se crea y ya no se admite, por lo que no es necesario tener referencias a ella en el código. Otras condiciones son siempre ciertas. Por ejemplo, las funciones se agregan con la compilación condicional para que se pueda usar una sola versión del código para las versiones anteriores del software donde la función no está disponible y las versiones más nuevas donde está disponible (más o menos). Eventualmente, las versiones antiguas sin la característica ya no son compatibles, todo usa la característica, por lo que la condición de si la característica está presente o no debe eliminarse, y el código 'cuando la función está ausente' también debe eliminarse. Me gustaría tener una herramienta para hacer el trabajo automáticamente porque será más rápido y más confiable que hacerlo manualmente (lo cual es bastante crítico cuando la base del código incluye 21,500 archivos fuente).

(Una versión realmente inteligente de la herramienta podría leer#include 'd para determinar si las macros de control, las especificadas por -D o -U en la línea de comando, están definidas en esos archivos. No estoy seguro de si eso es realmente útil, excepto como diagnóstico de respaldo. Sin embargo, haga lo que haga, el pseudo-preprocesador no debe expandir las macros o incluir archivos textualmente. La salida debe ser una fuente similar, pero generalmente más simple que el código de entrada.)

Informe de estado (un año después)

Después de un año de uso, estoy muy contento con ' sunifdef 'recomendado por la respuesta seleccionada. Todavía no ha cometido un error, y no espero que lo haga. La única objeción que tengo es estilística. Dada una entrada como:

#if (defined(A) && defined(B)) || defined(C) || (defined(D) && defined(E))

y ejecutar con '-UC' (C nunca se define), t, la salida es:

#if defined(A) && defined(B) || defined(D) && defined(E)

Esto es técnicamente correcto porque '&&' se une más fuerte que '||', pero es una invitación abierta a la confusión. Preferiría que incluyera paréntesis alrededor de los conjuntos de condiciones '&&', como en el original:

#if (defined(A) && defined(B)) || (defined(D) && defined(E))

Sin embargo, dada la oscuridad de algunos de los códigos con los que tengo que trabajar, para que esa sea la mayor selección es un gran cumplido; Es una herramienta valiosa para mí.

The New Kid on the Block

abiendo comprobado la URL para su inclusión en la información anterior, veo que (como se predijo) hay un nuevo programa llamado Coan ese es el sucesor de 'sunifdef'. Está disponible en SourceForge y lo ha estado desde enero de 2010. Lo revisaré ... más informes más adelante este año, o tal vez el año que viene, o en algún momento, o nunca.

Respuestas a la pregunta(5)

Su respuesta a la pregunta