Provided by: tclx8.4-doc_8.4.1-2_all bug

NAME

       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 existing editor, communications program, window
       manager,  etc.   C programming information can also be found in the *.3 manual pages in the doc directory
       of the Berkeley distribution, and in the *.3 manpages in the man directory of Extended Tcl.

WRITING TCL EXTENSIONS IN C

       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 pointers to character strings containing the Tcl arguments
       to the command.

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

           #include "tcl.h"

           int App_EchoCmd(clientData, interp, argc, argv)
               void       *clientData;
               Tcl_Interp *interp;
               int         argc;
               char      **argv;
           {
                   int i;

                   for (i = 1; i < argc; i++) {
                           printf("%s",argv[i]);
                     if (i < argc - 1) printf(" ");
                   }
                   printf("\n");
                   return TCL_OK;
           }

       The client data pointer will be described later.

       The interpreter pointer is the ``key'' to an interpreter.  It is returned by Tcl_CreateInterp and is used
       extensively  within  Tcl,  and  will  be  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 currently defined procedures, commands, variables, arrays and the
       execution state of that interpreter.  (For more information on creating and deleting interpreters, please
       examine  the  CrtInterp(3)  manpage  in  the  Berkeley  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 Berkeley Tcl.)

       The argument count and pointer to an array of pointers to textual arguments is handled by your C code  in
       the  same  manner  that  you  would  use  in writing a C main function -- the 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  argv array.  Similar to a C main, the first argument (argv[0]) is the name the routine was called as
       (in a main, the name the program was invoked as).

       In the above example, all of the arguments are output with a space between each one  by  looping  through
       argv  from  one to the argument count, argc, and a newline is output to terminate the line -- an ``echo''
       command.

       All arguments from a Tcl call to a Tcl C extension are passed as strings.   If  your  C  routine  expects
       certain  numeric  arguments,  your  routine must first convert them using the Tcl_GetInt or Tcl_GetDouble
       function, Extended Tcl's Tcl_GetLong or Tcl_GetUnsigned, or some  other  method  of  your  own  devising.
       Likewise  for  converting  boolean  values,  Tcl_GetBoolean should be used.  These routines automatically
       leave an appropriate error message in the Tcl interpreter's result  buffer  and  return  TCL_ERROR  if  a
       conversion  error occurs.   (For more information on these routines, please look at the GetInt(3) manpage
       in the Berkeley Tcl distribution.)

       Likewise, if you program produces a numeric result, it should return a string equivalent to that  numeric
       value.  A common way of doing this is something like...

            sprintf(interp->result, "%ld", result);

       Writing  results directly into the interpreter's result buffer is only good for relatively short results.
       Tcl has a function, Tcl_SetResult, which provides the ability for your C extensions to return very  large
       strings to Tcl, with the ability to tell the interpreter whether it ``owns'' the string (meaning that Tcl
       should delete the string when it's done with it), that the string is likely to be changed or  overwritten
       soon  (meaning that Tcl should make a copy of the string right away), or that the string won't change (so
       Tcl can use the string as is and not worry about it).  Understanding how results are passed back  to  Tcl
       is  essential  to  the  C  extension  writer.   Please  study  the  SetResult(3)  manual  page in the Tcl
       distribution.

       Sophisticated commands should verify their arguments whenever possible, both by  examining  the  argument
       count,  by  verifying that numeric fields are really numeric, that values are in range (when their ranges
       are known), and so forth.

       Tcl is designed to be as bullet-proof as possible, in the sense that no Tcl program  should  be  able  to
       cause  Tcl to dump core.  Please carry this notion forward with your C extensions by validating arguments
       as above.

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 three arguments (the pointer to the ``max''
       command text itself, argv[0], and pointers to at least two arguments to compare the values of).

       This routine also shows the use of the programmer labor-saving Tcl_AppendResult  routine.   See  the  Tcl
       manual  page,  SetResult(3),  for details.  Also examine the calls Tcl_AddErrorInfo, Tcl_SetErrorCode and
       Tcl_PosixError documented in the Tcl manual page AddErrInfo(3).

           int
           Tcl_MaxCmd (clientData, interp, argc, argv)
               char       *clientData;
               Tcl_Interp *interp;
               int         argc;
               char      **argv;
           {
               int maxVal = MININT;
               int maxIdx = 1;
               int value, idx;

               if (argc < 3) {
                   Tcl_AppendResult (interp, "bad # arg: ", argv[0],
                                     " num1 num2 [..numN]", (char *)NULL);
                   return TCL_ERROR;
               }

               for (idx = 1; idx < argc; idx++) {
                   if (Tcl_GetInt (argv[idx], 10, &Value) != TCL_OK)
                       return TCL_ERROR;

                   if (value > maxVal) {
                       maxVal = value;
                       maxIdx = idx;
                   }
               }
               Tcl_SetResult (interp, argv [maxIdx], TCL_VOLATILE);
               return TCL_OK;
           }

       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 command 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 the open 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  control and/or looping structures to Tcl.  To see these values in action, examine the source code to
       Tcl's while, for and if, and Extended Tcl's loop commands.

       Note the call to Tcl_SetResult in the above command to set the return value to Tcl.  TCL_VOLATILE is used
       because the memory containing the result will be freed upon the function's return.

