Ctags: Universal ctags inserta caracteres `utf-8` no válidos para ciertos archivos

Creado en 30 jul. 2018  ·  7Comentarios  ·  Fuente: universal-ctags/ctags

(
Gracias por contactarnos.

Si informa un problema con el resultado del análisis, complete
la siguiente plantilla. Como su configuración personalizada de CTags puede
afectar los resultados, utilice siempre --options=NONE como el primero
opción al ejecutar ctags .

De lo contrario, elimine la plantilla y escriba su problema desde cero.
Los ejemplos pueden ayudar a los desarrolladores a comprender mejor su problema.

Utilice la interfaz web de GitHub y la notación de rebajas.
El uso de resultados de correo en la representación de texto roto que hace
los desarrolladores se vuelven locos.
)


El nombre del analizador:

La línea de comando que usó para ejecutar ctags:

$ ctags -R

No tengo ninguna configuración especial en .ctags ni en ningún otro lugar. Esta es una máquina virtual nueva en la que se ejecutó esta prueba.

El contenido del archivo de entrada: https://github.com/pallets/jinja/blob/master/jinja2/_identifier.py

La salida de etiquetas con la que no está satisfecho:

Universal-ctags inserta caracteres utf-8 no válidos en determinadas circunstancias.

La salida de etiquetas que espera:

Salida de etiqueta esperada con todos los caracteres válidos utf-8 .

La versión de ctags:

$ ctags --version
Universal Ctags 0.0.0(3522685), Copyright (C) 2015 Universal Ctags Team
Universal Ctags is derived from Exuberant Ctags.
Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
  Compiled: July 27 1018, 23:16:36
  URL: https://ctags.io/
  Optional compiled features: +wildcards, +regex, +iconv, +option-directory, +xpath

¿Cómo se obtienen los ctags binarios?

(
El binario ctags se basa en ubuntu-16.04 VM sin modificaciones más que instalar las bibliotecas necesarias como automate , autoreconf para compilar ctags y las bibliotecas necesarias para compilar vim basado en https://github.com/Valloric/YouCompleteMe/wiki/Building-Vim-from-source#a-for-a-debian-like-linux-distribution-like-ubuntu-type
)

@lilydjwg me señaló que ctags estaba insertando caracteres utf-8 inválidos a pesar de que el archivo que se usa para generar las etiquetas tiene todos los caracteres utf-8 válidos aquí:
https://github.com/vim/vim/issues/3213#issuecomment -406961075

La versión compilada de ctags funciona muy bien en general.

Recientemente descubrí que resulta que ctags tiene un error debido al cual el
antiguo Execuberant ctags instalado por sudo apt-get install ctags en Ubuntu
16.04 no inserta caracteres utf-8 inválidos, pero si compilo
Universal-ctags de la fuente e instalarlo según las instrucciones aquí:
https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst , es
insertará utf-8 caracteres no válidos. Aquí está la evidencia:

Con exuberant-ctags instalado usando solo sudo apt-get install ctags :

2018-07-29_19-03-44

Con Universal-ctags compilado desde la fuente (última confirmación) a partir de esta publicación,
compilado con instrucciones de aquí:
https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst :

2018-07-29_19-10-22

Esto causa muchos problemas en vim, porque si los caracteres utf-8 son válidos
pasado a vim.eval , vim.eval descansos y esto conduce a que no se devuelvan etiquetas en
todos. Actualmente, solo hay una forma de transferir datos contenidos en un viml
variable al espacio python-name , usando vim.eval . Entonces, cualquier otro complemento en
vim o si no, donde también tendrá problemas similares. @ludovicchabant para
example tuvo que posprocesar su archivo de etiquetas para detener tales problemas:
https://ludovic.chabant.com/devblog/2017/02/25/aaa-gamedev-with-vim/

También tuvo que cambiar ctrl-py-matcher para detectar este problema.
https://github.com/ludovicchabant/ctrlp-py-matcher/blob/2f6947480203b734b069e5d9f69ba440db6b4698/autoload/pymatcher.py#L22

Hay muchos otros archivos que he visto que tienen problemas similares, pero no
acabo de proporcionar uno aquí para delimitar el problema.

Supongo que esto es un error, y no espero que ctags lo haga por
diseño. ¿Se puede rectificar esto, ya que solía funcionar bien en Exuberant Ctags?
¿en qué se basa Universal-ctags?

