[patch] Tcl 20030128-3 changes to handle Cygwin pathnames
Earnie Boyd
earnie_boyd@yahoo.com
Mon Feb 3 00:37:00 GMT 2003
Hi Mumit,
If cygwin specific code already exists in the official source then I
suggest you submit your patch to the tcl.sf.net project.
Earnie.
Mumit Khan wrote:
> Jeff Hobbs had put in some of my changes that allows Cygwin pathnames
> into Tcl 8.3.5, but it doesn't work with the new filesystem code in Tcl
> 8.4. The new filesystem code does make it a bit easier to support such
> "non-native" filenames. Hopefully these will go into Tcl core at some
> point.
>
> The 3 cases that the appended patch fixes:
>
> 1. Translate Cygwin POSIX path correctly into native form.
>
> $ /usr/local/tcl8.4.1-redhat/bin/tclsh84 /tmp/foo.tcl
>
> will do the right thing.
>
> $ /usr/local/tcl8.4.1-redhat/bin/tclsh84
> % file native /
> C:\cygwin
> %
>
> 2. Support globbing with Cygwin POSIX pathnames.
>
> $ /usr/local/tcl8.4.1-redhat/bin/tclsh84
> % glob /
> C:/cygwin
> % glob /home
> C:/cygwin/home
> % glob "/home/Mumit Khan/.bash*"
> {C:/cygwin/home/Mumit Khan/.bash_profile}
>
> 3. Chdir. Use Cygwin's chdir to keep the internal state consistent.
>
> 2003-02-02 Mumit Khan <khan@nanotech.wisc.edu>
>
> * generic/tclIOUtil.c (SetFsPathFromAny): Add Cygwin specific
> code to convert POSIX filename to native format.
> * generic/tclFileName.c (Tcl_TranslateFileName): And remove
> from here.
> (TclDoGlob): Adjust.
> * win/tclWinFile.c (TclpObjChdir): Use chdir on Cygwin.
>
> Index: generic/tclFileName.c
> ===================================================================
> RCS file: /home/khan/src/tcltk/CVSROOT/tcltk8.4.1/tcl/generic/tclFileName.c,v
> retrieving revision 1.1.1.1
> diff -u -3 -p -r1.1.1.1 tclFileName.c
> --- generic/tclFileName.c 2003/01/31 22:26:16 1.1.1.1
> +++ generic/tclFileName.c 2003/02/02 04:37:23
> @@ -1356,31 +1356,12 @@ Tcl_TranslateFileName(interp, name, buff
> */
>
> if (tclPlatform == TCL_PLATFORM_WINDOWS) {
> -#if defined(__CYGWIN__) && defined(__WIN32__)
> -
> - extern int cygwin_conv_to_win32_path
> - _ANSI_ARGS_((CONST char *, char *));
> - char winbuf[MAX_PATH];
> -
> - /*
> - * In the Cygwin world, call conv_to_win32_path in order to use the
> - * mount table to translate the file name into something Windows will
> - * understand. Take care when converting empty strings!
> - */
> - if (Tcl_DStringLength(bufferPtr)) {
> - cygwin_conv_to_win32_path(Tcl_DStringValue(bufferPtr), winbuf);
> - Tcl_DStringFree(bufferPtr);
> - Tcl_DStringAppend(bufferPtr, winbuf, -1);
> - }
> -#else /* __CYGWIN__ && __WIN32__ */
> -
> register char *p;
> for (p = Tcl_DStringValue(bufferPtr); *p != '\0'; p++) {
> if (*p == '/') {
> *p = '\\';
> }
> }
> -#endif /* __CYGWIN__ && __WIN32__ */
> }
> return Tcl_DStringValue(bufferPtr);
> }
> @@ -2336,25 +2317,6 @@ TclDoGlob(interp, separators, headPtr, t
> * element. Add an extra slash if this is a UNC path.
> */
>
> -#if defined(__CYGWIN__) && defined(__WIN32__)
> - {
> -
> - extern int cygwin_conv_to_win32_path
> - _ANSI_ARGS_((CONST char *, char *));
> - char winbuf[MAX_PATH];
> -
> - /*
> - * In the Cygwin world, call conv_to_win32_path in order to use
> - * the mount table to translate the file name into something
> - * Windows will understand.
> - */
> - cygwin_conv_to_win32_path(Tcl_DStringValue(headPtr), winbuf);
> - Tcl_DStringFree(headPtr);
> - Tcl_DStringAppend(headPtr, winbuf, -1);
> -
> - }
> -#endif /* __CYGWIN__ && __WIN32__ */
> -
> if (*name == ':') {
> Tcl_DStringAppend(headPtr, ":", 1);
> if (count > 1) {
> @@ -2570,11 +2532,24 @@ TclDoGlob(interp, separators, headPtr, t
> if (Tcl_DStringLength(headPtr) == 0) {
> if (((*name == '\\') && (name[1] == '/' || name[1] == '\\'))
> || (*name == '/')) {
> - Tcl_DStringAppend(headPtr, "\\", 1);
> + Tcl_DStringAppend(headPtr, "/", 1);
> } else {
> Tcl_DStringAppend(headPtr, ".", 1);
> }
> }
> +#if defined(__CYGWIN__) && defined(__WIN32__)
> + {
> +
> + extern int cygwin_conv_to_win32_path
> + _ANSI_ARGS_((CONST char *, char *));
> + char winbuf[MAX_PATH+1];
> +
> + cygwin_conv_to_win32_path(Tcl_DStringValue(headPtr), winbuf);
> + Tcl_DStringFree(headPtr);
> + Tcl_DStringAppend(headPtr, winbuf, -1);
> +
> + }
> +#endif /* __CYGWIN__ && __WIN32__ */
> /*
> * Convert to forward slashes. This is required to pass
> * some Tcl tests. We should probably remove the conversions
> Index: generic/tclIOUtil.c
> ===================================================================
> RCS file: /home/khan/src/tcltk/CVSROOT/tcltk8.4.1/tcl/generic/tclIOUtil.c,v
> retrieving revision 1.1.1.1
> diff -u -3 -p -r1.1.1.1 tclIOUtil.c
> --- generic/tclIOUtil.c 2003/01/31 22:26:18 1.1.1.1
> +++ generic/tclIOUtil.c 2003/02/03 00:16:51
> @@ -3947,6 +3947,28 @@ SetFsPathFromAny(interp, objPtr)
> transPtr = Tcl_FSJoinToPath(objPtr,0,NULL);
> }
>
> +#if defined(__CYGWIN__) && defined(__WIN32__)
> + {
> +
> + extern int cygwin_conv_to_win32_path
> + _ANSI_ARGS_((CONST char *, char *));
> + char winbuf[MAX_PATH+1];
> +
> + /*
> + * In the Cygwin world, call conv_to_win32_path in order to use the
> + * mount table to translate the file name into something Windows will
> + * understand. Take care when converting empty strings!
> + */
> + name = Tcl_GetStringFromObj(transPtr, &len);
> + if (len > 0) {
> + cygwin_conv_to_win32_path(name, winbuf);
> + TclWinNoBackslash(winbuf);
> + Tcl_SetStringObj(transPtr, winbuf, -1);
> + }
> +
> + }
> +#endif /* __CYGWIN__ && __WIN32__ */
> +
> /*
> * Now we have a translated filename in 'transPtr'. This will have
> * forward slashes on Windows, and will not contain any ~user
> Index: win/tclWinFile.c
> ===================================================================
> RCS file: /home/khan/src/tcltk/CVSROOT/tcltk8.4.1/tcl/win/tclWinFile.c,v
> retrieving revision 1.1.1.1
> diff -u -3 -p -r1.1.1.1 tclWinFile.c
> --- win/tclWinFile.c 2003/01/31 22:27:10 1.1.1.1
> +++ win/tclWinFile.c 2003/02/01 01:01:15
> @@ -1330,9 +1330,25 @@ TclpObjChdir(pathPtr)
> {
> int result;
> CONST TCHAR *nativePath;
> +#ifdef __CYGWIN__
> + extern int cygwin_conv_to_posix_path
> + _ANSI_ARGS_((CONST char *, char *));
> + char posixPath[MAX_PATH+1];
> + CONST char *path;
> + Tcl_DString ds;
> +#endif /* __CYGWIN__ */
>
> +
> nativePath = (CONST TCHAR *) Tcl_FSGetNativePath(pathPtr);
> +#ifdef __CYGWIN__
> + /* Cygwin chdir only groks POSIX path. */
> + path = Tcl_WinTCharToUtf(nativePath, -1, &ds);
> + cygwin_conv_to_posix_path(path, posixPath);
> + result = (chdir(posixPath) == 0 ? 1 : 0);
> + Tcl_DStringFree(&ds);
> +#else /* __CYGWIN__ */
> result = (*tclWinProcs->setCurrentDirectoryProc)(nativePath);
> +#endif /* __CYGWIN__ */
>
> if (result == 0) {
> TclWinConvertError(GetLastError());
>
More information about the Cygwin-patches
mailing list