Ctags: Universal ctags fügt für bestimmte Dateien ungültige `utf-8`-Zeichen ein

Erstellt am 30. Juli 2018  ·  7Kommentare  ·  Quelle: universal-ctags/ctags

(
Danke, dass Sie uns kontaktiert haben.

Wenn Sie ein Problem mit der Parsing-Ausgabe melden, füllen Sie bitte
die folgende Vorlage. Wie es Ihre benutzerdefinierte CTags-Konfiguration kann
Auswirkungen auf die Ergebnisse haben, verwenden Sie bitte immer --options=NONE als erstes
Option beim Ausführen von ctags .

Löschen Sie andernfalls die Vorlage und schreiben Sie Ihr Problem von Grund auf.
Beispiele können Entwicklern helfen, Ihr Problem besser zu verstehen.

Verwenden Sie die GitHub-Weboberfläche und die Markdown-Notation.
Die Verwendung von E-Mail-Ergebnissen zum Rendering von fehlerhaftem Text macht
die Entwickler werden verrückt.
)


Der Name des Parsers:

Die Befehlszeile, die Sie zum Ausführen von ctags verwendet haben:

$ ctags -R

Ich habe keine speziellen Konfigurationen in .ctags oder anderswo. Dies ist eine neue VM, auf der dieser Test ausgeführt wurde.

Der Inhalt der Eingabedatei: https://github.com/pallets/jinja/blob/master/jinja2/_identifier.py

Die Tag-Ausgabe, mit der Sie nicht zufrieden sind:

Universal-ctags fügt unter bestimmten Umständen ungültige utf-8 Zeichen ein.

Die erwartete Ausgabe der Tags:

Erwartete Tag-Ausgabe mit allen gültigen utf-8 Zeichen.

Die Ctags-Version:

$ 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

Wie erhalten Sie die Ctags-Binärdatei:

(
Die ctags-Binärdatei basiert auf einer ubuntu-16.04 VM ohne Änderungen außer der Installation notwendiger Bibliotheken wie automate , autoreconf zum Kompilieren von ctags und der notwendigen Bibliotheken zum Kompilieren von vim basierend auf https://github.com/Valloric/YouCompleteMe/wiki/Building-Vim-from-source#a-for-a-debian-like-linux-distribution-like-ubuntu-type
)

@lilydjwg hat mich darauf hingewiesen, dass ctags ungültige utf-8 Zeichen eingefügt hat, obwohl die Datei, die zum Generieren der Tags verwendet wird, hier alle gültigen utf-8 Zeichen enthält:
https://github.com/vim/vim/issues/3213#issuecomment -406961075

Die kompilierte Version von ctags funktioniert im Allgemeinen hervorragend.

Kürzlich herausgefunden, dass ctags einen Fehler hat, aufgrund dessen die
altes Execuberant ctags installiert von sudo apt-get install ctags auf Ubuntu
16.04 fügt keine ungültigen utf-8 Zeichen ein, aber wenn ich kompiliere
Universal-ctags aus der Quelle und basiert nicht auf den Anweisungen hier:
https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst , it
fügt ungültige utf-8 Zeichen ein. Hier der Beweis:

Wenn exuberant-ctags mit nur sudo apt-get install ctags installiert ist:

2018-07-29_19-03-44

Mit Universal-ctags aus dem Quellcode (neuester Commit) ab diesem Beitrag kompiliert,
zusammengestellt mit Anleitung von hier:
https://github.com/universal-ctags/ctags/blob/master/docs/autotools.rst :

2018-07-29_19-10-22

Dies verursacht viele Probleme in vim, denn wenn ungültige utf-8 Zeichen sind
an vim.eval , vim.eval bricht ab und dies führt dazu, dass keine Tags zurückgegeben werden bei
alle. Derzeit gibt es nur eine Möglichkeit, Daten zu übertragen, die in einem viml
Variable in das Leerzeichen python-name mit vim.eval . Also, jedes andere Plugin in
vim oder sonst wo wird ähnliche Probleme haben. @ludovicchabant für
Beispiel musste seine Tags-Datei nachbearbeiten, um solche Probleme zu stoppen:
https://ludovic.chabant.com/devblog/2017/02/25/aaa-gamedev-with-vim/

Außerdem musste er ctrl-py-matcher ändern, um dieses Problem zu beheben.
https://github.com/ludovicchabant/ctrlp-py-matcher/blob/2f6947480203b734b069e5d9f69ba440db6b4698/autoload/pymatcher.py#L22

Es gibt mehrere andere Dateien, die ich gesehen habe und die ähnliche Probleme haben, aber ich
habe hier gerade einen bereitgestellt, um das Problem einzugrenzen.

