From 8f37158e88f5a8ec913d12220b295dca907ed6b9 Mon Sep 17 00:00:00 2001 From: Takuji Tanaka Date: Sat, 25 Jan 2014 07:36:00 +0000 Subject: kpathsea [win32]: Allow Unicode file name in kpsewhich, add new functions in knj.[ch] git-svn-id: svn://tug.org/texlive/trunk@32783 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/kpathsea/ChangeLog | 8 +++ Build/source/texk/kpathsea/knj.c | 103 +++++++++++++++++++++++++++++++- Build/source/texk/kpathsea/knj.h | 6 +- Build/source/texk/kpathsea/kpsewhich.c | 26 ++++++++ Build/source/texk/kpathsea/line.c | 6 ++ Build/source/texk/kpathsea/pathsearch.c | 7 +++ 6 files changed, 152 insertions(+), 4 deletions(-) (limited to 'Build') diff --git a/Build/source/texk/kpathsea/ChangeLog b/Build/source/texk/kpathsea/ChangeLog index 0d8dfdf6697..18623145e16 100644 --- a/Build/source/texk/kpathsea/ChangeLog +++ b/Build/source/texk/kpathsea/ChangeLog @@ -1,3 +1,11 @@ +2014-01-25 TANAKA Takuji + + * knj.[ch]: Add a new function win32_getc(), win32_ungetc(), + win32_fputs(), and win32_puts(). (Windows only) + * kpsewhich.c, pathsearch.c, line.c: + Allow Unicode file name in kpsewhich. (Windows only) + * knj.c: Fix typo in error message. (Windows only) + 2014-01-14 Peter Breitenlohner * knj.c: Add #include as required for MinGW32. diff --git a/Build/source/texk/kpathsea/knj.c b/Build/source/texk/kpathsea/knj.c index 52b4a43b9bc..cd9eb474129 100644 --- a/Build/source/texk/kpathsea/knj.c +++ b/Build/source/texk/kpathsea/knj.c @@ -84,7 +84,7 @@ get_mbstring_from_wstring(int cp, const wchar_t *wstr, char *mbstr) len = WideCharToMultiByte(cp, 0, wstr, -1, mbstr, 0, NULL, NULL); if (len==0) { - FATAL("cannot convert string to wide string"); + FATAL("cannot convert string to multibyte string"); } if (mbstr==NULL) { mbstr = xmalloc(len+1); @@ -200,13 +200,13 @@ fsyscp_popen (const char *command, const char *mode) return f; } -void +int get_command_line_args_utf8 (const_string enc, int *p_ac, char ***p_av) { int argc; string *argv; - if (!enc || !strncmp(enc,"",1)) return; + if (!enc || !strncmp(enc,"",1)) return 0; #ifdef DEBUG fprintf(stderr, "command_line_encoding (%s)\n", enc); @@ -237,8 +237,10 @@ get_command_line_args_utf8 (const_string enc, int *p_ac, char ***p_av) argv[argcw] = NULL; *p_ac = argc; *p_av = argv; + return file_system_codepage; } else { WARNING1("kpathsea: Ignoring unknown encoding `%s'", enc); + return 0; } } @@ -331,3 +333,98 @@ fsyscp_system (const char *cmd) free (av[2]); return ret; } + +static int getc_len; +static int getc_buff[4]; + +int win32_getc(FILE *fp) +{ + const int fd = fileno(fp); + HANDLE hStdin; + DWORD ret; + wchar_t wc[3]; + char mbc[5]; + int j; + static wchar_t wcbuf = L'\0'; + + if (!(fd == fileno(stdin) && _isatty(fd) && file_system_codepage == CP_UTF8)) + return getc(fp); + + if (getc_len == 0) + { + hStdin = GetStdHandle(STD_INPUT_HANDLE); + if (wcbuf) { + wc[0] = wcbuf; + wcbuf = L'\0'; + } + else if (ReadConsoleW(hStdin, wc, 1, &ret, NULL) == 0) + return EOF; + if (0xd800<=wc[0] && wc[0]<0xdc00) { + if (ReadConsoleW(hStdin, wc+1, 1, &ret, NULL) == 0) + return EOF; + if (0xdc00<=wc[1] && wc[1]<0xe000) { + wc[2]=L'\0'; + } else { + wcbuf=wc[1]; + wc[0]=0xfffd; /* illegal surrogate pair */ + wc[1]=L'\0'; + } + } else if (0xdc00<=wc[0] && wc[0]<0xe000) { + wc[0]=0xfffd; /* illegal surrogate pair */ + wc[1]=L'\0'; + } else { + wc[1]=L'\0'; + } + get_utf8_from_wstring(wc,mbc); + j=strlen(mbc)-1; + while(j>=0) { + getc_buff[getc_len++]=(int)mbc[j--]; + } + } + return getc_buff[--getc_len]; +} + +int win32_ungetc(int c, FILE *fp) +{ + const int fd = fileno(fp); + + if (!(fd == fileno(stdin) && _isatty(fd) && file_system_codepage == CP_UTF8)) + return ungetc(c, fp); + + assert(getc_len < 4); + return getc_buff[getc_len++] = c; +} + +int win32_fputs(const char *str, FILE *fp) +{ + const int fd = fileno(fp); + HANDLE hStdout; + DWORD ret; + wchar_t *wstr; + int j; + + if (!((fd == fileno(stdout) || fd == fileno(stderr)) && _isatty(fd) + && file_system_codepage == CP_UTF8)) + return fputs(str, fp); + + hStdout = (fd == fileno(stdout)) ? + GetStdHandle(STD_OUTPUT_HANDLE) : GetStdHandle(STD_ERROR_HANDLE); + + wstr = get_wstring_from_utf8(str, wstr=NULL); + + if (WriteConsoleW(hStdout, wstr, wcslen(wstr), &ret, NULL) == 0) { + free(wstr); + return EOF; + } + + free(wstr); + return ret; +} + +int win32_puts(const char *str) +{ + if (win32_fputs(str, stdout)==EOF) { + return EOF; + } + return puts(""); +} diff --git a/Build/source/texk/kpathsea/knj.h b/Build/source/texk/kpathsea/knj.h index 0e942d518d6..df73074b8ad 100644 --- a/Build/source/texk/kpathsea/knj.h +++ b/Build/source/texk/kpathsea/knj.h @@ -36,7 +36,11 @@ extern KPSEDLL FILE* fsyscp_fopen(const char *filename, const char *mode); extern KPSEDLL FILE* fsyscp_popen(const char *command, const char *mode); extern KPSEDLL int fsyscp_spawnvp(int mode, const char *command, const char* const *argv); extern KPSEDLL int fsyscp_system(const char *cmd); -extern KPSEDLL void get_command_line_args_utf8(const char *enc, int *p_ac, char ***p_av); +extern KPSEDLL int get_command_line_args_utf8(const char *enc, int *p_ac, char ***p_av); +extern KPSEDLL int win32_getc(FILE *fp); +extern KPSEDLL int win32_ungetc(int c, FILE *fp); +extern KPSEDLL int win32_fputs(const char *str, FILE *fp); +extern KPSEDLL int win32_puts(const char *str); #ifdef __cplusplus } diff --git a/Build/source/texk/kpathsea/kpsewhich.c b/Build/source/texk/kpathsea/kpsewhich.c index 4bcb77ac48b..59739e56c9c 100644 --- a/Build/source/texk/kpathsea/kpsewhich.c +++ b/Build/source/texk/kpathsea/kpsewhich.c @@ -30,6 +30,12 @@ #include #include +#ifdef WIN32 +#undef fputs +#undef puts +#define fputs win32_fputs +#define puts win32_puts +#endif /* For variable and path expansion. (-expand-var, -expand-path, -show-path) */ @@ -672,6 +678,10 @@ kpathsea_set_program_enabled (kpse, fmt, false, kpse_src_cmdline - 1) int main (int argc, string *argv) { +#ifdef WIN32 + string *av, enc; + int ac; +#endif unsigned unfound = 0; kpathsea kpse = kpathsea_new(); @@ -679,6 +689,22 @@ main (int argc, string *argv) read_command_line (kpse, argc, argv); kpathsea_set_program_name (kpse, argv[0], progname); +#ifdef WIN32 + if(strstr(progname,"xetex") || strstr(progname,"xelatex") + || strstr(progname,"uptex") || strstr(progname,"uplatex") + || strstr(progname,"dvipdfm") || strstr(progname,"extractbb") + || strstr(progname,"xbb") || strstr(progname,"ebb") + || strstr(progname,"dvips")) + { + enc = kpathsea_var_value (kpse, "command_line_encoding"); + if (get_command_line_args_utf8(enc, &ac, &av)) { + optind = 0; + read_command_line (kpse, ac, av); + argv = av; + argc = ac; + } + } +#endif init_more (kpse); diff --git a/Build/source/texk/kpathsea/line.c b/Build/source/texk/kpathsea/line.c index c26303a3012..b221a4032dc 100644 --- a/Build/source/texk/kpathsea/line.c +++ b/Build/source/texk/kpathsea/line.c @@ -18,6 +18,12 @@ #include #include +#ifdef WIN32 +#undef getc +#undef ungetc +#define getc win32_getc +#define ungetc win32_ungetc +#endif /* Allocate in increments of this size. */ #define BLOCK_SIZE 75 diff --git a/Build/source/texk/kpathsea/pathsearch.c b/Build/source/texk/kpathsea/pathsearch.c index f5eb216b2a4..0f59ac5ed95 100644 --- a/Build/source/texk/kpathsea/pathsearch.c +++ b/Build/source/texk/kpathsea/pathsearch.c @@ -34,6 +34,13 @@ #include /* for stat bits */ #endif +#ifdef WIN32 +#undef fputs +#undef puts +#define fputs win32_fputs +#define puts win32_puts +#endif + /* The very first search is for texmf.cnf, called when someone tries to initialize the TFM path or whatever. init_path calls kpse_cnf_get which calls kpse_all_path_search to find all the texmf.cnf's. We -- cgit v1.2.3