imprimindo “forma canônica de escape de impressão” de uma string

5

Estou tentando escrever uma função, vou chamá-la de escape , que se comportará assim:

% IFS=$' \t\n
escape () {
    local varname=$1
    local value="$2"
    print -n "$varname=\$'"
    # ???
    print "'"
}
0' % escape FOO $IFS FOO=$' \t\n
% escape HELLO $( echo 'hello world' )
HELLO=$'hello world\n'
% escape SUBSEP $( perl -e 'print $;' )
SUBSEP=$'4'
% abc=$'122232'
% print -n $abc
a
b
c
% escape ABC $abc
ABC=$'a\nb\nc\n'
0'

Em outras palavras, escape pega dois argumentos, e então, pegando o primeiro para ser um nome de variável, imprime uma linha um código-fonte zsh no qual uma variável daquele nome é atribuída uma string $'' -quoted, "canonically print -escaped", de tal forma que, ao avaliar essa linha de código fonte, a variável nomeada pelo primeiro argumento terá o segundo argumento como seu valor. (Tenho certeza que foi tão claro quanto a lama, então eu vou dar mais exemplos de como escape deve se comportar no final deste post.)

Veja uma implementação incompleta da função escape :

% IFS=$' \t\n
escape () {
    local varname=$1
    local value="$2"
    print -n "$varname=\$'"
    # ???
    print "'"
}
0' % escape FOO $IFS FOO=$' \t\n
% escape HELLO $( echo 'hello world' )
HELLO=$'hello world\n'
% escape SUBSEP $( perl -e 'print $;' )
SUBSEP=$'4'
% abc=$'122232'
% print -n $abc
a
b
c
% escape ABC $abc
ABC=$'a\nb\nc\n'
0'

A parte que falta (indicada por ??? ) é onde o conteúdo de $value é "canonicamente print -escaped". O qualificador "canônico" é necessário porque há muitos caracteres para os quais há pelo menos algumas representações que print os reconhecerão como. Por exemplo, print sabe \n também como 2 e como \C-J . Nesse caso, \n é a forma canônica. Em geral, as seqüências de escape padrão \n , \r , \t , etc. são as formas canônicas de seus caracteres correspondentes. O formulário de exibição padrão de caracteres ASCII imprimíveis (por exemplo, A , = , 9 ) é canônico. Para os caracteres restantes, se houver uma escolha de representação, eu escolheria o formulário octal como o canônico (pelo menos até 7 ; não tenho certeza de como $'' lida com códigos mais altos), mas isso a preferência não é strong.

Claro, não estou querendo ver código para implementar essa funcionalidade "do zero", por assim dizer. Em vez disso, espero que já exista um utilitário para executar essa conversão de bytes em uma representação de texto print -escaped.

Todos os ponteiros seriam muito apreciados!

Aqui estão mais alguns exemplos de escape em ação (hipoteticamente):

%pre%     
por kjo 24.04.2012 / 02:24

1 resposta

4

Estou pensando no sinalizador de expansão do parâmetro q , especificamente a variante qqqq .

FOO=${(qqqq)IFS}

Assim, você pode escrever sua função dessa maneira (usando o P flag para expandir o parâmetro cujo nome é $2 ):

escape () {
  print -r -- "$1=${(Pqqqq)2}"
}
    
por 24.04.2012 / 02:27

Tags