Ich vermute, dass dies ein Fehler ist, und ich erwarte nicht, dass ctags dies tun würde
Entwurf. Kann dies behoben werden, da dies in Exuberant Ctags gut funktioniert hat?
auf welchem ​​Universal-ctags basiert?

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

Alle 7 Kommentare

Klingt für mich nach #1275: Die neue Option pattern-length-limit schneidet an einer beliebigen Byte-Position, die zufällig mitten in einer Zeichenfolge liegt. Siehe #163, #640 und #1018.

Etwas wie https://github.com/universal-ctags/ctags/issues/1275#issuecomment -274489859 sollte wahrscheinlich implementiert werden, um dies zu beheben.

@alphaCTzo7G siehe #1807, behebt das richtig für Sie?

@b4n , danke für deine schnelle Antwort...

In der Datei, die ich hier _identifier.py gepostet habe, fügt ctags mit dem #1805-Commit keine ungültigen Zeichen/Schnitte mehr an einer beliebigen Stelle ein.

Ich werde diese PR in den nächsten Tagen auf meinem realen System ausprobieren, um zu sehen, ob sie für meine gesamten Repositories funktioniert oder andere Fehler ausgibt

Da ctrlp und ctrlp-py-matcher sehr beliebte Plugins sind, wäre es großartig, wenn #1807 zusammengeführt würde, damit vim und andere Texteditor-Benutzer ctrlp und ctrlp-py-matcher ohne sich um dieses Problem kümmern zu müssen.

Es gab eine andere Datei, die mit vim.eval Probleme verursachte und die ungültige utf-8 Zeichen enthielt, wie durch grep -axv '.*' misc.html ( misc.html in https:/ /github.com/alphaCTzo7G/test). Was mir aufgefallen ist, ist, dass ctags die ungültigen utf-8 Zeichen in die Tags-Datei von misc.html .

Ist es für ctags sinnvoll, ungültige Zeichen in Dateien zu erkennen und sie stattdessen durch etwas zu ersetzen, das @tonymec hier vorgeschlagen hat? (Ersetzen Sie die ungültige Sequenz durch eine oder mehrere Instanzen des Zeichens (U+FFFD REPLACEMENT CHARACTER), das genau für diesen Zweck gedacht ist.): https://github.com/vim/vim/issues/3213#issuecomment -405211243 ?

