Pengkodean salah saat memanggil shell

9

Saya sedang bereksperimen dengan diagram DOT dan mencoba melakukan hal berikut:

:! dot -Tpng -oFab.png %

Saya mendapat kesalahan karena nama file saya memiliki karakter khusus (" ó" dalam "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...

Seperti yang Anda lihat, karakter khusus sedang diubah untuk " ├│". Ini dengan vim dan gVim 7.4 di bawah Win7 dan NTFS, jadi saya berasumsi nama filenya ada di UTF16 . Saya juga berasumsi bahwa ketika menjalankan shell / cmd nama file sedang ditafsirkan sebagai beberapa pengkodean lainnya (terima kasih kepada Carpetsmoker untuk menunjukkannya secara default ke kode halaman 850 ).

Bagaimana saya bisa memperbaikinya?

Tentu, saya cukup mengganti nama file, tetapi saya ingin tahu mengapa ini terjadi dan bagaimana cara memperbaikinya.

Pembaruan : Saya baru saja menemukan pertanyaan ini di superuser.SE (terima kasih atas umpan balik dari @ ChristianBrabandt ), tetapi sepertinya juga tidak membantu.

Roflo
sumber
1
Saya ingin tahu apakah Anda akan mendapatkan kesalahan yang sama dengan menggunakan Vim pada baris perintah di bawah Cygwin atau MobaXterm (lingkungan seperti Unix portabel untuk Windows). Saya kira tidak. Mungkin ada cara untuk benar-benar memperbaiki ini sehingga Windows cmdmenerima nama file, tetapi menginstal lingkungan seperti Unix akan menjadi pilihan saya sendiri.
Wildcard
2
Dari apa yang saya baca, default untuk cmd.exebukan unicode, tetapi kode halaman 850 . Lihat juga jawaban ini .
Martin Tournoij
Terima kasih @Carpetsmoker. Saya mengambil kebebasan memperbarui pertanyaan saya dengan informasi yang Anda berikan.
Roflo
Saya tidak sepenuhnya yakin, tetapi Anda mungkin ingin mengubah opsi 'termencoding'.
Christian Brabandt
@ChristianBrabandt Kecuali jika saya melakukan sesuatu yang salah, itu sepertinya tidak membantu. Saya mencoba mengatur tenc ke latin1, utf8, dan cp850. Sepertinya tidak ada yang berhasil.
Roflo

Jawaban:

2

Jawaban singkat

Masalahnya terletak pada dot.exe. GraphViz dapat membuka file dengan jalur Unicode di Linux tetapi tidak Windows, kecuali (mungkin) jika dikompilasi dengan Visual Studio 2005.

Penelitian

Halaman kode diatur ke 850, Vim encoding ke UTF-8.

masukkan deskripsi gambar di sini

Itu tidak memberikan kesalahan yang sama persis, tetapi dot.exetampaknya menerima argumen yang salah. Saya mencoba meneruskan nama file yang sama ke program lain.

masukkan deskripsi gambar di sini

Dan itu bekerja dengan baik. Menjalankan keduanya dot.exedan typelangsung dari cmd.exememberikan hasil yang sama, sehingga baik Windows Console maupun Vim tidak menjadi masalah. Hal berikutnya yang dapat menyebabkan kesalahan itu dot.exesendiri. Kecurigaan saya adalah bahwa ia tidak tahu bagaimana menangani argumen kode Unicode dengan benar, karena tidak semua perintah konsol melakukannya:

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

Jika Anda memerlukan dukungan Unicode penuh, gunakan PowerShell. Masih ada dukungan SANGAT terbatas untuk Unicode di shell CMD, perpipaan, pengalihan dan sebagian besar perintah masih ANSI saja. Satu-satunya perintah yang berfungsi adalah DIR, FOR / F dan TYPE, ini memungkinkan membaca dan menulis file dan nama file (UTF-16LE / BOM) tetapi tidak banyak lagi.

Saya mencari di web jika ada dukungan untuk Unicode di GraphViz dan menemukan bahwa itu mendukung file Unicode tetapi tidak ada tentang dukungan Unicode untuk nama file. Saya tidak menemukan laporan tentang pelacak bug GraphViz atau posting di forum tentang orang lain yang tertarik membaca file bernama Unicode. Jadi saya mencarinya di sumber. dot.exeSeperti apa titik masuknya:

graphviz-2.40.1\cmd\dot\dot.c

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

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

    . . .

Mengikuti bagian argvbawah lubang kelinci: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];
    }

Dan akhirnya 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")))  {

        . . .

    }

Seperti yang dinyatakan MDSN:

Fungsi fopen membuka file yang ditentukan oleh nama file. _wfopen adalah versi fopen karakter lebar ; argumen untuk _wfopen adalah string karakter lebar. _wfopen dan fopen berperilaku identik sebaliknya. Cukup menggunakan _wfopen tidak berpengaruh pada set karakter kode yang digunakan dalam aliran file.

Dalam Visual C ++ 2005, fopen mendukung stream file Unicode.

Sayangnya, satu-satunya pilihan di sana adalah mengubah nama file.


sumber