Skip to content

Commit 0dbf9e8

Browse files
committed
Builds for Tcl 8 and 9. Passes test suite on Win and Ubuntu
1 parent 25eae97 commit 0dbf9e8

File tree

11 files changed

+2627
-3625
lines changed

11 files changed

+2627
-3625
lines changed

configure

Lines changed: 2528 additions & 3565 deletions
Large diffs are not rendered by default.

configure.ac

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,8 @@ AC_CONFIG_AUX_DIR(tclconfig)
3434
#--------------------------------------------------------------------
3535

3636
TEA_PATH_TCLCONFIG
37-
if test x"${with_tcl8}" != x; then
38-
with_tcl8=""
39-
AC_MSG_WARN([--with-tcl8 option ignored])
40-
fi
4137
TEA_LOAD_TCLCONFIG
4238

43-
if test "${TCL_MAJOR_VERSION}" -eq 8; then
44-
AC_MSG_ERROR([${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 9.0+
45-
Found config for Tcl ${TCL_VERSION}])
46-
fi
47-
4839
#--------------------------------------------------------------------
4940
# Load the tkConfig.sh file if necessary (Tk extension)
5041
#--------------------------------------------------------------------
@@ -213,16 +204,19 @@ TEA_PROG_TCLSH
213204
#--------------------------------------------------------------------
214205
# Zipfs support - Tip 430
215206
#--------------------------------------------------------------------
216-
AC_ARG_ENABLE(zipfs,
217-
AS_HELP_STRING([--enable-zipfs],[build with Zipfs support (default: on)]),
218-
[tcl_ok=$enableval], [tcl_ok=yes])
219-
if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then
220-
ZIPFS_BUILD=1
221-
THREAD_ZIP_FILE=lib${PACKAGE_NAME}${PACKAGE_VERSION}.zip
222-
else
223-
ZIPFS_BUILD=0
224-
THREAD_ZIP_FILE=
207+
if test "${TCL_MAJOR_VERSION}" -gt 8; then
208+
AC_ARG_ENABLE(zipfs,
209+
AS_HELP_STRING([--enable-zipfs],[build with Zipfs support (default: on)]),
210+
[tcl_ok=$enableval], [tcl_ok=yes])
211+
if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then
212+
ZIPFS_BUILD=1
213+
THREAD_ZIP_FILE=lib${PACKAGE_NAME}${PACKAGE_VERSION}.zip
214+
else
215+
ZIPFS_BUILD=0
216+
THREAD_ZIP_FILE=
217+
fi
225218
fi
219+
226220
# Do checking message here to not mess up interleaved configure output
227221
AC_MSG_CHECKING([for building with zipfs])
228222
if test "${ZIPFS_BUILD}" = 1; then

generic/tclThread.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,34 @@
2222

2323
#include <tcl.h>
2424

25+
/*
26+
* Bunch of Tcl8 and Tcl9 compatibility definitions.
27+
*/
28+
#ifdef Tcl_Size
29+
# undef Tcl_Size
30+
typedef int Tcl_Size;
31+
#endif
32+
#ifndef TCL_INDEX_NONE
33+
# define TCL_INDEX_NONE (-1)
34+
#endif
35+
36+
#if TCL_MAJOR_VERSION < 9
37+
typedef Tcl_ObjCmdProc Tcl_ObjCmdProc2;
38+
# ifndef TCL_HASH_TYPE
39+
# define TCL_HASH_TYPE size_t
40+
# endif
41+
#endif
42+
43+
#ifndef TCL_Z_MODIFIER
44+
# if defined(__GNUC__) && !defined(_WIN32)
45+
# define TCL_Z_MODIFIER "z"
46+
# elif defined(_WIN64)
47+
# define TCL_Z_MODIFIER TCL_LL_MODIFIER
48+
# else
49+
# define TCL_Z_MODIFIER ""
50+
# endif
51+
#endif /* !TCL_Z_MODIFIER */
52+
2553
/*
2654
* Exported from threadCmd.c file.
2755
*/

generic/tclThreadInt.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ MODULE_SCOPE const char *TpoolInit(Tcl_Interp *interp);
135135
* Utility macros
136136
*/
137137

138+
#if TCL_MAJOR_VERSION < 9
139+
# define Tcl_CreateObjCommand2 Tcl_CreateObjCommand
140+
#endif
138141
#define TCL_CMD(a,b,c) \
139142
if (Tcl_CreateObjCommand2((a),(b),(c),NULL, NULL) == NULL) \
140143
return NULL;
@@ -147,6 +150,19 @@ MODULE_SCOPE const char *TpoolInit(Tcl_Interp *interp);
147150
(ThreadSpecificData*)Tcl_GetThreadData((keyPtr),sizeof(ThreadSpecificData))
148151
#endif
149152

153+
#ifdef TCL_QUEUE_ALERT_IF_EMPTY
154+
static inline void
155+
ThreadQueueEvent(Tcl_ThreadId thrId, Tcl_Event *evPtr, int position) {
156+
Tcl_ThreadQueueEvent(thrId, evPtr, position|TCL_QUEUE_ALERT_IF_EMPTY);
157+
}
158+
#else
159+
static inline void
160+
ThreadQueueEvent(Tcl_ThreadId thrId, Tcl_Event *evPtr, int position) {
161+
Tcl_ThreadQueueEvent(thrId, evPtr, position);
162+
Tcl_ThreadAlert(thrId);
163+
}
164+
#endif
165+
150166
/*
151167
* Structure to pass to NsThread_Init. This holds the module
152168
* and virtual server name for proper interp initializations.

generic/tclXkeylist.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,9 @@ const Tcl_ObjType keyedListType = {
312312
DupKeyedListInternalRep, /* dupIntRepProc */
313313
UpdateStringOfKeyedList, /* updateStringProc */
314314
NULL, /* setFromAnyProc */
315+
#if TCL_MAJOR_VERSION >= 9
315316
TCL_OBJTYPE_V0
317+
#endif
316318
};
317319

