Diff of /perl/pl-CYG08-b722195e_CYG17_utf8_paths.patch [000000] .. [6565f5]  Maximize  Restore

  Switch to side-by-side view

--- a
+++ b/perl/pl-CYG08-b722195e_CYG17_utf8_paths.patch
@@ -0,0 +1,375 @@
+From: Reini Urban <rurban@x-ray.at>
+Subject: [PATCH] CYG17 utf8 paths
+Author: Reini Urban <rurban@x-ray.at>
+Date:   Tue Apr 12 12:19:36 2011 +0200
+commit b722195e24a6c67310eb30e8f18601966a96ba78
+
+    CYG17 utf8 paths
+    
+    Use cygwin_conv_path since cygwin-1.7 and support native utf-8 paths.
+
+diff --git a/cygwin/cygwin.c b/cygwin/cygwin.c
+index aa6938d..3206f91 100644
+--- a/cygwin/cygwin.c
++++ b/cygwin/cygwin.c
+@@ -10,9 +10,13 @@
+ #include <unistd.h>
+ #include <process.h>
+ #include <sys/cygwin.h>
++#include <cygwin/version.h>
+ #include <mntent.h>
+ #include <alloca.h>
+ #include <dlfcn.h>
++#if (CYGWIN_VERSION_API_MINOR >= 181)
++#include <wchar.h>
++#endif
+ 
+ /*
+  * pp_system() implemented via spawn()
+@@ -125,7 +129,7 @@ do_spawn (char *cmd)
+ 	    return do_spawnvp("sh",command);
+ 	}
+ 
+-    Newx (PL_Argv,(s-cmd)/2+2,const char*);
++    Newx (PL_Argv,(s-cmd)/2+2,char*);
+     PL_Cmd=savepvn (cmd,s-cmd);
+     a=PL_Argv;
+     for (s=PL_Cmd; *s;) {
+@@ -143,6 +147,44 @@ do_spawn (char *cmd)
+     return do_spawnvp(PL_Argv[0],(const char * const *)PL_Argv);
+ }
+ 
++#if (CYGWIN_VERSION_API_MINOR >= 181)
++char*
++wide_to_utf8(const wchar_t *wbuf)
++{
++    char *buf;
++    int wlen = 0;
++    char *oldlocale = setlocale(LC_CTYPE, NULL);
++    setlocale(LC_CTYPE, "utf-8");
++
++    /* uvuni_to_utf8(buf, chr) or Encoding::_bytes_to_utf8(sv, "UCS-2BE"); */
++    wlen = wcsrtombs(NULL, (const wchar_t **)&wbuf, wlen, NULL);
++    buf = (char *) safemalloc(wlen+1);
++    wcsrtombs(buf, (const wchar_t **)&wbuf, wlen, NULL);
++
++    if (oldlocale) setlocale(LC_CTYPE, oldlocale);
++    else setlocale(LC_CTYPE, "C");
++    return buf;
++}
++
++wchar_t*
++utf8_to_wide(const char *buf)
++{
++    wchar_t *wbuf;
++    mbstate_t mbs;
++    char *oldlocale = setlocale(LC_CTYPE, NULL);
++    int wlen = sizeof(wchar_t)*strlen(buf);
++
++    setlocale(LC_CTYPE, "utf-8");
++    wbuf = (wchar_t *) safemalloc(wlen);
++    /* utf8_to_uvuni(pathname, wpath) or Encoding::_utf8_to_bytes(sv, "UCS-2BE"); */
++    wlen = mbsrtowcs(wbuf, (const char**)&buf, wlen, &mbs);
++
++    if (oldlocale) setlocale(LC_CTYPE, oldlocale);
++    else setlocale(LC_CTYPE, "C");
++    return wbuf;
++}
++#endif /* cygwin 1.7 */
++
+ /* see also Cwd.pm */
+ XS(Cygwin_cwd)
+ {
+@@ -194,7 +236,12 @@ XS(XS_Cygwin_winpid_to_pid)
+ 
+     pid = (pid_t)SvIV(ST(0));
+ 
+-    if ((RETVAL = cygwin32_winpid_to_pid(pid)) > 0) {
++#if (CYGWIN_VERSION_API_MINOR >= 181)
++    RETVAL = cygwin_winpid_to_pid(pid);
++#else
++    RETVAL = cygwin32_winpid_to_pid(pid);
++#endif
++    if (RETVAL > 0) {
+         XSprePUSH; PUSHi((IV)RETVAL);
+         XSRETURN(1);
+     }
+@@ -202,34 +249,91 @@ XS(XS_Cygwin_winpid_to_pid)
+ }
+ 
+ XS(XS_Cygwin_win_to_posix_path)
++
+ {
+     dXSARGS;
+     int absolute_flag = 0;
+     STRLEN len;
+     int err;
+-    char *pathname, *buf;
++    char *src_path;
++    char *posix_path;
++    int isutf8 = 0;
+ 
+     if (items < 1 || items > 2)
+         Perl_croak(aTHX_ "Usage: Cygwin::win_to_posix_path(pathname, [absolute])");
+ 
+-    pathname = SvPV(ST(0), len);
++    src_path = SvPV(ST(0), len);
+     if (items == 2)
+ 	absolute_flag = SvTRUE(ST(1));
+ 
+     if (!len)
+ 	Perl_croak(aTHX_ "can't convert empty path");
+-    buf = (char *) safemalloc (len + 260 + 1001);
++    isutf8 = SvUTF8(ST(0));
+ 
++#if (CYGWIN_VERSION_API_MINOR >= 181)
++    /* Check utf8 flag and use wide api then.
++       Size calculation: On overflow let cygwin_conv_path calculate the final size.
++     */
++    if (isutf8) {
++	int what = absolute_flag ? CCP_WIN_W_TO_POSIX : CCP_WIN_W_TO_POSIX | CCP_RELATIVE;
++	int wlen = sizeof(wchar_t)*(len + 260 + 1001);
++	wchar_t *wpath = (wchar_t *) safemalloc(sizeof(wchar_t)*len);
++	wchar_t *wbuf = (wchar_t *) safemalloc(wlen);
++	if (!IN_BYTES) {
++	    mbstate_t mbs;
++            char *oldlocale = setlocale(LC_CTYPE, NULL);
++            setlocale(LC_CTYPE, "utf-8");
++	    /* utf8_to_uvuni(src_path, wpath) or Encoding::_utf8_to_bytes(sv, "UCS-2BE"); */
++	    wlen = mbsrtowcs(wpath, (const char**)&src_path, wlen, &mbs);
++	    if (wlen > 0)
++		err = cygwin_conv_path(what, wpath, wbuf, wlen);
++            if (oldlocale) setlocale(LC_CTYPE, oldlocale);
++            else setlocale(LC_CTYPE, "C");
++	} else { /* use bytes; assume already ucs-2 encoded bytestream */
++	    err = cygwin_conv_path(what, src_path, wbuf, wlen);
++	}
++	if (err == ENOSPC) { /* our space assumption was wrong, not enough space */
++	    int newlen = cygwin_conv_path(what, wpath, wbuf, 0);
++	    wbuf = (wchar_t *) realloc(&wbuf, newlen);
++	    err = cygwin_conv_path(what, wpath, wbuf, newlen);
++	    wlen = newlen;
++	}
++	/* utf16_to_utf8(*p, *d, bytlen, *newlen) */
++	posix_path = (char *) safemalloc(wlen*3);
++	Perl_utf16_to_utf8(aTHX_ (U8*)&wpath, (U8*)posix_path, (I32)wlen*2, (I32*)&len);
++	/*
++	wlen = wcsrtombs(NULL, (const wchar_t **)&wbuf, wlen, NULL);
++	posix_path = (char *) safemalloc(wlen+1);
++	wcsrtombs(posix_path, (const wchar_t **)&wbuf, wlen, NULL);
++	*/
++    } else {
++	int what = absolute_flag ? CCP_WIN_A_TO_POSIX : CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
++	posix_path = (char *) safemalloc (len + 260 + 1001);
++	err = cygwin_conv_path(what, src_path, posix_path, len + 260 + 1001);
++	if (err == ENOSPC) { /* our space assumption was wrong, not enough space */
++	    int newlen = cygwin_conv_path(what, src_path, posix_path, 0);
++	    posix_path = (char *) realloc(&posix_path, newlen);
++	    err = cygwin_conv_path(what, src_path, posix_path, newlen);
++	}
++    }
++#else
++    posix_path = (char *) safemalloc (len + 260 + 1001);
+     if (absolute_flag)
+-	err = cygwin_conv_to_full_posix_path(pathname, buf);
++	err = cygwin_conv_to_full_posix_path(src_path, posix_path);
+     else
+-	err = cygwin_conv_to_posix_path(pathname, buf);
++	err = cygwin_conv_to_posix_path(src_path, posix_path);
++#endif
+     if (!err) {
+-	ST(0) = sv_2mortal(newSVpv(buf, 0));
+-	safefree(buf);
+-       XSRETURN(1);
++	EXTEND(SP, 1);
++	ST(0) = sv_2mortal(newSVpv(posix_path, 0));
++	if (isutf8) { /* src was utf-8, so result should also */
++	    /* TODO: convert ANSI (local windows encoding) to utf-8 on cygwin-1.5 */
++	    SvUTF8_on(ST(0));
++	}
++	safefree(posix_path);
++        XSRETURN(1);
+     } else {
+-	safefree(buf);
++	safefree(posix_path);
+ 	XSRETURN_UNDEF;
+     }
+ }
+@@ -240,29 +344,80 @@ XS(XS_Cygwin_posix_to_win_path)
+     int absolute_flag = 0;
+     STRLEN len;
+     int err;
+-    char *pathname, *buf;
++    char *src_path, *win_path;
++    int isutf8 = 0;
+ 
+     if (items < 1 || items > 2)
+         Perl_croak(aTHX_ "Usage: Cygwin::posix_to_win_path(pathname, [absolute])");
+ 
+-    pathname = SvPV(ST(0), len);
++    src_path = SvPVx(ST(0), len);
+     if (items == 2)
+ 	absolute_flag = SvTRUE(ST(1));
+ 
+     if (!len)
+ 	Perl_croak(aTHX_ "can't convert empty path");
+-    buf = (char *) safemalloc(len + 260 + 1001);
+-
++    isutf8 = SvUTF8(ST(0));
++#if (CYGWIN_VERSION_API_MINOR >= 181)
++    /* Check utf8 flag and use wide api then.
++       Size calculation: On overflow let cygwin_conv_path calculate the final size.
++     */
++    if (isutf8) {
++	int what = absolute_flag ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_W | CCP_RELATIVE;
++	int wlen = sizeof(wchar_t)*(len + 260 + 1001);
++	wchar_t *wpath = (wchar_t *) safemalloc(sizeof(wchar_t)*len);
++	wchar_t *wbuf = (wchar_t *) safemalloc(wlen);
++	char *oldlocale = setlocale(LC_CTYPE, NULL);
++	setlocale(LC_CTYPE, "utf-8");
++	if (!IN_BYTES) {
++	    mbstate_t mbs;
++	    /* utf8_to_uvuni(src_path, wpath) or Encoding::_utf8_to_bytes(sv, "UCS-2BE"); */
++	    wlen = mbsrtowcs(wpath, (const char**)&src_path, wlen, &mbs);
++	    if (wlen > 0)
++		err = cygwin_conv_path(what, wpath, wbuf, wlen);
++	} else { /* use bytes; assume already ucs-2 encoded bytestream */
++	    err = cygwin_conv_path(what, src_path, wbuf, wlen);
++	}
++	if (err == ENOSPC) { /* our space assumption was wrong, not enough space */
++	    int newlen = cygwin_conv_path(what, wpath, wbuf, 0);
++	    wbuf = (wchar_t *) realloc(&wbuf, newlen);
++	    err = cygwin_conv_path(what, wpath, wbuf, newlen);
++	    wlen = newlen;
++	}
++	/* also see utf8.c: Perl_utf16_to_utf8() or Encoding::_bytes_to_utf8(sv, "UCS-2BE"); */
++	wlen = wcsrtombs(NULL, (const wchar_t **)&wbuf, wlen, NULL);
++	win_path = (char *) safemalloc(wlen+1);
++	wcsrtombs(win_path, (const wchar_t **)&wbuf, wlen, NULL);
++	if (oldlocale) setlocale(LC_CTYPE, oldlocale);
++	else setlocale(LC_CTYPE, "C");
++    } else {
++	int what = absolute_flag ? CCP_POSIX_TO_WIN_A : CCP_POSIX_TO_WIN_A | CCP_RELATIVE;
++	win_path = (char *) safemalloc(len + 260 + 1001);
++	err = cygwin_conv_path(what, src_path, win_path, len + 260 + 1001);
++	if (err == ENOSPC) { /* our space assumption was wrong, not enough space */
++	    int newlen = cygwin_conv_path(what, src_path, win_path, 0);
++	    win_path = (char *) realloc(&win_path, newlen);
++	    err = cygwin_conv_path(what, src_path, win_path, newlen);
++	}
++    }
++#else
++    if (isutf8)
++	Perl_warn(aTHX_ "can't convert utf8 path");
++    win_path = (char *) safemalloc(len + 260 + 1001);
+     if (absolute_flag)
+-	err = cygwin_conv_to_full_win32_path(pathname, buf);
++	err = cygwin_conv_to_full_win32_path(src_path, win_path);
+     else
+-	err = cygwin_conv_to_win32_path(pathname, buf);
++	err = cygwin_conv_to_win32_path(src_path, win_path);
++#endif
+     if (!err) {
+-	ST(0) = sv_2mortal(newSVpv(buf, 0));
+-	safefree(buf);
+-       XSRETURN(1);
++	EXTEND(SP, 1);
++	ST(0) = sv_2mortal(newSVpv(win_path, 0));
++	if (isutf8) {
++	    SvUTF8_on(ST(0));
++	}
++	safefree(win_path);
++	XSRETURN(1);
+     } else {
+-	safefree(buf);
++	safefree(win_path);
+ 	XSRETURN_UNDEF;
+     }
+ }
+@@ -293,24 +448,22 @@ XS(XS_Cygwin_mount_flags)
+ {
+     dXSARGS;
+     char *pathname;
+-    char flags[260];
++    char flags[PATH_MAX];
++    flags[0] = '\0';
+ 
+     if (items != 1)
+-        Perl_croak(aTHX_ "Usage: Cygwin::mount_flags(mnt_dir|'/cygwin')");
++        Perl_croak(aTHX_ "Usage: Cygwin::mount_flags( mnt_dir | '/cygdrive' )");
+ 
+     pathname = SvPV_nolen(ST(0));
+ 
+-    /* TODO: Check for cygdrive registry setting,
+-     *       and then use CW_GET_CYGDRIVE_INFO
+-     */
+     if (!strcmp(pathname, "/cygdrive")) {
+-	char user[260];
+-	char system[260];
+-	char user_flags[260];
+-	char system_flags[260];
++	char user[PATH_MAX];
++	char system[PATH_MAX];
++	char user_flags[PATH_MAX];
++	char system_flags[PATH_MAX];
+ 
+-	cygwin_internal (CW_GET_CYGDRIVE_INFO, user, system, user_flags,
+-			 system_flags);
++	cygwin_internal (CW_GET_CYGDRIVE_INFO, user, system,
++			 user_flags, system_flags);
+ 
+         if (strlen(user) > 0) {
+             sprintf(flags, "%s,cygdrive,%s", user_flags, user);
+@@ -323,6 +476,7 @@ XS(XS_Cygwin_mount_flags)
+ 
+     } else {
+ 	struct mntent *mnt;
++	int found = 0;
+ 	setmntent (0, 0);
+ 	while ((mnt = getmntent (0))) {
+ 	    if (!strcmp(pathname, mnt->mnt_dir)) {
+@@ -331,12 +485,42 @@ XS(XS_Cygwin_mount_flags)
+ 		    strcat(flags, ",");
+ 		    strcat(flags, mnt->mnt_opts);
+ 		}
++		found++;
+ 		break;
+ 	    }
+ 	}
+ 	endmntent (0);
+-	ST(0) = sv_2mortal(newSVpv(flags, 0));
+-	XSRETURN(1);
++
++	/* Check if arg is the current volume moint point if not default,
++	 * and then use CW_GET_CYGDRIVE_INFO also.
++	 */
++	if (!found) {
++	    char user[PATH_MAX];
++	    char system[PATH_MAX];
++	    char user_flags[PATH_MAX];
++	    char system_flags[PATH_MAX];
++
++	    cygwin_internal (CW_GET_CYGDRIVE_INFO, user, system,
++			     user_flags, system_flags);
++
++	    if (strlen(user) > 0) {
++		if (strcmp(user,pathname)) {
++		    sprintf(flags, "%s,cygdrive,%s", user_flags, user);
++		    found++;
++		}
++	    } else {
++		if (strcmp(user,pathname)) {
++		    sprintf(flags, "%s,cygdrive,%s", system_flags, system);
++		    found++;
++		}
++	    }
++	}
++	if (found) {
++	    ST(0) = sv_2mortal(newSVpv(flags, 0));
++	    XSRETURN(1);
++	} else {
++	    XSRETURN_UNDEF;
++	}
+     }
+ }
+ 

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks