Короткий ответ
Проблема заключается в dot.exe
. GraphViz может открывать файлы с путями Unicode в Linux, но не в Windows, если (возможно), если они скомпилированы с Visual Studio 2005.
Исследование
Кодовая страница установлена в 850
, Vim кодировка в UTF-8
.
Это не дает точно такую же ошибку, но, dot.exe
кажется, получает неправильный аргумент. Я попытался передать то же имя файла другой программе.
И это сработало как раз правильно. Выполнение обоих dot.exe
и type
непосредственно из cmd.exe
дает один и тот же результат, поэтому ни Windows Console, ни Vim не являются проблемой. Следующее, что могло вызвать эту ошибку, было dot.exe
само по себе. Я подозревал, что он просто не знает, как правильно обрабатывать закодированные аргументы Unicode, как это делают даже не все консольные команды:
https://ss64.com/nt/chcp.html
Если вам нужна полная поддержка Unicode, используйте PowerShell. Все еще ОЧЕНЬ ограниченная поддержка Unicode в оболочке CMD, трубопровод, перенаправление, и большинство команд по-прежнему только ANSI. Единственными работающими командами являются DIR, FOR / F и TYPE, это позволяет читать и записывать (UTF-16LE / BOM) файлы и имена файлов, но не намного.
Я искал в Интернете, есть ли поддержка Unicode в GraphViz и обнаружил, что он поддерживает файлы Unicode, но ничего о поддержке Unicode для имен файлов. На трекере ошибок GraphViz и в сообщениях на форуме я не нашел никаких сообщений о том, что кто-то еще заинтересован в чтении файла с именами Unicode. Так что я посмотрел в источнике. Вот как dot.exe
выглядит точка входа:
graphviz-2.40.1\cmd\dot\dot.c
int main(int argc, char **argv)
{
. . .
/* --------------------> ARGS ARE BEING PASSED HERE */
gvParseArgs(Gvc, argc, argv);
. . .
Следуя argv
вниз по кроличьей норе: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];
}
И наконец 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"))) {
. . .
}
Как утверждает MDSN:
Функция fopen открывает файл, указанный в имени файла. _wfopen - широкоформатная версия fopen ; аргументы _wfopen - строки широких символов. _wfopen и fopen ведут себя одинаково иначе. Простое использование _wfopen не влияет на набор кодированных символов, используемый в файловом потоке.
В Visual C ++ 2005 fopen поддерживает файловые потоки Unicode.
К сожалению, единственный вариант - переименовать файл.
cmd
приняла имя файла, но установка Unix-подобной среды была бы моей собственной предпочтительной обработкой.