ANSI-Escape-Sequenz-Parser

Code-Stücke können hier veröffentlicht werden.
Antworten
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Ich hab mal angefangen, den hier beschriebenen Parser in Python umzusetzen. Nun bin ich auf das Problem der Zeichenkodierung gestoßen und hab auch einen Hack für UTF8 drin, der allerdings alles andere als gut ist, da er mit anderen Steuerzeichen kollidiert. Leider schweigt sich die xterm-Doku hierzu aus und ich muß wohl tiefer in dessen Sourcecode abtauchen. Kennt jemand eine gute Quelle, die beschreibt, wie Terminals (bzw. locale) mit Charmaps umgehen?

Hier eine erste Version des Parsers.
Bis auf DCS-Kommandos (fehlen noch) und Kollisionen aufgrund des UTF8-Hacks sollte der Parser alle mögliche ESC-Sequenzen der VT-Reihe erkennen, sofern diese abwärtskompatibel zum VT500 sind (Ausnahmen siehe obigen Link zur Parser-Doku).

(Die FSM kommt von http://code.activestate.com/recipes/146 ... chine-fsm/ ).
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Die Umstellung des Parsers auf Unicode ist abgeschlossen und war auch relativ problemlos möglich. Einzig Dateianfang/-ende sind noch ein Knackpunkt für Multibyte-Encodings:
Was, wenn der Datenstrom nach X Bytes mitten in einem Multibytezeichen vorläufig endet? Der Parser behandelt dies nicht (ist derzeit noch ein Problem-anderer-Leute-Feld, da er einfach die Eingabe in Unicode erwartet). Wahrscheinlich muss für die korrekte Behandlung dieses Randfalls die Unicode-Dekodierung doch zum Parser (oder einer übergeordneten Lib) gepackt werden, da hier sonst Datenverlust droht. Gibts da schon was vorgefertigtes in Python, vllt. im codecs-Modul? Hinzu kommt, dass der Parser seine Daten in der Regel von einem Character-Device bekommen wird und daher Tricks mit seek() nicht nutzbar sind und die Bytes des "unfertigen" Multibytezeichens zwischengespeichert werden müssten.

Das hier geschilderte C1-Problem scheint eher Bedenkenträgertum meinerseits gewesen zu sein, da in allen Tests die C0-Variante genutzt wurde. Prinzipiell funktionieren die C1-Sequenzen parserseitig. Allerdings ist zwingend nötig, dass das gewählte Encoding 8-bittig ist (reines ASCII scheidet damit aus), was ja eigentlich auch spec-konform ist.

Der Parser ist im Unicode-Gewand 1:1 umsetzbar. Da xterm inzwischen Quasi-Standard ist, wird es über eine Subklasse bessere xterm-Kompatibilität geben (z.B. Setzen des Terminalfenster-Titels etc.).

Zum Punkt APC/PM:
Hier hatte ich überlegt, ob es nicht sinnvoll wäre, den Parser dieses auch verarbeiten zu lassen (wird derzeit einfach verschluckt). Damit könnte man einen potenziellen Emulator, der den Parser einsetzt, zur Laufzeit umprogrammieren oder Features unterschieben. Z.B. könnte man hierüber die Ausgabe von Bildern ermöglichen (falls der Output des Emulators das überhaupt unterstützt). Die Idee ist noch nicht ausgereift und würde einiges an Zusatzaufwand im Emulator bedeuten (Interface-/Pluginschnittstelle). Ist eine solche Funktionalität Eurer Meinung nach überhaupt sinnvoll?

Update:
Hier die überarbeitete Unicode-Version mit optionaler Eingabedekodierung.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Eine bereinigte Version --> http://paste.pocoo.org/show/520269/

Das APC/PM-Parsing ist nicht implementiert, da man mit DCS eine vergleichbare Funktionalität erreichen kann.

Nach wie vor unglücklich ist die Dekodierung gelöst:
Jedes Parserobjekt registriert nun seinen eigenen Errorhandler. Da der Errorhandler objektgebunden ist, flitzen im Mapping der codecs-Errorhandler Objektreferenzen rum, die mit close() zwar gelöst werden (und dem GC das Aufräumen ermöglichen) aber der Eintrag im Mapping bleibt bestehen. Ein Pandon zu codecs.register_error() zum Löschen des Eintrages konnte ich nicht finden. (Auch wollte ich nicht auf die Implementierungsdetails dahinter gehen, da mir nicht klar ist, inwieweit diese für andere Pythonversionen verbindlich sind.)

Sollten weitere Tests keine größeren Fehler mehr zutage fördern, ist der Parser einsatzbereit. Vielleicht hat ja jemand Lust, einem Emulator in einem der GUI-Toolkits (oder webbasiert) zu schreiben :twisted:
Antworten