plucky (3) critcl_tcl9.3tcl.gz

Provided by: critcl_3.3.1+dfsg-1_amd64 bug

NAME

       critcl_tcl9 - How To Adapt Critcl Packages for Tcl 9

DESCRIPTION

       Be  welcome  to the C Runtime In Tcl (short: CriTcl), a system for embedding and using C code from within
       Tcl [http://core.tcl-lang.org/tcl] scripts.

       This guide contains notes and actions to take by writers of CriTcl-based  packages  to  make  their  code
       workable for both Tcl 8.6 and 9.

       [1]    Generally,  if  there  is  no interest in moving to Tcl 9, i.e. Tcl 8.[456] are the only supported
              runtimes, then just keep using CriTcl 3.2.

              The remainder of this document can be ignored.

       [2]    Use CriTcl version 3.3.1 if, and only if Tcl 9 support is wanted.

              With some work this will then also provide backward compatibility with Tcl 8.6.

       [3]    Header "tcl.h"

              Replace any inclusion of Tcl's public "tcl.h" header  file  in  the  package's  C  code  with  the
              inclusion of CriTcl's new header file "tclpre9compat.h".

              This  includes  "tcl.h"  and  further  provides  a  set  of  compatibility  definitions which make
              supporting both Tcl 8.6 and Tcl 9 in a single code base easier.

              The following notes assume that this compatibility layer is in place.

       [4]    critcl::tcl

              Before CriTcl 3.3.1 a single default (8.4) was used for the minimum Tcl version, to  be  overriden
              by an explicit critcl::tcl in the package code.

              Now the default is dynamic, based on the runtime version, i.e.  package provide Tcl, CriTcl is run
              with/on.

              When running on Tcl 9 the new default is version 9, and 8.6 else.  Note how this other default was
              bumped up from 8.4.

              As a consequence it is possible to

              [1]    Support just Tcl 8.4+, 8.5+, by having an explicit critcl::tcl 8.x in the package code.

                     Remember however, it is better to simply stick with CriTcl 3.2 for this.

              [2]    Support just Tcl 9 by having an explicit critcl::tcl 9 in the package code.

              [3]    Support both Tcl 8.6 and Tcl 9 (but not 8.4/8.5) by leaving critcl::tcl out of the code and
                     using the proper tclsh version to run CriTcl with.

       [5]    Code checking

              CriTcl 3.3.1 comes with a very basic set of code checks pointing out  places  where  compatibility
              might or will be an issue.

              The  implementation  checks  all  inlined  C  code  declared  by  critcl::ccode, critcl::ccommand,
              critcl::cproc (and related/derived commands), as well as  the  C  companion  files  declared  with
              critcl::csources.

              It  is  very  basic  because  it  simply  greps the code line by line for a number of patterns and
              reports on their presence. The C code is not fully parsed.  The check can and will report  pattern
              found in C code comments, for example.

              The main patterns deal with functions affected by the change to Tcl_Size, the removal of old-style
              interpreter state handling, and command creation.

              A warning message is printed for all detections.

              This is disabled for the Tcl_Size-related pattern if the line also matches the pattern *OK tcl9*.

              In this way all places in the code already handled can be marked and excluded from the warnings.

              [1]    Interpreter State handling

                     Tcl 9 removed  the  type  Tcl_SavedResult  and  its  associated  functions  Tcl_SaveResult,
                     Tcl_RestoreResult, and Tcl_DiscardResult.

                     When a package uses this type and the related functions a rewrite is necessary.

                     With   Tcl   9   use   of  type  Tcl_InterpState  and  its  functions  Tcl_SaveInterpState,
                     Tcl_RestoreInterpState, and Tcl_DiscardInterpState is now required.

                     As these were introduced with Tcl 8.5 the rewrite gives us compatibility with Tcl  8.6  for
                     free.

              [2]    Tcl_Size

                     One  of  the  main  changes introduced with Tcl 9 is the breaking of the 2G barrier for the
                     number of bytes in a string, elements in a list, etc.  In  a  lot  of  interfaces  int  was
                     replaced with Tcl_Size, which is effectively ptrdiff_t behind the scenes.

                     The "tclpre9compat.h" header mentioned above provides a suitable definition of Tcl_Size for
                     8.6, i.e. maps it to int.  This enables the package code to  use  Tcl_Size  everywhere  and
                     still have it work for both Tcl 8.6 and 9.

                     It is of course necessary to rewrite the package code to use Tcl_Size.

                     The checker reports all lines in the C code using a function whose signature was changed to
                     use Tcl_Size over int.

                     Note that it is necessary to manually check the package code for places  where  a  %d  text
                     formatting specification should be replaced with TCL_SIZE_FMT.

                     I.e.  all  places  where  Tcl_Size  values  are  formatted  with  printf-style  functions a
                     formatting string

                     "... %d ..."

              has

                     "... " TCL_SIZE_FMT " ..."

              The macro TCL_SIZE_FMT is defined  by  Critcl's  compatibility  layer,  as  an  extension  of  the
              TCL_SIZE_MODIFIER  macro  which only contains the formatting modifier to insert into a plain %d to
              handle Tcl_Size values.

              Note how the original formatting string is split into multiple strings.  The C compiler will  fuse
              these back together into a single string.

              [3]    Command creation.

                     This is technically a part of the Tcl_Size changes.

                     All  places  using  Tcl_CreateObjCommand  have to be rewritten to use Tcl_CreateObjCommand2
                     instead, and the registered command functions to use Tcl_Size for their objc argument.

                     The "tclpre9compat.h" header maps this back to the old function when  compilation  is  done
                     against Tcl 8.6.

                     CriTcl  does  this itself for the commands created via critcl::ccommand, critcl::cproc, and
                     derived places (critcl::class).

              [4]    TIP 494. This TIP adds three semantic constants wrapping -1 to Tcl 9 to make the meaning of
                     code clearer. As part of this it also casts the constant to the proper type. They are:

                     •      TCL_IO_FAILURETCL_AUTO_LENGTHTCL_INDEX_NONE

              Critcl's compatibility layer provides the same constants to Tcl 8.6.

              Critcl's new checker highlights places where TCL_AUTO_LENGTH is suitable.

              Doing this for the other two constants looks to require deeper and proper parsing of C code, which
              the checker does not do.

ADDITIONAL REFERENCES

       [1]    https://wiki.tcl-lang.org/page/Porting+extensions+to+Tcl+9

       [2]    https://wiki.tcl-lang.org/page/Tcl+9+functions+using+Tcl%5FSize

       [3]    https://core.tcl-lang.org/tcl/wiki?name=Migrating%20scripts%20to%20Tcl%209

       [4]    https://core.tcl-lang.org/tcl/wiki?name=Migrating%20C%20extensions%20to%20Tcl%209

AUTHORS

       Jean Claude Wippler, Steve Landers, Andreas Kupries

BUGS, IDEAS, FEEDBACK

       This document, and the package it describes, will undoubtedly contain bugs and  other  problems.   Please
       report them at https://github.com/andreas-kupries/critcl/issues.  Ideas for enhancements you may have for
       either package, application, and/or the documentation are also very welcome and  should  be  reported  at
       https://github.com/andreas-kupries/critcl/issues as well.

KEYWORDS

       C  code,  Embedded C Code, calling C code from Tcl, code generator, compile & run, compiler, dynamic code
       generation, dynamic compilation, generate package, linker, on demand compilation, on-the-fly compilation

CATEGORY

       Glueing/Embedded C code

       Copyright (c) Jean-Claude Wippler
       Copyright (c) Steve Landers
       Copyright (c) 2011-2024 Andreas Kupries