m4 macro usando número variável de abas para alinhar uma coluna

2

Esta é a macro que tenho até agora:

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')),'   ')dnl'0
#endif

')

O objetivo é colocar o número correto de guias entre os caracteres _DEBUG e 0 para que todos eles se alinhem. Pode estar faltando parênteses ou citações, mas espero que você tenha a ideia de para onde estou indo.

Estou usando o Xcode e tenho minhas guias definidas como 4. Aqui estão as alterações que fiz para acomodar isso:

divert('-1')
# forloop(var, from, to, stmt)
define('forloop',
'pushdef('$1', '$2')_forloop('$1', '$2', '$3', '$4')popdef('$1')')
define('_forloop',
'$4''ifelse($1, '$3', ,
'define('$1', incr($1))_forloop('$1', '$2', '$3', '$4')')')
divert''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 > 1), 0, '0', '1')))),'   ')0
#endif

')
changecom()dnl

Como não encontrei o 'forloop.m4' no meu sistema, acabei de incluí-lo. A divisão por 4 rodadas, então eu adicionei a verificação para quando o resto é maior que 1. Eu também mudo a execução de espaços para um único caractere de tabulação.

Para os interessados, eu uso essa macro para definir as constantes que uso para ativar a depuração de diferentes áreas do meu aplicativo. Este arquivo é verificado no git. Existe então um arquivo pessoal e não verificado que se parece com isso:

//#define NETWORK_DEBUG  1

O arquivo está incluído no arquivo myapp.pch antes de incluir o arquivo acima. Dessa forma, cada programador pode ter suas próprias áreas de depuração ativadas ou desativadas conforme desejado.

    
por MyTallest 19.12.2014 / 22:07

1 resposta

0

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 que define é avaliado, e não no momento em que debug_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 ser ifelse(…, 0, 0, 1) ou ifelse(… == 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 macro debug_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
    
por 22.12.2014 / 01:31