ANOTHER C EXTENSION - THE LREVERSE COMMAND

       In the command below, one 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, argv[0], and a pointer to the list to reverse.

       Once  lreverse  has  determined  that  it  has received the correct number of arguments, Tcl_SplitList is
       called to break the list into an argc and argv array of pointers.

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

       Finally  Tcl_Merge is calleds to create a single new string containing the reversed list and it is set as
       the result via Tcl_SetResult.  Note that TCL_DYNAMIC is used to tell Tcl_SetResult that it now  owns  the
       string and it is up to Tcl to free the string when it is done with it.

       Note that it is safe to play around with the argv list like this, and that a single call to ckfree can be
       made to free all the data returned by Tcl_SplitList in this manner.

       int
       Tcl_LreverseCmd(notUsed, interp, argc, argv)
           ClientData notUsed;            /* Not used. */
           Tcl_Interp *interp;            /* Current interpreter. */
           int argc;                 /* Number of arguments. */
           char **argv;              /* Argument strings. */
       {
           int listArgc, lowListIndex, hiListIndex;
           char **listArgv;
           char *temp, *resultList;

           if (argc != 2) {
            Tcl_AppendResult(interp, "wrong # args: should be
                 " list
            return TCL_ERROR;
           }

           if (Tcl_SplitList(interp, argv[1], &listArgc, &listArgv) != TCL_OK) {
            return TCL_ERROR;
           }
           for (lowListIndex = 0, hiListIndex = listArgc;
             --hiListIndex > lowListIndex; lowListIndex++) {
            temp = listArgv[lowListIndex];
            listArgv[lowListIndex] = listArgv[hiListIndex];
            listArgv[hiListIndex] = temp;
           }
           resultList = Tcl_Merge (listArgc, listArgv);
           ckfree (listArgv);
           Tcl_SetResult (interp, resultList, TCL_DYNAMIC);
           return TCL_OK;
       }

INSTALLING YOUR COMMAND

       To install your command into Tcl  you  must  call  Tcl_CreateCommand,  passing  it  the  pointer  to  the
       interpreter  you  want  to install the command into, the name of the command, a pointer to the C function
       that implements the command, 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,  incidentally,  comes  from  TclX's  tclXmath.c  in  the
       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 callback function pointer are NULL.  (For complete information on Tcl_CreateCommand and its companion
       routine,   Tcl_CommandInfo,   please   examine  the  CrtCommand(3)  command  page  in  the  Berkeley  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
       information to them.  DStrings reduce the amount of allocating and copying required to add information to
       a  string.  Further, they simplify the process of doing so.  For complete information on dynamic strings,
       please examine the DString(3) manual page in the Berkeley Tcl distribution.

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 permanent data they need on a per-interpreter basis.  Otherwise there would be
       reentrancy problems.  Tcl solves this through the client data mechanism.  When  you  are  about  to  call
       Tcl_CreateCommand  to  add a new command to an interpreter, if that command needs to keep some read/write
       data across invocations, you should allocate the space, preferably using ckalloc, then pass  the  address
       of that space as the ClientData pointer to Tcl_CreateCommand.

       When your command is called from Tcl, the ClientData pointer you gave to Tcl_CreateCommand when you added
       the command to that interpreter is 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 commands are added.

       It is important to note that the Tcl extensions in the tclX7.4/src 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 readily 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 representations, 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 stdio package
       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, as of release 6.1a, general support has been added for them.  If you
       need a similar capability, it would be best to use the  handle  routines,  documented  in  Handles(3)  in
       Extended  Tcl.  We recommend that you use a unique-to-your-package textual handle coupled with a specific
       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.

TRACKING MEMORY CORRUPTION PROBLEMS

       Occasionally  you may write code that scribbles past the end of an allocated piece of memory.  The memory
       debugging routines included in Tcl can help find these problems.  See Memory(TCL) for details.

INSTALLING YOUR EXTENSIONS INTO EXTENDED TCL

       To add your extensions to Extended Tcl, you must compile them and cause them to be linked with TclX.  For
       the  routines  to  be  linked  into  the  tcl and wishx executables, they must be referenced (directly or
       indirectly) from TclX.  For these extensions to be visible as Tcl commands, they must be  installed  into
       Tcl with Tcl_CreateCommand.

       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_CreateCommand and do  any  other  application-specific  startup  that  is
       necessary.

       The  naming  convention  for  application  startup  routines  is  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 routine is unable to initialize, it should use
       Tcl_AppendResult 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 information relevant to  Extended  Tcl,  including  the
       application's  name, descriptive name, patch level and version.  Your application's startup can set these
       variables to application-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 declarations 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 piece of your code allocates memory repeatedly without ever freeing
       it, or without always freeing it.

       It is often necessary for an application to perform special 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 Berkeley 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
       the Tcl_Eval, Tcl_VarEval, Tcl_EvalFile and Tcl_GlobalEval functions for the  purpose  of  executing  Tcl
       code from within a C extension.  The results of the call will be in interp->result.  For more information
       please consult the Eval(3) manual page within the Tcl distribution.

ACCESSING TCL VARIABLES AND ARRAYS FROM YOUR C EXTENSIONS

       Tcl variables and arrays can be read from a C extension through the Tcl_GetVar and Tcl_GetVar2 functions,
       and  set  from C extensions through the Tcl_SetVar and Tcl_SetVar2 functions.  They can also be unset via
       the Tcl_UnsetVar and Tcl_UnsetVar2 functions.  For complete information on these functions, please  refer
       to the SetVar(3) manual page in the doc directory of the Berkeley 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 variables.  Once a Tcl variable has been linked to a C variable with Tcl_LinkVar, anytime
       the  Tcl  variable  is  read  the  value of the C variable will be 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.

       Whenever  the  Tcl  variable  is  read the value of the C variable will be returned, and whenever the Tcl
       variable is written the C variable will be updated to have the same value.

       Int, double, boolean and char * variables are  supported.   For  more  information,  please  examine  the
       LinkVar(3) manual page in the Berkeley 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 calls for  these  functions
       for many releases.

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

       For more information on adding math functions, please  examine  the  CrtMathFnc(3)  manual  page  in  the
       Berkeley Tcl distribution.

PERFORMING TILDE SUBSTITUTIONS ON FILENAMES

       The  Tcl_TildeSubst  function  is  available  to  C  extension  writers to perform tilde substitutions on
       filenames.  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
       TildeSubst(3) manual page in the Berkeley Tcl distribution.

SETTING THE RECURSION LIMIT

       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, are exceeded.

       The default limit is just a guess, however, and applications 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 Berkeley 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 middle 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 Berkeley Tcl distribution.

PARSING BACKSLASH SEQUENCES

       The Tcl_Backslash function is called to parse Tcl backslash 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_Backslash 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) manual page in the Berkeley Tcl distribution.  For
       information on the valid backslash sequences, consult the summary of Tcl 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 elements, 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 processed per run over the life of the program.

       For  more  information  on  hash  tables,  please  consult  the  Hash(3)  manual page in the Berkeley 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 widgets 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 information about traces and
       to delete them.

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

TRACING EXECUTION

       Tcl  has the ability to call C routines for every command it executes, 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.

       For  complete  information  on  execution  tracing,  please  look  at the CrtTrace(3) manual pages in the
       Berkeley Tcl distribution.

EVALUATING TCL EXPRESSIONS FROM C

       Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBool, and Tcl_ExprString can be called to evaluate Tcl  expressions
       from  within  a  C  routine.  Depending on the routine called, the result is either a C long, a double, a
       boolean (int with a value of 0 or 1), or a char * (pointed to by interp->result).

       For complete information on evaluating Tcl expressions from C, you are invited to examine the ExprLong(3)
       manpage in the Berkeley 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 format.

       More  information  about  Tcl_StringMatch  is  available  in  the StrMatch(3) manpage in the Berkeley 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.

       For  more  information  on  this  function,  please  consult  the  RegExp(3)  manpage in the Berkeley Tcl
       distribution.

MANIPULATING TCL LISTS FROM C EXTENSIONS

       The C extension writer often needs to create, manipulate and decompose Tcl lists.  Tcl_SplitList parses a
       list  into  an  argv  and  argc  like  to  the  way command-line arguments are passed to a Tcl extension.
       Tcl_Merge, likewise, creates a single string (pointer to a char *) from an argv and argc.

       Two routines, Tcl_ScanElement and Tcl_ConvertElement, do most of the work of Tcl_Merge, and may  also  be
       of use to the C programmer.

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

CONCATENATING STRINGS

       Tcl_Concat concatenates zero or more strings into a single  string.   The  strings  are  space-separated.
       Tcl_Concat  works  like  Tcl_Merge,  except that Tcl_Concat does not attempt to make the resulting string
       into a valid Tcl list.

       Tcl_Concat is documented in the Concat(3) manpage in the Berkeley 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.)  Tcl_CommandComplete can be used to tell whether  or  not
       you have a complete command.

       For more information examine CmdCmplt(3) in the Berkeley Tcl distribution.

