Como interpretar intervalos de caracteres em arquivos charmap?

6

O arquivo charmap /usr/share/i18n/charmaps/UTF-8.gz tem esta linha:

<U3400>..<U343F> /xe3/x90/x80 <CJK Ideograph Extension A>

A página do mapa para charmap(5) diz apenas que isso significa um intervalo. Então eu encontrei a especificação , mas ela diz que o número no nome do personagem é supostamente estar em decimal, não em hexadecimal, e usa 3 pontos em oposição a 2 na página man. Então, como devo interpretar intervalos de caracteres em arquivos charmap? Especialmente se eu vejo algo como

<U3400>..<U3430> /xe3/x90/x80 <CJK Ideograph Extension A>

então é o intervalo em decimal ou hex?

    
por yt7b97q- 03.05.2017 / 11:20

2 respostas

5

O glibc permite intervalos decimais de três pontos (como em POSIX) e intervalos hexadecimais de dois pontos. Isso não parece estar documentado em nenhum lugar, mas podemos vê-lo no código-fonte. Isso não é um comportamento portátil definido, mas uma extensão da glibc e possivelmente de outros. Se você está escrevendo seus próprios arquivos, use decimal.

Vamos confirmar que esse é o comportamento real da glibc.

Ao processar um intervalo, o glibc usa :

   if (decimal_ellipsis)
     while (isdigit (*cp) && cp >= from)
       --cp;
   else
     while (isxdigit (*cp) && cp >= from)
       {
         if (!isdigit (*cp) && !isupper (*cp))
           lr_error (lr, _("\
 hexadecimal range format should use only capital characters"));
         --cp;
       }

em que isxdigit valida um dígito hexadecimal e isdigit decimal. Posteriormente, ele ramifica a conversão para inteiro da substring consumida da mesma maneira e continua como esperado. Anteriormente, determinou o tipo de reticências em questão durante a análise , obtida da lexer .

O arquivo de mapeamento UTF-8 é gerado mecanicamente do UnicodeData.txt do unicode.org, criando intervalos de 64 codepontos com dois pontos. Suponho que essa auto-geração conveniente esteja pelo menos parcialmente por trás da extensão, mas não sei. Versões anteriores da glibc também geraram, mas usando um programa diferente e o mesmo formato.

Mais uma vez, isso não parece estar documentado em lugar algum, e como é gerado automaticamente próximo de onde é usado, é possível que ele mude, mas imagino que seja estável.

Se receber algo como

<U3400>..<U3430> /xe3/x90/x80 <CJK Ideograph Extension A>

então é um intervalo hexadecimal , porque usa dois pontos. Com três pontos, seria um intervalo decimal POSIX.

Se você estiver em outro sistema que não tenha essa extensão, seria apenas um erro de sintaxe. Um arquivo de mapa de caracteres portátil deve usar apenas os intervalos decimais.

    
por 03.05.2017 / 12:10
-1

A parte em parênteses angulares ( <U3400> ) é o nome do caractere UCS e os dígitos estão em hexadecimal , como você pode ver ao comparar o nome simbólico <ESC> e seu equivalente UCS <U001B> na especificação vinculada.

A próxima parte é a codificação. Como você pode ver na especificação, ele tem 3 formas:

\d123 where 123 is decimal,
\x123 where 123 is hexadecimal, and
3 where 123 is octal.

Portanto, <U3400> é representado pela seqüência de bytes hexadecimais e3 90 80 , <U3401> é representada pela seqüência de bytes hexadecimais e3 90 81 e assim por diante.

Se você comparar isso com a descrição da codificação UTF-8 , verá que corresponde: Seqüência de 3 bytes como bits é

11100011  10010000  10000000

e se você comparar isso com

1110xxxx  10yyyyyy  10zzzzzz

você vê que o número codificado é xxxx yyyy yyzz zzzz , ou 0011 0100 0000 000 ou 3400 em hexadecimal.

    
por 03.05.2017 / 12:13