Implementa a inclusão de outro arquivo em um fluxo (leia de stdin)

1

Antecedentes

Estou enfrentando o seguinte problema: Insisto em usar m4_include([some/file.m4]) no meu arquivo configure.ac, em que alguns arquivos / file.m4 contêm padrões como 'AC_INIT' e 'LT_INIT' que são necessários para que o libtoolize funcione. Em outras palavras, eu preciso configurar.ac para ser pré-processado por m4 antes libtoollize alimenta-lo para sed procurando esses padrões.

NÃO quero gerar o configure.ac (se puder evitá-lo). O único gancho que libtoolize fornece que pode me ajudar é que eles procuram pela variável de ambiente SED e usam isso em vez de / bin / sed quando encontrados.

Eu escrevi um script de shell que analisa os argumentos do sed e os passa para o verdadeiro sed. Infelizmente, libtoolize concatena m4local.ac e configure.ac e alimenta isso para $ SED em algum momento, então, procurar por um arquivo de entrada chamado 'configure.ac' falha. No entanto, depois de analisar os argumentos passados para $ SED eu posso apenas concatenar todos os arquivos de entrada e / ou stdin, porque no final ele tem que funcionar lendo de um fluxo (stdin) de qualquer maneira.

Problema restante

O problema que estou enfrentando, portanto, é o seguinte:

Meu script deve ler stdin e gravar em stdout, até encontrar uma linha como m4_include([cwm4/configure_ac_top.m4]) , que deve então engolir e, em vez disso, inserir o conteúdo de cwm4 / configure_ac_top.m4, nenhum outro pré-processamento de m4 é necessário, apenas os includes vai fazer. De fato, como o sed também é usado para inúmeras outras pequenas coisas, seria absolutamente perigoso fazer qualquer outro pré-processamento do que o do m4_include. No entanto, também preciso que ele seja recursivo: se um arquivo incluído contiver uma linha m4_sinclude([lt_init.m4]) , esse arquivo também precisará ser incluído.

Eu encontrei várias perguntas e suas respostas neste site que perguntam como inserir um arquivo em outro, mas o nome do arquivo a ser inserido é conhecido (não lido no arquivo original), não é recursivo e em muitos casos não estava lendo de stdin (mas do primeiro, conhecido, arquivo pelo nome).

    
por Carlo Wood 27.01.2017 / 22:01

1 resposta

1

No final, resolvi isso usando m4. Para fazer qualquer comando 'sed' que possa ser lançado neste trabalho, o m4 não deve fazer qualquer coisa exceto processar as macros do m4_include (), embora uma vez feito isso ele possa assumir que estamos realmente processando m4 entrada e fazer mais, como remover citações e, claro, inclusão recursiva etc, é ok.

Então, o que eu faço é substituir todas as ocorrências de 'm4_' no fluxo de entrada com alguma string mágica (xyzzy), altere as aspas para none inserindo um m4_changequote(,) no início e canalize o resultado em m4. Isso garante que o m4 não fará absolutamente nada com a entrada. No entanto, eu quero processar m4_include , então, antes de canalizá-lo para o m4, eu substituo xyzzyinclude([]) por m4_changequote([,])m4_include([])m4_changequote(,) , fazendo com que o m4 processe o arquivo incluído com a cotação correta. Finalmente, a saída de m4 -P é processada por sed novamente, substituindo a string mágica por 'm4 _'.

magic="xyzzy"
cat first.txt | /bin/sed "s/m4_/$magic/g;s/$magic""include(\[\([^]]*\)\])/m4_changequote([,])m4_include()m4_changequote(,)/g;1s/^/m4_changequote(,)/" | m4 -P - | sed "s/$magic/m4_/g"

Note que as restrições na string mágica são: ela não pode conter (a substring) m4_, ela não pode começar com um sublinhado ou com 4_ nem terminar em um m ou m4. Ele também não deve terminar com o mesmo caractere de início. Finalmente, se ocorrer no fluxo de entrada, ele não deverá prejudicar o propósito do script quando ele for substituído por 'm4 _'.

Tendo a seguinte entrada:

A1 m4_dnl Nothing should be changed.
A2 m4___file__
m4_include([second.txt])
A4 m4___line__
A5 [' Unmatched quoting: no problem.

e

This is second.txt, an m4 file.
The wizard said xyzzy,
and nothing happened.

Usando uma string 'mágica' de 'xyzzy', obtemos o resultado:

A1 m4_dnl Nothing should be changed.
A2 m4___file__
This is second.txt, an m4 file.
The wizard said m4_,
and nothing happened.

A4 m4___line__
A5 [' Unmatched quoting: no problem.

Para o propósito de libtoolize, usando um configure.ac que use m4_include's, isso é suficiente. Para o script completo do SED, consulte o link

Edit: acabou por não ser suficiente; Eu também tive que substituir m4 como um hack com link

    
por 27.01.2017 / 23:53