Как определить макрос M4, который принимает varargs?

Как определить макрос M4, который принимает переменное количество аргументов и обрабатывает каждый аргумент? Я просмотрел макросы "shift" и "foreach (из примеров)", но, похоже, не могу собрать свой собственный макрос, используя их. Спасибо за любую помощь.

define(UL, `wrap each arg in <li> tag, then wrap the whole output in <ul>')

UL(foo, bar, baz) #returns <ul><li>foo</li><li>bar</li><li>baz</li></ul>

m4
person rebnoob    schedule 05.06.2013    source источник


Ответы (1)


Я предложу это как решение, хотя я не гарантирую, что оно не содержит ошибки цитирования.

define(`UL',`<ul>IT($@)<\ul>')dnl
define(`LI',`ifelse(`$1',`', `', `<li>`$1'<\li>')')dnl
define(`IT',`ifelse(`$#', `0',, `$#', `1',`LI(`$1')', 
    `LI(`$1')IT(shift($@))')')dnl
dnl
UL(foo,bar,baz)
UL(`UL',`LI',`IT')
UL(``UL'',``LI'',``IT'')

Для потомков, вот мое оригинальное решение, которое, безусловно, содержит ошибку цитирования:

define(`UL',`<ul>IT($@)<\ul>')dnl
define(`LI',`ifelse(`$1',`', `', `<li>$1<\li>')')dnl
define(`IT',`ifelse(`$#', `0',, `$#', `1',`LI(`$1')', 
    `LI(`$1')IT(shift($*))')')dnl
dnl
UL(foo,bar,baz)
UL(`UL',`LI',`IT')
UL(``UL'',``LI'',``IT'')

В первом решении окончательный вызов UL не совсем то, что я ожидаю, но я настолько не уверен в правилах цитирования m4, что действительно не знаю, чего ожидать, поэтому я подозреваю, что есть ошибка цитирования. Помощь приветствуется.

person William Pursell    schedule 06.06.2013
comment
Потрясающий! Любые намеки на то, что здесь происходит? Огромное спасибо! - person rebnoob; 07.06.2013
comment
UL помещает <ul></ul> тегов вокруг списка аргументов, LI помещает <li></li> тегов вокруг своего аргумента, а IT выполняет итерацию по списку. - person William Pursell; 07.06.2013
comment
foo, bar, baz также должны заключаться в кавычки, потому что они могут быть именами макросов. - person mug896; 18.07.2020