Mauvais encodage lors de l'appel du shell

9

J'expérimentais avec un diagramme DOT et j'ai essayé de faire ce qui suit:

:! dot -Tpng -oFab.png %

J'ai reçu une erreur car mon nom de fichier a un caractère spécial (" ó" dans "Fabricación"):

C:\windows\system32\cmd.exe /c ( dot -Tpng -oFab.png Fabricaci├│n.gv)
Error: dot: can't open Fabricaci├│n.gv
shell returned 2
Hit any key to close this window...

Comme vous pouvez le voir, le caractère spécial est modifié pour " ├│". C'est avec vim et gVim 7.4 sous Win7 et NTFS, donc je suppose que le nom de fichier est en UTF16 . Je suppose également qu'en invoquant le shell / cmd, le nom de fichier est interprété comme un autre encodage (merci à Carpetsmoker de l' avoir signalé par défaut à la page de code 850 ).

Comment puis-je réparer cela?

Bien sûr, je peux simplement renommer le fichier, mais j'aimerais savoir pourquoi cela se produit et comment le corriger.

Mise à jour : Je viens de trouver cette question dans superuser.SE (grâce aux commentaires de @ ChristianBrabandt ), mais cela ne semble pas aider non plus.

Roflo
la source
1
Je suis curieux de savoir si vous obtiendriez la même erreur en utilisant Vim sur la ligne de commande sous Cygwin ou MobaXterm (environnements portables de type Unix pour Windows). Je suppose que non. Il peut y avoir un moyen de résoudre ce problème afin que Windows cmdaccepte le nom de fichier, mais l'installation d'un environnement de type Unix serait ma propre gestion préférée.
Wildcard
2
D'après ce que j'ai lu, la valeur par défaut cmd.exen'est pas unicode, mais la page de codes 850 . Voir également cette réponse .
Martin Tournoij
Merci @Carpetsmoker. J'ai pris la liberté de mettre à jour ma question avec les informations que vous avez fournies.
Roflo
Je ne suis pas complètement sûr, mais vous voudrez peut-être modifier l'option «termencoding».
Christian Brabandt du
@ChristianBrabandt À moins que je fasse quelque chose de mal, cela ne semble pas aider. J'ai essayé de régler tenc sur latin1, utf8 et cp850. Personne ne semble faire l'affaire.
Roflo

Réponses:

2

Réponse courte

Le problème réside dans dot.exe. GraphViz peut ouvrir des fichiers avec des chemins Unicode sous Linux mais pas Windows, sauf (peut-être) s'il est compilé avec Visual Studio 2005.

Recherche

La page de codes est définie sur 850, Vim codant sur UTF-8.

entrez la description de l'image ici

Il ne donne pas exactement la même erreur, mais le dot.exesemble recevoir un mauvais argument. J'ai essayé de passer le même nom de fichier à l'autre programme.

entrez la description de l'image ici

Et cela a bien fonctionné. L'exécution des deux dot.exeet typedirectement à partir de cmd.exedonne le même résultat, donc ni la console Windows ni Vim ne sont le problème. La prochaine chose qui pourrait provoquer cette erreur était dot.exeelle-même. Je soupçonnais qu'il ne savait tout simplement pas comment gérer correctement les arguments codés Unicode, car même toutes les commandes de la console ne le font pas:

https://ss64.com/nt/chcp.html

Si vous avez besoin d'une prise en charge complète d'Unicode, utilisez PowerShell. Il y a toujours un support TRÈS limité pour Unicode dans le shell CMD, la tuyauterie, la redirection et la plupart des commandes sont toujours ANSI uniquement. Les seules commandes qui fonctionnent sont DIR, FOR / F et TYPE, cela permet de lire et d'écrire des fichiers et des noms de fichiers (UTF-16LE / BOM) mais pas grand-chose d'autre.

J'ai cherché sur le Web s'il y avait un support pour Unicode dans GraphViz et j'ai trouvé qu'il supporte les fichiers Unicode mais rien sur le support Unicode pour les noms de fichiers. Je n'ai trouvé aucun rapport sur le traqueur de bogues GraphViz ni aucun message sur le forum concernant une autre personne intéressée à lire un fichier nommé Unicode. J'ai donc cherché dans la source. Voici à quoi dot.exeressemble le point d'entrée:

graphviz-2.40.1\cmd\dot\dot.c

int main(int argc, char **argv)
{
    . . .

/* --------------------> ARGS ARE BEING PASSED HERE */
    gvParseArgs(Gvc, argc, argv);

    . . .

En suivant le argvbas du terrier du lapin:graphviz-2.40.1\lib\common\args.c

int gvParseArgs(GVC_t *gvc, int argc, char** argv)
{
    int rv;
    if ((argc = neato_extra_args(gvc, argc, argv)) < 0)    return (1-argc);
    if ((argc = fdp_extra_args(gvc, argc, argv)) < 0)      return (1-argc);
    if ((argc = memtest_extra_args(gvc, argc, argv)) < 0)  return (1-argc);
    if ((argc = config_extra_args(gvc, argc, argv)) < 0)   return (1-argc);

/* -------------------->  HERE GO ALL NON-FLAG ARTUMENTS */
    if ((rv = dotneato_args_initialize(gvc, argc, argv)))  return rv;

    if (Verbose) gvplugin_write_status(gvc);
    return 0;
}

graphviz-2.40.1\lib\common\input.c

int dotneato_args_initialize(GVC_t * gvc, int argc, char **argv)
{
    for (i = 1; i < argc; i++) {
        if (argv[i] && argv[i][0] == '-') {

            . . .

/* -------------------->  JUST CASUALLY COPYING CHAR POINTERS */
        } else if (argv[i])
            gvc->input_filenames[nfiles++] = argv[i];
    }

Et enfin graphviz-2.40.1\lib\common\input.c

graph_t *gvNextInputGraph(GVC_t *gvc)
{
    . . . .

/* -------------------->  OPENING THE FILES FOR READ WITH FOPEN */
    while ((fn = gvc->input_filenames[fidx++]) && !(fp = fopen(fn, "r")))  {

        . . .

    }

Comme le dit le MDSN:

La fonction fopen ouvre le fichier spécifié par nom de fichier. _wfopen est une version à caractères larges de fopen ; les arguments de _wfopen sont des chaînes de caractères larges. _wfopen et fopen se comportent de manière identique dans le cas contraire. La simple utilisation de _wfopen n'a aucun effet sur le jeu de caractères codés utilisé dans le flux de fichiers.

Dans Visual C ++ 2005, fopen prend en charge les flux de fichiers Unicode.

Malheureusement, la seule option consiste à renommer le fichier.


la source