318320

generic/threadCmd.c

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -375,25 +375,15 @@ static const char *
375375
ThreadInit(
376376
Tcl_Interp *interp /* The current Tcl interpreter */
377377
) {
378-
/* Tcl 8.7 interps are only supported on 32-bit machines.
379-
* Lower than that is never supported. Bye!
380-
*/
381-
#if defined(TCL_WIDE_INT_IS_LONG) && TCL_MAJOR_VERSION < 9
382-
# error "Thread 3.0 is only supported with Tcl 9.0 and higher."
383-
# error "Please use Thread 2.8 (branch thread-2-8-branch)"
384-
#endif
385-
386-
/* Even though it's not supported, Thread 3.0 works with Tcl 8.7
387-
* on 32-bit platforms, so allow that for now. It could be that
388-
* Tcl 9.0 introduces a further binary incompatibility in the
389-
* future, so this is not guaranteed to stay like it is now!
390-
*/
391-
const char *ver = (sizeof(size_t) == sizeof(int))? "8.7-": "9.0";
392-
393-
if (!((Tcl_InitStubs)(interp, ver, (TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16),
394-
TCL_STUB_MAGIC))) {
378+
#ifdef USE_TCL_STUBS
379+
if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
395380
return NULL;
396381
}
382+
#else
383+
if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 0) == NULL) {
384+
return NULL;
385+
}
386+
#endif
397387

398388
if (threadMutex == NULL){
399389
Tcl_MutexLock(&threadMutex);
@@ -2469,7 +2459,7 @@ ThreadTransfer(
24692459
* Queue the event and poke the other thread's notifier.
24702460
*/
24712461

2472-
Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)evPtr, TCL_QUEUE_TAIL|TCL_QUEUE_ALERT_IF_EMPTY);
2462+
ThreadQueueEvent(thrId, (Tcl_Event *)evPtr, TCL_QUEUE_TAIL);
24732463

