TEA (tclconfig) Source Code

Update of ”Practcl Retrofit”
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview

Artifact ID: 94bcf5d5f19912194a3cd51dfdd631818e7a5b8d
Page Name:Practcl Retrofit
Date: 2016-06-24 16:21:49
Original User: hypnotoad
Next 10383a362fb2df0f101e9f49f8453201ba23031f
Content

For existing projects, which already have an established Makefile system this may not be practical or desired. So for our first example we will provide a minimal shim to allow make to invoke practcl.

The example here is a stylized version of the build system for odielib(http://fossil.etoyoc.com/fossil/odielib). Bits have been edited for clarity, and may vary slightly from the production code.


# Minimal make.tcl with a single target

set CWD pwd set ::project(builddir) $::CWD set ::project(srcdir) file dirname [file normalize [info script]] set ::project(sandbox) file dirname $::project(srcdir)

if {file exists [file join $CWD .. tclconfig practcl.tcl]} { source file join $CWD .. tclconfig practcl.tcl } else { source file join $SRCPATH tclconfig practcl.tcl }

array set ::project :practcl::config.tcl $CWD ::practcl::library create LIBRARY array get ::project LIBRARY source file join $::project(srcdir) library.ini LIBRARY implement $::project(builddir) set fout open pkgIndex.tcl w puts $fout " # # Tcl package index file # " puts $fout LIBRARY package-ifneeded close $fout

This make script has no options, not targets, and only has a single task which will: * Read our practcl build rules (in the library.ini file) * generate a *PKGNAME*.mk file (which is a supplementary list of instructions for the Makefile) * generate the pkgIndex.tcl file (which will notifies Tcl about the package and how to load it.)

The *library.ini* contains instructions for the *LIBRARY* object. For this package it looks like:

set SRCPATH file normalize [my define get srcdir]
my add file join $SRCPATH cmodules btree module.ini my add file join $SRCPATH cmodules odieutil module.ini my add file join $SRCPATH cmodules geometry module.ini
my define add public-include <tcl.h> my define add public-include <assert.h> my define add public-include <stdio.h> my define add public-include <stdlib.h> my define add public-include <string.h> my define add public-include <math.h> my define add include_dir my define get builddir

You will note the "my" in front of many statements. This is because the script is actually invoked within the namespace of a TclOO object. This object is the master controller for the project.

The *add* method introduces a new subordinate object. In this case we have added three modules, which themselves will be objects. The add method has an auto-dectection algorithm to pair the appropriate class for a new subordinate by file extension. If we want more control we could have specified:

my add class module filename file join $SRCPATH cmodules btree module.ini

Modules, in turn, can have subordinates.

The btree module is straightforward:

set here file dirname [file normalize [info script]] my add file join $here tree.tcl

The tree.tcl(http://fossil.etoyoc.com/fossil/odielib/info/822483fd556b93ba17510c8bbe1a6c5c40d3946b?txt=1&ln=0) file, in turn defines data structures and functions we want available within our library. That file contains a stream of commands along the lines of:

my c_structure Tree { /* A complete binary tree is defined by an instance of the following ** structure */ int (*xCompare)(const void*, const void*); /* Comparison function */ void *(*xCopy)(const void*); /* Key copy function, or NULL */ void (*xFree)(void*); /* Key delete function */ struct TreeElem *top; /* The top-most node of the tree */ };

And

my c_function {static void TreeClearNode(TreeElem *p, void (*xFree)(void*))} { /* Delete a single node of the binary tree and all of its children */ if( p==0 ) return; if( p->left ) TreeClearNode(p->left, xFree); if( p->right ) TreeClearNode(p->right, xFree); if( xFree ){ xFree(p->key); } Tcl_Free((char *)p); }

Methods also exist for injecting arbitrary block of C code into specific places in the resulting C file, defining Tcl commands, and building OO classes.

Source files can also be read in from pure C:

my add file join $here md5.c

or

my add class csource initfunc Md5_Init filename file join $here md5.c