IIUC, ctags (Exuberant ctags, ich meine, das ist nur eines der verfügbaren ctags-Programme) wird separat von Vim vertrieben (auch wenn der Autor Bram kennt und gelegentlich zusammenarbeiten, um Vim und ctags besser zusammenzuarbeiten.

Aus der Sicht von Ctags ist es legitim, Programmtext nur als Byte-Strings zu behandeln: Unabhängig davon, ob es sich um UTF-8, Latin1, Latin9 oder einen anderen ISO 8859-Zeichensatz handelt, ist ein Leerzeichen 0x20, ein Hardtab 0x09, ein Zeilenumbruch ist 0x0A, möglicherweise vor 0x0D usw.; und ein Null-Byte, das 0x00 wäre, sollte nicht in einer Textdatei erscheinen. Ctags behandelt jedes Programm gleich, unabhängig davon, in welcher ASCII-kompatiblen Codierung es geschrieben ist, und muss sich daher nicht darum kümmern, welches welches ist. Nur für einige ausgefallene Zeichensätze wie EBCDIC muss der Text definitiv als Nicht-ASCII behandelt werden (in EBCDIC sind IIRC, AI 0xC1-0xC9, JR sind 0xD1-0xD9, SZ sind 0xE2-0xE9, 0-9 sind 0xF0-0xF9 , und ich erinnere mich nicht, was die Codes für ein Leerzeichen, einen Tabulator, einen Zeilenumbruch, einen Bindestrich, einen Unterstrich usw. sind; aber Sie sehen, dass es aus ASCII-Sicht wirklich abwegig ist).

IMHO gilt bei ctag das gute alte Prinzip: Müll rein, Müll raus.

Mit freundlichen Grüßen,
Toni.

@tonymec .. macht Sinn.. Mir ist klar, dass es andere Tag-Generierungsprogramme geben kann, aber universal-ctags ist das beliebteste, und unter den Leuten, die universal-ctags würde ich davon ausgehen, dass es ein großer Teil ist ist vim Benutzer.

Ich frage mich also, ob diese 2 funktionieren könnten oder Sie andere Ideen haben, wie Sie mit Dateien umgehen sollen, die illegale utf-8 Zeichen enthalten?

  1. Mir ist auch aufgefallen, dass ctags diese Option von +iconv , was die Verwendung von libiconv . Bei Verwendung in der Befehlszeile kann iconv ungültige utf8 Zeichen entfernen. Ich wundere mich also, wenn ich --input-enconding=utf-8 und --output-encoding=utf-8 , dann würden alle unzulässigen utf-8-Zeichen in zulässige utf-8 Zeichen geändert.

Dies wird in Abschnitt 1.3.4 von https://media.readthedocs.org/pdf/ctags/latest/ctags.pdf erklärt :

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. Überlassen Sie es dem Editor, mit unzulässigen utf8 Zeichen umzugehen. In diesem Fall muss entweder vim.eval korrigiert werden oder es muss eine vimL Funktion vorhanden sein, die ungültige utf-8 Zeichen analysieren und entfernen kann, bevor sie an vim.eval ..

@alphaCTzo7G Ich stimme @tonymec und seinem Fazit zu.

Leider ist es sehr schwierig, die richtige Kodierung zu erkennen – und ich bestehe darauf, dass es einfach ist, eine Kodierung zu finden, in der die Eingabe technisch gültig wäre, sagen wir, die meisten, wenn nicht alle 8-Bit-Kodierungen würden, aber wissen, ob es die richtige ist man ist knifflig oder unmöglich: sagen wir, wie kann man sicher sein zwischen zB ISO 8859-1 und 8859-15? Die Lösungen umfassen komplexe Heuristiken zu Nutzungshäufigkeit und -kontext; oder eine naivere Idee, die auf einige Sprachen wie HTML anwendbar ist, wäre das Extrahieren der Codierungsanweisung in der Datei, aber das kann genauso gut falsch sein.

Außerdem befindet sich ctags hier in einer schwierigen Position: Viele, wenn nicht die meisten Verbraucher verarbeiten keine Codierungen, und generierte Tags müssen auf Byte-Ebene übereinstimmen. Wenn Sie beispielsweise nach einem Tag-Muster oder sogar nach einem Namen suchen, werden die Codierungen für Sie nicht konvertiert, daher sollte das Tag auf Byte-Ebene mit der Datei übereinstimmen. Es war einfach, als wir uns nur um ASCII kümmern mussten, aber wir haben nicht mehr so ​​viel Glück… UTF-8 wurde nicht früh genug angenommen.
Dies gilt auch für die Idee des Ersetzens durch Platzhalterzeichen: Was kann der Konsument mit einem solchen Ersatzzeichen anfangen? Es muss zumindest auf eine bestimmte Weise damit umgehen.

Wenn Sie jedoch damit zufrieden sind, ungültiges UTF-8 durch U+FFFD zu ersetzen oder sie zu entfernen, könnten Sie die Ausgabe von ctags vielleicht einfach nachbearbeiten?

@b4n , schätze deinen Kommentar. Ich beschäftige mich hauptsächlich mit utf-8 kodierten Dateien und habe utf-8 für die von mir erstellten Dateien kodiert. Leider verwende ich, wie Sie erwähnt haben, Bibliotheken, die manchmal willkürliche Codierungen haben.

Ich verwende vim-gutentags , und es bietet eine Nachbearbeitungsfunktion. Während ich die Tag-Datei manuell nachbearbeiten konnte, um alle Dateien in utf-8 Zeichen zu erhalten, funktionierte es nicht, als ich versuchte, die post-processing Funktionalität in vim-gutentags . Also dachte ich, es wäre vielleicht besser, eine robustere Lösung zu finden.

Um die Codierung der Datei zu erkennen, können Sie die zugrunde liegenden Bibliotheken hinter einer dieser Optionen nicht verwenden: https://stackoverflow.com/questions/805418/how-to-find-encoding-of-a-file-in-unix -über-Skripte

wie enca , file , uchardet , enguess ? Dies sind alles Kommandozeilen-Dienstprogramme.. aber es muss irgendwo eine Bibliothek geben, die vielleicht intern von ctags . Ich vermute aufgrund der Anzahl der Codierungen, wie Sie bereits erwähnt haben, dass es möglicherweise nie möglich ist, die Codierung perfekt vorherzusagen, aber eine einfache Lösung, die das meiste davon abdeckt, ist möglicherweise besser als nichts.

Ich werde das --input-encoding (and/or --input-encoding-<LANG>) and --output-encoding options ausprobieren. Ich bin mir nicht sicher, ob es die ganze Zeit funktioniert, da es sehr wahrscheinlich ist, dass bestimmte Dateien im selben Repository unterschiedliche Codierungen haben, es sei denn, ctags heraus korrekte Codierung einzeln und spuckt sie im gewünschten Format aus.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

cweagans picture cweagans  ·  8Kommentare

jayceekay picture jayceekay  ·  13Kommentare

EvanCarroll picture EvanCarroll  ·  14Kommentare

fabiensabatie picture fabiensabatie  ·  3Kommentare

lvc picture lvc  ·  8Kommentare