Есть ли какой-либо синтаксис m4, который эквивалентен этому препроцессору C?
#if defined A || defined B
do something
#endif
Есть ли какой-либо синтаксис m4, который эквивалентен этому препроцессору C?
#if defined A || defined B
do something
#endif
Короткий ответ: нет.
Длинный ответ:
define(`defined', `ifelse($1()$1, `$1()$1', ``0'', ``1'')')
ifelse(eval(defined(`A') || defined(`B')),
1,
``At least one is defined'',
``Neither are defined'')
Нет разумных способов проверить наличие определенного макроса в m4, поэтому вам придется прибегнуть к хакам, подобным приведенным выше.
ifelse
проверяет равенство двух строк. В макросе defined
я дважды расширил макрос в $1
(один раз как $1()
, один раз как $1
). Я сравниваю его с $1()$1
как строку, поэтому, если он не расширяется, он будет сравниваться с правдой. Причина указания макросов двумя разными способами заключается в том, что A
может быть определено как ``A''
или ``A()''
, что в противном случае привело бы к ложным отрицательным результатам при использовании этого метода для проверки того, определен ли он.
Затем я использую этот макрос defined
в eval
, чтобы добавить логику ||
сверху.
defined
в своем документе, вы можете дать макросу другое имя.defined
не будет работать в макросах, определенных для расширения до синтаксических маркеров без кавычек, таких как (
, ,
или )
.defined
также никогда не вернется. (По сути, поймите, что подобный хак все еще фактически выполняет макрос.)Хотя последние 2 пункта - это то, что вы ожидаете от любой ifelse
проверки макроса, может быть не интуитивно ожидать этого от макроса, предназначенного для проверки того, определен ли другой макрос.
Я бы предпочел, чтобы вы сначала определили переменные с некоторым значением по умолчанию и просто избегали проблемы проверки того, определено ли оно или нет.
Это сделать намного проще:
# Define this right off the bat:
define(`A', ``0'')
# Maybe later this line will come up...
# Quotes around the A are mandatory
define(`A', ``1'')
# Then soon after that, you can check:
ifelse(A, `0', , ``hey, A is nonzero!'')
||
— проверьте такжеifelse
иeval
— несколько полезных заметок здесь: mbreen.com/m4.html< /а> - person Paul R   schedule 15.09.2015ifelse(eval(A==1) || eval(B==1),1, echo true, echo false )
- person xor76rox   schedule 15.09.2015||
должен быть внутриeval
:ifelse(eval(A==1 || B==1), 1, echo true, echo false )
- person Paul R   schedule 15.09.2015m4:test.m4:7: bad expression in eval (bad input): 1==1 || B==1
- person xor76rox   schedule 16.09.2015