Найти другой способ написания __unix__
.Возможна следующая версия:
#define C(x,y) x##y
#define UNIX_ C(__un,ix__)
#if !defined(__linux__) && !UNIX_
Этот хак не будет работать с defined
, поскольку defined(UNIX_)
проверяет, определено ли UNIX_
, а не определено, на что оно распространяется.Но обычно встроенные символы, такие как __unix__
, фактически определяются как 1, если они определены, а директива #if
обрабатывает любой идентификатор, который не является # define'd, как если бы он был 0, что означает, что вы обычно можетеоставьте использование x
вместо defined(x)
.(Однако, если результат был #define x 0
, он даст другие результаты, так что это не совсем идеальная замена.)
Flex, как и многие приложения m4, переопределяет кавычки m4быть [[
и ]]
.И гибкий багги, и исправленные версии заменяют эти кавычки довольно сложной последовательностью, которая эффективно заключает в кавычки.Тем не менее, версия с ошибками не заключает в кавычки пользовательский текст, поэтому подстановки макросов будут выполняться в пользовательском тексте.(Как уже упоминалось, именно поэтому __unix__
становится пустой строкой.
В версиях flex, в которых пользовательский текст не заключен в кавычки, можно вызывать макрос m4, который переопределяет кавычки. Эти новые кавычкиЗатем можно использовать метки для заключения в кавычки строки #if
, предотвращая подстановку макросов __unix__
. Однако определение кавычки должно быть восстановлено, иначе будет полностью нарушена обработка макроса остальной части файла. Это немного сложно, потому что этоневозможно написать [[
. (Flex заменит его другой строкой.)
Кажется, что сработает следующее. Обратите внимание, что вызовы макросов помещаются внутри комментариев C. Макросы changequote будут расширены допустая строка, если они раскрываются. Но в гибких версиях начиная с v2.6.2 предоставленный пользователем текст заключен в кавычки, поэтому макросы changequote не будут расширены. Помещение их в комментарии скрывает их от компилятора C.
%{
/*m4_changequote(<<,>>)<<*/
#if !defined(__linux__) && !defined(__unix__)
/*>>m4_changequote(<<[>><<[>>,<<]>><<]>>)*/
/* Maybe on windows */
#endif
(Макрос m4, который изменяет кавычки, changequote
, но flex вызывает m4
с -P
флаг, который изменяет встроенные функции, такие как changequote
на m4_changequote
.Во втором вызове changequote два [
, составляющие знак [[
, по отдельности заключаются в временные кавычки <<
, что скрывает их от кода в flex, который изменяет использование [[
.)
Я не знаю, насколько надежен этот хак, но он работал на тех версиях flex, которые у меня были на моей машине, включая 2.5.4 (до M4), 2.5.39 (глючит), 2.6.1 (с ошибками), 2.6.2 (несколько отлажены) и 2.6.4 (более отлажены).