Ref: https://github.com/vim/vim/issues/3213#issuecomment -408727629

Todos 7 comentarios

Me suena como # 1275: la nueva opción pattern-length-limit está cortando en una posición de byte arbitraria, que resulta estar en el medio de una secuencia de caracteres. Vea # 163, # 640 y # 1018.

Algo como https://github.com/universal-ctags/ctags/issues/1275#issuecomment -274489859 probablemente debería implementarse para solucionar este problema.

@ alphaCTzo7G vea # 1807, ¿eso lo soluciona correctamente?

@ b4n , gracias por su rápida respuesta ...

En el archivo que publiqué aquí _identifier.py , usando la confirmación # 1805, ctags ya no inserta caracteres / cortes no válidos en una ubicación arbitraria.

Probaré este PR en mi sistema real durante los próximos días para ver si funciona para todos mis repositorios o emite otros errores.

Como ctrlp y ctrlp-py-matcher son complementos muy populares, sería genial si # 1807 se fusionara para que vim y otros usuarios del editor de texto puedan usar ctrlp y ctrlp-py-matcher sin tener que preocuparse por este problema.

Había otro archivo que encontré que estaba causando problemas, con vim.eval , y contenía caracteres utf-8 no válidos según lo determinado por grep -axv '.*' misc.html ( misc.html en https: / /github.com/alphaCTzo7G/test). Lo que noté es que ctags insertará los caracteres invalidos utf-8 en el archivo de etiquetas de misc.html .

¿Tiene sentido que ctags detecte caracteres no válidos en archivos y, en su lugar, los reemplace con algo como lo que @tonymec sugirió aquí? (reemplace la secuencia no válida por una o más instancias del carácter (CARÁCTER DE REEMPLAZO DE U + FFFD) que está destinado exactamente a ese propósito): https://github.com/vim/vim/issues/3213#issuecomment -405211243 ?

