Ниже приведена опечатка для C ++ include guard. Оба должны читать _MYFILE_H_
,
#ifndef _MYFILE_H_
#define _MYFLIE_H_
Как бы вы предложили поискать в некоторых заголовочных файлах опечатку, подобную этой, с помощью GNU coreutils (например, grep, awk)?
Вы могли бы использовать awk
:
{
if ($1 == "#ifndef") { was_ifdef = 1; def = $2 }
else if ($1 == "#define" && was_ifdef)
{
if ($2 != def) printf("Mismatch in %s: expected %s found %s\n", FILENAME, def, $2);
}
else was_ifdef = 0;
}
Могут быть более умные способы сделать это, но это (для меня) довольно ясно и легко.
Примечание: это покажет «ложные срабатывания», если файл содержит что-то вроде
#ifndef FOO_DEFINED
typedef int foo;
#define FOO_DEFINED
#endif
grep
само по себе здесь не сработает, потому что регулярные выражения недостаточно мощны, чтобы соответствовать набору строк, которые вы описываете.
В частности, язык всех строк вида
#ifndef X
#define Y
куда X
≠ Y
это не обычный язык. Вы можете доказать это, используя теорему Майхилла-Нерода (поскольку любые две строки вида #ifndef X
для разных вариантов X
попадают в различные классы эквивалентности отношения различимости). В результате нет никакого способа написать регулярное выражение, которое может соответствовать строкам этой формы, и так как grep
использует чисто математические регулярные выражения, нет возможности использовать grep
Для решения этой проблемы.
Извините за отрицательный результат, но я надеюсь, что это поможет!
Несколько команд Sed могут сделать свое дело.
for FILENAME in ./*.h; do
[[ $(sed -n '1p' "$FILENAME" | sed -e 's/#ifndef //') != $(sed -n '2p' "$FILENAME" | sed -e 's/#define //') ]] && echo "$FILENAME"end
Проблема с этой реализацией заключается в том, что над защитой не может быть заголовка авторского права.
И я вполне уверен, что это можно было бы написать более кратким.