Ctags: Universal ctags insère des caractères 'utf-8' invalides pour certains fichiers

Créé le 30 juil. 2018  ·  7Commentaires  ·  Source: universal-ctags/ctags

(
Merci de nous contacter.

Si vous signalez un problème avec la sortie d'analyse, veuillez remplir
le modèle suivant. Comme votre configuration de CTags personnalisés peut
affecter les résultats, veuillez toujours utiliser --options=NONE comme premier
option lors de l'exécution de ctags .

Sinon, supprimez le modèle et rédigez votre problème à partir de zéro.
Des exemples peuvent aider les développeurs à mieux comprendre votre problème.

Utilisez l'interface Web GitHub et la notation Markdown.
Utilisation du rendu de texte cassé des résultats de messagerie qui rend
les développeurs deviennent fous.
)


Le nom de l'analyseur :

La ligne de commande que vous avez utilisée pour exécuter ctags :

$ ctags -R

Je n'ai aucune configuration spéciale dans .ctags ou ailleurs. Il s'agit d'une nouvelle machine virtuelle sur laquelle ce test a été exécuté.

Le contenu du fichier d'entrée : https://github.com/pallets/jinja/blob/master/jinja2/_identifier.py

Les balises dont vous n'êtes pas satisfait :

Universal-ctags insère des caractères utf-8 invalides dans certaines circonstances.

La sortie des balises que vous attendez :

Sortie de balise attendue avec tous les caractères valides utf-8 .

La version 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

Comment obtenez-vous le binaire ctags :

(
Le binaire ctags est construit sur ubuntu-16.04 VM sans aucune modification autre que l'installation des bibliothèques nécessaires telles que automate , autoreconf pour compiler ctags et les bibliothèques nécessaires pour compiler vim basé sur https://github.com/Valloric/YouCompleteMe/wiki/Building-Vim-from-source#a-for-a-debian-like-linux-distribution-like-ubuntu-type
)

@lilydjwg me fit remarquer que ctags insérait invalide utf-8 caractères même si le fichier utilisé pour générer les balises ont tous valides utf-8 caractères ici:
https://github.com/vim/vim/issues/3213#issuecomment-406961075

La version compilée de ctags fonctionne très bien en général.

Récemment découvert, qu'il s'avère que ctags a un bogue à cause duquel le
ancien Execuberant ctags installé par sudo apt-get install ctags sur Ubuntu
16.04 n'insère aucun caractère utf-8 invalide, mais si je compile
Universal-ctags de la source et n'est pas basé sur les instructions ici :
https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst , il
insérera des caractères utf-8 invalides. Voici la preuve :

Avec exuberant-ctags installé en utilisant seulement sudo apt-get install ctags :

2018-07-29_19-03-44

Avec Universal-ctags compilé à partir des sources (dernier commit) à partir de ce post,
compilé avec les instructions d'ici :
https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst :

2018-07-29_19-10-22

Cela cause beaucoup de problèmes dans vim, car si des caractères utf-8 invalides sont
passé à vim.eval , vim.eval casse et cela conduit à aucune balise retournée à
tous. Actuellement, il n'y a qu'une seule façon de transférer les données contenues dans un viml
variable à l'espace python-name , en utilisant vim.eval . Ainsi, tout autre plugin dans
vim ou ailleurs où aura également des problèmes similaires. @ludovicchabant pour
exemple a dû post-traiter son fichier de balises pour arrêter de tels problèmes :
https://ludovic.chabant.com/devblog/2017/02/25/aaa-gamedev-with-vim/

Il a également dû changer ctrl-py-matcher pour attraper ce problème.
https://github.com/ludovicchabant/ctrlp-py-matcher/blob/2f6947480203b734b069e5d9f69ba440db6b4698/autoload/pymatcher.py#L22

Il y a plusieurs autres fichiers que j'ai vu qui ont des problèmes similaires, mais je
viens d'en fournir un ici pour affiner le problème.

Je suppose qu'il s'agit d'un bug, et je ne m'attends pas à ce que ctags le fasse en
conception. Cela peut-il être rectifié, car cela fonctionnait bien dans Exuberant Ctags
sur quoi Universal-ctags est-il basé ?

