Пользовательский препроцессор gcc
Не могли бы вы привести пример написания специального препроцессора gcc?
Моя цель - заменить SID ( "foo" ) одинаковые макросы соответствующими CRC32 вычисленными значениями. Для любого другого макроса я хотел бы использовать стандартный препроцессор cpp.
Похоже, что достичь этой цели можно с помощью опций -no-integrated-cpp -B
, однако я не могу найти простой пример их использования.
Ответы
Ответ 1
Предупреждение: опасный и уродливый взлом. Закройте глаза Теперь вы можете подключить свой собственный препроцессор, добавив переключатели '-no-integrated-cpp' и '-B' в командную строку gcc. '-no-integrated-cpp' означает, что gcc выполняет поиск по пути '-B' для своих препроцессоров, прежде чем он использует свой внутренний путь поиска. Вызовы препроцессора могут быть идентифицированы, если программы 'cc1', 'cc1plus' или 'cc1obj' (это компиляторы C, С++ и Objective-c) вызывается с помощью опции -E. Вы можете сделать свою собственную предварительную обработку, когда увидите эту опцию. Когда опция "-E" не передаёт все параметры исходным программам. Когда есть такой вариант, вы можете сделать свою собственную предварительную обработку и передать управляемый файл исходному компилятору.
Он выглядит следующим образом:
> cat cc1
#!/bin/sh
echo "My own special preprocessor -- [email protected]"
/usr/lib/gcc/i486-linux-gnu/4.3/cc1 [email protected]
exit $?
> chmod 755 cc1
> gcc -no-integrated-cpp -B$PWD x.c
My own special preprocessor -- -E -quiet x.c -mtune=generic -o /tmp/cc68tIbc.i
My own special preprocessor -- -fpreprocessed /tmp/cc68tIbc.i -quiet -dumpbase x.c -mtune=generic -auxbase x -o /tmp/cc0WGHdh.s
Этот пример вызывает исходный препроцессор, но печатает дополнительное сообщение и параметры. Вы можете заменить script на собственный препроцессор.
Плохой взлом закончился. Теперь вы можете открыть глаза.
Ответ 2
Один из способов - использовать , чтобы" переписать" только вызов макроса SID для того, что вы хотите, прежде чем выполнять компиляции, оставив всю обработку препроцессора самому компилятору.
Наш DMS Software Reengineering Toolkit - такая система, которая может применяться ко многим языкам, включая C и, в частности, GCC 2/3/4 серии компиляторов.
Чтобы реализовать эту идею с помощью DMS, вы должны запустить DMS с C front end
над исходным кодом до этапа компиляции. DMS может анализировать код без расширения директив препроцессора, сборки
абстрактные синтаксические деревья, представляющие его, выполняют преобразования в AST, а затем выплевывают результат как компилируемый текст C.
Конкретное правило преобразования, которое вы используете:
rule replace_SID_invocation(s:STRING):expression->expression
= "SID(\s)" -> ComputeCRC32(s);
где ComputeCRC32 - это настраиваемый код, который делает то, что он говорит. (DMS включает реализацию CRC32, поэтому пользовательский код для этого довольно короткий.
DMS - это хороший молот для этой задачи. Вы можете использовать PERL для реализации чего-то довольно похожего. Разница с PERL (или некоторым другим сочетанием строк/замены взлома) заключается в том, что: a) он может найти шаблон где-нибудь, где вы не хотите замену, например.
... QSID("foo")... // this isn't a SID invocation
который вы, вероятно, можете исправить, тщательно закодировав свой шаблон, b) не соответствует запросу SID, найденному в следующих обстоятельствах:
... SID ( /* master login id */ "Joel" ) ... // need to account for formatting and whitespace
и c) не могут обрабатывать различные типы escape-символов, которые отображаются в самой литеральной строке:
... SID("f\no\072") ... // need to handle all of GCC weird escapes
Передняя панель DMS C обрабатывает все экраны для вас; функция ComputeCRC32 выше увидит строку, содержащую фактические предназначенные символы, а не исходный текст, который вы видите в исходном коде.
Итак, это действительно вопрос о том, заботитесь ли вы о делах с темными углами, или если вы думаете, что у вас может быть больше специальной обработки.
Учитывая то, как вы описали проблему, я был бы очень соблазнен первым пройти маршрут Perl и просто запретить забавные случаи. Если вы не можете этого сделать, тогда большой молот имеет смысл.