RECORDING COMMANDS FOR COMMAND HISTORY

       Tcl has a history mechanism that is accessed from Tcl through the history command.  To propagate commands
       into the command history, your extension should call Tcl_RecordAndEval.  This  command  works  just  like
       Tcl_Eval, except that it records the command as well as executing it.

       Tcl_RecordAndEval 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 this function, please examine the RecordEval.3 manual page  in  the  Berkeley
       Tcl distribution.

CONVERTING FLOATING POINT VALUES TO STRINGS

       Tcl_PrintDouble  converts  a  C  double  into  an  ASCII  string.  It ensures that the string output will
       continue to be interpreted 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 Tcl_PrintDouble, examine PrintDbl(3) in the Berkeley Tcl distribution.

CREATING CHILD PROCESSES AND PIPELINES FROM C

       Tcl_CreatePipeline is a useful procedure for  spawning  child  processes.   The  child  (or  pipeline  of
       children)  can  have  its standard input, output and error redirected 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_CreatePipeline, please examine CrtPipelin(3).

ACCESSING TCL FILEHANDLES FROM C

       Files  opened from your C code can be made visible to Tcl code via the Tcl_EnterFile function.  Likewise,
       Tcl filehandles passed to your C extension can be translated to  a  Posix  FILE  *  structure  using  the
       Tcl_GetOpenFile function.

       For  complete  explanations  of  these  commands,  please  look  at  EnterFile(3)  in  the  Berkeley  Tcl
       distribution.

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 waitpid,  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.

       Tcl_ReapDetachedProcs  is  the C routine that will detect the termination of any processes turned over to
       Tcl, permitting the processes to be fully reclaimed by the operating system.

       For  complete  information  on  these  routines,  please  look  at  DetachPids(3)  in  the  Berkeley  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.  The comp.lang.tcl  Usenet  newsgroup  is  read  by  tens  of
       thousands of Tcl people, and is a good place to ask questions.  Finally, if you have interactive Internet
       access, you can ftp to ftp.aud.alcatel.com, the site for contributed Tcl  sources.   This  site  contains
       quite a few extensions, applications, and so forth, including several object-oriented extension packages.

AUTHORS

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