Частично предварительно обработать исходный файл C или C ++? - PullRequest
7 голосов
/ 26 июня 2011

Есть ли способ частичной предварительной обработки исходного файла C или C ++? Под «частично предварительной обработкой» я подразумеваю расширение некоторых, но не всех директив #include. Например, я хотел бы расширить #includes, указывая на заголовки моего проекта, но не #includes, указывая на заголовки других библиотек.

Я попытался сделать это, запустив gcc -E только с флагами -I для заголовков моего проекта, а не с флагами -I для библиотек, но это не работает, потому что gcc выдает ошибку при обнаружении # Включите, он не может расширяться.

РЕДАКТИРОВАТЬ : Меня не особо волнует поведение препроцессора в отношении расширения макроса.

Ответы [ 5 ]

6 голосов
/ 26 июня 2011

Препроцессор C не достаточно умен, чтобы делать это самостоятельно.Если вас интересует только #include, вам нужно просто запустить свой собственный инструмент (скажем, в Perl) для обработки исходных файлов, расширяя #include интересующие вас строки и игнорируя остальные.

Этот скрипт ставит префикс неинтересных строк заголовка с // Ignored:

#!/usr/bin/perl

use warnings;
use strict;

my @uninteresting = qw(iostream vector map);
my $uninteresting = join '|', @uninteresting;

while (<>) {
    s%(#include <(?:$uninteresting)>)%// Ignored $1%;
    print;
}

Теперь вы можете сделать:

cat sourcefile.cpp | perl ignore-meh.pl | g++ -E

А если вы хотите по-настоящему вычурно:

#!/usr/bin/perl

use warnings;
use strict;

while (<>) {
    s%// Ignored (#include <[^>]+>)%$1%;
    print;
}

Теперь вы можете сделать:

cat sourcefile.cpp | perl ignore-meh.pl | g++ -E | perl restore-meh.pl
3 голосов
/ 26 июня 2011

#include, который вы не хотите расширять, вы можете заменить на что-то вроде $$$include (короче говоря, это не может понять препроцессор). Желательно сначала скопировать исходные файлы во временные файлы, а затем запустить gcc -E <filename>;. Как только вы закончите, снова замените исходные файлы.

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

2 голосов
/ 26 июня 2011

Используйте -nostdinc для gcc (или cpp ).

gcc ... -nostdinc ...
2 голосов
/ 26 июня 2011

Как насчет этого:

#include <always_include.h>
#include <another_always_include.h>

#ifdef PART_2_INCLUDES
 #include <part2.h>
 #include <part2a.h>
#endif

#ifdef PART_3_INCLUDES
 #include <part3.h>
 #include <part3a.h>
#endif

...

Затем, чтобы скомпилировать все, gcc -DPART_2_INCLUDES -DPART_2_INCLUDES ... Или, поскольку, как обычно, все должно быть включено по умолчанию, а некоторые элементы не включены, это особый случай, обратныйсмысл тестов:

#include <always_include.h>
#include <another_always_include.h>

#ifndef PART_2_INCLUDES_OMITTED
 #include <part2.h>
 #include <part2a.h>
#endif
...
0 голосов
/ 26 июня 2011

В общем случае частичное расширение заголовка не имеет смысла. Рассмотрим следующий пример:

#include <limits.h>

#if UINT_MAX > 0xffffffff
# include "fasthash_64.h"
#elif UINT_MAX == 0xffffffff
# include "hash.h"
#else
# error "int too small for hash implementation."
#endif
...