In Tcl_ChannelType, the second spot is the version field, a pointer to
struct Tcl_ChannelTypeVersion_, see tcl.h. For historic reasons, that's
where the ExpBlockModeProc function pointer sits. llvm22 is unhappy:

/usr/obj/ports/expect-5.45.4/expect5.45.4/exp_chan.c:62:5: error: incompatible 
pointer types initializing 'Tcl_ChannelTypeVersion' (aka 'struct 
Tcl_ChannelTypeVersion_ *') with an expression of type 'int (ClientData, int)' 
(aka 'int (void *, int)') [-Wincompatible-pointer-types]
   62 |     ExpBlockModeProc,                   /* Set blocking/nonblocking 
mode.*/

The intention is that works via this piece of beauty in lang/tcl/8.x:

Tcl_DriverBlockModeProc *
Tcl_ChannelBlockModeProc(
    const Tcl_ChannelType *chanTypePtr)
                                /* Pointer to channel type. */
{
    if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_2)) {
        return chanTypePtr->blockModeProc;
    } else {
        /*
         * The v1 structure had the blockModeProc in a different place.
         */

        return (Tcl_DriverBlockModeProc *) (chanTypePtr->version);
    }
}

Now, passing a function pointer through a normal pointer is undefined
behavior, so I'm a bit uneasy with doing this, although it currently
works:

-    ExpBlockModeProc,                  /* Set blocking/nonblocking mode.*/
+    (Tcl_ChannelTypeVersion)ExpBlockModeProc, /* Set blocking/nonblocking 
mode.*/

I decided to set the version to 2 and to move the ExpBlockModeProc to
the proper spot in the struct.

But perhaps that breaks something else. For example, it seems that
Tcl 9 only supports TCL_CHANNEL_VERSION_5...

Index: Makefile
===================================================================
RCS file: /cvs/ports/lang/expect/Makefile,v
diff -u -p -r1.77 Makefile
--- Makefile    21 Jan 2026 22:03:31 -0000      1.77
+++ Makefile    20 May 2026 20:49:33 -0000
@@ -1,6 +1,8 @@
 COMMENT =      sophisticated scripter based on Tcl/Tk
 
 VERSION =      5.45.4
+REVISION =     0
+
 DISTNAME =     expect${VERSION}
 PKGNAME =      expect-${VERSION}
 SHARED_LIBS =  expect5454 0.0
Index: patches/patch-exp_chan_c
===================================================================
RCS file: /cvs/ports/lang/expect/patches/patch-exp_chan_c,v
diff -u -p -r1.2 patch-exp_chan_c
--- patches/patch-exp_chan_c    11 Mar 2022 19:28:56 -0000      1.2
+++ patches/patch-exp_chan_c    20 May 2026 21:20:44 -0000
@@ -1,7 +1,10 @@
 Get rid of implicit declaration of function warning
 
---- exp_chan.c.orig    Thu Sep  9 19:29:43 2010
-+++ exp_chan.c Thu Sep  9 19:30:27 2010
+error: incompatible pointer types initializing 'Tcl_ChannelTypeVersion' (aka 
'struct Tcl_ChannelTypeVersion_ *') with an expression of type 'int 
(ClientData, int)' (aka 'int (void *, int)') [-Wincompatible-pointer-types]
+
+Index: exp_chan.c
+--- exp_chan.c.orig
++++ exp_chan.c
 @@ -37,6 +37,7 @@
  #include "exp_log.h"
  #include "tcldbg.h" /* Dbg_StdinMode */
@@ -10,3 +13,20 @@ Get rid of implicit declaration of funct
  extern int            expSetBlockModeProc _ANSI_ARGS_((int fd, int mode));
  static int            ExpBlockModeProc _ANSI_ARGS_((ClientData instanceData,
                            int mode));
+@@ -58,7 +59,7 @@ static int           ExpGetHandleProc 
_ANSI_ARGS_((ClientData i
+ 
+ Tcl_ChannelType expChannelType = {
+     "exp",                            /* Type name. */
+-    ExpBlockModeProc,                 /* Set blocking/nonblocking mode.*/
++    TCL_CHANNEL_VERSION_2,            /* Version. */
+     ExpCloseProc,                     /* Close proc. */
+     ExpInputProc,                     /* Input proc. */
+     ExpOutputProc,                    /* Output proc. */
+@@ -68,6 +69,7 @@ Tcl_ChannelType expChannelType = {
+     ExpWatchProc,                     /* Initialize notifier. */
+     ExpGetHandleProc,                 /* Get OS handles out of channel. */
+     NULL,                             /* Close2 proc */
++    ExpBlockModeProc,                 /* Set blocking/nonblocking mode.*/
+ };
+ 
+ typedef struct ThreadSpecificData {

Reply via email to