Réf : https://github.com/vim/vim/issues/3213#issuecomment-408727629

Tous les 7 commentaires

Cela ressemble à #1275 pour moi : la nouvelle option pattern-length-limit coupe à une position d'octet arbitraire, qui se trouve au milieu d'une séquence de caractères. Voir #163, #640 et #1018.

Quelque chose comme https://github.com/universal-ctags/ctags/issues/1275#issuecomment -274489859 devrait probablement être implémenté pour résoudre ce problème.

@alphaCTzo7G voir #1807, est-ce que cela le résout correctement pour vous ?

@b4n , merci pour votre réponse rapide...

Sur le fichier que j'ai posté ici _identifier.py , en utilisant le commit #1805, ctags n'insère plus de caractères/coupures invalides à un emplacement arbitraire.

Je vais essayer ce PR sur mon système réel au cours des prochains jours pour voir s'il fonctionne pour l'ensemble de mes référentiels ou émet d'autres erreurs

Comme ctrlp et ctrlp-py-matcher sont des plugins très populaires, ce serait génial si #1807 est fusionné afin que vim et d'autres utilisateurs d'éditeurs de texte puissent utiliser ctrlp et ctrlp-py-matcher sans avoir à vous soucier de ce problème.

Il y avait un autre fichier que j'ai trouvé causait des problèmes, avec vim.eval , et il contenait des caractères utf-8 invalides comme déterminé par grep -axv '.*' misc.html ( misc.html dans https :/ /github.com/alphaCTzo7G/test). Ce que j'ai remarqué, c'est que ctags insère les caractères invalides utf-8 dans le fichier de balises à partir de misc.html .

Est-il logique que ctags détecte les caractères invalides dans les fichiers et les remplace à la place par quelque chose comme ce que @tonymec avait suggéré ici ? (remplacez la séquence invalide par une ou plusieurs instances du caractère (U+FFFD CARACTÈRE DE REMPLACEMENT) qui est destiné exactement à cette fin.): https://github.com/vim/vim/issues/3213#issuecomment -405211243 ?

