Codifica errata durante la chiamata della shell


9

Stavo sperimentando un diagramma DOT e ho provato a fare quanto segue:

:! dot -Tpng -oFab.png %

Ho ricevuto un errore perché il mio nome file ha un carattere speciale (" ó" in "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...

Come puoi vedere, il carattere speciale è stato cambiato per " ├│". Questo è con vim e gVim 7.4 in Win7 e NTFS, quindi suppongo che il nome del file sia in UTF16 . Suppongo anche che quando si richiama la shell / cmd il nome del file venga interpretato come un'altra codifica (grazie a Carpetsmoker per averlo indicato per impostazione predefinita alla code page 850 ).

Come posso risolvere questo problema?

Certo, posso semplicemente rinominare il file, ma vorrei sapere perché questo accade e come correggerlo.

Aggiornamento : ho appena trovato questa domanda in superuser.SE (grazie al feedback di @ ChristianBrabandt ), ma non sembra aiutare neanche.


1
Sono curioso di sapere se otterresti lo stesso errore usando Vim dalla riga di comando in Cygwin o MobaXterm (ambienti portatili simili a Unix per Windows). Sospetto di no. Potrebbe esserci un modo per risolvere il problema in modo che Windows cmdaccetti il ​​nome del file, ma ottenere un ambiente simile a Unix sarebbe la mia gestione preferita.
Wildcard

2
Da quello che ho letto, l'impostazione predefinita cmd.exenon è Unicode, ma la pagina di codice 850 . Vedi anche questa risposta .
Martin Tournoij,

Grazie @Carpetsmoker. Mi sono preso la libertà di aggiornare la mia domanda con le informazioni fornite.
Roflo,

Non ne sono completamente sicuro, ma potresti voler modificare l'opzione "termencoding".
Christian Brabandt,

@ChristianBrabandt A meno che non stia facendo qualcosa di sbagliato, ciò non sembra aiutare. Ho provato a impostare tenc su latin1, utf8 e cp850. Nessuno sembra fare il trucco.
Roflo,

Risposte:


2

Risposta breve

Il problema sta nel dot.exe. GraphViz può aprire file con percorsi Unicode in Linux ma non in Windows, a meno che (forse) se compilato con Visual Studio 2005.

Ricerca

La tabella codici è impostata su 850, codifica Vim su UTF-8.

inserisci qui la descrizione dell'immagine

Non dà lo stesso errore esatto, ma dot.exesembra ricevere un argomento sbagliato. Ho provato a passare lo stesso nome file all'altro programma.

inserisci qui la descrizione dell'immagine

E ha funzionato perfettamente. L'esecuzione di entrambi dot.exee typedirettamente da cmd.exedà lo stesso risultato, quindi né la console di Windows né Vim sono il problema. La cosa successiva che poteva causare quell'errore era dot.exese stessa. Il mio sospetto era che non sapesse come gestire correttamente gli argomenti codificati Unicode, come nemmeno tutti i comandi della console fanno:

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

Se hai bisogno del pieno supporto Unicode usa PowerShell. C'è ancora un supporto MOLTO limitato per Unicode nella shell CMD, piping, reindirizzamento e la maggior parte dei comandi sono ancora solo ANSI. Gli unici comandi che funzionano sono DIR, FOR / F e TYPE, questo permette di leggere e scrivere file (UTF-16LE / BOM) e nomi di file, ma non molto altro.

Ho cercato sul web se c'è supporto per Unicode in GraphViz e ho scoperto che supporta i file Unicode ma nulla riguardo al supporto Unicode per i nomi dei file. Né ho trovato alcun report sul tracker di bug GraphViz né post sul forum su chiunque fosse interessato a leggere un file denominato Unicode. Quindi ho cercato nella fonte. Ecco dot.execome appare il punto di ingresso:

graphviz-2.40.1\cmd\dot\dot.c

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

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

    . . .

Seguendo la argvtana del coniglio: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];
    }

E infine 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")))  {

        . . .

    }

Come afferma l'MDSN:

La funzione fopen apre il file specificato dal nome file. _wfopen è una versione a caratteri larghi di fopen ; gli argomenti di _wfopen sono stringhe di caratteri ampi. _wfopen e fopen si comportano in modo identico altrimenti. Il semplice utilizzo di _wfopen non ha alcun effetto sul set di caratteri codificati utilizzato nel flusso di file.

In Visual C ++ 2005, fopen supporta flussi di file Unicode.

Purtroppo, l'unica opzione è quella di rinominare il file.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.