TclCommandWriting  - Writing C language extensions to Tcl.


OVERVIEW

       This document is  intended  to  help  the  programmer  who
       wishes  to extend Tcl with C language routines.  It should
       also be useful to someone wishing to add Tcl to an  exist­
       ing  editor,  communications program, window manager, etc.
       Experienced extension writers may find this manual helpful
       in  rewriting their applications to use the new Tcl object
       system.  We assume you are already fluent in  the  C  pro­
       gramming  language  and  that you have built and installed
       Tcl on your machine.

       Information on the available C interface routines  to  Tcl
       can  be found in the *.3 manual pages in the doc directory
       of the baseline Tcl distribution, and in the *.3  manpages
       in the doc directory of Extended Tcl.


TCL OBJECT SYSTEM

       With  the  release  of Tcl version 8, Tcl has a new system
       for managing Tcl values internally.  To the  Tcl  program­
       mer, the new objects look and act like strings, as before.
       But at the C level, these objects can now also hold cached
       internal  representations of the strings in various native
       datatypes.  For example, an  object  containing  a  string
       consisting of an integer, will now maintain a machine-code
       integer representation, if an integer  representation  has
       been  needed.   Using these objects is much more efficient
       than using the older-style Tcl strings, although the older
       style is still (currently) supported.

       Although  the object system has almost no effect at all on
       how the Tcl programmer uses Tcl,  the  object  system's  C
       interfaces to strings, integers, lists, etc., have changed
       considerably.  While converting a package to use  the  new
       system can be a lot of work, the combination of the object
       system, which saves Tcl from having to constantly  convert
       strings  to  integers  and  back, etc., and the on-the-fly
       bytecode compiler (which keeps Tcl from having to continu­
       ally  reparse  code  it  is to execute) yield Tcl programs
       that routinely execute several  times  more  quickly  than
       with  previous  versions  (Tcl  7 and before), and in some
       cases run as much as 2500 (!) times faster than before.

       We have chosen, then, to rewrite the Command Writer's man­
       page, which has been shipping with Extended Tcl for a num­
       ber of years, to produce this new version based on the new
       object  system.   The  old  manpage,  based  on  the older
       string-oriented routines, will still be included  in  TclX
       releases  for now, as it is still relevant to Tcl releases
       through version 7, and may be  of  use  to  those  modify­
       ing/upgrading packages written for the old model.  The old
       manual will be dropped from the release once  we  deem  it

       legacy interfaces, and all new development should be  done
       using the new object interfaces, unless backwards compati­
       bility to pre-Tcl-8 releases is needed.


A SIMPLE C EXTENSION

       All C-based Tcl commands are called with four arguments: a
       client  data  pointer, an interpreter pointer, an argument
       count and a pointer to an array of Tcl objects  containing
       the arguments to the command.

       A  simple  C  extension  to  Tcl  is  now  presented,  and
       described below:

           #include "tcl.h"

           int App_DumpArgsObjCmd(clientData, interp, objc, objv)
               void          *clientData;
               Tcl_Interp    *interp;
               int            objc;
               Tcl_Obj      **objv;
           {
                   int   i;
                int   stringLen;
                char *stringPtr;

                   for (i = 1; i < objc; i++) {
                     stringPtr = Tcl_GetStringFromObj (objv [i], &stringLen);
                           printf("%s", stringPtr);
                     if (i < objc - 1) printf(" ");
                   }
                   printf("\n");
                   return TCL_OK;
           }

       The client data pointer will be described later.


INTERPRETERS

       The interpreter pointer is the ``key'' to an  interpreter.
       It is returned by Tcl_CreateInterp and is used extensively
       within Tcl, and will be used by your  C  extensions.   The
       data  structure pointed to by the interpreter pointer, and
       all of the subordinate structures that branch off  of  it,
       make  up a Tcl interpreter, which includes all of the cur­
       rently defined procedures, commands, variables, arrays and
       the execution state of that interpreter.  (For more infor­
       mation on creating and deleting interpreters, please exam­
       ine the CrtInterp(3) manpage in the core Tcl distribution.
       For information on creating interpreters that include  the
       commands   provided   by   Extended  Tcl,  check  out  the
       TclX_Init(3) manpage of Extended Tcl.  For a  manual  page
       describing  the  user-visible fields of a Tcl interpreter,
       please look at Interp(3) in core Tcl.)

       The argument count, or object count (objc), and pointer to
       an array of pointers to Tcl objects of the command's argu­
       ments (objv) is handled by your C code, in a manner  simi­
       lar  to the one you would use in writing a C main function
       -- an argument count and array of pointers works the  same
       as  in  a  C  main  call; pointers to the arguments to the
       function are contained in the objv array.  Similar to a  C
       main, the first argument (objv[0]) is an object containing
       the name the routine was called as (in a C main, the  name
       the program was invoked as).

       In Tcl, however, the array of pointers are not pointers to
       character strings (although they were in  all  version  of
       Tcl before 8.0).

       In the above example, all of the arguments are output with
       a space between each one by looping  through  elements  of
       the objv array from one to the argument count, objc, and a
       newline is output  to  terminate  the  line  --  a  simple
       ``echo''  command.   This example uses printf for simplic­
       ity.  Of course in production code you would want  to  use
       the Tcl filesystem interfaces.  See GetFile(3) and friends
       for more information.

       All arguments from a Tcl call to a  Tcl  C  extension  are
       passed as Tcl Objects.  If your C routine wants to look at
       one of those arguments as an integer, you need to  make  a
       call  to  a  routine  to  fetch  the representation of the
       object  that  you  need.   In  the  earlier  example,  for
       instance,  Tcl_GetStringFromObj is called to obtain a tex­
       tual representation of an object.  Additional routines are
       available to fetch the representation of a data element as
       other data types.   Tcl_GetBooleanFromObj,  Tcl_GetDouble­
       FromObj,   Tcl_GetIntFromObj,   Tcl_GetLongFromObj,    and
       Tcl_GetIndexFromObj, fetch object representations  of  Tcl
       strings  as  booleans,  double-precision  floating  point,
       integer, long integer, and lists, among others.

       These routines automatically leave  an  appropriate  error
       message  in the Tcl interpreter's result object and return
       TCL_ERROR if a conversion error occurs.   (For more infor­
       mation  on  these  routines,  please look at the Object(3)
       manpage in the core Tcl distribution.)


