summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakuji Tanaka <KXD02663@nifty.ne.jp>2014-01-25 07:36:00 +0000
committerTakuji Tanaka <KXD02663@nifty.ne.jp>2014-01-25 07:36:00 +0000
commit8f37158e88f5a8ec913d12220b295dca907ed6b9 (patch)
treef7c4c387c2a1b866f693e1e1fdc22c3b2023f780
parentdce8da8c3072b543be8fb371e9060ad0a2d1c7c0 (diff)
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
-rw-r--r--Build/source/texk/kpathsea/ChangeLog8
-rw-r--r--Build/source/texk/kpathsea/knj.c103
-rw-r--r--Build/source/texk/kpathsea/knj.h6
-rw-r--r--Build/source/texk/kpathsea/kpsewhich.c26
-rw-r--r--Build/source/texk/kpathsea/line.c6
-rw-r--r--Build/source/texk/kpathsea/pathsearch.c7
6 files changed, 152 insertions, 4 deletions
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 <KXD02663@nifty.ne.jp>
+
+ * 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 <peb@mppmu.mpg.de>
* knj.c: Add #include <wchar.h> 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 <kpathsea/variable.h>
#include <kpathsea/version.h>
+#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 <kpathsea/config.h>
#include <kpathsea/line.h>
+#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 <sys/stat.h> /* 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