Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Command	Writing(TCL)					  Command Writing(TCL)

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, win-
       dow 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  re-
       turned by Tcl_CreateInterp and is used extensively within Tcl, and will
       be  by  your C extensions.  The data structure pointed to by the	inter-
       preter 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  in-
       clude 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 argu-
       ments  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	point-
       ers  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 be-
       tween each one by looping through argv from one to the argument	count,
       argc, and a newline is output to	terminate the line -- an ``echo'' com-
       mand.

       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 over-
       written 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	SetRe-
       sult(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_Ap-
       pendResult  routine.   See  the	Tcl manual page, SetResult(3), for de-
       tails.  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  re-
       turned.	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, pass-
       ing  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	imple-
       ments  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	inter-
       preter.	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	avail-
       able with Tcl 7.0.  Dynamic strings, or	DStrings,  provide  a  way  to
       build up	arbitrarily long strings through a repeated process of append-
       ing  information	to them.  DStrings reduce the amount of	allocating and
       copying required	to add information to a	string.	  Further,  they  sim-
       plify  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 envi-
       ronment (where a	single program has created and is making use of	multi-
       ple Tcl interpreters) for the C routines	to maintain any	permanent data
       they  need  on a	per-interpreter	basis.	Otherwise there	would be reen-
       trancy 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	 argu-
       ment.

       Commands	that need to share this	data with one another can do so	by us-
       ing the same ClientData pointer when the	commands are added.

       It  is important	to note	that the Tcl extensions	in the tclX7.4/src di-
       rectory have had	all of their data set up in this way.	Since  release
       6.2,  Extended Tcl has supported	multiple interpreters within one invo-
       cation of Tcl.

THEORY OF HANDLES
       Sometimes you need to have a data element  that	isn't  readily	repre-
       sentable	 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.  Han-
       dles 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  rou-
       tines  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 allo-
       cated  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 indi-
       rectly) 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  ap-
       plication-specific  init	 function  which  you  create.	 This function
       should take the address of the interpreter it should install  its  com-
       mands 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  ap-
       plication 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 de-
       fined, 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  re-
       peatedly	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 re-
       sults 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 var-
       Name 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 in-
       formation, 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 di-
       rectly 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 Crt-
       MathFnc(3) manual page in the Berkeley Tcl distribution.

PERFORMING TILDE SUBSTITUTIONS ON FILENAMES
       The Tcl_TildeSubst function is available	to C extension writers to per-
       form 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 de-
       tecting infinite	recursions before other	limits	such  as  the  process
       memory  limit  or,  worse,  available swap space	on the system, are ex-
       ceeded.

       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) man-
       ual 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  exe-
       cuted,  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  oc-
       curred,	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 pro-
       gramming	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  se-
       quences,	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	 vari-
       ables,  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  ex-
       posing 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 in-
       formation 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  Crt-
       Trace(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  in-
       terp->result).

       For  complete information on evaluating Tcl expressions from C, you are
       invited to examine the ExprLong(3) manpage in the Berkeley Tcl distrib-
       ution.

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  distribu-
       tion.

RECORDING COMMANDS FOR COMMAND HISTORY
       Tcl  has	a history mechanism that is accessed from Tcl through the his-
       tory command.  To propagate commands into the command history, your ex-
       tension 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  eas-
       ily access, edit	and reissue previously issued commands.

       For  complete information on this function, please examine the RecordE-
       val.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_Cre-
       atePipeline, 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 ex-
       tension	can  be	 translated  to	 a  Posix  FILE	 * structure using the
       Tcl_GetOpenFile function.

       For complete explanations of these  commands,  please  look  at	Enter-
       File(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	mecha-
       nism, can turn over responsibility for detecting	the processes'	termi-
       nation and calling waitpid to obtain its	exit status by calling Tcl_De-
       tachPids.

       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  Detach-
       Pids(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  Ex-
       tended  Tcl.   The  comp.lang.tcl  Usenet  newsgroup is read by tens of
       thousands of Tcl	people,	and is a good place  to	 ask  questions.   Fi-
       nally,  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).

Tcl							  Command Writing(TCL)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=TclCommandWriting&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help