Как очистить результаты предварительной обработки, удалив некоторые или все #include - PullRequest
0 голосов
/ 04 декабря 2018

В заголовочных файлах происходит много магии предварительной обработки.Я хотел бы просмотреть результаты такой магии в моем исходном файле, но без всего этого, #include.

Например, когда я запускаю препроцессор на

#include<stdio.h>    
#define astring "hello world"                         
int main()                
{                           
    printf("%s\n",astring); 
    return 0;
} 

Iполучить 27 тыс. строк вывода.В этом случае я хотел бы только последние 7 или около того строк.

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

Редко я буду включать директивы в необычных местах, эти тоже я бы хотел, чтобы опция пропускала или оставляла вывод.

Существуют ли какие-либо инструменты / методы, чтобы помочь мне?

РЕДАКТИРОВАТЬ: цель не получить компилируемый код.В моем случае препроцессор функционально изменяет исходный код (например, используя препроцессор для реализации шаблона, подобного функциональности в c), а просмотр исходного кода после обработки полезен для отладки.Я использую cpreprocessor gnu через gcc / g ++, который, насколько я знаю, вызывает cpp.

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Возможное простое решение - вставить начальный и конечный маркеры вокруг текста программы, расширение которого вас интересует.Хотя вы не можете вставлять маркеры с помощью комментариев, вы можете добиться того же эффекта с помощью директив #pragma, по крайней мере с обычными компиляторами C.

В соответствии со стандартом (§6.10.6) директива прагмы распознается либореализация, а затем имеет поведение, определяемое реализацией (что может привести к сбою компиляции), или оно не распознается реализацией, и в этом случае оно игнорируется.Поскольку поведение, определяемое реализацией, должно быть задокументировано соответствующей реализацией, теоретически должно быть возможно определить, какие прагмы распознаются реализацией, и тогда вы можете использовать все, что не соответствует этому шаблону.На практике это редко бывает так просто, но в общем первый токен, следующий за "#pragma", будет идентифицировать компилятор или подсистему, поэтому большинство прагм, распознаваемых gcc, будут начинаться с токена GCC.(Тем не менее, существует множество устаревших прагм.)

Так что вам, возможно, придется немного поэкспериментировать, но, по крайней мере, на компиляторах, которые я использовал, строки

#pragma X_PPTRACE 0

и

#pragma X_PPTRACE 1

только что прошел препроцессор (хотя и с предупреждением -Wall), что позволило создать очень простую программу awk:

gcc -Wall -Wno-unknown-pragmas -E ... |
awk '/#pragma[[:space:]]+X_PPTRACE/{trace=$3;}trace'
0 голосов
/ 04 декабря 2018

Я придумал это, просто играя с gcc -E и awk.Я заметил, что gcc -E выводит строки формата # <linenum> "<filename>" <other stuff> при переходе в другие файлы.Таким образом, в принципе, если я могу отслеживать это имя файла, я могу распечатать строки, которые меня волнуют.

Я не разбираюсь в awk, так что может быть более эффективный способ сделать это.

gcc -E example.c | awk '
/^#/ { filename = $3 }
!/^#/ {
    if (filename == "\"example.c\"")
        print $0
}'

Если строка начинается с #, сохраните имя файла.В противном случае, если имя файла является тем, которое мне не безразлично, выведите строку.Замените example.c именем вашего файла.

Для вашего примера это выдает:

int main()
{
    printf("%s\n","hello world");
    return 0;
}

Я не уверен, что это на 100% правильно (я не знаю, могут ли быть другиестроки начинающиеся с # например).Вы можете поиграть с ним, чтобы получить то, что вы хотите.

...