critcl_tcl93tcl
How to adapt critcl packages for tcl 9
Overview
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::tclBefore CriTcl 3.3.1 a single default (
8.4) was used for the minimum Tcl version, to be overriden by an explicitcritcl::tclin 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, and8.6else. Note how this other default was bumped up from8.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.2for 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::tclout of the code and using the propertclshversion 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 withcritcl::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_SavedResultand its associated functionsTcl_SaveResult,Tcl_RestoreResult, andTcl_DiscardResult.When a package uses this type and the related functions a rewrite is necessary.
With Tcl 9 use of type
Tcl_InterpStateand its functionsTcl_SaveInterpState,Tcl_RestoreInterpState, andTcl_DiscardInterpStateis now required.As these were introduced with Tcl 8.5 the rewrite gives us compatibility with Tcl 8.6 for free.
- [2]
-
Tcl_SizeOne 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
intwas replaced withTcl_Size, which is effectivelyptrdiff_tbehind the scenes.The "tclpre9compat.h" header mentioned above provides a suitable definition of
Tcl_Sizefor8.6, i.e. maps it toint. This enables the package code to useTcl_Sizeeverywhere 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_Sizeoverint.Note that it is necessary to manually check the package code for places where a
%dtext formatting specification should be replaced withTCL_SIZE_FMT.I.e. all places where
Tcl_Sizevalues are formatted withprintf-style functions a formatting string"... %d ..."
- has
-
"... " TCL_SIZE_FMT " ..."
The macro
TCL_SIZE_FMTis defined by Critcl's compatibility layer, as an extension of theTCL_SIZE_MODIFIERmacro which only contains the formatting modifier to insert into a plain%dto handleTcl_Sizevalues.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_Sizechanges.All places using
Tcl_CreateObjCommandhave to be rewritten to useTcl_CreateObjCommand2instead, and the registered command functions to useTcl_Sizefor 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
-1to 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_FAILURE
- •
-
TCL_AUTO_LENGTH
- •
-
TCL_INDEX_NONE
Critcl's compatibility layer provides the same constants to Tcl 8.6.
Critcl's new checker highlights places where
TCL_AUTO_LENGTHis 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
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