 |
|
| |
critcl_tcl9(n) |
C Runtime In Tcl (CriTcl) |
critcl_tcl9(n) |
critcl_tcl9 - How To Adapt Critcl Packages for Tcl 9
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
- 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_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_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.
- [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
Jean Claude Wippler, Steve Landers, Andreas Kupries
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.
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
Copyright (c) Jean-Claude Wippler
Copyright (c) Steve Landers
Copyright (c) 2011-2024 Andreas Kupries
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc.
|