24742464
/*
24752465
* (*) Block until the other thread has either processed the transfer
@@ -2810,9 +2800,9 @@ ThreadSend(
28102800

28112801
eventPtr->event.proc = ThreadEventProc;
28122802
if ((flags & THREAD_SEND_HEAD)) {
2813-
Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_HEAD|TCL_QUEUE_ALERT_IF_EMPTY);
2803+
ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_HEAD);
28142804
} else {
2815-
Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_TAIL|TCL_QUEUE_ALERT_IF_EMPTY);
2805+
ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_TAIL);
28162806
}
28172807

28182808
if ((flags & THREAD_SEND_WAIT) == 0) {
@@ -3087,7 +3077,7 @@ ThreadReserve(
30873077
evPtr->clbkData = NULL;
30883078
evPtr->resultPtr = resultPtr;
30893079

3090-
Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)evPtr, TCL_QUEUE_TAIL|TCL_QUEUE_ALERT_IF_EMPTY);
3080+
ThreadQueueEvent(thrId, (Tcl_Event*)evPtr, TCL_QUEUE_TAIL);
30913081

30923082
if (dowait) {
30933083
while (resultPtr->result == NULL) {

generic/threadPoolCmd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1815,7 +1815,7 @@ SignalWaiter(
18151815
evPtr = (Tcl_Event *)Tcl_Alloc(sizeof(Tcl_Event));
18161816
evPtr->proc = RunStopEvent;
18171817

1818-
Tcl_ThreadQueueEvent(waitPtr->threadId,(Tcl_Event*)evPtr,TCL_QUEUE_TAIL|TCL_QUEUE_ALERT_IF_EMPTY);
1818+
ThreadQueueEvent(waitPtr->threadId,(Tcl_Event*)evPtr,TCL_QUEUE_TAIL);
18191819
}
18201820

18211821
/*

generic/threadSpCmd.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,8 @@ ThreadMutexObjCmd(
190190
static const char *const cmdOpts[] = {
191191
"create", "destroy", "lock", "unlock", NULL
192192
};
193-
enum options {
194-
m_CREATE, m_DESTROY, m_LOCK, m_UNLOCK
195-
} opt;
193+
enum options { m_CREATE, m_DESTROY, m_LOCK, m_UNLOCK };
194+
int opt;
196195

197196
/*
198197
* Syntax:
@@ -367,7 +366,8 @@ ThreadRWMutexObjCmd(
367366
};
368367
enum options {
369368
w_CREATE, w_DESTROY, w_RLOCK, w_WLOCK, w_UNLOCK
370-
} opt;
369+
};
370+
int opt;
371371

372372
/*
373373
* Syntax:
@@ -527,9 +527,8 @@ ThreadCondObjCmd(
527527
static const char *const cmdOpts[] = {
528528
"create", "destroy", "notify", "wait", NULL
529529
};
530-
enum options {
531-
c_CREATE, c_DESTROY, c_NOTIFY, c_WAIT
532-
} opt;
530+
enum options { c_CREATE, c_DESTROY, c_NOTIFY, c_WAIT };
531+
int opt;
533532

534533
/*
535534
* Syntax:

generic/threadSvCmd.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,8 @@ SvArrayObjCmd(
12331233
enum options {
12341234
ASET, ARESET, AGET, ANAMES, ASIZE, AEXISTS, AISBOUND,
12351235
ABIND, AUNBIND
1236-
} index;
1236+
};
1237+
int index;
12371238

12381239
svObj = (Container*)arg;
12391240

generic/threadSvListCmd.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,25 @@
1313
#include "threadSvCmd.h"
1414
#include "threadSvListCmd.h"
1515

16+
/* Tcl 8 only defines Tcl_GetIntForIndex in its internal stubs */
17+
#if TCL_MAJOR_VERSION < 9 && defined(USE_TCL_STUBS)
18+
/* Little hack to eliminate the need for "tclInt.h" here:
19+
Just copy a small portion of TclIntStubs, just
20+
enough to make it work */
21+
typedef struct TclIntStubs {
22+
int magic;
23+
void *hooks;
24+
void (*dummy[34]) (void); /* dummy entries 0-33, not used */
25+
int (*tclGetIntForIndex) (Tcl_Interp *interp, Tcl_Obj *objPtr, int endValue, int *indexPtr); /* 34 */
26+
} TclIntStubs;
27+
extern const TclIntStubs *tclIntStubsPtr;
28+
29+
# undef Tcl_GetIntForIndex
30+
# define Tcl_GetIntForIndex(interp, obj, max, ptr) ((tclIntStubsPtr->tclGetIntForIndex == NULL)? \
31+
((int (*)(Tcl_Interp*, Tcl_Obj *, int, int*))(void *)((&(tclStubsPtr->tcl_PkgProvideEx))[645]))((interp), (obj), (max), (ptr)): \
32+
tclIntStubsPtr->tclGetIntForIndex((interp), (obj), (max), (ptr)))
33+
#endif
34+
1635
/*
1736
* Implementation of list commands for shared variables.
1837
* Most of the standard Tcl list commands are implemented.
@@ -661,7 +680,8 @@ SvLsearchObjCmd(
661680
Container *svObj = (Container*)arg;
662681

663682
static const char *const modes[] = {"-exact", "-glob", "-regexp", NULL};
664-
enum {LS_EXACT, LS_GLOB, LS_REGEXP} mode;
683+
enum { LS_EXACT, LS_GLOB, LS_REGEXP };
684+
int mode;
665685

666686
mode = LS_GLOB;
667687

0 commit comments

Comments
 (0)