A maneira mais simples de recuar alguma coisa é usar espaços, não abas. Especialmente não guias com uma largura não padrão (na medida em que há uma largura padrão para guias, é 8).
A segunda maneira mais simples de recuar algo com guias é gerar um arquivo com espaços e chamar unexpand
para substituir espaços por tabulações.
Dito isto, você pode fazer isso em m4, mas terá que se familiarizar mais com isso. Construa suas expressões de forma incremental: consiga uma peça para trabalhar e passe para a próxima.
forloop
não é uma macro m4 padrão. Acho que você está falando da macro forloop
apresentada no manual do GNU m4 . Este é um código de exemplo que vem com o GNU m4 (o manual não deixa isso muito claro); para usá-lo em seu código, você precisa incluí-lo explicitamente. Distribuições podem ou não ser enviadas, então é melhor distribuí-lo com seu código.
Existem vários problemas de sintaxe no seu código.
- Você deixou a chamada para
forloop
fora de qualquer cotação, por isso é avaliada no momento em quedefine
é avaliado, e não no momento em quedebug_macro
é avaliado. - A macro
ifelse
não escolhe com base no valor do primeiro argumento sozinho, compara seus dois primeiros argumentos - é mais uma macro de caso: a chamada deve serifelse(…, 0, 0, 1)
ouifelse(… == 0, 1, 0, 1)
. -
#
inicia um comentário. M4 ignora tudo depois de um comentário. Altere o delimitador de comentários enquanto você defina a macrodebug_macro
.
O código a seguir funciona desde que o argumento não seja muito longo:
include('/usr/share/doc/m4/examples/forloop.m4')dnl
changecom()dnl
define('debug_macro', '
#ifndef $1_DEBUG
#define $1_DEBUG''forloop('i','1',eval(5-(len($1)/4+ifelse(eval(len($1)%4), 0, '0', '1'))),' ')0
#endif
')dnl
changecom('#')dnl
Com um argumento que faz com que o índice de loop máximo seja igual a 0 ou menos, o loop é executado cerca de 2 32 vezes (m4 usa aritmética de módulo de 32 bits). Você precisa de um teste adicional neste caso. Aqui está o código que insere uma única guia quando o argumento é muito longo.
include('/usr/share/doc/m4/examples/forloop.m4')dnl
changecom()dnl
define('debug_macro', '
#ifndef $1_DEBUG
#define $1_DEBUG''forloop('i', '1', ifelse(eval(len($1) >= 16), 1, 1, eval(5-(len($1)/4+ifelse(eval(len($1)%4), 0, '0', '1')))),' ')0
#endif
')dnl
changecom('#')dnl