Оригинальный вопрос
Я бы хотел, чтобы это был не стандартный предварительный процессор C, а вариация на нем, которая могла бы принять откуда-то - возможно, командная строка через опции -DNAME1 и -UNAME2 - спецификация макросов, которые будут определены, и тогда устранить мертвый код.
Мне может быть легче понять, что мне нужно с некоторыми примерами:
#ifdef NAME1
#define ALBUQUERQUE "ambidextrous"
#else
#define PHANTASMAGORIA "ghostly"
#endif
Если команда была запущена с помощью "-DNAME1", результатом будет:
#define ALBUQUERQUE "ambidextrous"
Если команда была запущена с помощью "-UNAME1", результатом будет:
#define PHANTASMAGORIA "ghostly"
Если команда была запущена ни с одной опцией, выход был бы таким же, как и вход.
Это простой случай - я надеюсь, что код может обрабатывать и более сложные случаи.
Чтобы проиллюстрировать реальный, но все же простой пример:
#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 */
Я хотел бы запустить команду с -DUSE_VOID -UPLATFORM1
и получить вывод:
#undef VOID
typedef void VOID;
typedef void * VOIDPTR;
Другой пример:
#ifndef DOUBLEPAD
#if (defined NT) || (defined OLDUNIX)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */
В идеале я хотел бы работать с -UOLDUNIX
и получить результат:
#ifndef DOUBLEPAD
#if (defined NT)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */
Это может подтолкнуть мою удачу!
Мотивация: большая, древняя база кода с большим количеством условного кода. Многие из условий больше не применяются - платформа OLDUNIX, например, больше не выполняется и больше не поддерживается, поэтому нет необходимости иметь ссылки на нее в коде. Другие условия всегда верны. Например, функции добавляются с условной компиляцией, так что одна версия кода может использоваться как для старых версий программного обеспечения, где эта функция недоступна, так и для более новых версий, где она доступна (более или менее). В конце концов, старые версии без этой функции больше не поддерживаются - все использует эту функцию, поэтому необходимо исключить условие наличия или отсутствия функции, а также удалить код "когда функция отсутствует". Я хотел бы иметь инструмент для выполнения задания автоматически, потому что он будет быстрее и надежнее, чем делать это вручную (что весьма важно, когда база кода содержит 21 500 исходных файлов).
(На самом деле умная версия инструмента может читать файлы #include
'd, чтобы определить, определены ли в этих файлах макросы управления - те, которые указаны в -D или -U в командной строке. Я не уверен, действительно полезный, кроме как для резервного копирования. Однако, что бы он ни делал, псевдо-предварительный процессор не должен расширять макросы или включать файлы дословно. Результат должен быть источником, похожим на, но обычно более простым, чем код ввода.)
Отчет о состоянии (через год)
После года использования я очень доволен " sunifdef ", рекомендованным выбранным ответом. Он еще не совершил ошибку, и я этого не ожидаю. Единственный куб, который у меня есть, стилистичен. Учитывая такой ввод, как:
#if (defined(A) && defined(B)) || defined(C) || (defined(D) && defined(E))
и запустить с помощью -U C '(C никогда не определяется), выход:
#if defined(A) && defined(B) || defined(D) && defined(E)
Это технически корректно, потому что '&&' связывается более жестко, чем '||', но это открытое приглашение к путанице. Я бы предпочел, чтобы он включал круглые скобки вокруг наборов условий "&&", как в оригинале:
#if (defined(A) && defined(B)) || (defined(D) && defined(E))
Однако, учитывая неясность некоторого кода, с которым мне приходится работать, поскольку это самый большой нит-кик, это сильный комплимент; это ценный инструмент для меня.
Новый малыш на блоке
Проверяя URL-адрес для включения в вышеприведенную информацию, я вижу, что (как и было предсказано) существует новая программа под названием Coan, которая является преемником "sunifdef". Он доступен на SourceForge и с января 2010 года. Я буду проверять его... дальнейшие отчеты в конце этого года или, возможно, в следующем году или когда-нибудь, или никогда.