Отдельные ветки #ifdef - PullRequest
6 голосов
/ 07 мая 2010

Вкратце: Я хочу сгенерировать два разных дерева источника из текущего, основываясь только на том, что определен один макрос препроцессора, а другой - неопределен, без других изменений в источнике.

Если вам интересно, вот моя история ...

Сначала мой код был чистым. Тогда мы сделали новый продукт, и да, это было лучше. Но код видел только одни и те же периферийные устройства, поэтому мы могли сохранить один и тот же код.

Ну, почти.

Было одно маленькое условие, которое нужно было изменить, поэтому я добавил:

#if defined(PRODUCT_A)
condition = checkCat();
#elif defined(PRODUCT_B)
condition = checkCat() && checkHat();
#endif

... в один и только один исходный файл. В общем заголовочном файле all-source-files-include-this у меня было:

#if !(defined(PRODUCT_A)||defined(PRODUCT_B))
#error "Don't make me replace you with a small shell script. RTFM."
#endif

... чтобы люди не могли скомпилировать его, если они явно не определили тип продукта.

Все было хорошо. Ох ... кроме того, что были сделаны модификации, изменились компоненты, и поскольку новое оборудование работало лучше, мы могли бы существенно переписать системы управления. Теперь, когда я смотрю на лицо кода, есть более 60 отдельных областей, обозначенных либо:

#ifdef PRODUCT_A
...
#else
...
#endif

... или то же самое, но для PRODUCT_B. Или даже:

#if defined(PRODUCT_A)
...
#elif defined(PRODUCT_B)
...
#endif

И, конечно же, иногда здравомыслие уходило в более долгий отпуск и:

#ifdef PRODUCT_A
...
#endif
#ifdef PRODUCT_B
...
#endif

Эти условия переносятся от одной до двухсот строк (вы могли бы подумать, что последнее можно сделать, переключая заголовочные файлы, но имена функций должны совпадать).

Это безумие. Я бы лучше поддерживал две отдельные ветки на основе продуктов в репозитории исходного кода и переносил любые общие изменения. Теперь я это понимаю.

Есть ли что-то, что может генерировать два разных исходных дерева, которые мне нужны, основываясь только на том, что PRODUCT_A определено и PRODUCT_B не определено (и наоборот), без не касается чего-либо еще (т.е. .не включение заголовка, не расширение макроса и т.д.)?

1 Ответ

6 голосов
/ 07 мая 2010

Я верю Коан сделает то, что вы ищете.По ссылке:

Учитывая конфигурацию и некоторый исходный код, Коан может ответить на ряд вопросов о том, как будет выглядеть исходный код для препроцессора C / C ++, если бы эта конфигурация символов применялась вadvance.

А также:

Исходный код, переписанный Коаном, не является предварительно обработанным кодом, созданным препроцессором Си.Он по-прежнему содержит комментарии, макро-вызовы и директивы #.Это все еще исходный код, но упрощенный в соответствии с выбранной конфигурацией.

Таким образом, вы можете запустить его дважды, сначала указав продукт A, а затем продукт B.

...