2010-11-04 5 views
4

Je construis une application telnet en C# (pour écrire des jeux de portes sur les systèmes BBS oldschool comme Wildcat) et ne peux pas construire un analyseur de travail pour les codes d'échappement ANSI (mouvement du curseur, colorisation, etc.) J'ai testé envoyer des séquences indéfinies qui défient toute "norme". Il semble également y avoir très peu de ressources sur le sujet, Wikipedia has the most in-depth list I've found so far mais même ils disent que c'est incomplet - et la plupart des autres sites que j'ai rencontrés ne font que copier/coller l'article de Wikipedia.Analyse des codes d'échappement ANSI?

Ma question: Y a-t-il une bibliothèque? Si non, que diriez-vous d'un certain code d'analyse/Regex? À tout le moins une documentation appropriée pour des choses comme ESC[!_ serait incroyablement utile.

Je me sens vraiment comme si je réinvente la roue à ce sujet, surtout en voyant que Telnet est plus ou moins l'équivalent Internet de la roue (au moins sage âge;)

EDIT: Ajouté un exemple de bizarrerie:

00000075h: 1B 5B 73 1B 5B 32 35 35 42 1B 5B 32 35 35 43 08 ; .[s.[255B.[255C. 
00000085h: 5F 1B 5B 36 6E 1B 5B 75 1B 5B 21 5F 02 02 3F 48 ; _.[6n.[u.[!_..?H 
00000095h: 54 4D 4C 3F 1B 5B 30 6D 5F 1B 5B 32 4A 1B 5B 48 ; TML?.[0m_.[2J.[H 
000000a5h: 0C 0D 0A          ; ... 
The mysterious part is '21' in line 2 ---^^ 
+0

C'est rien reconnaissable. Considérez que vous l'avez mal interprété. Publiez les valeurs * byte *, évitez d'utiliser des chaînes. –

+0

Il est peu probable que vous trouviez une seule ressource canonique qui ne ressemble pas à Wikipédia, puisque chaque terminal gère différemment les codes ANSI.La référence officielle est la [norme ANSI] (http://www.ecma-international.org/publications/standards/Ecma-048.htm) (à laquelle Wikipédia renvoie), mais cela ne vous dira que ce que tout le monde a accepté. fais, pas ce qui a été réellement fait. – dimo414

+0

La documentation appropriée serait [ECMA-48] (http://www.ecma-international.org/publications/standards/Ecma-048.htm). Cela couvre bien plus que simplement déplacer le curseur et rendre les choses colorées, cependant. – Joey

Répondre

3

Une bonne réponse dépend de la façon dont on a l'intention d'utiliser la bibliothèque. Tout émulateur de terminal lit ces séquences et exécute les actions en fonction de ces séquences. Mais même un simple émulateur de terminal comprendra une centaine de séquences.

Votre exemple, sous une forme peut-être plus facile à lire, ressemble à ceci:

 
\E[s 
\E[255B 
\E[255C\t_ 
\E[6n 
\E[u 
\E[!_^B^B?HTML? 
\E[0m_ 
\E[2J 
\E[H\f\r 
\n 

utilisant unmap (rendant le caractère d'échappement \E et montrant tous caractères imprimables — et commencer une nouvelle ligne pour les caractères d'échappement) .

ECMA-48 décrit le format d'

  • caractères de contrôle d'un octet, et
  • séquences de contrôle multi-octets (en commençant par le caractère d'échappement).

Les séquences de contrôle ont un contenu (paramètres) qui est limité à certains caractères tels que les chiffres et les séparateurs, par exemple, ';'. Les séquences de contrôle ont également une fin définie, appelée le final. La séquence \E[!_^B^B? ne suit pas ces règles. Comme suggéré dans un commentaire, peut-être votre enregistrement a été confondu par la réponse du terminal à la demande de position du curseur \E[6n.

Avec beaucoup contexte:

  • quelques-unes des actions effectuées par un émulateur de terminal pour modifier l'affichage (\E[2J efface l'écran)
  • quelques-unes des actions effectuées par un émulateur de terminal dire l'hôte au sujet l'affichage (\E[6n demande au terminal où le curseur est )
  • quelques-unes des actions effectuées par un émulateur de terminal modifier le comportement du terminal (\E[s et \E[u enregistrer la position du curseur et restaurer plus tard)

vous En bref, voir que pour traiter les séquences de commande reçues par un terminal, vous avez vraiment besoin d'un programme terminal pour faire tout cela. Cependant, tous les émulateurs de terminaux ne sont pas identiques. Certains utilisent une série d'instructions de cas, pour gérer les étapes successives d'échappement, de parenthèses, de chiffres, etc. Mais votre programme doit garder à l'esprit que les contrôles à un octet peuvent apparaître au milieu de séquences de contrôle multi-octets. Comme ils sont codés différemment, il n'y a pas de conflit. Mais cela rend le programme plus compliqué que vous ne le pensez en lisant une séquence à la fois. Xterm utilise des instructions de cas (pour le caractère final, essentiellement), mais la plupart des transitions d'état lors du décodage d'une séquence de contrôle sont effectuées à l'aide d'un ensemble de tables. Ils sont très répétitifs, mais pas évidents à construire: Paul Williams a souligné que pour un VT100, ceux-ci devraient être symétriques (traitant essentiellement l'entrée comme un ASCII 7 bits). Certains des états sont traités comme des erreurs et ignorés; des séquences bien formatées sont tout ce qui compte de toute façon. En théorie, vous pouvez réutiliser les tables d'état et ajouter un "petit" parsing. Les tables sont 8500 lignes (un état par ligne).

Mis à part (a) la lecture émulateurs existants et de les imiter à plus petite échelle, ou (b) la modification d'un émulateur de terminal ... vous pouvez enquêter sur libvterm:

Une bibliothèque abstraite C99 qui met en œuvre une VT220 ou émulateur de terminal de type xterm. Il n'utilise pas de toolkit graphique ou de système de sortie en particulier, il invoque à la place des pointeurs de fonction de rappel que son programme d'intégration devrait lui fournir pour dessiner en son nom. Cela évite d'appeler malloc() pendant un état de fonctionnement normal, ce qui lui permet d'être utilisé dans des situations noyau noyées.

Cependant, ce n'est pas dans C# (et la source est la documentation). Pourtant, ce n'est que 5500 lignes de code.

Pour en savoir plus:

Questions connexes