Skip to content

Commit d3d6b96

Browse files
author
jan.nijtmans
committed
Make everything work for Tcl 8.6+ too
2 parents 25eae97 + c055621 commit d3d6b96

File tree

12 files changed

+162
-96
lines changed

12 files changed

+162
-96
lines changed

.github/workflows/linux-build.yml

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,48 @@ jobs:
1212
matrix:
1313
compiler:
1414
- "gcc"
15+
- "clang"
1516
steps:
1617
- name: Checkout
1718
uses: actions/checkout@v4
18-
- name: Setup Environment
19+
- name: Setup Environment (compiler=${{ matrix.compiler }})
1920
run: |
21+
sudo apt-get install tcl8.6-dev libgdbm-dev liblmdb-dev
22+
mkdir "$HOME/install dir"
2023
curl https://core.tcl-lang.org/tclconfig/tarball/main/tclconfig.tar.gz >tclconfig.tar.gz
2124
tar xfz tclconfig.tar.gz
22-
- name: Configure (not really, just enough to do a "make dist")
25+
echo "CFGOPT=--with-tcl=/usr/lib/tcl8.6 --with-gdbm --with-lmdb" >> $GITHUB_ENV
26+
echo "CC=$COMPILER" >> $GITHUB_ENV
27+
env:
28+
COMPILER: ${{ matrix.compiler }}
29+
OPTS: ${{ matrix.compiler }}
30+
- name: Configure
2331
run: |
24-
sed s/@srcdir@/\./ <Makefile.in | sed s/@abs_top_builddir@/./ | sed s/@SHELL@/bash/ | sed s/@PACKAGE_NAME@/thread/ | sed s/@PACKAGE_VERSION@/9.0a1/ | sed "s/@INSTALL@/tclconfig\/install-sh/" | sed "s/@INSTALL_DATA_DIR@/tclconfig\/install-sh -d -m 755/" >Makefile
25-
touch config.status
32+
./configure $CFGOPT "--prefix=$HOME/install dir" "--exec-prefix=$HOME/install dir" || {
33+
cat config.log
34+
echo "::error::Failure during Configure"
35+
exit 1
36+
}
37+
- name: Build
38+
run: |
39+
make || {
40+
echo "::error::Failure during Build"
41+
exit 1
42+
}
43+
- name: Run Tests
44+
run: |
45+
make test || {
46+
echo "::error::Failure during Test"
47+
exit 1
48+
}
49+
env:
50+
ERROR_ON_FAILURES: 1
51+
- name: Test-Drive Installation
52+
run: |
53+
make install || {
54+
echo "::error::Failure during Install"
55+
exit 1
56+
}
2657
- name: Create Distribution Package
2758
run: |
2859
make dist || {

configure

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2834,11 +2834,6 @@ printf "%s\n" "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
28342834
fi
28352835
fi
28362836

2837-
if test x"${with_tcl8}" != x; then
2838-
with_tcl8=""
2839-
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl8 option ignored" >&5
2840-
printf "%s\n" "$as_me: WARNING: --with-tcl8 option ignored" >&2;}
2841-
fi
28422837

28432838

28442839

@@ -4027,11 +4022,6 @@ printf "%s\n" "#define BUILD_${SAFE_PKG_NAME} /**/" >>confdefs.h
40274022

40284023

40294024

4030-
if test "${TCL_MAJOR_VERSION}" -eq 8; then
4031-
as_fn_error $? "${PACKAGE_NAME} ${PACKAGE_VERSION} requires Tcl 9.0+
4032-
Found config for Tcl ${TCL_VERSION}" "$LINENO" 5
4033-
fi
4034-
40354025
#--------------------------------------------------------------------
40364026
# Load the tkConfig.sh file if necessary (Tk extension)
40374027
#--------------------------------------------------------------------
@@ -9468,7 +9458,8 @@ printf "%s\n" "${TCLSH_PROG}" >&6; }
94689458
#--------------------------------------------------------------------
94699459
# Zipfs support - Tip 430
94709460
#--------------------------------------------------------------------
9471-
# Check whether --enable-zipfs was given.
9461+
if test "${TCL_MAJOR_VERSION}" -gt 8; then
9462+
# Check whether --enable-zipfs was given.
94729463
if test ${enable_zipfs+y}
94739464
then :
94749465
enableval=$enable_zipfs; tcl_ok=$enableval
@@ -9477,13 +9468,15 @@ else case e in #(
94779468
esac
94789469
fi
94799470

9480-
if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then
9481-
ZIPFS_BUILD=1
9482-
THREAD_ZIP_FILE=lib${PACKAGE_NAME}${PACKAGE_VERSION}.zip
9483-
else
9484-
ZIPFS_BUILD=0
9485-
THREAD_ZIP_FILE=
9471+
if test "$tcl_ok" = "yes" -a "x$enable_framework" != "xyes"; then
9472+
ZIPFS_BUILD=1
9473+
THREAD_ZIP_FILE=lib${PACKAGE_NAME}${PACKAGE_VERSION}.zip
9474+
else
9475+
ZIPFS_BUILD=0
9476+
THREAD_ZIP_FILE=
9477+
fi
94869478
fi
9479+
94879480
# Do checking message here to not mess up interleaved configure output
94889481
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5
94899482
printf %s "checking for building with zipfs... " >&6; }

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: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,36 @@
2222

2323
#include <tcl.h>
2424

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

generic/tclThreadInt.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@
6565

