Выполнять только препроцессор, но только для определенных операторов
У меня есть ряд операторов отладки, определенных в программе, и я хочу иметь возможность сделать копию источника без этих утверждений.
Для этого я впервые рассмотрел аргумент командной строки GCC -E, в котором работает только препроцессор, однако это намного больше, чем я хотел, расширяя включенные файлы и добавляя операторы #line.
Например:
#include <stdio.h>
#ifdef DEBUG
#define debug( s ) puts ( s );
#else
#define debug( s )
#endif
int main( int argc, char* argv[] )
{
debug( "Foo" )
puts( "Hello, World!" );
return 0;
}
Я хочу, чтобы это было обработано:
#include <stdio.h>
int main( int argc, char* argv[] )
{
puts( "Hello, World!" );
return 0;
}
Тогда я мог бы убрать это с помощью чего-то вроде астиля, и никакой ручной работы не потребуется, чтобы получить именно то, что я хочу.
Есть ли какая-либо директива, которую я пропускаю для GCC или есть инструмент, способный это сделать?
Ответы
Ответ 1
Если -E
не помогает, попробуйте использовать -fdump-tree-all
, и если вы не видите, что вы хотите, чтобы он не был доступен (или) не был предоставлен GCC
.
OTOH, этот вопрос обсуждался в SO следующим образом, пожалуйста, обратитесь к ниже, чтобы получить некоторые идеи.
Надеюсь, что это поможет!
Hi Mat,
Я видел ваш комментарий к @nos. Но у меня есть один такой script удобный и, таким образом, делясь с вами. Вы можете попробовать прочитать мой ответ по аналогичному вопросу здесь
Скопируйте приведенный ниже код в файл, скажем convert.sh
. Назначьте разрешение на выполнение этого файла chmod +x convert.sh
и запустите его следующим образом:
$./convert.sh <filename>.c
$cat filename.c.done
<filename>.c.done
будет иметь то, что вам нужно!
#!/bin/bash
if [[ $# -ne 1 || ! -f $1 ]] ; then
echo "Invalid args / Check file "
exit
fi
file_name=$1
grep '^\s*#\s*include' $file_name > /tmp/include.c
grep -Pv '^\s*#\s*include\b' $file_name > /tmp/code.c
gcc -E /tmp/code.c | grep -v ^# > /tmp/preprocessed.c
cat /tmp/include.c > $file_name.done
cat /tmp/preprocessed.c >> $file_name.done
Надеюсь, это поможет!
Ответ 2
gcc -E -nostdinc test.c
производит
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"
# 9 "test.c"
int main( int argc, char* argv[] )
{
puts( "Hello, World!" );
return 0;
}
и ошибка для stderr
test.c:1:19: error: no include path in which to search for stdio.h
Вы можете легко отфильтровать # строки... и повторно добавить включенные.
Ответ 3
Можно использовать такие инструменты, как unifdef, unifdefall - удалить условные обозначения препроцессора из кода. (Запустите "препроцессор" для GCC)
Ответ 4
Нет прямого способа сделать это с помощью препроцессора gcc, хотя если вы включите только заголовки системы, вам может быть повезло с gcc -E -nostdinc
.
Однако вы можете прокомментировать директивы #include
и другие директивы препроцессора, которые вы не хотите обрабатывать, и запустить код через препроцессор (gcc -E
или cpp
), таким образом, только макрос, который вы хотите расширенные (те, которые не прокомментированы) расширяются.
Ответ 5
Я знаю, что вопрос старый, но теперь у него есть ответ. "C Partial Preprocessor" выполняет именно это.
http://www.muppetlabs.com/~breadbox/software/cppp.html
Для справки, если кто-то еще удивляется (я нашел и нашел эту страницу).