RETURNING RESULTS

       As you might expect, the API for setting  results  from  C
       extensions has changed significantly under the object sys­
       tem.  The old technique of writing small results directory
       into  the  interpreter's  result buffer is no longer used,
       for example.  The notion of having to tell Tcl  whether  a
       result  is  static or dynamic is also a thing of the past.
       Under the object system, results are objects that are  set
       up  by  your  code,  and  objects  are  freed  when  their


       If  you  program  produces a numeric result, it should set
       the result object to contain that numeric value.  A common
       way of doing this is something like...

               Tcl_Obj *obj;

               obj = Tcl_GetObjResult (interp);
            Tcl_SetIntObj (obj, value);

       The  above code obtains a pointer to the result object (an
       object made available to your routine that you're supposed
       to  store  your  results  into) and sets the integer value
       value into it.

       Another way to do it would be to set up a new  object  and
       tell Tcl that this object contains the result...

               Tcl_Obj *resultObj;

               /* create a new object for use as a result */
            resultObj = Tcl_NewObj ();

            Tcl_SetIntObj (obj, value);
            Tcl_SetObjResult (interp, resultObj);

       Understanding how results are passed back to Tcl is essen­
       tial to the C extension writer.  Please study  the  SetOb­
       jResult(3)  manual  page  in the Tcl distribution for more
       information.


VALIDATING ARGUMENTS

       It is a design goal of Tcl that no Tcl program be able  to
       cause  Tcl  to dump core.  It is important that the exten­
       sion writers, likewise, use the avaiable methods and tools
       to  make sure that their extensions do not allow unchecked
       input, for example, to cause the code to get some kind  of
       runtime exception.

       The object system has simplified, to some degree, the task
       of validating arguments, in that the object  system  auto­
       matically  attempts  type  conversions as needed, and will
       return an error when a type conversion fails.

       A simple, but important,  check  that  every  C  extension
       should  do is verify that it has the right number of argu­
       ments.

       The act of trying to use, say, a  string  as  an  integer,
       implicitly performs the type conversion of the string and,
       if it doesn't work as an integer, returns TCL_ERROR.   The
       developer  should  check for the TCL_ERROR return from all
       of  the  GetXxxFromObj  commands,  and  handle   them   as

       on back to the user, or to an  intevening  catch,  as  the
       case may be.

       You should also check that values are in range (when their
       ranges are known), and so forth.  When C  data  structures
       need to be handled in Tcl in some form or another, yet the
       contents of the data must remain opaque to Tcl, as is usu­
       ally  the case with binary data (although futures releases
       of Tcl are expected to  have  native  abilities  to  read,
       write  and manipulate binary data instrinsically), handles
       need to be used.  Handles will be described  and  examples
       presented, later in this doc.


ANOTHER C EXTENSION - THE MAX COMMAND

       In  the command below, two or more arguments are compared,
       and the one with the maximum value  is  returned,  if  all
       goes  well.   It  is  an error if there are fewer than two
       arguments (the pointer to the ``max'' command text itself,
       objv[0],  and  a pointer to at least one object to compare
       the values of).

           int
           Tcl_MaxCmd (clientData, interp, objc, objv)
               char         *clientData;
               Tcl_Interp   *interp;
               int           objc;
               Tcl_Obj     **objv;
           {
               int maxVal = MININT;
               int value, idx;

               if (objc < 3)
                return TclX_WrongArgs (interp, objv[0],
                                          " num1 num2 [..numN]");

               for (idx = 1; idx < objc; idx++) {
                   if (Tcl_GetIntFromObj (interp, objv[idx], &value) != TCL_OK)
                       return TCL_ERROR;

                   if (value > maxVal) {
                       maxVal = value;
                   }
               }
            Tcl_SetIntObj (Tcl_GetObjResult (interp), value);
               return TCL_OK;
           }

       Here  we  introduce  the  Extended  Tcl  helper   function
       TclX_WrongArgs.   This  routine makes it easy to create an
       error message and error return in response to  the  common
       mistake of being called with a wrong number.

       the remaining arguments.  If any fail to be converted,  we
       return a Tcl error.  If an interpreter is specified in the
       call to Tcl_GetIntFromObj, an  appropriate  error  message
       about  the  conversion failure will be left in the result,
       so we do that here.

       After examining all of the arguments to find  the  largest
       value, we set the result object to contain that value, and
       return TCL_OK.


RETURNING RESULTS

       When Tcl-callable functions complete, they should normally
       return  TCL_OK  or TCL_ERROR.  TCL_OK is returned when the
       command succeeded, and TCL_ERROR is returned when the com­
       mand has failed in some abnormal way.  TCL_ERROR should be
       returned for all syntax errors,  non-numeric  values  when
       numeric  ones  were expected, and so forth.  Less clear in
       some cases is whether Tcl errors  should  be  returned  or
       whether a function should just return a status value.  For
       example, end-of-file during a gets returns a  status,  but
       open  returns  an error if it fails.  Errors can be caught
       from Tcl programs using the  catch  command.   (See  Tcl's
       catch(n) and error(n) manual pages.)

       Less  common  return  values are TCL_RETURN, TCL_BREAK and
       TCL_CONTINUE.  These are used if you are adding  new  con­
       trol  and/or looping structures to Tcl.  To see these val­
       ues in action, examine the source code to  Extended  Tcl's
       loop  commands.   Tcl's while, for and if commands used to
       work in the just same manner, but are  now  compiled  into
       bytecode by the bytecode for performance.


