JLy%        ,  /      %4C 3K##)*>5/>D3-# QcԀ ͼ ȼcritcl.tkd :jq|ƂȂʁ%        ,  /      %4C 3K##)*>5/>D3-# D ::::._x[F%gUb_bD ::::._x[F%gUb_b]ELE.*o clean the fileitcl cache. YoG;O EGB*DAGO<;Eb_b```ffffffffffffff```f`f```+;;;;;>E.*o clean the fileitcl cache. YoG;O EGB*DAGO<;ECritcl - Embed C code in Tcl scriptsWiKitSearchAbout CritclRecent ChangesHistoryFormatting Rules7Contents.cgi.tcloptions.tclfiles...cachefiles...filesCritcl CacheForce compilationKeepShared LibraryPackageCompile and RunCriTcl BenefitsMD5CriTcl ReferenceCriTcl Overviewgcccompiledcritcl::cproccritcl::ccodecritcl::ccommandcritcl::cachecritcl::cdatacritcl::compilingcritcl::scriptingcritcl::failedcritcl::donecritcl::tsourcescritcl::platformCriTcl Procedures pageshared librariesStarkitTcl Stubsinclusion of both Tcl and C implementationsActiveTclTclKitDual Tcl and C ImplementationsstubsTcler's WikiWriting extensions for stubs and pre-stubs TclJean-Claude WipplerPaul DuffinJan NijtmansTcl/TkMetaKitincrTcltclvfsMemchanCriTcl TutorialsCriTcl ProceduresTutorial 1Tutorial 2CriTcl TutorialBlowfishBuild FeaturesCritLibpackagesDocumentationHints-crossCross compilingCross compilingkeepinfo sharedlibextensionStarkitCross compilingCleanvery longCritcl configurationstring match *-macosx $platformauto_execok clstring\ match\ *-macosx\ \$platform\info\ exists\ ::env(SDKROOT)\string length MacOSXglob\ -tails\ -directory\ /Developer/SDKs\ MacOSX*\string\ trimright\ \\ { [file rootname [string range $dir $pos endpackage\ vcompare\ \$ver\ 10.4\llength\ \$sdklist\lindex [lsort -command "package vcompare" $sdklistexec\ grep\ -m1\ MACOSX_DEPLOYMENT_TARGET\ \\ { $SDKROOT/SDKSettings.pliststring trim [lindex [split $info =split $::tcl_platform(osVersion) .exec lipo -info /usr/lib/libSystem.dylibsplit [string trim [lindex [split $info :expr\ \{\[exec\ gcc\ -v\ -arch\ ppc\ >\ /dev/null\ 2>@stdout\exec\ gcc\ -v\ -arch\ i386\ >\ /dev/null\ 2>@stdout\info exists ::env(SDKROOT)glob -tails -directory /Developer/SDKs MacOSX*string trimright \ [file rootname [string range $dir $pos endpackage vcompare $ver 10.4llength $sdklistexec grep -m1 MACOSX_DEPLOYMENT_TARGET \ $SDKROOT/SDKSettings.plistexpr {[exec gcc -v -arch ppc > /dev/null 2>@stdoutexec gcc -v -arch i386 > /dev/null 2>@stdoutCode - showconfigfile join [file directory $wikidirCode: showconfigCode - showpage[Code - showpage][Code - showconfig]Code - platformsCode - showallconfigCode - platforms]`[Critcl overview][Critcl reference][Critcl tutorials][Hints][Critcl procedures][package][Critcl configuration][Critcl cache][Cross compiling]'''Critcl''' allows C code to be embedded in Tcl scripts, and called like any Tcl procedure. Critcl allows you to go the last few percent that scripting can't take you - without losing the many benefits of a scripted approach to software development. For more information see the [Critcl Overview], [Critcl Reference], [Critcl Tutorials] and [Hints] pages. See also [Cross compiling] for information on generating Windows packages on Linux or Unix. To [compile and run] a Tcl script containing C procedure definitions === critcl ''options'' ''filename''[[.tcl]] === To build a [shared library] or [package] === critcl ''options'' [['''-lib'''|'''-pkg''']] ''name'' ''[files...]'' === Options include: +++ -clean clean out the [Critcl cache before compiling -debug create debug symbols in compiled code -force [Force compilation] of C files -help display this help wiki -target ''target'' generate binary for specified target platform/architecture -show show the [Critcl configuration] options being used -test perform a simple test to see if Critcl works on the current platform +++ Other options that are useful for controlling Critcl's behaviour in specialised situations (e.g. when invoking Critcl from within a Makefile or debugging the generated C code): +++ -I ''dir'' adds ''dir'' to the include path when compiling -cache ''dir'' sets the Critcl cache directory to ''dir'' (default is ~/.critcl) -keep [keep] intermediate C files in the [Critcl cache] -config ''file'' read the Critcl configuration options from ''file'' -libdir ''dir'' location of generated library/package (defaults to ./lib) -showall show [Critcl configuration] for all supported platforms -targets show all available target platforms +++ Examples: * build a package (these are equivalent - the .tcl is optional) === $ critcl -pkg ''yourpackage''.tcl $ critcl -pkg ''yourpackage'' === * compile (if necessary), load and run a script === $ critcl ''yourscript'' === * clean out the [Critcl cache] === $ critcl -clean === * compile a package, forcing compilation and keeping intermediate C files - this is a really long line really long line really long line === $ critcl -force -keep ''yourpackage'' === * show [Critcl configuration] for the current platform === $ critcl -show =====This page is generated by ''WiKit'', a "wiki wiki web" implementation based on Tcl, Tk, and MetaKit. See http://www.equi4.com/wikit/ for further details.''This page is a placeholder - do not change for now...CriTcl started life as an experiment by '''Jean-Claude Wippler'''. It was somewhat inspired by Brian Ingerson's Inline for Perl, but is considerably more lightweight. Subsequently, Jean-Claude implemented [CritLib] - a set of Tcl extensions - and CritBind - a utility script that uses CriTcl to build a [Shared Library] out of the CritLib extensions. CritLib provided valuable experience in building common compiled Tcl/Tk extensions, including blowfish, mathf, md5c, tkHtml and zlib (see http://equi4.com/critlib). '''Steve Landers''' adapted CriTcl to generate [package]s, added the [build features], this [Documentation], [Starkit] and [Cross compiling] support. ''Something about licensing?'' ''Ackowledge other packages used?'' ''Show current version number?'' ''History of changes?'' ''Acknowlege Eolas's sponsorship'' Jean-Claude Wippler Steve Landers 2''This page is a placeholder - do not change for now...''''This page is a placeholder - do not change for now...'''''References:''' 1. You can refer to another page by putting its name in square brackets like this: [[PAGE]] 1. URLs will automatically be recognized and underlined: http://your.site/contents.html 1. If you put URLs in square brackets, they'll be shown as a tiny reference [http://your.site/contents.html] instead. ''In this situation'', the system assumes that any url ending in '''.jpg''', '''.png''', or '''.gif''' is an image and displays it inline. 1. URL methods recognized are: * http://www.w3.org/ * ftp://ftp.x.org/ * mailto:user@somehost.com * news:comp.lang.tcl '''Adding highlights:''' * Surround text by pairs of single quotes to make it ''display in italic'' * Surround text by triples of single quotes to make it '''display in bold''' '''Adding structure to your text:''' * Lines of text are normally joined, with empty lines used to delineate paragraphs * Lines starting with three spaces, a "*", and another space are shown as bulleted items. The entire item must be entered as one line (possibly wrapping). * Lines starting with three spaces, a "1.", and another space are shown as a numbered list. Each numbered item must be entered as one logical line. 1. first numbered bullet 1. second numbered bullet * Lines starting with three spaces, item tag name, ":", three spaces, and then the item tag body (entered as 1 logical line) are shown as taggest lists. tag: text tag: text2 All other lines beginning with white space are shown as is - no highlighting, reference generating, or even text wrapping occur. * Put four or more dashes on a line to get a horizontal separator, like the "----" below: ---- ''Using brackets in your text'' can be done by doubling them, so '''[[[[''' shows as '''[['''.''This page is a placeholder - do not change for now...General +++ Overview [Critcl overview] Reference [Critcl reference] Tutorials [Critcl tutorials] Hints [Hints] +++ References +++ Procedures [Critcl procedures] Commands [package] +++ Advanced +++ Configuration [Critcl configuration] Cache [Critcl cache] X-compiling [Cross compiling] +++''# this code is executed on each CGI invocation # pages which may not be edited through CGI (page 9 better be included!) set ProtectedPages {1 2 3 4 5 6 7 8 9} # the text that gets shown at the bottom of an edit page set EditInstructions {
Editing quick-reference:
LINK to [Formatting Rules] - or to http://here.com/ - use [http://here.com/] to show as [1]
BULLETS are lines with 3 spaces, an asterisk, a space - the item must be one (wrapped) line
PARAGRAPHS are split with empty lines, UNFORMATTED TEXT starts with white space
HIGHLIGHTS are indicated by groups of single quotes - use two for ''italics'', three for '''bold'''
SECTIONS can be separated with a horizontal line - insert a line containing just 4 dashes

}The '''.tcl''' file extension is optional. When looking for source files, CriTcl will append a '''.tcl''' if necessary.The option '''files...''' tells CriTcl which Tcl files to process. If omitted, CriTcl looks for ''name''.tcl, where ''name'' is the name of the library or package specifiedThe ''files...'' argument is optional. If not specified, CriTcl will look for ''name''.tclCritcl caches all object files in a per-user directory (by default, ~/.critcl) to avoid recompiling generated C code on subsequent uses. Separate subdirectories are used for each platform, so the CriTcl cache may be on a shared volume. An [MD5] checksum of each source file is kept in the cache, so CriTcl is able to determine if the source has changed and needs regenerating and recompiling. Usually the generated C code is deleted between invocations of Critcl, but the -[keep] flag can be used to tell Critcl to retain the generated C code, should you wish to view it. The -[Clean] flag is used to clean out the files in the Critcl cache.The '''-force''' flag causes CriTcl to compile all C files, replacing the content of the [Critcl Cache] even if the C source files haven't changed.The '''-keep''' flag causes Critcl to retain intermediate C files in the [Critcl cache]. Usually intermediate C files are deleted after a successful compilation.CriTcl allows C procedure definitions to be embedded in Tcl scripts, and compiles the C code into a Tcl/Tk extension on the fly. The C code is * wrapped into something that can be compiled into a Tcl extension, * (if necessary) [compiled] when the end user runs the application * and then dynamically loaded into the running Tcl/Tk interpreter. An [MD5] checksum is generated for each source file, and this and the compiled shared library are cached (see [CriTcl cache]). The checksum is used to decide if the code needs re-compiling, so subsequent use is almost instantaneous. The use of Tcl stubs, and the fact that CriTcl has all the include files it needs to make compilation self-contained, means that this is a pure Tcl package, which works with any (8.1 and up) installation of Tcl. See also [CriTcl Benefits]CriTcl addresses the (often heard but equally often fallacious) concern that "scripting programs are too slow". Rather than build in a compiled language, CriTcl allows an application to be developed in Tcl/Tk (with all the associated productivity and flexibility benefits). In the event that a performance bottleneck is identified, CriTcl allows that bottleneck to be re-cast in C. But more importantly, it allows this decision to be deferred - there's no sense in scratching before it itches. And by allowing the developer to continue working with Tcl, it increases the chances that performance will addressed at the architectural level.Place holder for the Critcl overviewe. A '''Starkit''' is a single file (compressed) packaging of Tcl scripts, platform specific compiled code and application data; designed to facilitate simple deployment of cross platform applications. They are made '''cross platform''' by developing in '''Tcl/Tk''' wherever possible, and by including compiled extensions for multiple platforms if necessary. Starkits are interpreted using [TclKit] - a platform specific single file Tcl/Tk interpreter. You will need to download TclKit for each platform that you want to run a Starkit on. There is an archive of Starkits available at http://mini.net/sdarchive/n. '''TclKit''' is the name of a package which combines the standard Tcl/Tk distribution (tcl, msgcat, http, tcltest, opt, etc.), MetaKit, the zlib library), incrTcl and tclvfs (vfslib, zipvfs, scripdoc), Memchan and a couple of other packages (pwb, rechan). The best introduction to TclKit is probably at http://www.equi4.com/tclkit. The result is a single stand-alone executable, which acts as hassle-free runtime for [Starkit]s, or you can use it like any other Tcl/Tk system. It embeds all the startup scripts and support libraries in the executable, and loads Tk optionally so it can be used as either tclsh or wish - although on Windows and Mac (prior to MacOS X) this dual use is not possible. The point of all this? TclKit is ''single'' file which acts as 100% complete runtime for Tcl/Tk without requiring any installation: * '''install == cp/copy''' * '''uninstall == rm/del''' ''Things can't really get much simpler...'' There are over a dozen platform builds ready to use, including many Unix systems, Windows, and Macintosh. See the TclKit homepage at: http://www.equi4.com/tclkit/ The Windows and Linux TclKit binaries are compressed, and are automatically decompressed at run-time (using UPX). They therefore offer an extremely small footprint Tcl/Tk (around 800k on Windows). Each TclKit distribution will fit on a floppy (though on some platforms it will have to be bzip2-compressed). In addition, the size of TclKit binaries - and Starkits in general - is reduced because all embedded data is zlib-compressed.[Tutorial 1] - [compile and run] a Tcl script with embedded C procedures [Tutorial 2] - build a [Blowfish] encryption [package]Example use of C procedures within a Tcl script ---- '''Example Script - tst.tcl''' package require critcl critcl::cproc noop {} void {} critcl::cproc add {int x int y} int { return x + y; } critcl::cproc cube {int x} int { return x * x * x; } puts "add 123 456 : [add 123 456]" catch {add 1} err; puts "add 1 : $err" catch {add 1 2 3} err; puts "add 1 2 3 : $err" catch {add 0 zero} err; puts "add 0 zero : $err" proc sum {a b} { return [expr {$a+$b}] } proc pow3 {a} { return [expr {$a*$a*$a}] } proc ntimes {n cmd t} { set on $n set r {} while {[incr n -1] >= 0} { lappend r $cmd } set v [uplevel 1 [list time [join $r {; }] $t]] return [lreplace $v 0 0 [expr {[lindex $v 0]/(1.0*$on)}]] } puts "" puts "Tcl noop: [ntimes 100 {} 1000]" puts " C noop: [ntimes 100 {noop} 1000]" set a 1 set b 2 puts "" puts "Tcl expr: [ntimes 100 {expr {1+2}} 1000]" puts "Tcl vars: [ntimes 100 {expr {$a+$b}} 1000]" puts "Tcl sum: [ntimes 100 {sum 1 2} 1000]" puts " C add: [ntimes 100 {add 1 2} 1000]" puts " C vars: [ntimes 100 {add $a $b} 1000]" puts "" puts "Tcl expr: [ntimes 100 {expr {2*2*2}} 1000]" puts "Tcl vars: [ntimes 100 {expr {$b*$b*$b}} 1000]" puts "Tcl pow3: [ntimes 100 {pow3 2} 1000]" puts " C cube: [ntimes 100 {cube 2} 1000]" puts " C vars: [ntimes 100 {cube $b} 1000]" ---- '''Run Using''' critcl tst.tcl '''Sample output''' add 123 456 : 579 add 1 : wrong # args: should be "add x y" add 1 2 3 : wrong # args: should be "add x y" add 0 zero : expected integer but got "zero" Tcl noop: 0.01 microseconds per iteration C noop: 1.04 microseconds per iteration Tcl expr: 0.51 microseconds per iteration Tcl vars: 2.47 microseconds per iteration Tcl sum: 4.39 microseconds per iteration C add: 1.51 microseconds per iteration C vars: 3.7 microseconds per iteration Tcl expr: 0.89 microseconds per iteration Tcl vars: 3.81 microseconds per iteration Tcl pow3: 4.79 microseconds per iteration C cube: 1.35 microseconds per iteration C vars: 2.46 microseconds per iteration Build a [Package] from for Eric Young's implementation of Blowfish encryption ---- '''blowfish.tcl''' if {[catch {package require critcl}] \ || ![critcl::compiling]} { puts stderr "This package cannot be compiled without critcl enabled" exit 1 } package provide blowfish 0.10 namespace eval blowfish { critcl::cheaders blowfish_c/*.h critcl::csources blowfish_c/*.c critcl::ccode { #include "blowfish.h" } critcl::ccommand blowfish {dummy ip objc objv} { int index, dlen, klen, count = 0; unsigned char *data, *key; Tcl_Obj *obj; BF_KEY kbuf; unsigned char ivec[] = {0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; static char* cmds[] = { "encode", "decode", NULL }; if (objc != 4) { Tcl_WrongNumArgs(ip, 1, objv, "mode data key"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(ip, objv[1], cmds, "option", 0, &index) != TCL_OK) return TCL_ERROR; obj = objv[2]; if (Tcl_IsShared(obj)) obj = Tcl_DuplicateObj(obj); data = Tcl_GetByteArrayFromObj(obj, &dlen); key = Tcl_GetByteArrayFromObj(objv[3], &klen); BF_set_key(&kbuf, klen, key); BF_cfb64_encrypt(data, data, dlen, &kbuf, ivec, &count, index == 0 ? BF_ENCRYPT : BF_DECRYPT); Tcl_SetObjResult(ip, obj); return TCL_OK; } }The CriTcl documentation is implemented using a local mode Wiki (see http://wiki.tcl.tk/wiki for more information on Wiki's). It is implemented using the WiKit Tcl/Tk wiki implementation (see http://wiki.tcl.tk/wikit). If you want to build your own wiki, download http://www.equi4.com/pub/sk/wikit.kit. You'll also need TclKit but you may already have that if you are running CriTcl (see http://www.equi4.com/tclkit) * when developing, don't use the [critcl::failed] package to detect if the compilation failed, because it stops compile errors being displayed on stderr - wait until you have finished developing and then use something like the following at the end of your CriTcl script if {[critcl::failed]} { puts stderr "compiled failed - check in [critcl::cache] for errors" m.CriTcl supports cross compiling libraries and packages for Windows on Linux/Unix using the Xmingwin cross-compiler (based on mingw - http://www.mingw.org). To set up an Xmingwin cross compiler use the script provided by Mo de Jong, available at http://mini.net/sdarchive/xmingwin.sh. The script downloads Xmingwin, builds it and installs under /usr/local/Xmingwin (you can edit the script and change the PREFIX variable if you want to install it elsewhere). Once you have Xmingwin installed, you'll need to set your PATH to include the Xmingwin bin directory before using CriTcl. One convenient way of doing this is to create a script called ''cross'' (in /usr/local/bin or ~/bin). $ cat /usr/local/bin/cross PATH=/usr/local/Xmingwin/i386-mingw32msvc/bin:$PATH export PATH exec $@ Then, you can cross compile using the standard CriTcl package building commands $ cross critcl -pkg yourpkg Cross compiling for Windows using Xmingwin Source: yourpkg.tcl Library: yourpkg.dll Package: /path/to/yourpkg/lib/yourpkg When Critcl recognises a cross compiler environment, it manipulates the tcl_platform array to match that found on Windows 2000. Specifically, the following values are set tcl_platform(byteOrder) = littleEndian tcl_platform(machine) = intel tcl_platform(os) = Windows NT tcl_platform(osVersion) = 5.0 tcl_platform(platform) = windows tcl_platform(wordSize) = 4 Intermediate files are be stored in '''~/.critcl/Windows-x86''' (irrespective of the platform on which cross compiling occurs) and the shared library extension can be obtained via the '''critcl::sharedlibext''' procedure (which should be used instead of '''info sharedlibextension''').The '''-clean''' flag is used to clean the files in the Critcl cache. You can also use the critcl::clean_cache procedure from within your Critcl scriptThe Critcl configuration information is stored in the '''Config''' file within the Critcl package. This contains a description of the compiler toolchain commands and features available on each supported platform, and allows Critcl to be more easily ported to a new platform or compiler. This version of Critcl is supported on the following platforms: ` +eval [Code - platforms] ` Several Critcl options can be used to view or modify the configuration information +++ critcl '''-show''' displays the configuration for the current platform critcl '''-targets''' displays the list of supported target platforms critcl '''-showall''' displays the configuration for all supported platforms critcl '''-config''' ''file'' reads the Critcl configuration from the specified file +++ For example, the output of the '''critcl -show''' command on the current platform is: ====== +eval [Code - showconfig] ====== The configuration file for all supported platforms is ====== +eval [Code - showallconfig] ====== ====== # show current Critcl configuration package require critcl 2.0 critcl::showconfig ====== ====== # show supported platforms package require critcl 2.0 set critcl::v::platforms ====== ====== # show Critcl configuration file package require critcl 2.0 critcl::showallconfig ======s..ws C code to be em]EL\ /dev/null\ 2>@stdout\exec\ gcc\ -v\ -arch\ i386\ >\ /dev/null\ 2>@stdout\info exists ::env(SDKROOT)glob -tails -directory /Developer/SDKs MacOSX*string trimright \ [file rootname [string range $dir $pos endpackage vcompare $ver 10.4llength $sdklistexec grep -m1 MACOSX_DEPLOYMENT_TARGET \ $SDKROOT/SDKSettings.plistexpr {[exec gcc -v -arch ppc > /dev/null 2>@stdoutexec gcc -v -arch i386 > /dev/null 2>@stdoutCode - showconfigfile join [file directory $wikidirCode: showconfigCode - showpage[Code - showpage][Code - showconfig]Code - platformsCode - showallconfigCode - platforms]`[Critcl overview][Critcl reference][Critcl tutorials][Hints][Critcl procedures][package][Critcl configuration][Critcl cache][Cross compiling]'''Critcl''' allows C code to be embedded in Tcl scripts, and called like any Tcl procedure. Critcl allows you to go the last few percent that scripting can't take you - without losing the many benefits of a scripted approach to software development. For more information see the [Critcl Overview], [Critcl Reference], [Critcl Tutorials] and [Hints] pages. See also [Cross compiling] for information on generating Windows packages on Linux or Unix. To [compile and run] a Tcl script containing C procedure definitions === critcl ''options'' ''filename''[[.tcl]] === To build a [shared library] or [package] === critcl ''options'' [['''-lib'''|'''-pkg''']] ''name'' ''[files...]'' === Options include: +++ -clean clean out the [Critcl cache before compiling -debug create debug symbols in compiled code -force [Force compilation] of C files -help display this help wiki -target ''target'' generate binary for specified target platform/architecture -show show the [Critcl configuration] options being used -test perform a simple test to see if Critcl works on the current platform +++ Other options that are useful for controlling Critcl's behaviour in specialised situations (e.g. when invoking Critcl from within a Makefile or debugging the generated C code): +++ -I ''dir'' adds ''dir'' to the include path when compiling -cache ''dir'' sets the Critcl cache directory to ''dir'' (default is ~/.critcl) -keep [keep] intermediate C files in the [Critcl cache] -config ''file'' read the Critcl configuration options from ''file'' -libdir ''dir'' location of generated library/package (defaults to ./lib) -showall show [Critcl configuration] for all supported platforms -targets show all available target platforms +++ Examples: * build a package (these are equivalent - the .tcl is optional) === $ critcl -pkg ''yourpackage''.tcl $ critcl -pkg ''yourpackage'' === * compile (if necessary), load and run a script === $ critcl ''yourscript'' === * clean out the [Critcl cache] === $ critcl -clean === * compile a package, forcing compilation and keeping intermediate C files - this is a really long line really long line really long line === $ critcl -force -keep ''yourpackage'' === * show [Critcl configuration] for the current platform === $ critcl -show =====This page is generated by ''WiKit'', a "wiki wiki web" implementation based on Tcl, Tk, and MetaKit. See http://www.equi4.com/wikit/ for further details.''This page is a placeholder - do not change for now...CriTcl started life as an experiment by '''Jean-Claude Wippler'''. It was somewhat inspired by Brian Ingerson's Inline for Perl, but is considerably more lightweight. Subsequently, Jean-Claude implemented [CritLib] - a set of Tcl extensions - and CritBind - a utility script that uses CriTcl to build a [Shared Library] out of the CritLib extensions. CritLib provided valuable experience in building common compiled Tcl/Tk extensions, including blowfish, mathf, md5c, tkHtml and zlib (see http://equi4.com/critlib). '''Steve Landers''' adapted CriTcl to generate [package]s, added the [build features], this [Documentation], [Starkit] and [Cross compiling] support. ''Something about licensing?'' ''Ackowledge other packages used?'' ''Show current version number?'' ''History of changes?'' ''Acknowlege Eolas's sponsorship'' Jean-Claude Wippler Steve Landers 2''This page is a placeholder - do not change for now...''''This page is a placeholder - do not change for now...'''''References:''' 1. You can refer to another page by putting its name in square brackets like this: [[PAGE]] 1. URLs will automatically be recognized and underlined: http://your.site/contents.html 1. If you put URLs in square brackets, they'll be shown as a tiny reference [http://your.site/contents.html] instead. ''In this situation'', the system assumes that any url ending in '''.jpg''', '''.png''', or '''.gif''' is an image and displays it inline. 1. URL methods recognized are: * http://www.w3.org/ * ftp://ftp.x.org/ * mailto:user@somehost.com * news:comp.lang.tcl '''Adding highlights:''' * Surround text by pairs of single quotes to make it ''display in italic'' * Surround text by triples of single quotes to make it '''display in bold''' '''Adding structure to your text:''' * Lines of text are normally joined, with empty lines used to delineate paragraphs * Lines starting with three spaces, a "*", and another space are shown as bulleted items. The entire item must be entered as one line (possibly wrapping). * Lines starting with three spaces, a "1.", and another space are shown as a numbered list. Each numbered item must be entered as one logical line. 1. first numbered bullet 1. second numbered bullet * Lines starting with three spaces, item tag name, ":", three spaces, and then the item tag body (entered as 1 logical line) are shown as taggest lists. tag: text tag: text2 All other lines beginning with white space are shown as is - no highlighting, reference generating, or even text wrapping occur. * Put four or more dashes on a line to get a horizontal separator, like the "----" below: ---- ''Using brackets in your text'' can be done by doubling them, so '''[[[[''' shows as '''[['''.''This page is a placeholder - do not change for now...General +++ Overview [Critcl overview] Reference [Critcl reference] Tutorials [Critcl tutorials] Hints [Hints] +++ References +++ Procedures [Critcl procedures] Commands [package] +++ Advanced +++ Configuration [Critcl configuration] Cache [Critcl cache] X-compiling [Cross compiling] +++''# this code is executed on each CGI invocation # pages which may not be edited through CGI (page 9 better be included!) set ProtectedPages {1 2 3 4 5 6 7 8 9} # the text that gets shown at the bottom of an edit page set EditInstructions {
Editing quick-reference:
LINK to [Formatting Rules] - or to http://here.com/ - use [http://here.com/] to show as [1]
BULLETS are lines with 3 spaces, an asterisk, a space - the item must be one (wrapped) line
PARAGRAPHS are split with empty lines, UNFORMATTED TEXT starts with white space
HIGHLIGHTS are indicated by groups of single quotes - use two for ''italics'', three for '''bold'''
SECTIONS can be separated with a horizontal line - insert a line containing just 4 dashes

}The '''.tcl''' file extension is optional. When looking for source files, CriTcl will append a '''.tcl''' if necessary.The option '''files...''' tells CriTcl which Tcl files to process. If omitted, CriTcl looks for ''name''.tcl, where ''name'' is the name of the library or package specifiedThe ''files...'' argument is optional. If not specified, CriTcl will look for ''name''.tclCritcl caches all object files in a per-user directory (by default, ~/.critcl) to avoid recompiling generated C code on subsequent uses. Separate subdirectories are used for each platform, so the CriTcl cache may be on a shared volume. An [MD5] checksum of each source file is kept in the cache, so CriTcl is able to determine if the source has changed and needs regenerating and recompiling. Usually the generated C code is deleted between invocations of Critcl, but the -[keep] flag can be used to tell Critcl to retain the generated C code, should you wish to view it. The -[Clean] flag is used to clean out the files in the Critcl cache.The '''-force''' flag causes CriTcl to compile all C files, replacing the content of the [Critcl Cache] even if the C source files haven't changed.The '''-keep''' flag causes Critcl to retain intermediate C files in the [Critcl cache]. Usually intermediate C files are deleted after a successful compilation.CriTcl allows C procedure definitions to be embedded in Tcl scripts, and compiles the C code into a Tcl/Tk extension on the fly. The C code is * wrapped into something that can be compiled into a Tcl extension, * (if necessary) [compiled] when the end user runs the application * and then dynamically loaded into the running Tcl/Tk interpreter. An [MD5] checksum is generated for each source file, and this and the compiled shared library are cached (see [CriTcl cache]). The checksum is used to decide if the code needs re-compiling, so subsequent use is almost instantaneous. The use of Tcl stubs, and the fact that CriTcl has all the include files it needs to make compilation self-contained, means that this is a pure Tcl package, which works with any (8.1 and up) installation of Tcl. See also [CriTcl Benefits]CriTcl addresses the (often heard but equally often fallacious) concern that "scripting programs are too slow". Rather than build in a compiled language, CriTcl allows an application to be developed in Tcl/Tk (with all the associated productivity and flexibility benefits). In the event that a performance bottleneck is identified, CriTcl allows that bottleneck to be re-cast in C. But more importantly, it allows this decision to be deferred - there's no sense in scratching before it itches. And by allowing the developer to continue working with Tcl, it increases the chances that performance will addressed at the architectural level.Place holder for the Critcl overviewe. A '''Starkit''' is a single file (compressed) packaging of Tcl scripts, platform specific compiled code and application data; designed to facilitate simple deployment of cross platform applications. They are made '''cross platform''' by developing in '''Tcl/Tk''' wherever possible, and by including compiled extensions for multiple platforms if necessary. Starkits are interpreted using [TclKit] - a platform specific single file Tcl/Tk interpreter. You will need to download TclKit for each platform that you want to run a Starkit on. There is an archive of Starkits available at http://mini.net/sdarchive/n. '''TclKit''' is the name of a package which combines the standard Tcl/Tk distribution (tcl, msgcat, http, tcltest, opt, etc.), MetaKit, the zlib library), incrTcl and tclvfs (vfslib, zipvfs, scripdoc), Memchan and a couple of other packages (pwb, rechan). The best introduction to TclKit is probably at http://www.equi4.com/tclkit. The result is a single stand-alone executable, which acts as hassle-free runtime for [Starkit]s, or you can use it like any other Tcl/Tk system. It embeds all the startup scripts and support libraries in the executable, and loads Tk optionally so it can be used as either tclsh or wish - although on Windows and Mac (prior to MacOS X) this dual use is not possible. The point of all this? TclKit is ''single'' file which acts as 100% complete runtime for Tcl/Tk without requiring any installation: * '''install == cp/copy''' * '''uninstall == rm/del''' ''Things can't really get much simpler...'' There are over a dozen platform builds ready to use, including many Unix systems, Windows, and Macintosh. See the TclKit homepage at: http://www.equi4.com/tclkit/ The Windows and Linux TclKit binaries are compressed, and are automatically decompressed at run-time (using UPX). They therefore offer an extremely small footprint Tcl/Tk (around 800k on Windows). Each TclKit distribution will fit on a floppy (though on some platforms it will have to be bzip2-compressed). In addition, the size of TclKit binaries - and Starkits in general - is reduced because all embedded data is zlib-compressed.[Tutorial 1] - [compile and run] a Tcl script with embedded C procedures [Tutorial 2] - build a [Blowfish] encryption [package]Example use of C procedures within a Tcl script ---- '''Example Script - tst.tcl''' package require critcl critcl::cproc noop {} void {} critcl::cproc add {int x int y} int { return x + y; } critcl::cproc cube {int x} int { return x * x * x; } puts "add 123 456 : [add 123 456]" catch {add 1} err; puts "add 1 : $err" catch {add 1 2 3} err; puts "add 1 2 3 : $err" catch {add 0 zero} err; puts "add 0 zero : $err" proc sum {a b} { return [expr {$a+$b}] } proc pow3 {a} { return [expr {$a*$a*$a}] } proc ntimes {n cmd t} { set on $n set r {} while {[incr n -1] >= 0} { lappend r $cmd } set v [uplevel 1 [list time [join $r {; }] $t]] return [lreplace $v 0 0 [expr {[lindex $v 0]/(1.0*$on)}]] } puts "" puts "Tcl noop: [ntimes 100 {} 1000]" puts " C noop: [ntimes 100 {noop} 1000]" set a 1 set b 2 puts "" puts "Tcl expr: [ntimes 100 {expr {1+2}} 1000]" puts "Tcl vars: [ntimes 100 {expr {$a+$b}} 1000]" puts "Tcl sum: [ntimes 100 {sum 1 2} 1000]" puts " C add: [ntimes 100 {add 1 2} 1000]" puts " C vars: [ntimes 100 {add $a $b} 1000]" puts "" puts "Tcl expr: [ntimes 100 {expr {2*2*2}} 1000]" puts "Tcl vars: [ntimes 100 {expr {$b*$b*$b}} 1000]" puts "Tcl pow3: [ntimes 100 {pow3 2} 1000]" puts " C cube: [ntimes 100 {cube 2} 1000]" puts " C vars: [ntimes 100 {cube $b} 1000]" ---- '''Run Using''' critcl tst.tcl '''Sample output''' add 123 456 : 579 add 1 : wrong # args: should be "add x y" add 1 2 3 : wrong # args: should be "add x y" add 0 zero : expected integer but got "zero" Tcl noop: 0.01 microseconds per iteration C noop: 1.04 microseconds per iteration Tcl expr: 0.51 microseconds per iteration Tcl vars: 2.47 microseconds per iteration Tcl sum: 4.39 microseconds per iteration C add: 1.51 microseconds per iteration C vars: 3.7 microseconds per iteration Tcl expr: 0.89 microseconds per iteration Tcl vars: 3.81 microseconds per iteration Tcl pow3: 4.79 microseconds per iteration C cube: 1.35 microseconds per iteration C vars: 2.46 microseconds per iteration Build a [Package] from for Eric Young's implementation of Blowfish encryption ---- '''blowfish.tcl''' if {[catch {package require critcl}] \ || ![critcl::compiling]} { puts stderr "This package cannot be compiled without critcl enabled" exit 1 } package provide blowfish 0.10 namespace eval blowfish { critcl::cheaders blowfish_c/*.h critcl::csources blowfish_c/*.c critcl::ccode { #include "blowfish.h" } critcl::ccommand blowfish {dummy ip objc objv} { int index, dlen, klen, count = 0; unsigned char *data, *key; Tcl_Obj *obj; BF_KEY kbuf; unsigned char ivec[] = {0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; static char* cmds[] = { "encode", "decode", NULL }; if (objc != 4) { Tcl_WrongNumArgs(ip, 1, objv, "mode data key"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(ip, objv[1], cmds, "option", 0, &index) != TCL_OK) return TCL_ERROR; obj = objv[2]; if (Tcl_IsShared(obj)) obj = Tcl_DuplicateObj(obj); data = Tcl_GetByteArrayFromObj(obj, &dlen); key = Tcl_GetByteArrayFromObj(objv[3], &klen); BF_set_key(&kbuf, klen, key); BF_cfb64_encrypt(data, data, dlen, &kbuf, ivec, &count, index == 0 ? BF_ENCRYPT : BF_DECRYPT); Tcl_SetObjResult(ip, obj); return TCL_OK; } }The CriTcl documentation is implemented using a local mode Wiki (see http://wiki.tcl.tk/wiki for more information on Wiki's). It is implemented using the WiKit Tcl/Tk wiki implementation (see http://wiki.tcl.tk/wikit). If you want to build your own wiki, download http://www.equi4.com/pub/sk/wikit.kit. You'll also need TclKit but you may already have that if you are running CriTcl (see http://www.equi4.com/tclkit) * when developing, don't use the [critcl::failed] package to detect if the compilation failed, because it stops compile errors being displayed on stderr - wait until you have finished developing and then use something like the following at the end of your CriTcl script if {[critcl::failed]} { puts stderr "compiled failed - check in [critcl::cache] for errors" m.CriTcl supports cross compiling libraries and packages for Windows on Linux/Unix using the Xmingwin cross-compiler (based on mingw - http://www.mingw.org). To set up an Xmingwin cross compiler use the script provided by Mo de Jong, available at http://mini.net/sdarchive/xmingwin.sh. The script downloads Xmingwin, builds it and installs under /usr/local/Xmingwin (you can edit the script and change the PREFIX variable if you want to install it elsewhere). Once you have Xmingwin installed, you'll need to set your PATH to include the Xmingwin bin directory before using CriTcl. One convenient way of doing this is to create a script called ''cross'' (in /usr/local/bin or ~/bin). $ cat /usr/local/bin/cross PATH=/usr/local/Xmingwin/i386-mingw32msvc/bin:$PATH export PATH exec $@ Then, you can cross compile using the standard CriTcl package building commands $ cross critcl -pkg yourpkg Cross compiling for Windows using Xmingwin Source: yourpkg.tcl Library: yourpkg.dll Package: /path/to/yourpkg/lib/yourpkg When Critcl recognises a cross compiler environment, it manipulates the tcl_platform array to match that found on Windows 2000. Specifically, the following values are set tcl_platform(byteOrder) = littleEndian tcl_platform(machine) = intel tcl_platform(os) = Windows NT tcl_platform(osVersion) = 5.0 tcl_platform(platform) = windows tcl_platform(wordSize) = 4 Intermediate files are be stored in '''~/.critcl/Windows-x86''' (irrespective of the platform on which cross compiling occurs) and the shared library extension can be obtained via the '''critcl::sharedlibext''' procedure (which should be used instead of '''info sharedlibextension''').The '''-clean''' flag is used to clean the files in the Critcl cache. You can also use the critcl::clean_cache procedure from within your Critcl scriptThe Critcl configuration information is stored in the '''Config''' file within the Critcl package. This contains a description of the compiler toolchain commands and features available on each supported platform, and allows Critcl to be more easily ported to a new platform or compiler. This version of Critcl is supported on the following platforms: ` +eval [Code - platforms] ` Several Critcl options can be used to view or modify the configuration information +++ critcl '''-show''' displays the configuration for the current platform critcl '''-targets''' displays the list of supported target platforms critcl '''-showall''' displays the configuration for all supported platforms critcl '''-config''' ''file'' reads the Critcl configuration from the specified file +++ For example, the output of the '''critcl -show''' command on the current platform is: ====== +eval [Code - showconfig] ====== The configuration file for all supported platforms is ====== +eval [Code - showallconfig] ====== ====== # show current Critcl configuration package require critcl 2.0 critcl::showconfig ====== ====== # show supported platforms package require critcl 2.0 set critcl::v::platforms ====== ====== # show Critcl configuration file package require critcl 2.0 critcl::showallconfig ======s..ws C code to be emted by ''WiKit'', a "wiki wiki web" implementation based on Tcl, Tk, and MetaKit. See http://www.equi4.com/wikit/ for further details.''This page is a placeholder - do not change for now...CriTcl started life as an experiment by '''Jean-Claude Wippler'''. It was somewhat inspired by Brian Ingerson's Inline for Perl, but is considerably more lightweight. Subsequently, Jean-Claude implemented [CritLib] - a set of Tcl extensions - and CritBind - a utility script that uses CriTcl to build a [Shared Library] out of the CritLib extensions. CritLib provided valuable experience in building common compiled Tcl/Tk extensions, including blowfish, mathf, md5c, tkHtml and zlib (see http://equi4.com/critlib). '''Steve Landers''' adapted CriTcl to generate [package]s, added the [build features], this [Documentation], [Starkit] and [Cross compiling] support. ''Something about licensing?'' ''Ackowledge other packages used?'' ''Show current version number?'' ''History of changes?'' ''Acknowlege Eolas's sponsorship'' Jean-Claude Wippler Steve Landers 2''This page is a placeholder - do not change for now...''''This page is a placeholder - do not change for now...'''''References:''' 1. You can refer to another page by putting its name in square brackets like this: [[PAGE]] 1. URLs will automatically be recognized and underlined: http://your.site/contents.html 1. If you put URLs in square brackets, they'll be shown as a tiny reference [http://your.site/contents.html] instead. ''In this situation'', the system assumes that any url ending in '''.jpg''', '''.png''', or '''.gif''' is an image and displays it inline. 1. URL methods recognized are: * http://www.w3.org/ * ftp://ftp.x.org/ * mailto:user@somehost.com * news:comp.lang.tcl '''Adding highlights:''' * Surround text by pairs of single quotes to make it ''display in italic'' * Surround text by triples of single quotes to make it '''display in bold''' '''Adding structure to your text:''' * Lines of text are normally joined, with empty lines used to delineate paragraphs * Lines starting with three spaces, a "*", and another space are shown as bulleted items. The entire item must be entered as one line (possibly wrapping). * Lines starting with three spaces, a "1.", and another space are shown as a numbered list. Each numbered item must be entered as one logical line. 1. first numbered bullet 1. second numbered bullet * Lines starting with three spaces, item tag name, ":", three spaces, and then the item tag body (entered as 1 logical line) are shown as taggest lists. tag: text tag: text2 All other lines beginning with white space are shown as is - no highlighting, reference generating, or even text wrapping occur. * Put four or more dashes on a line to get a horizontal separator, like the "----" below: ---- ''Using brackets in your text'' can be done by doubling them, so '''[[[[''' shows as '''[['''.''This page is a placeholder - do not change for now...General +++ Overview [Critcl overview] Reference [Critcl reference] Tutorials [Critcl tutorials] Hints [Hints] +++ Reference +++ Procedures [Critcl procedures] Commands [package] +++ Advanced +++ Configuration [Critcl configuration] Cache [Critcl cache] X-compiling [Cross compiling] +++''# this code is executed on each CGI invocation # pages which may not be edited through CGI (page 9 better be included!) set ProtectedPages {1 2 3 4 5 6 7 8 9} # the text that gets shown at the bottom of an edit page set EditInstructions {
Editing quick-reference:
LINK to [Formatting Rules] - or to http://here.com/ - use [http://here.com/] to show as [1]
BULLETS are lines with 3 spaces, an asterisk, a space - the item must be one (wrapped) line
PARAGRAPHS are split with empty lines, UNFORMATTED TEXT starts with white space
HIGHLIGHTS are indicated by groups of single quotes - use two for ''italics'', three for '''bold'''
SECTIONS can be separated with a horizontal line - insert a line containing just 4 dashes

}The '''.tcl''' file extension is optional. When looking for source files, CriTcl will append a '''.tcl''' if necessary.The option '''files...''' tells CriTcl which Tcl files to process. If omitted, CriTcl looks for ''name''.tcl, where ''name'' is the name of the library or package specifiedThe ''files...'' argument is optional. If not specified, CriTcl will look for ''name''.tclCritcl caches all object files in a per-user directory (by default, ~/.critcl) to avoid recompiling generated C code on subsequent uses. Separate subdirectories are used for each platform, so the CriTcl cache may be on a shared volume. An [MD5] checksum of each source file is kept in the cache, so CriTcl is able to determine if the source has changed and needs regenerating and recompiling. Usually the generated C code is deleted between invocations of Critcl, but the -[keep] flag can be used to tell Critcl to retain the generated C code, should you wish to view it. The -[Clean] flag is used to clean out the files in the Critcl cache.The '''-force''' flag causes CriTcl to compile all C files, replacing the content of the [Critcl Cache] even if the C source files haven't changed.The '''-keep''' flag causes Critcl to retain intermediate C files in the [Critcl cache]. Usually intermediate C files are deleted after a successful compilation.CriTcl allows C procedure definitions to be embedded in Tcl scripts, and compiles the C code into a Tcl/Tk extension on the fly. The C code is * wrapped into something that can be compiled into a Tcl extension, * (if necessary) [compiled] when the end user runs the application * and then dynamically loaded into the running Tcl/Tk interpreter. An [MD5] checksum is generated for each source file, and this and the compiled shared library are cached (see [CriTcl cache]). The checksum is used to decide if the code needs re-compiling, so subsequent use is almost instantaneous. The use of Tcl stubs, and the fact that CriTcl has all the include files it needs to make compilation self-contained, means that this is a pure Tcl package, which works with any (8.1 and up) installation of Tcl. See also [CriTcl Benefits]CriTcl addresses the (often heard but equally often fallacious) concern that "scripting programs are too slow". Rather than build in a compiled language, CriTcl allows an application to be developed in Tcl/Tk (with all the associated productivity and flexibility benefits). In the event that a performance bottleneck is identified, CriTcl allows that bottleneck to be re-cast in C. But more importantly, it allows this decision to be deferred - there's no sense in scratching before it itches. And by allowing the developer to continue working with Tcl, it increases the chances that performance will addressed at the architectural level.Place holder for the Critcl overviewe. A '''Starkit''' is a single file (compressed) packaging of Tcl scripts, platform specific compiled code and application data; designed to facilitate simple deployment of cross platform applications. They are made '''cross platform''' by developing in '''Tcl/Tk''' wherever possible, and by including compiled extensions for multiple platforms if necessary. Starkits are interpreted using [TclKit] - a platform specific single file Tcl/Tk interpreter. You will need to download TclKit for each platform that you want to run a Starkit on. There is an archive of Starkits available at http://mini.net/sdarchive/n. '''TclKit''' is the name of a package which combines the standard Tcl/Tk distribution (tcl, msgcat, http, tcltest, opt, etc.), MetaKit, the zlib library), incrTcl and tclvfs (vfslib, zipvfs, scripdoc), Memchan and a couple of other packages (pwb, rechan). The best introduction to TclKit is probably at http://www.equi4.com/tclkit. The result is a single stand-alone executable, which acts as hassle-free runtime for [Starkit]s, or you can use it like any other Tcl/Tk system. It embeds all the startup scripts and support libraries in the executable, and loads Tk optionally so it can be used as either tclsh or wish - although on Windows and Mac (prior to MacOS X) this dual use is not possible. The point of all this? TclKit is ''single'' file which acts as 100% complete runtime for Tcl/Tk without requiring any installation: * '''install == cp/copy''' * '''uninstall == rm/del''' ''Things can't really get much simpler...'' There are over a dozen platform builds ready to use, including many Unix systems, Windows, and Macintosh. See the TclKit homepage at: http://www.equi4.com/tclkit/ The Windows and Linux TclKit binaries are compressed, and are automatically decompressed at run-time (using UPX). They therefore offer an extremely small footprint Tcl/Tk (around 800k on Windows). Each TclKit distribution will fit on a floppy (though on some platforms it will have to be bzip2-compressed). In addition, the size of TclKit binaries - and Starkits in general - is reduced because all embedded data is zlib-compressed.[Tutorial 1] - [compile and run] a Tcl script with embedded C procedures [Tutorial 2] - build a [Blowfish] encryption [package]Example use of C procedures within a Tcl script ---- '''Example Script - tst.tcl''' package require critcl critcl::cproc noop {} void {} critcl::cproc add {int x int y} int { return x + y; } critcl::cproc cube {int x} int { return x * x * x; } puts "add 123 456 : [add 123 456]" catch {add 1} err; puts "add 1 : $err" catch {add 1 2 3} err; puts "add 1 2 3 : $err" catch {add 0 zero} err; puts "add 0 zero : $err" proc sum {a b} { return [expr {$a+$b}] } proc pow3 {a} { return [expr {$a*$a*$a}] } proc ntimes {n cmd t} { set on $n set r {} while {[incr n -1] >= 0} { lappend r $cmd } set v [uplevel 1 [list time [join $r {; }] $t]] return [lreplace $v 0 0 [expr {[lindex $v 0]/(1.0*$on)}]] } puts "" puts "Tcl noop: [ntimes 100 {} 1000]" puts " C noop: [ntimes 100 {noop} 1000]" set a 1 set b 2 puts "" puts "Tcl expr: [ntimes 100 {expr {1+2}} 1000]" puts "Tcl vars: [ntimes 100 {expr {$a+$b}} 1000]" puts "Tcl sum: [ntimes 100 {sum 1 2} 1000]" puts " C add: [ntimes 100 {add 1 2} 1000]" puts " C vars: [ntimes 100 {add $a $b} 1000]" puts "" puts "Tcl expr: [ntimes 100 {expr {2*2*2}} 1000]" puts "Tcl vars: [ntimes 100 {expr {$b*$b*$b}} 1000]" puts "Tcl pow3: [ntimes 100 {pow3 2} 1000]" puts " C cube: [ntimes 100 {cube 2} 1000]" puts " C vars: [ntimes 100 {cube $b} 1000]" ---- '''Run Using''' critcl tst.tcl '''Sample output''' add 123 456 : 579 add 1 : wrong # args: should be "add x y" add 1 2 3 : wrong # args: should be "add x y" add 0 zero : expected integer but got "zero" Tcl noop: 0.01 microseconds per iteration C noop: 1.04 microseconds per iteration Tcl expr: 0.51 microseconds per iteration Tcl vars: 2.47 microseconds per iteration Tcl sum: 4.39 microseconds per iteration C add: 1.51 microseconds per iteration C vars: 3.7 microseconds per iteration Tcl expr: 0.89 microseconds per iteration Tcl vars: 3.81 microseconds per iteration Tcl pow3: 4.79 microseconds per iteration C cube: 1.35 microseconds per iteration C vars: 2.46 microseconds per iteration Build a [Package] from for Eric Young's implementation of Blowfish encryption ---- '''blowfish.tcl''' if {[catch {package require critcl}] \ || ![critcl::compiling]} { puts stderr "This package cannot be compiled without critcl enabled" exit 1 } package provide blowfish 0.10 namespace eval blowfish { critcl::cheaders blowfish_c/*.h critcl::csources blowfish_c/*.c critcl::ccode { #include "blowfish.h" } critcl::ccommand blowfish {dummy ip objc objv} { int index, dlen, klen, count = 0; unsigned char *data, *key; Tcl_Obj *obj; BF_KEY kbuf; unsigned char ivec[] = {0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; static char* cmds[] = { "encode", "decode", NULL }; if (objc != 4) { Tcl_WrongNumArgs(ip, 1, objv, "mode data key"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(ip, objv[1], cmds, "option", 0, &index) != TCL_OK) return TCL_ERROR; obj = objv[2]; if (Tcl_IsShared(obj)) obj = Tcl_DuplicateObj(obj); data = Tcl_GetByteArrayFromObj(obj, &dlen); key = Tcl_GetByteArrayFromObj(objv[3], &klen); BF_set_key(&kbuf, klen, key); BF_cfb64_encrypt(data, data, dlen, &kbuf, ivec, &count, index == 0 ? BF_ENCRYPT : BF_DECRYPT); Tcl_SetObjResult(ip, obj); return TCL_OK; } }The CriTcl documentation is implemented using a local mode Wiki (see http://wiki.tcl.tk/wiki for more information on Wiki's). It is implemented using the WiKit Tcl/Tk wiki implementation (see http://wiki.tcl.tk/wikit). If you want to build your own wiki, download http://www.equi4.com/pub/sk/wikit.kit. You'll also need TclKit but you may already have that if you are running CriTcl (see http://www.equi4.com/tclkit) * when developing, don't use the [critcl::failed] package to detect if the compilation failed, because it stops compile errors being displayed on stderr - wait until you have finished developing and then use something like the following at the end of your CriTcl script if {[critcl::failed]} { puts stderr "compiled failed - check in [critcl::cache] for errors" m.CriTcl supports cross compiling libraries and packages for Windows on Linux/Unix using the Xmingwin cross-compiler (based on mingw - http://www.mingw.org). To set up an Xmingwin cross compiler use the script provided by Mo de Jong, available at http://mini.net/sdarchive/xmingwin.sh. The script downloads Xmingwin, builds it and installs under /usr/local/Xmingwin (you can edit the script and change the PREFIX variable if you want to install it elsewhere). Once you have Xmingwin installed, you'll need to set your PATH to include the Xmingwin bin directory before using CriTcl. One convenient way of doing this is to create a script called ''cross'' (in /usr/local/bin or ~/bin). $ cat /usr/local/bin/cross PATH=/usr/local/Xmingwin/i386-mingw32msvc/bin:$PATH export PATH exec $@ Then, you can cross compile using the standard CriTcl package building commands $ cross critcl -pkg yourpkg Cross compiling for Windows using Xmingwin Source: yourpkg.tcl Library: yourpkg.dll Package: /path/to/yourpkg/lib/yourpkg When Critcl recognises a cross compiler environment, it manipulates the tcl_platform array to match that found on Windows 2000. Specifically, the following values are set tcl_platform(byteOrder) = littleEndian tcl_platform(machine) = intel tcl_platform(os) = Windows NT tcl_platform(osVersion) = 5.0 tcl_platform(platform) = windows tcl_platform(wordSize) = 4 Intermediate files are be stored in '''~/.critcl/Windows-x86''' (irrespective of the platform on which cross compiling occurs) and the shared library extension can be obtained via the '''critcl::sharedlibext''' procedure (which should be used instead of '''info sharedlibextension''').The '''-clean''' flag is used to clean the files in the Critcl cache. You can also use the critcl::clean_cache procedure from within your Critcl scriptThe Critcl configuration information is stored in the '''Config''' file within the Critcl package. This contains a description of the compiler toolchain commands and features available on each supported platform, and allows Critcl to be more easily ported to a new platform or compiler. This version of Critcl is supported on the following platforms: ` +eval [Code - platforms] ` Several Critcl options can be used to view or modify the configuration information +++ critcl '''-show''' displays the configuration for the current platform critcl '''-targets''' displays the list of supported target platforms critcl '''-showall''' displays the configuration for all supported platforms critcl '''-config''' ''file'' reads the Critcl configuration from the specified file +++ For example, the output of the '''critcl -show''' command on the current platform is: ====== +eval [Code - showconfig] ====== The configuration file for all supported platforms is ====== +eval [Code - showallconfig] ====== ====== # show current Critcl configuration package require critcl 2.0 critcl::showconfig ====== ====== # show supported platforms package require critcl 2.0 set critcl::v::platforms ====== ====== # show Critcl configuration file package require critcl 2.0 critcl::showallconfig ======s..ws C code to be emkage require critcl critcl::showconfig ====== ====== # show supported platforms puts stderr "auto_path = $auto_path" package require critcl set critcl::v::platforms ====== ====== # show Critcl configuration file lappend auto_path [file join [file dirname $wikidir] lib] package require critcl critcl::showallconfig ======s..ws C code to be emo_path $dir] == -1} { lappend auto_path $dir } } extend_path [file join [file dirname $wikidir] lib] package require critcl set critcl::v::platforms ====== ====== # show Critcl configuration file lappend auto_path [file join [file dirname $wikidir] lib] package require critcl critcl::showallconfig ======s..ws C code to be em if (objc != 4) { Tcl_WrongNumArgs(ip, 1, objv, "mode data key"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(ip, objv[1], cmds, "option", 0, &index) != TCL_OK) return TCL_ERROR; obj = objv[2]; if (Tcl_IsShared(obj)) obj = Tcl_DuplicateObj(obj); data = Tcl_GetByteArrayFromObj(obj, &dlen); key = Tcl_GetByteArrayFromObj(objv[3], &klen); BF_set_key(&kbuf, klen, key); BF_cfb64_encrypt(data, data, dlen, &kbuf, ivec, &count, index == 0 ? BF_ENCRYPT : BF_DECRYPT); Tcl_SetObjResult(ip, obj); return TCL_OK; } }The CriTcl documentation is implemented using a local mode Wiki (see http://wiki.tcl.tk/wiki for more information on Wiki's). It is implemented using the WiKit Tcl/Tk wiki implementation (see http://wiki.tcl.tk/wikit). If you want to build your own wiki, download http://www.equi4.com/pub/sk/wikit.kit. You'll also need TclKit but you may already have that if you are running CriTcl (see http://www.equi4.com/tclkit) * when developing, don't use the [critcl::failed] package to detect if the compilation failed, because it stops compile errors being displayed on stderr - wait until you have finished developing and then use something like the following at the end of your CriTcl script if {[critcl::failed]} { puts stderr "compiled failed - check in [critcl::cache] for errors" }CriTcl supports cross compiling libraries and packages for Windows on Linux/Unix using the Xmingwin cross-compiler (based on mingw - http://www.mingw.org). To set up an Xmingwin cross compiler use the script provided by Mo DeJong (a copy is available at http://mini.net/sdarchive/xmingwin.sh). This script downloads Xmingwin, builds it and installs under /usr/local/Xmingwin (you can edit the script and change the PREFIX variable if you want to install it elsewhere). Once you have Xmingwin installed, you'll need to set your PATH to include the Xmingwin bin directory before using CriTcl. One convenient way of doing this is to create a script called ''cross'' (in /usr/local/bin or ~/bin). $ cat /usr/local/bin/cross PATH=/usr/local/Xmingwin/i386-mingw32msvc/bin:$PATH export PATH exec $@ Then, you can cross compile using the usual CriTcl package (or library) building commands $ cross critcl -pkg yourpkg Cross compiling for Windows using Xmingwin Source: yourpkg.tcl Library: yourpkg.dll Package: /path/to/yourpkg/lib/yourpkg If CriTcl recognises a cross compile environment, it manipulates the tcl_platform array so that it matches that found on Windows 2000. Specifically, the following values are set tcl_platform(byteOrder) = littleEndian tcl_platform(machine) = intel tcl_platform(os) = Windows NT tcl_platform(osVersion) = 5.0 tcl_platform(platform) = windows tcl_platform(wordSize) = 4 Critcl also provides the '''[[critcl::sharedlibext]]''' procedure, which returns the shared library extension for the target platform. If you plan on cross-compiling you should use this variable in your CriTcl scripts instead of '''[[info sharedlibextension]]''' (although overlaying the '''info sharedlibextension''' command will probably happen at some stage). Intermediate files are stored in '''~/.critcl/Windows-x86''' irrespective of the platform on which cross compiling occurs. For an example, download http://mini.net/sdarchive/critex.tar.gz, unload and change to the ex2/ directory. This contains a blowfish extension for Tcl. To build on Linux/Unix, run $ critcl -pkg blowfish Source: blowfish.tcl Library: blowfish.so Package: /path/to/ex2/lib/blowfish Then, to cross compile (via the above '''cross''' script) run $ cross critcl -pkg blowfish Cross compiling for Windows using Xmingwin Source: blowfish.tcl Library: blowfish.dll Package: /path/to/ex2/lib/blowfish If you look under ex2/lib/blowfish you'll see lib/blowfish lib/blowfish/critcl.tcl lib/blowfish/pkgIndex.tcl lib/blowfish/Windows-x86 lib/blowfish/Windows-x86/critcl.tcl lib/blowfish/Windows-x86/blowfish.dll lib/blowfish/Linux-x86 lib/blowfish/Linux-x86/critcl.tcl lib/blowfish/Linux-x86/blowfish.so The pkgIndex.tcl will autoload the correct binary for a particular platform.CriTcl supports cross compiling libraries and packages for Windows on Linux/Unix using the Xmingwin cross-compiler (based on mingw - http://www.mingw.org). To set up an Xmingwin cross compiler use the script provided by Mo de Jong, available at http://mini.net/sdarchive/xmingwin.sh. The script downloads Xmingwin, builds it and installs under /usr/local/Xmingwin (you can edit the script and change the PREFIX variable if you want to install it elsewhere). Once you have Xmingwin installed, you'll need to set your PATH to include the Xmingwin bin directory before using CriTcl. One convenient way of doing this is to create a script called ''cross'' (in /usr/local/bin or ~/bin). $ cat /usr/local/bin/cross PATH=/usr/local/Xmingwin/i386-mingw32msvc/bin:$PATH export PATH exec $@ Then, you can cross compile using the standard CriTcl package building commands $ cross critcl -pkg yourpkg Cross compiling for Windows using Xmingwin Source: yourpkg.tcl Library: yourpkg.dll Package: /path/to/yourpkg/lib/yourpkg When Critcl recognises a cross compiler environment, it manipulates the tcl_platform array to match that found on Windows 2000. Specifically, the following values are set tcl_platform(byteOrder) = littleEndian tcl_platform(machine) = intel tcl_platform(os) = Windows NT tcl_platform(osVersion) = 5.0 tcl_platform(platform) = windows tcl_platform(wordSize) = 4 Intermediate files are be stored in '''~/.critcl/Windows-x86''' (irrespective of the platform on which cross compiling occurs) and the shared library extension can be obtained via the '''critcl::sharedlibext''' procedure (which should be used instead of '''info sharedlibextension''').The '''-clean''' flag is used to clean the files in the Critcl cache. You can also use the critcl::clean_cache procedure from within your Critcl scriptThe Critcl configuration information is stored in the '''Config''' file within the Critcl package. This contains a description of the compiler toolchain commands and features available on each supported platform, and allows Critcl to be more easily ported to a new platform or compiler. This version of Critcl is supported on the following platforms: ` +eval [Code - platforms] ` Several Critcl options can be used to view or modify the configuration information +++ critcl '''-show''' displays the configuration for the current platform critcl '''-targets''' displays the list of supported target platforms critcl '''-showall''' displays the configuration for all supported platforms critcl '''-config''' ''file'' reads the Critcl configuration from the specified file +++ For example, the output of the '''critcl -show''' command on the current platform is: ====== +eval [Code - showconfig] ====== The configuration file for all supported platforms is ====== +eval [Code - showallconfig] ====== ====== # show current Critcl configuration lappend auto_path [file join [file dirname $wikidir] lib] package require critcl critcl::showconfig ====== ====== # show supported platforms lappend auto_path [file join [file dirname $wikidir] lib] package require critcl set critcl::v::platforms ====== ====== # show Critcl configuration file lappend auto_path [file join [file dirname $wikidir] lib] package require critcl critcl::showallconfig ======s..ws C code to be em'Config''' file within the Critcl package. This contains a description of the compiler toolchain commands and features available on each supported platform, and allows Critcl to be more easily ported to a new platform or compiler. Several Critcl options can be used to view or modify the configuration information * '''critcl -show''' displays the configuration for the current platform * '''critcl -targets''' displays the list of supported target platforms * '''critcl -showall''' displays the configuration for all supported platforms * '''critcl -config''' '''''dir''''' reads the Critcl configuration from the specified file For example, the output of the '''critcl -show''' command on the current platform is: ====== +eval [Code - showconfig] ====== The supported target platforms are: ++include |critcl -targets The configuration file for all supported platforms is ====== ++include $wikidir/../lib/critcl/Config ====== ====== # show current Critcl configuration lappend auto_path [file join [file dirname $wikidir] lib] puts stderr "auto_path = $auto_path" package require critcl critcl::showconfig ======s..ws C code to be emt care a bit where Tcl is installed, nor even whether it was built as a static or as a dynamic executable. CriTcl keeps an [MD5] checksum for each C source file, and uses it detect changes and only re-compile if necessary. This means that subsequent invocations are almost instantaneous. Both the [MD5] checksum and the compiled shared library are cached in a directory that may be safely mounted on multiple platforms (see [CriTcl cache]). CriTcl includes procedures for defining C procedures, injecting C code into the generated code, for specifying header files and C command line parameters, and for tying code to a Tcl command. See the [CriTcl Reference] page for more information. But CriTcl also provides some [Build Features] such as procedures to check if CriTcl is available on the current platform, and to a mechanism to force a compile and check whether it was successful. These two facilities allow the inclusion of [dual Tcl and C implementations] in a package. If the compiled C version is available on a particular platform, it will be used. If not, the Tcl version. This is useful in projects such as Tcllib, which must be guaranteed to work on platforms without a C compiler but that contain modules which could benefit from the speed of a C implementation. Another procedure indicates whether a piece of C code could be succesfully compiled. This allows build information to be embedded in the Tcl program (e.g. a check for header files such as limits.h, and generation of the correct -DHAVE_LIMITS_H compiler flag). CriTcl takes the Tcl concept of "'''glueware'''" to new levels. One can start with a Tcl/Tk interpreter (either traditional tclsh/wish, [ActiveTcl], or [TclKit]) and develop with Tcl being at the center and everything else being small pieces of C code. CriTcl becomes the means to "run that last mile", to get performance and to connect to other C code. A '''Starkit''' is a single file (compressed) packaging of Tcl scripts, platform specific compiled code and application data; designed to facilitate simple deployment of cross platform applications. They are made '''cross platform''' by developing in '''Tcl/Tk''' wherever possible, and by including compiled extensions for multiple platforms if necessary. Starkits are interpreted using [TclKit] - a platform specific single file Tcl/Tk interpreter. You will need to download TclKit for each platform that you want to run a Starkit on. There is an archive of Starkits available at http://mini.net/sdarchive/From the [Tcler's Wiki] at http://wiki.tcl.tk/tcl/stubs Stubs: A dynamic linking mechanism for Tcl, Tk and extensions. http://www.purl.org/tcl/home/doc/howto/stubs.html '''What does it do ?''' 1. Adds support for backlinking to all platforms, thus making it possible for static executables to dynamically load extensions on any platform. 2. Eliminates all the operating system specific problems associated with dynamically linking an extension to Tcl/Tk and any other library which exports a stub interface. This may sound like a wild claim but it is true simply because the operating system does not have to do anything. 3. Extensions and libraries built with different compilers will work together even if it is not possible to link them normally. The only requirement for them to be able to work together is that function calls are compatible. 4. As extensions do not have a hard coded reference to the library it is possible to use them with any library which is compatible. e.g. an extension which was originally built for Tcl 8.0 should work with Tcl 8.1, and an extension built for Tcl 8.1 could work with Tcl 8.0. '''How does it do it ?''' Basically the stub mechanism provides a cross platform dynamic linking mechanism using tables of function pointers. * A library which wishes to provide a stub interface populates a function table with the addresses of its interface functions. * A pointer to that table is then made available to any extension which needs to access that library's interface. * Once an extension has obtained the pointer it simply uses it to get the address of the function it wants to call and calls it. * At no time in this process does the operating system become involved. To see the differences take a look at the following which describes what happens when Tcl loads two different extensions. * Loading an extension which is linked directly to Tcl. 1) Tcl asks the operating system to load the extension. 2) The operating system loads the extension and then tries to resolve any undefined symbols. This process is very operating system dependent but involves one or more of the following steps. 1) Resolve any symbols which are defined in the current process context. (Backlinking). 2) Find and load any libraries that the extension is dependent on. This involves searching paths defined through a variety of operating system dependent methods. 3) Resolve any symbols which are defined in the new libraries. 3) Tcl then calls the extension's initialisation entry point. * Loading an extension which uses Tcl's stub interface. 1) Tcl asks the operating system to load the extension. 2) The operating system does so, resolving any non Tcl symbols. 3) Tcl calls the extension's initialisation entry point. 4) The extension obtains the pointer(s) to Tcl's stub table(s) and uses that to call Tcl. ---- Who's responsible for it? Perhaps Jean-Claude Wippler suggested it to Paul Duffin in 1999, and Paul and Jan Nijtmans, with whom Jean-Claude had also been discussing ideas, implemented it in 2000. Others were involved in the first generation. '''TclKit''' is the name of a package which combines the standard Tcl/Tk distribution (tcl, msgcat, http, tcltest, opt, etc.), MetaKit, the zlib library), incrTcl and tclvfs (vfslib, zipvfs, scripdoc), Memchan and a couple of other packages (pwb, rechan). The best introduction to TclKit is probably at http://www.equi4.com/tclkit. The result is a single stand-alone executable, which acts as hassle-free runtime for [Starkit]s, or you can use it like any other Tcl/Tk system. It embeds all the startup scripts and support libraries in the executable, and loads Tk optionally so it can be used as either tclsh or wish - although on Windows and Mac (prior to MacOS X) this dual use is not possible. The point of all this? TclKit is ''single'' file which acts as 100% complete runtime for Tcl/Tk without requiring any installation: * '''install == cp/copy''' * '''uninstall == rm/del''' ''Things can't really get much simpler...'' There are over a dozen platform builds ready to use, including many Unix systems, Windows, and Macintosh. See the TclKit homepage at: http://www.equi4.com/tclkit/ The Windows and Linux TclKit binaries are compressed, and are automatically decompressed at run-time (using UPX). They therefore offer an extremely small footprint Tcl/Tk (around 800k on Windows). Each TclKit distribution will fit on a floppy (though on some platforms it will have to be bzip2-compressed). In addition, the size of TclKit binaries - and Starkits in general - is reduced because all embedded data is zlib-compressed.[Tutorial 1] - [compile and run] a Tcl script with embedded C procedures [Tutorial 2] - build a [Blowfish] encryption [package]Example use of C procedures within a Tcl script ---- '''Example Script - tst.tcl''' package require critcl critcl::cproc noop {} void {} critcl::cproc add {int x int y} int { return x + y; } critcl::cproc cube {int x} int { return x * x * x; } puts "add 123 456 : [add 123 456]" catch {add 1} err; puts "add 1 : $err" catch {add 1 2 3} err; puts "add 1 2 3 : $err" catch {add 0 zero} err; puts "add 0 zero : $err" proc sum {a b} { return [expr {$a+$b}] } proc pow3 {a} { return [expr {$a*$a*$a}] } proc ntimes {n cmd t} { set on $n set r {} while {[incr n -1] >= 0} { lappend r $cmd } set v [uplevel 1 [list time [join $r {; }] $t]] return [lreplace $v 0 0 [expr {[lindex $v 0]/(1.0*$on)}]] } puts "" puts "Tcl noop: [ntimes 100 {} 1000]" puts " C noop: [ntimes 100 {noop} 1000]" set a 1 set b 2 puts "" puts "Tcl expr: [ntimes 100 {expr {1+2}} 1000]" puts "Tcl vars: [ntimes 100 {expr {$a+$b}} 1000]" puts "Tcl sum: [ntimes 100 {sum 1 2} 1000]" puts " C add: [ntimes 100 {add 1 2} 1000]" puts " C vars: [ntimes 100 {add $a $b} 1000]" puts "" puts "Tcl expr: [ntimes 100 {expr {2*2*2}} 1000]" puts "Tcl vars: [ntimes 100 {expr {$b*$b*$b}} 1000]" puts "Tcl pow3: [ntimes 100 {pow3 2} 1000]" puts " C cube: [ntimes 100 {cube 2} 1000]" puts " C vars: [ntimes 100 {cube $b} 1000]" ---- '''Run Using''' critcl tst.tcl '''Sample output''' add 123 456 : 579 add 1 : wrong # args: should be "add x y" add 1 2 3 : wrong # args: should be "add x y" add 0 zero : expected integer but got "zero" Tcl noop: 0.01 microseconds per iteration C noop: 1.04 microseconds per iteration Tcl expr: 0.51 microseconds per iteration Tcl vars: 2.47 microseconds per iteration Tcl sum: 4.39 microseconds per iteration C add: 1.51 microseconds per iteration C vars: 3.7 microseconds per iteration Tcl expr: 0.89 microseconds per iteration Tcl vars: 3.81 microseconds per iteration Tcl pow3: 4.79 microseconds per iteration C cube: 1.35 microseconds per iteration C vars: 2.46 microseconds per iteration Build a [Package] from for Eric Young's implementation of Blowfish encryption ---- '''blowfish.tcl''' if {[catch {package require critcl}] \ || ![critcl::compiling]} { puts stderr "This package cannot be compiled without critcl enabled" exit 1 } package provide blowfish 0.10 namespace eval blowfish { critcl::cheaders blowfish_c/*.h critcl::csources blowfish_c/*.c critcl::ccode { #include "blowfish.h" } critcl::ccommand blowfish {dummy ip objc objv} { int index, dlen, klen, count = 0; unsigned char *data, *key; Tcl_Obj *obj; BF_KEY kbuf; unsigned char ivec[] = {0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; static char* cmds[] = { "encode", "decode", NULL }; if (objc != 4) { Tcl_WrongNumArgs(ip, 1, objv, "mode data key"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(ip, objv[1], cmds, "option", 0, &index) != TCL_OK) return TCL_ERROR; obj = objv[2]; if (Tcl_IsShared(obj)) obj = Tcl_DuplicateObj(obj); data = Tcl_GetByteArrayFromObj(obj, &dlen); key = Tcl_GetByteArrayFromObj(objv[3], &klen); BF_set_key(&kbuf, klen, key); BF_cfb64_encrypt(data, data, dlen, &kbuf, ivec, &count, index == 0 ? BF_ENCRYPT : BF_DECRYPT); Tcl_SetObjResult(ip, obj); return TCL_OK; } }The CriTcl documentation is implemented using a local mode Wiki (see http://wiki.tcl.tk/wiki for more information on Wiki's). It is implemented using the WiKit Tcl/Tk wiki implementation (see http://wiki.tcl.tk/wikit). If you want to build your own wiki, download http://www.equi4.com/pub/sk/wikit.kit. You'll also need TclKit but you may already have that if you are running CriTcl (see http://www.equi4.com/tclkit) * when developing, don't use the [critcl::failed] package to detect if the compilation failed, because it stops compile errors being displayed on stderr - wait until you have finished developing and then use something like the following at the end of your CriTcl script if {[critcl::failed]} { puts stderr "compiled failed - check in [critcl::cache] for errors" }CriTcl supports cross compiling libraries and packages for Windows on Linux/Unix using the Xmingwin cross-compiler (based on mingw - http://www.mingw.org). To set up an Xmingwin cross compiler use the script provided by Mo DeJong (a copy is available at http://mini.net/sdarchive/xmingwin.sh). This script downloads Xmingwin, builds it and installs under /usr/local/Xmingwin (you can edit the script and change the PREFIX variable if you want to install it elsewhere). Once you have Xmingwin installed, you'll need to set your PATH to include the Xmingwin bin directory before using CriTcl. One convenient way of doing this is to create a script called ''cross'' (in /usr/local/bin or ~/bin). $ cat /usr/local/bin/cross PATH=/usr/local/Xmingwin/i386-mingw32msvc/bin:$PATH export PATH exec $@ Then, you can cross compile using the usual CriTcl package (or library) building commands $ cross critcl -pkg yourpkg Cross compiling for Windows using Xmingwin Source: yourpkg.tcl Library: yourpkg.dll Package: /path/to/yourpkg/lib/yourpkg If CriTcl recognises a cross compile environment, it manipulates the tcl_platform array so that it matches that found on Windows 2000. Specifically, the following values are set tcl_platform(byteOrder) = littleEndian tcl_platform(machine) = intel tcl_platform(os) = Windows NT tcl_platform(osVersion) = 5.0 tcl_platform(platform) = windows tcl_platform(wordSize) = 4 Critcl also provides the '''[[critcl::sharedlibext]]''' procedure, which returns the shared library extension for the target platform. If you plan on cross-compiling you should use this variable in your CriTcl scripts instead of '''[[info sharedlibextension]]''' (although overlaying the '''info sharedlibextension''' command will probably happen at some stage). Intermediate files are stored in '''~/.critcl/Windows-x86''' irrespective of the platform on which cross compiling occurs. For an example, download http://mini.net/sdarchive/critex.tar.gz, unload and change to the ex2/ directory. This contains a blowfish extension for Tcl. To build on Linux/Unix, run $ critcl -pkg blowfish Source: blowfish.tcl Library: blowfish.so Package: /path/to/ex2/lib/blowfish Then, to cross compile (via the above '''cross''' script) run $ cross critcl -pkg blowfish Cross compiling for Windows using Xmingwin Source: blowfish.tcl Library: blowfish.dll Package: /path/to/ex2/lib/blowfish If you look under ex2/lib/blowfish you'll see lib/blowfish lib/blowfish/critcl.tcl lib/blowfish/pkgIndex.tcl lib/blowfish/Windows-x86 lib/blowfish/Windows-x86/critcl.tcl lib/blowfish/Windows-x86/blowfish.dll lib/blowfish/Linux-x86 lib/blowfish/Linux-x86/critcl.tcl lib/blowfish/Linux-x86/blowfish.so The pkgIndex.tcl will autoload the correct binary for a particular platform.CriTcl supports cross compiling libraries and packages for Windows on Linux/Unix using the Xmingwin cross-compiler (based on mingw - http://www.mingw.org). To set up an Xmingwin cross compiler use the script provided by Mo de Jong, available at http://mini.net/sdarchive/xmingwin.sh. The script downloads Xmingwin, builds it and installs under /usr/local/Xmingwin (you can edit the script and change the PREFIX variable if you want to install it elsewhere). Once you have Xmingwin installed, you'll need to set your PATH to include the Xmingwin bin directory before using CriTcl. One convenient way of doing this is to create a script called ''cross'' (in /usr/local/bin or ~/bin). $ cat /usr/local/bin/cross PATH=/usr/local/Xmingwin/i386-mingw32msvc/bin:$PATH export PATH exec $@ Then, you can cross compile using the standard CriTcl package building commands $ cross critcl -pkg yourpkg Cross compiling for Windows using Xmingwin Source: yourpkg.tcl Library: yourpkg.dll Package: /path/to/yourpkg/lib/yourpkg When Critcl recognises a cross compiler environment, it manipulates the tcl_platform array to match that found on Windows 2000. Specifically, the following values are set tcl_platform(byteOrder) = littleEndian tcl_platform(machine) = intel tcl_platform(os) = Windows NT tcl_platform(osVersion) = 5.0 tcl_platform(platform) = windows tcl_platform(wordSize) = 4 Intermediate files are be stored in '''~/.critcl/Windows-x86''' (irrespective of the platform on which cross compiling occurs) and the shared library extension can be obtained via the '''critcl::sharedlibext''' procedure (which should be used instead of '''info sharedlibextension''').The '''-clean''' flag is used to clean the files in the Critcl cache. You can also use the critcl::clean_cache procedure from within your Critcl scriptThe Critcl configuration information is stored in the '''Config''' file within the Critcl package. This contains a description of the compiler toolchain commands and features available on each supported platform, and allows Critcl to be more easily ported to a new platform or compiler. Several Critcl options can be used to view or modify the configuration information * '''critcl -show''' displays the configuration for the current platform * '''critcl -targets''' displays the list of supported target platforms * '''critcl -showall''' displays the configuration for all supported platforms * '''critcl -config''' '''''dir''''' reads the Critcl configuration from the specified file For example, the output of the '''critcl -show''' command on the current platform is: [Showconfig] ====== +include |critcl -show ====== The supported target platforms are: +include |critcl -targets The configuration file for all supported platforms is ====== +include $wikidir/../lib/critcl/Config ======# show current Critcl configuration lappend auto_path [file join [file directory $wikidir] lib]s..ws C code to be emg). To set up an Xmingwin cross compiler use the script provided by Mo de Jong, available at http://mini.net/sdarchive/xmingwin.sh. The script downloads Xmingwin, builds it and installs under /usr/local/Xmingwin (you can edit the script and change the PREFIX variable if you want to install it elsewhere). Once you have Xmingwin installed, you'll need to set your PATH to include the Xmingwin bin directory before using CriTcl. One convenient way of doing this is to create a script called ''cross'' (in /usr/local/bin or ~/bin). $ cat /usr/local/bin/cross PATH=/usr/local/Xmingwin/i386-mingw32msvc/bin:$PATH export PATH exec $@ Then, you can cross compile using the standard CriTcl package building commands $ cross critcl -pkg yourpkg Cross compiling for Windows using Xmingwin Source: yourpkg.tcl Library: yourpkg.dll Package: /path/to/yourpkg/lib/yourpkg When Critcl recognises a cross compiler environment, it manipulates the tcl_platform array to match that found on Windows 2000. Specifically, the following values are set tcl_platform(byteOrder) = littleEndian tcl_platform(machine) = intel tcl_platform(os) = Windows NT tcl_platform(osVersion) = 5.0 tcl_platform(platform) = windows tcl_platform(wordSize) = 4 Intermediate files are be stored in '''~/.critcl/Windows-x86''' (irrespective of the platform on which cross compiling occurs) and the shared library extension can be obtained via the '''critcl::sharedlibext''' procedure (which should be used instead of '''info sharedlibextension''').The '''-clean''' flag is used to clean the files in the Critcl cache. You can also use the critcl::clean_cache procedure from within your Critcl scriptThe Critcl configuration information is stored in the '''Config''' file within the Critcl package. This contains a description of the compiler toolchain commands and features available on each supported platform, and allows Critcl to be more easily ported to a new platform or compiler. Several Critcl options can be used to view or modify the configuration information * '''critcl -show''' displays the configuration for the current platform * '''critcl -targets''' displays the list of supported target platforms * '''critcl -showall''' displays the configuration for all supported platforms * '''critcl -config''' '''''dir''''' reads the Critcl configuration from the specified file For example, the output of the '''critcl -show''' command on the current platform is: ====== ++include |critcl -show ====== The supported target platforms are: +include |critcl -targets The configuration file for all supported platforms is ====== +include $wikidir/../lib/critcl/Config ======s..ws C code to be em debug_symbols -g include -I link gcc -bundle -arch i386 -arch ppc link_debug link_preload -undefined dynamic_lookup -mmacosx-version-min=10.3 link_release noassert -DNDEBUG object .o optimize -O2 output -o $outfile platform universal-macosx 10.4 powerpc-macosx ix86-macosx preproc_define gcc -E -dM preproc_enum gcc -E sharedlibext .dylib strip tclstubs -DUSE_TCL_STUBS threadflags -DUSE_THREAD_ALLOC=1 -D_REENTRANT=1 -D_THREAD_SAFE=1 \ -DHAVE_PTHREAD_ATTR_SETSTACKSIZE=1 -DHAVE_READDIR_R=1 \ -DTCL_THREADS=1 tkstubs -DUSE_TK_STUBS version gcc -v ====== +include $wikidir/../lib/critcl/Config ======s..ws C code to be emand are automatically decompressed at run-time (using UPX). They therefore offer an extremely small footprint Tcl/Tk (around 800k on Windows). Each TclKit distribution will fit on a floppy (though on some platforms it will have to be bzip2-compressed). In addition, the size of TclKit binaries - and scripted documents in general - is reduced because all embedded data is zlib-compressed.[Tutorial 1] - [compile and run] a Tcl script with embedded C procedures [Tutorial 2] - build a [Blowfish] encryption [package]Example use of C procedures within a Tcl script ---- '''Example Script - tst.tcl''' package require critcl critcl::cproc noop {} void {} critcl::cproc add {int x int y} int { return x + y; } critcl::cproc cube {int x} int { return x * x * x; } puts "add 123 456 : [add 123 456]" catch {add 1} err; puts "add 1 : $err" catch {add 1 2 3} err; puts "add 1 2 3 : $err" catch {add 0 zero} err; puts "add 0 zero : $err" proc sum {a b} { return [expr {$a+$b}] } proc pow3 {a} { return [expr {$a*$a*$a}] } proc ntimes {n cmd t} { set on $n set r {} while {[incr n -1] >= 0} { lappend r $cmd } set v [uplevel 1 [list time [join $r {; }] $t]] return [lreplace $v 0 0 [expr {[lindex $v 0]/(1.0*$on)}]] } puts "" puts "Tcl noop: [ntimes 100 {} 1000]" puts " C noop: [ntimes 100 {noop} 1000]" set a 1 set b 2 puts "" puts "Tcl expr: [ntimes 100 {expr {1+2}} 1000]" puts "Tcl vars: [ntimes 100 {expr {$a+$b}} 1000]" puts "Tcl sum: [ntimes 100 {sum 1 2} 1000]" puts " C add: [ntimes 100 {add 1 2} 1000]" puts " C vars: [ntimes 100 {add $a $b} 1000]" puts "" puts "Tcl expr: [ntimes 100 {expr {2*2*2}} 1000]" puts "Tcl vars: [ntimes 100 {expr {$b*$b*$b}} 1000]" puts "Tcl pow3: [ntimes 100 {pow3 2} 1000]" puts " C cube: [ntimes 100 {cube 2} 1000]" puts " C vars: [ntimes 100 {cube $b} 1000]" ---- '''Run Using''' critcl tst.tcl '''Sample output''' add 123 456 : 579 add 1 : wrong # args: should be "add x y" add 1 2 3 : wrong # args: should be "add x y" add 0 zero : expected integer but got "zero" Tcl noop: 0.01 microseconds per iteration C noop: 1.04 microseconds per iteration Tcl expr: 0.51 microseconds per iteration Tcl vars: 2.47 microseconds per iteration Tcl sum: 4.39 microseconds per iteration C add: 1.51 microseconds per iteration C vars: 3.7 microseconds per iteration Tcl expr: 0.89 microseconds per iteration Tcl vars: 3.81 microseconds per iteration Tcl pow3: 4.79 microseconds per iteration C cube: 1.35 microseconds per iteration C vars: 2.46 microseconds per iteration Build a [Package] from for Eric Young's implementation of Blowfish encryption ---- '''blowfish.tcl''' if {[catch {package require critcl}] \ || ![critcl::compiling]} { puts stderr "This package cannot be compiled without critcl enabled" exit 1 } package provide blowfish 0.10 namespace eval blowfish { critcl::cheaders blowfish_c/*.h critcl::csources blowfish_c/*.c critcl::ccode { #include "blowfish.h" } critcl::ccommand blowfish {dummy ip objc objv} { int index, dlen, klen, count = 0; unsigned char *data, *key; Tcl_Obj *obj; BF_KEY kbuf; unsigned char ivec[] = {0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; static char* cmds[] = { "encode", "decode", NULL }; if (objc != 4) { Tcl_WrongNumArgs(ip, 1, objv, "mode data key"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(ip, objv[1], cmds, "option", 0, &index) != TCL_OK) return TCL_ERROR; obj = objv[2]; if (Tcl_IsShared(obj)) obj = Tcl_DuplicateObj(obj); data = Tcl_GetByteArrayFromObj(obj, &dlen); key = Tcl_GetByteArrayFromObj(objv[3], &klen); BF_set_key(&kbuf, klen, key); BF_cfb64_encrypt(data, data, dlen, &kbuf, ivec, &count, index == 0 ? BF_ENCRYPT : BF_DECRYPT); Tcl_SetObjResult(ip, obj); return TCL_OK; } }The CriTcl documentation is implemented using a local mode Wiki (see http://wiki.tcl.tk/wiki for more information on Wiki's). It is implemented using the WiKit Tcl/Tk wiki implementation (see http://wiki.tcl.tk/wikit). If you want to build your own wiki, download http://mini.net/sdarchive/wikit.bin. You'll also need TclKit but you may already have that if you are running CriTcl (see http://www.equi4.com/tclkit) * when developing, don't use the [critcl::failed] package to detect if the compilation failed, because it stops compile errors being displayed on stderr - wait until you have finished developing and then use something like the following at the end of your CriTcl script if {[critcl::failed]} { puts stderr "compiled failed - check in [critcl::cache] for errors" }CriTcl supports cross compiling for Windows on Linux/Unix using the Xmingwin cross-compiler (based on mingw - http://www.mingw.org). To set up an Xmingwin cross compiler use the script provided by Mo de Jong, available at http://mini.net/sdarchve/xmingwin.sh. The script installs Xmingwin under /usr/local/Xmingwin (you can edit it and change the PREFIX variable if you want to install it elsewhere). Once you have Xmingwin installed, you'll need to set your PATH to include the Xmingwin bin directory before using CriTcl. One convenient way of doing this is to create a script called '''cross'' (in /usr/local/bin or ~/bin). $ cat /usr/local/bin/cross PATH=/usr/local/Xmingwin/i386-mingw32msvc/bin:$PATH export PATH exec $@ Then, you can cross compile using cross critcl -cross -pkg yourpackage When you specify the '''-cross''' flag, CriTcl manipulates the tcl_platform array so that it maches that found on Windows 2000. Specifically, the following values are set tcl_platform(byteOrder) = littleEndian tcl_platform(machine) = intel tcl_platform(os) = Windows NT tcl_platform(osVersion) = 5.0 tcl_platform(platform) = windows tcl_platform(wordSize) = 4 This allows scripts that use these variables to correctly set variables and headers. For example, a Tk extension CriTcl script might contain the following code switch $tcl_platform(platform) { unix { switch $tcl_platform(os) { Darwin { set xinclude /usr/X11R6/include set xlib /usr/X11R6/lib } SunOS { set xinclude /usr/openwin/include set xlib /usr/openwin/lib } default { set xinclude /usr/X11R6/lib set xlib $xinclude } } critcl::cheaders -I$xinclude critcl::clibraries -L$xlib -lX11 } windows { critcl::cheaders -I$tk_prefix/win -I$tk_prefix/xlib } default { puts stderr \ "this extension hasn't been ported to \ $tcl_platform(platform)" exit 1 } }i\a