IIUC, ctags (Exuberant ctags, quiero decir, que es solo uno de los programas ctags disponibles) se distribuye por separado de Vim (incluso si su autor conoce Bram e incluso si ocasionalmente trabajan juntos para hacer que Vim y ctags funcionen mejor juntos.

Desde el punto de vista de ctags, es legítimo tratar el texto del programa como solo cadenas de bytes: independientemente de si es UTF-8, Latin1, Latin9 o algún otro conjunto de caracteres ISO 8859, un espacio es 0x20, una pestaña dura es 0x09, un salto de línea es 0x0A posiblemente precedido por 0x0D, etc .; y un byte nulo, que sería 0x00, no debería aparecer en un archivo de texto. Ctags trata todos los programas de la misma manera, independientemente de la codificación compatible con ASCII en la que esté escrito, y por lo tanto, no necesita preocuparse por cuál es cuál. Solo para algunos juegos de caracteres extravagantes como EBCDIC, es necesario tratar el texto como definitivamente no ASCII (en EBCDIC, IIRC, AI son 0xC1-0xC9, JR son 0xD1-0xD9, SZ son 0xE2-0xE9, 0-9 son 0xF0-0xF9 , y no recuerdo cuáles son los códigos para un espacio, una pestaña, un salto de línea, un guión, un guión bajo, etc .; pero ves que desde un punto de vista ASCII es realmente extravagante).

En mi humilde opinión, en el caso de ctag, se aplica el viejo principio: basura dentro, basura fuera.

Atentamente,
Tony.

@tonymec .. tiene sentido .. Me doy cuenta de que puede haber otros programas de generación de etiquetas, pero universal-ctags es el más popular, y entre las personas que usan universal-ctags supongo que una gran parte es vim usuarios.

Entonces, me pregunto si estos 2 podrían funcionar o si tiene otras ideas sobre cómo manejar archivos que tienen caracteres utf-8 ilegales.

  1. También noté que ctags tiene esta opción de +iconv , que permite el uso de libiconv . Cuando se usa en la línea de comando iconv puede eliminar utf8 caracteres ilegales. Así que me pregunto si paso --input-enconding=utf-8 y --output-encoding=utf-8 , entonces todos los caracteres utf-8 ilegales se cambiarían a caracteres legales utf-8 .

Esto se explica en la sección 1.3.4 de https://media.readthedocs.org/pdf/ctags/latest/ctags.pdf :

Two new options have been introduced (--input-encoding=IN and --output-encoding=OUT). Using the encoding specified with these options ctags converts input from IN to OUT. ctags uses the converted strings when writing the pattern parts of each tag line. As a result the tags output is encoded in OUT encoding. In addition OUT is specified at the top the tags file as the value for the TAG_FILE_ENCODING pseudo tag. The default value of OUT is UTF-8. NOTE: Converted input is NOT passed to language parsers. The parsers still deal with input as a byte sequence. With --input-encoding-<LANG>=IN, you can specify a specific input encoding for LANG. It overrides the global default value given with --input-encoding

  1. deje que el editor maneje los caracteres utf8 ilegales. En ese caso, vim.eval tiene que ser arreglado o tiene que haber una función vimL que pueda analizar y eliminar los caracteres ilegales utf-8 antes de pasarlo a vim.eval ..

@ alphaCTzo7G Estoy de acuerdo con @tonymec y su conclusión.

Desafortunadamente, es un gran problema reconocer la codificación adecuada , e insisto en la adecuada, porque es fácil encontrar una codificación en la que la entrada sea técnicamente válida, digamos que la mayoría, si no todas, las codificaciones de 8 bits, pero sabiendo si es la correcta. uno es complicado o imposible: digamos, ¿cómo puede uno estar seguro entre, por ejemplo, ISO 8859-1 y 8859-15? Las soluciones incluyen heurística compleja sobre la frecuencia de uso y el contexto; o una idea más ingenua aplicable a algunos lenguajes como HTML sería extraer la declaración de codificación dentro del archivo, pero eso también puede ser incorrecto.

Además, ctags se encuentra en una posición difícil aquí: muchos, si no la mayoría, de los consumidores no manejan las codificaciones, y las etiquetas generadas deben coincidir a nivel de bytes. Por ejemplo, hacer grepping para un patrón de etiqueta o incluso un nombre no convertirá las codificaciones por usted, por lo que la etiqueta debe coincidir con el archivo a nivel de bytes. Era fácil cuando todo lo que teníamos que preocuparnos era ASCII, pero ya no tenemos tanta suerte ... UTF-8 no fue adoptado lo suficientemente temprano.
Esto también se aplica a la idea de reemplazar con caracteres de marcador de posición: ¿qué puede hacer el consumidor con ese carácter de reemplazo? Al menos tiene que manejarlo de una manera específica.

Sin embargo, si está satisfecho con reemplazar UTF-8 inválido con U + FFFD o eliminarlos, tal vez podría simplemente postprocesar la salida de ctags.

@ b4n , agradecemos tu comentario. De hecho, trato principalmente con archivos codificados utf-8 y tengo utf-8 codificados para los archivos que creo. Desafortunadamente, como mencionaste, utilizo bibliotecas que tienden a tener codificaciones a veces arbitrarias.

Yo uso vim-gutentags , y proporciona una funcionalidad de posprocesamiento. Si bien pude postprocesar manualmente el archivo de etiquetas para dar como resultado todos los archivos en utf-8 caracteres, cuando intenté usar la funcionalidad post-processing en vim-gutentags , no funcionó . Así que pensé que sería mejor encontrar una solución más sólida ... pero si eso no existe, tendré que investigarlo nuevamente ...

Para detectar la codificación del archivo, ¿no puede usar las bibliotecas subyacentes detrás de una de estas opciones: https://stackoverflow.com/questions/805418/how-to-find-encoding-of-a-file-in-unix -via-guiones

tales como enca , file , uchardet , enguess ? Todas estas son funciones de línea de comandos ... pero debe haber alguna biblioteca en algún lugar que pueda ser utilizada internamente por ctags quizás. Supongo que debido a la cantidad de codificaciones, como mencionaste, es posible que nunca sea posible predecir perfectamente la codificación, pero una solución simple que cubra la mayor parte puede ser mejor que nada.

Probaré el --input-encoding (and/or --input-encoding-<LANG>) and --output-encoding options .. No estoy seguro de si funcionará todo el tiempo, porque es muy posible que ciertos archivos tengan diferentes codificaciones en el mismo repositorio, a menos que ctags descubra el corrija la codificación individualmente y la escupe en el formato deseado.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

softinio picture softinio  ·  6Comentarios

blueyed picture blueyed  ·  4Comentarios

liuchengxu picture liuchengxu  ·  8Comentarios

trevordmiller picture trevordmiller  ·  9Comentarios

fommil picture fommil  ·  19Comentarios