summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--generic/tclFileName.c29
-rw-r--r--tests/fileName.test6
-rw-r--r--tests/msgcat.test4
-rwxr-xr-xunix/configure10
-rw-r--r--unix/tcl.m46
-rw-r--r--unix/tclUnixNotfy.c145
7 files changed, 198 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 3e35779..c8ecc4f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2012-06-25 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclfileName.c: [Patch #1536227]: Cygwin network pathname
+ * tests/fileName.test: support
+
+2012-06-23 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * unix/tclUnixNotfy.c: [Bug 3508771]: Cygwin notifier for handling
+ win32 events.
+
2012-06-21 Jan Nijtmans <nijtmans@users.sf.net>
* win/tclWinReg.c: [Bug #3362446]: registry keys command fails
diff --git a/generic/tclFileName.c b/generic/tclFileName.c
index 4c57256..a6bb932 100644
--- a/generic/tclFileName.c
+++ b/generic/tclFileName.c
@@ -414,9 +414,17 @@ TclpGetNativePathType(
}
#endif
if (path[0] == '/') {
+#ifdef __CYGWIN__
+ /*
+ * Check for Cygwin // network path prefix
+ */
+ if (path[1] == '/') {
+ path++;
+ }
+#endif
if (driveNameLengthPtr != NULL) {
/*
- * We need this addition in case the QNX code was used.
+ * We need this addition in case the QNX or Cygwin code was used.
*/
*driveNameLengthPtr = (1 + path - origPath);
@@ -643,11 +651,20 @@ SplitUnixPath(
}
#endif
- if (path[0] == '/') {
- Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj("/",1));
- p = path+1;
- } else {
- p = path;
+ p = path;
+ if (*p == '/') {
+ Tcl_Obj *rootElt = Tcl_NewStringObj("/", 1);
+ p++;
+#ifdef __CYGWIN__
+ /*
+ * Check for Cygwin // network path prefix
+ */
+ if (*p == '/') {
+ Tcl_AppendToObj(rootElt, "/", 1);
+ p++;
+ }
+#endif
+ Tcl_ListObjAppendElement(NULL, result, rootElt);
}
/*
diff --git a/tests/fileName.test b/tests/fileName.test
index c613068..a91f4b3 100644
--- a/tests/fileName.test
+++ b/tests/fileName.test
@@ -189,7 +189,7 @@ test filename-4.12 {Tcl_SplitPath: unix} {testsetplatform} {
test filename-4.13 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split //foo
-} {/ foo}
+} "[file split //] foo"
test filename-4.14 {Tcl_SplitPath: unix} {testsetplatform} {
testsetplatform unix
file split foo//bar
@@ -429,11 +429,11 @@ test filename-7.16 {Tcl_JoinPath: unix} {testsetplatform} {
test filename-7.17 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join //a b
-} {/a/b}
+} "[file split //]a/b"
test filename-7.18 {Tcl_JoinPath: unix} {testsetplatform} {
testsetplatform unix
file join /// a b
-} {/a/b}
+} "[file split //]a/b"
test filename-9.1 {Tcl_JoinPath: win} {testsetplatform} {
diff --git a/tests/msgcat.test b/tests/msgcat.test
index 0669810..6fe4b31 100644
--- a/tests/msgcat.test
+++ b/tests/msgcat.test
@@ -17,8 +17,8 @@ if {[catch {package require tcltest 2}]} {
puts stderr "Skipping tests in [info script]. tcltest 2 required."
return
}
-if {[catch {package require msgcat 1.4.2}]} {
- puts stderr "Skipping tests in [info script]. No msgcat 1.4.2 found to test."
+if {[catch {package require msgcat 1.4.4}]} {
+ puts stderr "Skipping tests in [info script]. No msgcat 1.4.4 found to test."
return
}
diff --git a/unix/configure b/unix/configure
index d30c2c3..27a7f50 100755
--- a/unix/configure
+++ b/unix/configure
@@ -7001,6 +7001,16 @@ echo "${ECHO_T}$ac_cv_cygwin" >&6
echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;}
{ (exit 1); exit 1; }; }
fi
+ if test "x${TCL_THREADS}" = "x0"; then
+ { { echo "$as_me:$LINENO: error: CYGWIN compile is only supported with --enable-threads" >&5
+echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ if test ! -f "../win/tcldde13.dll" -a ! -f "../win/tk85.dll"; then
+ { { echo "$as_me:$LINENO: error: Please configure and make the ../win directory first." >&5
+echo "$as_me: error: Please configure and make the ../win directory first." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
;;
dgux*)
SHLIB_CFLAGS="-K PIC"
diff --git a/unix/tcl.m4 b/unix/tcl.m4
index 4e0ac62..390f4ec 100644
--- a/unix/tcl.m4
+++ b/unix/tcl.m4
@@ -1260,6 +1260,12 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
if test "$ac_cv_cygwin" = "no"; then
AC_MSG_ERROR([${CC} is not a cygwin compiler.])
fi
+ if test "x${TCL_THREADS}" = "x0"; then
+ AC_MSG_ERROR([CYGWIN compile is only supported with --enable-threads])
+ fi
+ if test ! -f "../win/tcldde13.dll" -a ! -f "../win/tk85.dll"; then
+ AC_MSG_ERROR([Please configure and make the ../win directory first.])
+ fi
;;
dgux*)
SHLIB_CFLAGS="-K PIC"
diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c
index e7bf78d..904c9db 100644
--- a/unix/tclUnixNotfy.c
+++ b/unix/tclUnixNotfy.c
@@ -99,9 +99,16 @@ typedef struct ThreadSpecificData {
* from these pointers. You must hold the
* notifierMutex lock before accessing these
* fields. */
+#ifdef __CYGWIN__
+ void *event; /* Any other thread alerts a notifier
+ * that an event is ready to be processed
+ * by sending this event. */
+ void *hwnd; /* Messaging window. */
+#else /* !__CYGWIN__ */
Tcl_Condition waitCV; /* Any other thread alerts a notifier that an
* event is ready to be processed by signaling
* this condition variable. */
+#endif /* __CYGWIN__ */
int eventReady; /* True if an event is ready to be processed.
* Used as condition flag together with waitCV
* above. */
@@ -205,6 +212,48 @@ static int FileHandlerEventProc(Tcl_Event *evPtr, int flags);
*----------------------------------------------------------------------
*/
+#if defined(TCL_THREADS) && defined(__CYGWIN__)
+
+typedef struct {
+ void *hwnd;
+ unsigned int *message;
+ int wParam;
+ int lParam;
+ int time;
+ int x;
+ int y;
+} MSG;
+
+typedef struct {
+ unsigned int style;
+ void *lpfnWndProc;
+ int cbClsExtra;
+ int cbWndExtra;
+ void *hInstance;
+ void *hIcon;
+ void *hCursor;
+ void *hbrBackground;
+ void *lpszMenuName;
+ void *lpszClassName;
+} WNDCLASS;
+
+extern unsigned char __stdcall PeekMessageW(MSG *, void *, int, int, int);
+extern unsigned char __stdcall GetMessageW(MSG *, void *, int, int);
+extern unsigned char __stdcall TranslateMessage(const MSG *);
+extern int __stdcall DispatchMessageW(const MSG *);
+extern void __stdcall PostQuitMessage(int);
+extern void * __stdcall CreateWindowExW(void *, void *, void *, DWORD, int, int, int, int, void *, void *, void *, void *);
+extern unsigned char __stdcall DestroyWindow(void *);
+extern unsigned char __stdcall PostMessageW(void *, unsigned int, void *, void *);
+extern void *__stdcall RegisterClassW(const WNDCLASS *);
+extern DWORD __stdcall DefWindowProcW(void *, int, void *, void *);
+extern void *__stdcall CreateEventW(void *, unsigned char, unsigned char, void *);
+extern void __stdcall CloseHandle(void *);
+extern void __stdcall MsgWaitForMultipleObjects(DWORD, void *, unsigned char, DWORD, DWORD);
+extern unsigned char __stdcall ResetEvent(void *);
+
+#endif
+
ClientData
Tcl_InitNotifier(void)
{
@@ -308,7 +357,11 @@ Tcl_FinalizeNotifier(
* Clean up any synchronization objects in the thread local storage.
*/
+#ifdef __CYGWIN__
+ CloseHandle(tsdPtr->event);
+#else /* __CYGWIN__ */
Tcl_ConditionFinalize(&(tsdPtr->waitCV));
+#endif /* __CYGWIN__ */
Tcl_MutexUnlock(&notifierMutex);
#endif
@@ -341,7 +394,11 @@ Tcl_AlertNotifier(
ThreadSpecificData *tsdPtr = (ThreadSpecificData *) clientData;
Tcl_MutexLock(&notifierMutex);
tsdPtr->eventReady = 1;
+#ifdef __CYGWIN__
+ PostMessageW(tsdPtr->hwnd, 1024, 0, 0);
+#else
Tcl_ConditionNotify(&tsdPtr->waitCV);
+#endif
Tcl_MutexUnlock(&notifierMutex);
#endif
}
@@ -641,6 +698,31 @@ FileHandlerEventProc(
return 1;
}
+#if defined(TCL_THREADS) && defined(__CYGWIN__)
+
+static DWORD __stdcall
+NotifierProc(
+ void *hwnd,
+ unsigned int message,
+ void *wParam,
+ void *lParam)
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+ if (message != 1024) {
+ return DefWindowProcW(hwnd, message, wParam, lParam);
+ }
+
+ /*
+ * Process all of the runnable events.
+ */
+
+ tsdPtr->eventReady = 1;
+ Tcl_ServiceAll();
+ return 0;
+}
+#endif /* __CYGWIN__ */
+
/*
*----------------------------------------------------------------------
*
@@ -669,6 +751,9 @@ Tcl_WaitForEvent(
Tcl_Time vTime;
#ifdef TCL_THREADS
int waitForFiles;
+# ifdef __CYGWIN__
+ MSG msg;
+# endif
#else
/*
* Impl. notes: timeout & timeoutPtr are used if, and only if threads are
@@ -756,6 +841,29 @@ Tcl_WaitForEvent(
tsdPtr->pollState = 0;
}
+#ifdef __CYGWIN__
+ if (!tsdPtr->hwnd) {
+ WNDCLASS class;
+
+ class.style = 0;
+ class.cbClsExtra = 0;
+ class.cbWndExtra = 0;
+ class.hInstance = TclWinGetTclInstance();
+ class.hbrBackground = NULL;
+ class.lpszMenuName = NULL;
+ class.lpszClassName = L"TclNotifier";
+ class.lpfnWndProc = NotifierProc;
+ class.hIcon = NULL;
+ class.hCursor = NULL;
+
+ RegisterClassW(&class);
+ tsdPtr->hwnd = CreateWindowExW(NULL, class.lpszClassName, class.lpszClassName,
+ 0, 0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL);
+ tsdPtr->event = CreateEventW(NULL, 1 /* manual */,
+ 0 /* !signaled */, NULL);
+ }
+
+#endif
if (waitForFiles) {
/*
* Add the ThreadSpecificData structure of this thread to the list of
@@ -781,10 +889,41 @@ Tcl_WaitForEvent(
FD_ZERO(&(tsdPtr->readyMasks.exceptional));
if (!tsdPtr->eventReady) {
+#ifdef __CYGWIN__
+ if (!PeekMessageW(&msg, NULL, 0, 0, 0)) {
+ DWORD timeout;
+ if (timePtr) {
+ timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
+ } else {
+ timeout = 0xFFFFFFFF;
+ }
+ Tcl_MutexUnlock(&notifierMutex);
+ MsgWaitForMultipleObjects(1, &tsdPtr->event, 0, timeout, 1279);
+ Tcl_MutexLock(&notifierMutex);
+ }
+#else
Tcl_ConditionWait(&tsdPtr->waitCV, &notifierMutex, timePtr);
+#endif
}
tsdPtr->eventReady = 0;
+#ifdef __CYGWIN__
+ while (PeekMessageW(&msg, NULL, 0, 0, 0)) {
+ /*
+ * Retrieve and dispatch the message.
+ */
+ DWORD result = GetMessageW(&msg, NULL, 0, 0);
+ if (result == 0) {
+ PostQuitMessage(msg.wParam);
+ /* What to do here? */
+ } else if (result != (DWORD)-1) {
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+ }
+ ResetEvent(tsdPtr->event);
+#endif
+
if (waitForFiles && tsdPtr->onList) {
/*
* Remove the ThreadSpecificData structure of this thread from the
@@ -1042,7 +1181,11 @@ NotifierThreadProc(
tsdPtr->onList = 0;
tsdPtr->pollState = 0;
}
- Tcl_ConditionNotify(&tsdPtr->waitCV);
+#ifdef __CYGWIN__
+ PostMessageW(tsdPtr->hwnd, 1024, 0, 0);
+#else /* __CYGWIN__ */
+ Tcl_ConditionNotify(&tsdPtr->waitCV);
+#endif /* __CYGWIN__ */
}
}
Tcl_MutexUnlock(&notifierMutex);