6666
#if (TCL_MAJOR_VERSION == 8) && defined(USE_TCL_STUBS)
6767
#undef Tcl_Free
68-
#define Tcl_Free(p) tclStubsPtr->tcl_Free((void *)(p))
68+
#define Tcl_Free(p) tclStubsPtr->tcl_Free((char *)(p))
6969
#undef Tcl_Realloc
70-
#define Tcl_Realloc(p,m) tclStubsPtr->tcl_Realloc((void *)(p),(m))
70+
#define Tcl_Realloc(p,m) tclStubsPtr->tcl_Realloc((char *)(p),(m))
7171
#endif
7272

7373
#ifndef JOIN
@@ -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, Tcl_QueuePosition 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, Tcl_QueuePosition 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: 7 additions & 4 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

@@ -861,7 +863,7 @@ TclX_KeyedListGet(
861863
) {
862864
keylIntObj_t *keylIntPtr;
863865
const char *nextSubKey;
864-
size_t findIdx;
866+
Tcl_Size findIdx;
865867

866868
if (keylPtr->typePtr != &keyedListType) {
867869
if (SetKeyedListFromAny(interp, keylPtr) != TCL_OK) {
@@ -919,7 +921,7 @@ TclX_KeyedListSet(
919921
) {
920922
keylIntObj_t *keylIntPtr;
921923
const char *nextSubKey;
922-
size_t findIdx;
924+
Tcl_Size findIdx;
923925
int status;
924926
size_t keyLen;
925927
Tcl_Obj *newKeylPtr;
@@ -1022,7 +1024,7 @@ TclX_KeyedListDelete(
10221024
) {
10231025
keylIntObj_t *keylIntPtr, *subKeylIntPtr;
10241026
const char *nextSubKey;
1025-
size_t findIdx;
1027+
Tcl_Size findIdx;
10261028
int status;
10271029

10281030
if (keylPtr->typePtr != &keyedListType) {
@@ -1102,7 +1104,8 @@ TclX_KeyedListGetKeys(
11021104
keylIntObj_t *keylIntPtr;
11031105
Tcl_Obj *nameObjPtr, *listObjPtr;
11041106
const char *nextSubKey;
1105-
size_t idx, findIdx;
1107+
size_t idx;
1108+
Tcl_Size findIdx;
11061109

11071110
if (keylPtr->typePtr != &keyedListType) {
11081111
if (SetKeyedListFromAny(interp, keylPtr) != TCL_OK) {

generic/threadCmd.c

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -375,23 +375,7 @@ 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+
if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) {
395379
return NULL;
396380
}
397381

@@ -2469,7 +2453,7 @@ ThreadTransfer(
24692453
* Queue the event and poke the other thread's notifier.
24702454
*/
24712455

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

24742458
/*
24752459
* (*) Block until the other thread has either processed the transfer
@@ -2810,9 +2794,9 @@ ThreadSend(
28102794

28112795
eventPtr->event.proc = ThreadEventProc;
28122796
if ((flags & THREAD_SEND_HEAD)) {
2813-
Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_HEAD|TCL_QUEUE_ALERT_IF_EMPTY);
2797+
ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_HEAD);
28142798
} else {
2815-
Tcl_ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_TAIL|TCL_QUEUE_ALERT_IF_EMPTY);
2799+
ThreadQueueEvent(thrId, (Tcl_Event*)eventPtr, TCL_QUEUE_TAIL);
28162800
}
28172801

28182802
if ((flags & THREAD_SEND_WAIT) == 0) {
@@ -3015,7 +2999,8 @@ ThreadReserve(
30152999
int operation, /* THREAD_RESERVE | THREAD_RELEASE */
30163000
int wait /* Wait for thread to exit */
30173001
) {
3018-
int users, dowait = 0;
3002+
Tcl_Size users;
3003+
int dowait = 0;
30193004
ThreadEvent *evPtr;
30203005
ThreadSpecificData *tsdPtr;
30213006

@@ -3087,7 +3072,7 @@ ThreadReserve(
30873072
evPtr->clbkData = NULL;
30883073
evPtr->resultPtr = resultPtr;
30893074

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

30923077
if (dowait) {
30933078
while (resultPtr->result == NULL) {
@@ -3301,12 +3286,12 @@ ThreadSetResult(
33013286
result = "no target interp!";
33023287
size = strlen(result);
33033288
resultPtr->result = (size) ?
3304-
memcpy(Tcl_Alloc(1+size), result, 1+size) : threadEmptyResult;
3289+
(char *)memcpy(Tcl_Alloc(1+size), result, 1+size) : threadEmptyResult;
33053290
} else {
33063291
result = Tcl_GetString(Tcl_GetObjResult(interp));
33073292
size = Tcl_GetObjResult(interp)->length;
33083293
resultPtr->result = (size) ?
3309-
memcpy(Tcl_Alloc(1+size), result, 1+size) : threadEmptyResult;
3294+
(char *)memcpy(Tcl_Alloc(1+size), result, 1+size) : threadEmptyResult;
33103295
if (code == TCL_ERROR) {
33113296
errorCode = Tcl_GetVar2(interp, "errorCode", NULL, TCL_GLOBAL_ONLY);
33123297
errorInfo = Tcl_GetVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY);
@@ -3743,7 +3728,7 @@ ThreadExitProc(
37433728
* because the main thread is going to call free on it.
37443729
*/
37453730

3746-
resultPtr->result = strcpy(Tcl_Alloc(1+strlen(diemsg)), diemsg);
3731+
resultPtr->result = strcpy((char *)Tcl_Alloc(1+strlen(diemsg)), diemsg);
37473732
resultPtr->code = TCL_ERROR;
37483733
resultPtr->errorCode = resultPtr->errorInfo = NULL;
37493734
Tcl_ConditionNotify(&resultPtr->done);

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
/*

0 commit comments

Comments
 (0)