IIUC, ctags (ctags exubérants, je veux dire, qui n'est qu'un des programmes de ctags disponibles) est distribué séparément de Vim (même si son auteur connaît Bram et même s'ils travaillent occasionnellement ensemble pour que Vim et ctags fonctionnent mieux ensemble.

Du point de vue des ctags, il est légitime de traiter le texte du programme comme de simples chaînes d'octets : qu'il s'agisse d'UTF-8, Latin1, Latin9 ou d'un autre jeu de caractères ISO 8859, un espace vaut 0x20, une tabulation dure 0x09, un saut de ligne est 0x0A éventuellement précédé de 0x0D, etc. ; et un octet nul, qui serait 0x00, ne devrait pas apparaître dans un fichier texte. Ctags traite chaque programme de la même manière quel que soit l'encodage compatible ASCII dans lequel il est écrit, et donc il n'a pas besoin de se soucier de qui est lequel. Seulement pour certains jeux de caractères bizarres comme EBCDIC, il faut traiter le texte comme définitivement non-ASCII (dans EBCDIC, IIRC, AI sont 0xC1-0xC9, JR sont 0xD1-0xD9, SZ sont 0xE2-0xE9, 0-9 sont 0xF0-0xF9 , et je ne me souviens pas quels sont les codes pour un espace, une tabulation, un saut de ligne, un tiret, un trait de soulignement, etc.; mais vous voyez que d'un point de vue ASCII c'est vraiment bizarre).

À mon humble avis, dans le cas de ctag, le bon vieux principe s'applique : garbage in, garbage out.

Meilleures salutations,
Tony.

@tonymec .. a du sens .. Je me rends compte qu'il peut y avoir d'autres programmes de génération de balises, mais universal-ctags est le plus populaire, et parmi les personnes utilisant universal-ctags je suppose qu'une grande partie est vim utilisateurs.

Je me demande donc si ces 2 pourraient fonctionner ou si vous avez d'autres idées sur la façon de gérer les fichiers contenant des caractères utf-8 illégaux ?

  1. J'ai également remarqué que ctags a cette option de +iconv , qui permet l'utilisation de libiconv . Lorsqu'il est utilisé sur la ligne de commande, iconv peut supprimer les caractères utf8 illégaux. Je me demande donc si je passe --input-enconding=utf-8 et --output-encoding=utf-8 , alors tous les caractères utf-8 illégaux seraient remplacés par des caractères légaux utf-8 .

Ceci est expliqué dans la section 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. laissez à l'éditeur le soin de gérer les caractères utf8 illégaux. Dans ce cas, soit vim.eval doit être corrigé, soit il doit y avoir une fonction vimL qui peut analyser et supprimer les caractères utf-8 illégaux avant de les passer à vim.eval ..

@alphaCTzo7G Je suis d'accord avec @tonymec et sa conclusion.

Malheureusement, il est très difficile de reconnaître le bon encodage - et j'insiste sur le bon, car il est facile de trouver un encodage dans lequel l'entrée serait techniquement valide, disons que la plupart sinon tous les encodages 8 bits le seraient, mais savoir si c'est le bon on est délicat ou impossible : disons, comment peut-on être sûr entre par exemple ISO 8859-1 et 8859-15 ? Les solutions incluent une heuristique complexe sur la fréquence d'utilisation et le contexte ; ou une idée plus naïve applicable à certains langages comme HTML serait d'extraire l'instruction d'encodage à l'intérieur du fichier, mais cela peut tout aussi bien être incorrect.

De plus, ctags se trouve ici dans une position difficile : beaucoup, sinon la plupart, des consommateurs ne gèrent pas les encodages, et les balises générées doivent correspondre au niveau de l'octet. Par exemple, rechercher un modèle de balise ou même un nom ne convertira pas les encodages pour vous, donc la balise doit correspondre au fichier au niveau de l'octet. C'était facile quand tout ce qui nous importait était l'ASCII, mais nous n'avons plus autant de chance… UTF-8 n'a pas été adopté assez tôt.
Ceci s'applique également à l'idée de remplacer par des caractères de substitution : que peut faire le consommateur avec un tel caractère de remplacement ? Il doit au moins le gérer d'une manière spécifique.

Cependant, si vous êtes satisfait de remplacer l'UTF-8 invalide par U+FFFD ou de les supprimer, peut-être pourriez-vous simplement post-traiter la sortie des ctags ?

@b4n , appréciez votre commentaire. En fait, je traite principalement avec des fichiers encodés utf-8 et j'ai des utf-8 encodés pour les fichiers que je crée. Malheureusement, comme vous l'avez mentionné, j'utilise des bibliothèques qui ont parfois des encodages arbitraires.

J'utilise vim-gutentags , et il fournit une fonctionnalité de post-traitement. Bien que je puisse post-traiter manuellement le fichier de balises pour obtenir tous les fichiers en caractères utf-8 , lorsque j'ai essayé d'utiliser la fonctionnalité post-processing dans vim-gutentags , cela n'a pas fonctionné . J'ai donc pensé qu'il serait peut-être préférable de trouver une solution plus robuste.. mais si cela n'existe pas, je devrai y réfléchir à nouveau..

Pour détecter l'encodage du fichier, ne pouvez-vous pas utiliser les bibliothèques sous-jacentes derrière l'une de ces options : https://stackoverflow.com/questions/805418/how-to-find-encoding-of-a-file-in-unix -via-scripts

comme enca , file , uchardet , enguess ? Ce sont tous des utilitaires de ligne de commande... mais il doit y avoir une bibliothèque quelque part qui peut être utilisée en interne par ctags peut-être. Je suppose qu'en raison du nombre d'encodages, comme vous l'avez mentionné, il n'est peut-être jamais possible de prédire parfaitement l'encodage, mais une solution simple qui en couvre la majeure partie peut être mieux que rien.

Je vais essayer le --input-encoding (and/or --input-encoding-<LANG>) and --output-encoding options .. Je ne sais pas si cela fonctionnera tout le temps, car il est fort possible que certains fichiers aient des encodages différents dans le même référentiel, à moins que ctags ne comprenne le corriger l'encodage individuellement et le recracher dans le format souhaité.

Cette page vous a été utile?
0 / 5 - 0 notes