ANOTHER C EXTENSION - THE LREVERSE COMMAND

       In the command below, a list is passed as an argument, and
       a list containing all of  the  elements  of  the  list  in
       reverse  order  is  returned.   It is an error if anything
       other than two arguments are passed (the  pointer  to  the
       ``lreverse''  command  text itself, objv[0], and a pointer
       to the list to reverse.

       Once lreverse has determined that it has received the cor­
       rect number of arguments, Tcl_ListObjGetElements is called
       to split the list into its own objc count of elements  and
       objv array of pointers to the list's elements.

       lreverse  then operates on the array of pointers, swapping
       them from lowest to highest, second-lowest to second-high­
       est, and so forth.

       Tcl_ListObjAppendElement is called on successive list ele­
       ments to build up the new list, which is finally  returned


       int
       Tcl_LreverseObjCmd(notUsed, interp, objc, objv)
           ClientData    notUsed;         /* Not used. */
           Tcl_Interp   *interp;          /* Current interpreter. */
           int           objc;            /* Number of arguments. */
           Tcl_Obj     **obj;             /* Argument strings. */
       {
           int listObjc, lowListIndex, hiListIndex;
           Tcl_Obj **listObjv;
           char *temp, *resultList;
           Tcl_Obj **newListObjv;

           /* Verify argument count.  Since we take only one argument, argument
            * count must be 2 (command plus one argument).
            */
           if (objc != 2)
            return TclX_WrongArgs (interp, objv [0], "list");

           /* Create an object to handle the new list we're creating */
           newListObjv = Tcl_NewObj();

           /* Crack the list at objv[1] into its own count and array of object
            * pointers.
            */
           if (Tcl_ListObjGetElements (interp, objv[1], &listObjc, &listObjv) != TCL_OK) {
            return TCL_ERROR;
           }

           /* For each element in the source list from last to first, append an
            * element to the new list.
            */
           for (listIndex = listObjc - 1; listIndex >= 0; listIndex--) {
            Tcl_ListObjAppendElement (interp, newListObjv, listObjv[listIndex]);
           }
       FIX: NEED TO RETURN THE LIST.
           return TCL_OK;
       }


INSTALLING YOUR COMMAND

       To  install  your  command into Tcl you must call Tcl_Cre­
       ateObjCommand, passing it the pointer to  the  interpreter
       you want to install the command into, the name of the com­
       mand, a pointer to the C function that implements the com­
       mand,  a client data pointer, and a pointer to an optional
       callback routine.

       The client data pointer and the callback routine  will  be
       described later.

       For   example,   for   the   max  function  above  (which,

       TclX7.4/src directory):

           Tcl_CreateCommand (interp, "max", Tcl_MaxCmd, (ClientData)NULL,
                             (void (*)())NULL);

       In  the  above  example,  the max function is added to the
       specified interpreter.  The client data pointer and  call­
       back function pointer are NULL.  (For complete information
       on Tcl_CreateCommand and its companion  routine,  Tcl_Com­
       mandInfo, please examine the CrtCommand(3) command page in
       the core Tcl distribution.)


DYNAMIC STRINGS

       Dynamic strings are an important  abstraction  that  first
       became  available  with  Tcl  7.0.   Dynamic  strings,  or
       DStrings, provide a  way  to  build  up  arbitrarily  long
       strings  through  a repeated process of appending informa­
       tion to them.  DStrings reduce the  amount  of  allocating
       and copying required to add information to a string.  Fur­
       ther, they simplify the process of doing so.

       At first glance, it may seem that the object system super­
       sedes  DStrings.   It  does  not,  in that the performance
       improvements made possible by the lazy  conversion  of  an
       object's  representation from one datatype to another does
       not come into play much while constructing strings as  the
       string  representation  is always available either without
       any type conversion or where type conversion would be nec­
       essary  in  any  case  as  a  string representation of the
       object is required when strings are being  constructed  by
       concatenation, etc.

       It  should  be  noted,  however,  that  the C level string
       manipulation capabilites of objects, such  as  Tcl_Append­
       ToObj  and Tcl_AppendStringsToObj, are often plenty enough
       for what you need to  do.   For  complete  information  on
       dynamic strings, please examine the DString(3) manual page
       in the core Tcl distribution.  For more  on  Tcl  object's
       string-oriented  calls,  seek Tcl_StringObj(3) in the same
       location.


CLIENT DATA

       The client data pointer provides a means for Tcl  commands
       to  have  data  associated with them that is not global to
       the C program nor included in the Tcl core.   Client  data
       is  essential  in a multi-interpreter environment (where a
       single program has created and is making use  of  multiple
       Tcl  interpreters) for the C routines to maintain any per­
       manent data they need  on  a  per-interpreter  basis.   If
       needed  static  data  was simply declared static in C, you
       will probably have reentrancy problems when you work  with


       Tcl  solves  this through the client data mechanism.  When
       you are about to call Tcl_CreateObjCommand to  add  a  new
       command  to  an interpreter, if your command needs to keep
       some read/write data across invocations, you should  allo­
       cate the space, preferably using Tcl_Alloc instead of mal­
       loc, then pass the address of that space as the ClientData
       pointer to Tcl_CreateObjCommand.

       When  your  command  is  called  from  Tcl, the ClientData
       pointer you passed to Tcl_CreateObjCommand will be  passed
       to  your  C routine through the ClientData pointer calling
       argument.

       Commands that need to share this data with one another can
       do  so  by using the same ClientData pointer when the com­
       mands are added.

       It is important to note that the  Tcl  extensions  in  the
       tclX8.0.0  directory  have had all of their data set up in
       this way.  Since release 6.2, Extended Tcl  has  supported
       multiple interpreters within one invocation of Tcl.


THEORY OF HANDLES

       Sometimes you need to have a data element that isn't read­
       ily representable as a string within Tcl,  for  example  a
       pointer  to  a complex C data structure.  It is not a good
       idea to try to pass pointers around within Tcl as  strings
       by  converting them to and from hex or integer representa­
       tions, for example.  It is too easy to mess  one  up,  and
       the likely outcome of doing that is a core dump.

       Instead  we  have developed and made use of the concept of
       handles.  Handles are identifiers a C extension  can  pass
       to,  and  accept  from, Tcl to make the transition between
       what your C code knows something  as  and  what  name  Tcl
       knows  it  by to be as safe and painless as possible.  For
       example, the I/O system included in Tcl uses file handles.
       When you open a file from Tcl, a handle is returned of the
       form filen where n is a file number.  When  you  pass  the
       file  handle back to puts, gets, seek, flush and so forth,
       they validate the file handle by  checking  the  the  file
       text  is  present,  then  converting the file number to an
       integer that they use to look into  a  data  structure  of
       pointers to Tcl open file structures, which contain a Unix
       file descriptor, flags indicating whether or not the  file
       is  currently  open,  whether the file is a file or a pipe
       and so forth.

       Handles have proven so useful  that,  since  TclX  release
       6.1a,  general  support  has been available to help create
       and manipulate them.   Many  of  these  capabilities  have
       migrated  into  baseline Tcl.  If you have a similar need,

       Handles(3)  in  Extended Tcl.  We recommend that you use a
       unique-to-your-package textual handle coupled with a  spe­
       cific  identifier  and  let the handle management routines
       validate it when it's passed back.  It is much  easier  to
       track down a bug with an implicated handle named something
       like file4 or bitmap6 than just 6.

       Note that Tcl's object offers another way for complex data
       structures  to  exist  in parallel with and underneath Tcl
       strings.  As of this writing (May 30, 1997) this is fairly
       new  territory,  but  things  are  looking  good  for  the
       prospects of using the Tcl object system in  this  manner,
       and  for enhancements to the object system that allow even
       Tcl objects to have methods in a very straightforward  and
       simple way.


USING COMMANDS TO DO THE SAME THING, AND MORE

       Another handle-like technique, first popularized in the Tk
       toolkit, offers handle-like capabilities as well  as  some
       neat additional capabilities.  That is to create a new Tcl
       command, from C, that uses ClientData to keep  a  "handle"
       on  its complex underlying data structure.  Then by having
       that command look at its second argument for what it is to
       do  (its sub-functions), you get these nice methods, where
       you have several additional sub-commands that  don't  pol­
       lute the global namespace and only work on (and are avail­
       able with) the objects (new commands)  they  are  relevant
       to.  For example, in Tk, creating a checkbutton (checkbut­
       ton .b) creates a new Tcl command (.b), that  has  methods
       to  configure  the  button,  select,  deselect, toggle and
       flash it.

       A lot of people think this is really the way to go, and  I
       am  pretty  much  leaning that way myself.  If you use the
       incr tcl script-level object system for Tcl, objects  that
       you  define  in  Tcl will be highly compatible in terms of
       their command interfaces and configuration management with
       objects  you create in C using the the command-and-Client­
       Data technique described here.  I believe Tk has some nice
       facilities  for  making  this easy for the Tcl programmer.
       Itcl certainly does.


TRACKING MEMORY CORRUPTION PROBLEMS

       Occasionally you may write code that  scribbles  past  the
       end  of  an  allocated piece of memory.  This will usually
       result in a core dump or memory allocation  failure  some­
       time  later in the program, often implicating code that is
       not actually responsible for the  problem  (as  you  start
       looking  from the point where the error is detected, which
       is usually where the later routine has failed).

       The memory debugging routines included  in  Tcl  can  help

       ory debugging routines are now part of baseline  Tcl,  and
       is to our knowledge the largest piece of TclX to drop into
       the core without being reengineered first.  (You see, sum­
       mer  back in '91, John was sitting in his office in the CS
       building at UC Berkeley trying to find a memory leak some­
       where in Tcl, when he was paid a visit by two long-haired-
       yet-polite programmers bearing gifts in the  form  of  the
       technology  grab-bag  known as Extended Tcl.  He saw that,
       using TclX's malloc routines, Tcl  could  be  prompted  to
       print  the filename and line number of every single memory
       allocation that did not have a corresponding free.  It was
       just  what  the  doctor  ordered  ;-)  See Memory(TCL) for
       details.


INSTALLING YOUR EXTENSIONS INTO TCL

       To add your extensions to Tcl, you used to have to  stati­
       cally  link them, together with any other extensions, into
       a single binary executable  image.   Today,  although  the
       statically  linked  executable  is  still  an option, most
       operating systems, even Microsoft Windows, support  shared
       libraries,  and  in  most  cases,  Tcl can now make use of
       those shared libraries such that you extensions, and  most
       others,  can  now  be built a shared libraries that can be
       loaded in (using package require)  by  scripts  that  need
       them.   Shared  libraries can simplify a Tcl installation,
       because only one copy of Tcl is required,  rather  than  a
       hodepodge  of  combinations of applications that you might
       have found at a big Tcl site in the previous era.


GNU AUTOCONF

       While the build procedure for shared libraries varies from
       system  to  system,  most  Unix and Unix workalike systems
       will figure out the nuances of  the  compiler  and  linker
       arguments  automatically when the configure script is run.
       If you are building a package that you plan to make gener­
       ally  available,  we  strongly  recommend that you use GNU
       autoconf  (ftp://prep.ai.mit.edu/pub/gnu)  to  set  up  an
       automatic  configure  script  for  it.  Be forewarned that
       autoconf uses some pretty heavy duty shell and sed  script
       magic  to  get the job done, and the learning curve can be
       pretty steep.  Once done  and  shaken  out,  though,  it's
       rewarding  to  know that your package can build and run on
       everything from a notebook to a Cray to a RISC SMP server.

       Application-specific  startup  is accomplished by creating
       or editing the Tcl_AppInit function.  In  Tcl_AppInit  you
       should add a call to an application-specific init function
       which you create.  This function should take  the  address
       of  the  interpreter  it should install its commands into,
       and it should install those commands  with  Tcl_CreateCom­
       mand and do any other application-specific startup that is
       necessary.

       App_Init,  where App is the name of your application.  For
       example, to add an application named cute one would create
       a  Cute_Init routine that expected a Tcl_Interp pointer as
       an argument, and add the following code to Tcl_AppInit:

           if (Cute_Init (interp) == TCL_ERROR) {
            return TCL_ERROR;
           }

       As you can guess from the above example, if your init rou­
       tine  is  unable  to  initialize, it should use Tcl_Appen­
       dResult to provide some kind of useful error message  back
       to  TclX,  then return TCL_ERROR to indicate that an error
       occurred.  If the routine executed successfully, it should
       return TCL_OK.

       When  you examine Tcl_AppInit, note that there is one call
       already there to install an application  --  the  call  to
       TclX_Init installs Extended Tcl into the Tcl core.


MAKING APPLICATION INFORMATION VISIBLE FROM EXTENDED TCL

       TclX's infox command can return several pieces of informa­
       tion relevant to Extended Tcl, including the application's
       name,  descriptive  name,  patch  level and version.  Your
       application's startup can set these variables to  applica­
       tion-specific  values.   If  it  doesn't,  they  are given
       default values for Extended Tcl.

       To set these values, first be sure that you include either
       tclExtend.h  or  tclExtdInt.h  from  the  source file that
       defines your init routine.  This will create external dec­
       larations  for  the variables.  Then, set the variables in
       your init route, for example:

           tclAppName = "cute";
           tclAppLongName = "Call Unix/Tcl Environment";
           tclAppVersion = "2.1";

       Note that the default values are set by TclX_Init,  so  if
       you wish to override them, you must call your init routine
       in Tcl_AppInit after its call to TclX_Init.


EXTENDED TCL EXIT

       When Extended Tcl exits, Tcl_DeleteInterp may be called to
       free  memory  used by Tcl -- normally, this is only called
       if TCL_MEM_DEBUG was defined, since Unix will  return  all
       of  the  allocated  memory back to the system, anyway.  If
       TCL_MEM_DEBUG was defined, it is called so that any memory
       that  was  allocated  without  ever  being  freed  can  be
       detected.  This greatly reduces  the  amount  of  work  to
       detect and track down memory leaks, a situation where some

       ever freeing it, or at least without always freeing it.

       It  is  often necessary for an application to perform spe­
       cial cleanup functions upon the deletion of an interpreter
       as  well.   To  facilitate this activity, Tcl provides the
       ability to perform a function callback when an interpreter
       is deleted.  To arrange for a C function to be called when
       the interpreter is deleted, call Tcl_CallWhenDeleted  from
       your  application  initialization routine.  For details on
       how to use this function, read the CallDel(3) manual  page
       that ships with core Tcl.


EXECUTING TCL CODE FROM YOUR C EXTENSION

       Suppose  you are in the middle of coding a C extension and
       you realize that you need some  operation  performed,  one
       that  would  be simple from Tcl, but possibly excruciating
       to do directly in C.  Tcl provides  a  number  of  C-level
       interfaces whereby you can cause Tcl code to be executeed.
       The old-style calls are Tcl_Eval,  Tcl_VarEval,  Tcl_Eval­
       File  and  Tcl_GlobalEval.  The results of these calls can
       be dug out of the interpreter  using  Tcl_GetStringResult,
       if  you  want  a  string  representation of the result, or
       Tcl_GetObjResult if you want  the  object.   (The  use  of
       interp->result to access the result string has been depre­
       cated.)

       The Tcl object system adds Tcl_EvalObj and Tcl_GlobalEval­
       Obj.   The  difference  here  is that we are evaluating an
       object, not just a string, and  using  these  routines  in
       preference  to  the  aforementioned  ones  can result in a
       major performance improvement in your code, when the  code
       is  executed repeatedly (even if it only executes once but
       loops several times within itself), as these routines make
       it  possible for the bytecode compiler to compile the code
       being evaluated and save the compiled code with  the  data
       structure, in an implementation-dependent manner.

       For  more  information  please  consult the EvalObj(3) and
       Eval(3) manual pages within the Tcl distribution.


ACCESSING TCL VARIABLES AND ARRAYS FROM YOUR C EXTENSIONS

       In addition to the non-object-system ways of reading  from
       and  storing  to  Tcl  variables,  using  routines such as
       Tcl_SetVar2 and Tcl_GetVar2, Tcl variables and arrays  can
       be  read  from  a  C extension as Tcl objects by using the
       Tcl_ObjGetVar2 function, and set from C extensions through
       the Tcl_ObjSetVar2 function.

       Please  note that the object versions do not carry forward
       analogues to  the  one-variable-name-argument  Tcl_GetVar,

       scalar, call the object variable  get  and  set  functions
       with  a NULL second argument.  If your variable name might
       contain an array reference via a  self-contained  embedded
       array  index (i.e., I'm asking Tcl_ObjGetVar2 for "foo(5)"
       instead of "foo" "5"),  add  the  TCL_PARSE_PART1  to  the
       flags in your call.

       While  the fact that Tcl_ObjGetVar2 retrieves Tcl objects,
       rather than strings, is critical for the object system  to
       be able to provide the performance boosts from "lazy" type
       conversion and the binary data capabilities, the arguments
       containing  the  variable name, or the array name and ele­
       ment name if they've been split out, also must  be  speci­
       fied  as  Tcl  objects rather than strings.  While this is
       useful on occasion, those writing C extensions for Tcl  in
       the  post-object-system  era usually have the names avail­
       able as plain old char * variables,  requiring  conversion
       of the strings to objects before use and account for their
       possible destruction afterwards.

       To simplify  the  task  in  those  cases,  TclX  adds  the
       TclX_ObjGetVar2S   subroutine.    It   works   just   like
       Tcl_ObjGetVar2, except the one or two variable name  argu­
       ments are specified as strings, and the routine takes care
       of making and disposing of object equivalents.

       Tcl variables can be unset from C via the Tcl_UnsetVar and
       Tcl_UnsetVar2  functions.  There are currently (as of 8.0)
       no object-system equivalents, so in the  rare  case  where
       you  have  the  name  of the variable you want unset as an
       object instead of a string, you can call Tcl_GetStringFro­
       mObj to obtain the string representation first.

       For  complete information on these functions, please refer
       to the ObjSetVar(3) and SetVar(3) manual pages in the  doc
       directory of the core Tcl distribution.


LINKING TCL VARIABLES TO C VARIABLES

       Tcl_LinkVar and Tcl_UnlinkVar can be used to automatically
       keep Tcl variables synchronized with corresponding C vari­
       ables.   Once  a Tcl variable has been linked to a C vari­
       able with Tcl_LinkVar, anytime the Tcl variable  is  read,
       the  value  of  the C variable is converted (if necessary)
       and returned, and when the Tcl variable is written, the  C
       variable will be updated with the new value.

       Tcl_LinkVar  uses variable traces to keep the Tcl variable
       named by varName in  sync  with  the  C  variable  at  the
       address given by addr.

       Int,  double,  boolean and char * variables are supported.
       You can make your linked variables read only from the  Tcl

       tinually exist while they  are  linked,  in  other  words,
       linking  "automatic"  C  variables,  those  created on the
       stack while a routine  is  being  executed  and  destroyed
       afterwards,  will  result  in  a malfunctioning program at
       best and a coredump or more at worst.

       For more information, please examine the LinkVar(3) manual
       page in the core Tcl distribution.


ADDING NEW MATH FUNCTIONS TO TCL

       As  of  Tcl  version 7.0, math functions such as sin, cos,
       etc, are directly supported within Tcl expressions.  These
       obsolete  the Extended Tcl commands that provided explicit
       commands for these  functions  for  many,  many  releases,
       although  procs equivalencing the old TclX commands to the
       new math functions are still provided for  backwards  com­
       patibility.

       New  math  functions can be added to Tcl, or existing math
       functions can be replaced, by calling  Tcl_CreateMathFunc.


ACCESSING AND MANIPULATING THE RANDOM NUMBER GENERATOR

       Prior  to  Tcl  version  8.0, the Tcl core did not provide
       access to a random number generator, but TclX did, through
       its  random  command.   As of Tcl version 8.0, access to a
       random  number  generator  is  provided  by  baseline  Tcl
       through the new math functions, rand and srand.

       The  TclX random command is still available -- it has some
       useful capabilities not directly provided by the new base­
       line functions.

       For  more information on adding your own math functions to
       Tcl, please study the CrtMathFnc(3)  manual  page  in  the
       core Tcl distribution.


CONVERTING FILENAMES TO NATIVE FORM AND PERFORMING TILDE SUBSTI­

       TUTIONS
       The  Tcl_TranslateFileName  function  is  available  to  C
       extension  writers  to translate filenames to a form suit­
       able for use by the local operating system.   It  converts
       network names to their native form, and if the name starts
       with a ``~'' character, the function returns a new  string
       where  the name is replaced with the home directory of the
       given user.

       For more information please consult the Translate(3)  man­
       ual page in the core Tcl distribution.

       Tcl  has  a preset recursion limit that limits the maximum
       allowable nesting depth of calls  within  an  interpreter.
       This  is  useful  for detecting infinite recursions before
       other limits such as the process memory limit  or,  worse,
       available swap space on the system, run out.

       The  default  limit is just a guess, however, and applica­
       tions that make heavy use of recursion may  need  to  call
       Tcl_SetRecursionLimit  to  raise  this  limit.   For  more
       information, please consult the SetRecLmt(3)  manual  page
       in the core Tcl distribution.


HANDLING SIGNALS FROM TCL EXTENSIONS

       If  an event such as a signal occurs while a Tcl script is
       being executed, it isn't safe to do  much  in  the  signal
       handling  routine  -- the Tcl environment cannot be safely
       manipulated at this point because it could be in the  mid­
       dle  of some operation, such as updating pointers, leaving
       the interpreter in an unreliable state.

       The only safe approach is to set a  flag  indicating  that
       the  event  occurred, then handle the event later when the
       interpreter has returned to a safe state,  such  as  after
       the current Tcl command completes.

       The  Tcl_AsyncCreate,  Tcl_AsyncMark, Tcl_AsyncInvoke, and
       Tcl_AsyncDelete functions provide  a  safe  mechanism  for
       dealing  with  signals and other asynchronous events.  For
       more information on how to  use  this  capability,  please
       refer  to the Async(3) manual page in the core Tcl distri­
       bution.

       Note that Extended Tcl provides built-in support for  man­
       aging  signals in numerous ways, including generating them
       with alarm(2) and kill(2), ignoring them,  trapping  them,
       getting,  setting,  blocking and unblocking them.  You can
       cause specific code to execute at a  safe  point  after  a
       signal  occurs,  or  cause  a Tcl error backtrace on one's
       occurrence.  For more information, please examine the TclX
       documentation.


PARSING BACKSLASH SEQUENCES

       The  Tcl_Backslash  function  is called to parse Tcl back­
       slash sequences.  These backslash sequences are the  usual
       sort  that  you see in the C programming language, such as
       \n for newline, \r for return, and  so  forth.   Tcl_Back­
       slash  parses  a  single  backslash sequence and returns a
       single character corresponding to the backslash  sequence.

       For  more info on this call, look at the Backslash(3) man­
       ual page in the core Tcl distribution.  For information on

       language syntax, Tcl(n) in the same distribution.


HASH TABLES

       Hash tables provide Tcl with a  high-performance  facility
       for  looking  up  and managing key-value pairs located and
       maintained in memory.  Tcl uses hash tables internally  to
       locate  procedure  definitions,  Tcl variables, array ele­
       ments, file handles and so  forth.   Tcl  makes  the  hash
       table functions accessible to C extension writers as well.

       Hash tables grow  automatically  to  maintain  efficiency,
       rather  than  exposing the table size to the programmer at
       allocation time, which would needlessly add complexity  to
       Tcl  and would be prone to inefficiency due to the need to
       guess the number of items that will go into the table, and
       the  seemingly  inevitable  growth  in amount of data pro­
       cessed per run over the useful life of the program.

       For more information on hash tables,  please  consult  the
       Hash(3) manual page in the core Tcl distribution.


TRACING VARIABLE ACCESSES

       The  C  extension  writer  can arrange to have a C routine
       called whenever a Tcl variable is read, written, or unset.
       Variable traces are the mechanism by which Tk toolkit wid­
       gets such as radio and checkbuttons, messages and so forth
       update without Tcl programmer intervention when their data
       variables are changed.  They are also used by the  routine
       that  links  Tcl  and  C variables, Tcl_LinkVar, described
       above.

       Tcl_TraceVar is called  to  establish  a  variable  trace.
       Entire  arrays and individual array elements can be traced
       as well.  If the programmer already has an array  name  in
       one  string  and a variable name in another, Tcl_TraceVar2
       can be called.  Calls are also available to request infor­
       mation about traces and to delete them.

       For  more  information  on  variable  traces,  consult the
       TraceVar(3) manual page in the core Tcl distribution.


TRACING TCL EXECUTION

       Tcl has the ability to call C routines each time  it  exe­
       cutes  a  Tcl  command, up to a specified depth of nesting
       levels.  The command Tcl_CreateTrace creates an  execution
       trace; Tcl_DeleteTrace deletes it.

       Command  tracing  is used in Extended Tcl to implement the
       cmdtrace Tcl command, a useful command for  debugging  Tcl
       applications.

       at the CrtTrace(3) manual pages in the core Tcl  distribu­
       tion.


EVALUATING TCL EXPRESSIONS FROM C

       Tcl_ExprLong,     Tcl_ExprDouble,     Tcl_ExprBool,    and
       Tcl_ExprString all take string arguments and, when called,
       evaluate  those  strings as Tcl expressions.  Depending on
       the routine called, the result is either a C long, a  dou­
       ble,  a  boolean (int with a value of 0 or 1), or a char *
       (obtainable through Tcl_GetResult).

       To take  advantage  of  the  performance  gains  available
       through    the    bytecode    compiler,   Tcl_ExprLongObj,
       Tcl_ExprDoubleObj, Tcl_ExprBoolObj,  and  Tcl_ExprObj  all
       take  an  object  containing an expression to be evaluated
       (rather than a string.)  The result is that  bytecode-com­
       piled  version  of  the  expression  will  be  kept in the
       object,  alongside  the  string  representation.   If  the
       expression  is  evaluated again, without being changed, it
       does not have to be recompiled... a major performance win.

       For  complete  information  on  evaluating Tcl expressions
       from C, you are invited to  examine  the  ExprLong(3)  and
       ExprLongObj(3) manpages in the core Tcl distribution.


PATTERN MATCHING

       The  Tcl_StringMatch  function  can  be called to see if a
       string matches a specified  pattern.   Tcl_StringMatch  is
       called  by the Tcl string match command, so the format for
       patterns is identical.  The pattern format is  similar  to
       the one used by the C-shell; string(n) describes this for­
       mat.

       More information about Tcl_StringMatch is available in the
       StrMatch(3) manpage in the core Tcl distribution.


REGULAR EXPRESSION PATTERN MATCHING

       Tcl_RegExpMatch  can  be  called  to  determine  whether a
       string matches a regular expression.   Tcl_RegExpMatch  is
       used internally by the regexp Tcl command.

       As  regular  expressions  are  typically "compiled" before
       use, a fairly involved process, Tcl also supports routines
       that  separate  the  compilation of an expression from its
       use:  Tcl_RegExpCompile,  Tcl_RegExpExec,  and  Tcl_RegEx­
       pRange.   If  an  expression  is  going to be matched many
       times, doing the compile once  and  caching  the  compiled
       regular expression result, then reusing the cached version
       by using Tcl_RegExpExec, can be a significant  performance
       win.

       RegExp(3) manpage in the core Tcl distribution.


MANIPULATING TCL LISTS FROM C EXTENSIONS

       The C extension writer often needs to  create,  manipulate
       and decompose Tcl lists.  Tcl_SplitList and Tcl_Merge used
       to be the only way to parse strings into  lists  and  vice
       versa.   As  of  Tcl 8, lists can be parsed and assembled,
       object-style, using Tcl_ListObjGetElements and Tcl_SetLis­
       tObj,  and friends.  Once again the "win" of using object-
       system-based list manipulation, instead  of  the  previous
       string  based routines, is that the parsing of a string in
       an object to a list is cached in the object structure, the
       same as with integers and floating point numbers, compiled
       procedures, etc.  The next time this string  needs  to  be
       looked  at  as  a list, if the contents of the string have
       not changed, the string does not have to be parsed.

       In the author's experience,  working  with  an  admittedly
       degenerate  test  whereby we iterated rather inefficiently
       across a 6,000-element list, a speedup factor of more than
       2500  was obtained over the previous non-object-based ver­
       sion of Tcl.

       For more information on these commands, please consult the
       ListObj(3) manual page in the core Tcl distribution.


CONCATENATING STRINGS

       Tcl_ConcatObj  concatenates  the  string representation of
       zero or more objects into a single new object.   The  ele­
       ments  of  the new string are space-separated.  Tcl_Concat
       does the same thing for strings, as Tcl_ConcatObj does for
       objects.

       Concatenating  strings  is  similar  to constructing lists
       from them, except that Tcl_ConcatObj and Tcl_Concat do not
       attempt  to  make  the  resulting  string into a valid Tcl
       list.

       Tcl_Concat is documented in  the  Concat(3)  manpage,  and
       Tcl_ConcatObj  in  the  tringObj manpage, both in the core
       Tcl distribution.


DETECTING WHETHER OR NOT YOU HAVE A COMPLETE COMMAND

       C routines that collect data  to  form  a  command  to  be
       passed  to  Tcl_Eval often need a way to tell whether they
       have a complete command already or whether they need  more
       data.   (Programs that read typed-in Tcl input such as Tcl
       shells need this capability, for instance.)   Tcl_Command­
       Complete  can  be  used  to tell whether or not you have a
       complete command.

       distribution.


RECORDING COMMANDS FOR COMMAND HISTORY

       Tcl  has  a  history  mechanism  that is accessed from Tcl
       through the history command.  If you want  your  extension
       to propagate commands into the command history, you should
       call Tcl_RecordAndEvalObj (object system) or Tcl_RecordAn­
       dEval (old system),

       These commands work like Tcl_EvalObj and Tcl_Eval, respec­
       tively, except that these versions record the  command  as
       well as executing it.

       Tcl_RecordAndEval  and  Tcl_RecordAndEvlObj should only be
       called with user-entered  top-level  commands,  since  the
       history  mechanism  exists  to  allow  the  user to easily
       access, edit and reissue previously issued commands.

       For complete information on these functions, please  exam­
       ine  the RecordEval.3 and RecEvalObj.3 manual pages in the
       core Tcl distribution.


CONVERTING FLOATING POINT VALUES TO STRINGS

       The Tcl object system's Tcl_GetDoubleFromObj and  Tcl_Set­
       DoubleObj use Tcl objects, rather than the strings used by
       Tcl_PrintDouble, and convert,  when  necessary,  an  ASCII
       string to a double and back again.

       These routines ensure that the string output will continue
       to be interpretable as a  floating  point  number,  rather
       than  an  integer, by always putting a ``.'' or ``e'' into
       the string representing the number.

       The precision of the output string is  controlled  by  the
       Tcl tcl_precision variable.

       For complete information on these routines, please examine
       DoubleObj(3) and PrintDbl(3) in the core Tcl distribution.


CREATING CHILD PROCESSES AND PIPELINES FROM C

       Tcl_OpenCommandChannel provides a C-level interface to the
       exec and open commands.  The child (or pipeline  of  chil­
       dren)  can have its standard input, output and error redi­
       rected from files, variables or pipes.  To understand  the
       meaning  of  the  redirection  symbols  understood by this
       function, look at the exec(n) Tcl command.   For  complete
       information   on  Tcl_OpenCommandChannel,  please  examine
       OpenFileChnl(3).

       On Posix/Unix systems, Tcl filehandles passed  to  your  C
       extension  can  be  translated to a Posix FILE * structure
       using the Tcl_GetOpenFile function, documented  in  GetOp­
       nFl.3.


MANAGING BACKGROUND PROCESS TERMINATION AND CLEANUP

       When  a  Posix system does a fork to create a new process,
       the process ID of the child is  returned  to  the  caller.
       After  the  child  process  exits, its process table entry
       (and some other data associated with the  process)  cannot
       be reclaimed by the operating system until a call to wait­
       pid, or one of a couple of other,  similar  system  calls,
       has been made by the parent process.

       The  C  extension  writer who has created a subprocess, by
       whatever  mechanism,  can  turn  over  responsibility  for
       detecting  the  processes' termination and calling waitpid
       to obtain its exit status, by  calling  Tcl_DetachPids  on
       it.

       Tcl_ReapDetachedProcs  is  the  C routine that will detect
       the termination of any processes turned over to Tcl,  per­
       mitting the processes to be fully reclaimed by the operat­
       ing  system.   It  is  usually  not  necessary   to   call
       Tcl_ReapDetachedProcs, as it is called automatically every
       time exec is performed.

       For complete information on these routines, please look at
       DetachPids(3) in the core Tcl distribution.


FOR MORE INFORMATION

       In addition to the documentation referenced above, you can
       learn a lot by studying the source code  of  the  commands
       added by Tcl, Tk and Extended Tcl, etc.  The comp.lang.tcl
       Usenet newsgroup is read by hundreds of thousands  of  Tcl
       people.   A  number  of  Frequently Asked Questions (FAQs)
       about Tcl are posted there periodically.  The newsgroup is
       a  good  place  to  ask  questions (after you've made sure
       they're not already answered in the FAQ ;-)

       Finally, if you have interactive Internet access, you  can
       ftp  to  ftp://ftp.neosoft.com/pub/tcl,  the site for con­
       tributed Tcl sources.  This  site  contains  quite  a  few
       extensions,  applications, and so forth, including several
       object-oriented extension packages.

       If you have access via the world-wide web, check  out  the
       Sun Microsystems site (http://sunscript.sun.com), the con­
       tributed         sources          archive          website
       (http://www.neosoft.com/tcl),   and   the   homepage   for
       Extended Tcl (http://www.neosoft.com/tclx).

       Extended   Tcl   was   created    by    Karl    Lehenbauer
       (karl@neosoft.com)  and Mark Diekhans (markd@grizzly.com).


Man(1) output converted with man2html