Tcl_Eval(3)
π Tcl_Eval(3) β aka the "go run this script bestie" page π
okay so welcome to the Tcl_Eval(3) page of the Tcl Library Procedures, and no cap this one is lowkey the main character of the whole C API. grab a strawberry π, we're executing Tcl scripts from C and it's gonna be iconic.
β¨ NAME β¨
Tcl_EvalObjEx, Tcl_EvalFile, Tcl_EvalObjv, Tcl_Eval, Tcl_EvalEx, Tcl_GlobalEval, Tcl_GlobalEvalObj, Tcl_VarEval β literally just: execute Tcl scripts. that's the whole job description. slay. π
πΈ SYNOPSIS πΈ
#include <tcl.h>
int
Tcl_EvalObjEx(interp, objPtr, flags)
int
Tcl_EvalFile(interp, fileName)
int
Tcl_EvalObjv(interp, objc, objv, flags)
int
Tcl_Eval(interp, script)
int
Tcl_EvalEx(interp, script, numBytes, flags)
int
Tcl_GlobalEval(interp, script)
int
Tcl_GlobalEvalObj(interp, objPtr)
int
Tcl_VarEval(interp, part, part, ... (char *)NULL)
π ARGUMENTS π
Tcl_Interp *interp(in) β the interpreter where we're executing the script. its result gets overwritten to hold either the result or the error message from the script. so yeah, whatever was chilling in there before? gone. πTcl_Obj *objPtr(in) β a Tcl value that is the script we're about to execute.int flags(in) β an OR'ed combo of flag bits for extra options. right now the supported ones areTCL_EVAL_GLOBALandTCL_EVAL_DIRECT.const char *fileName(in) β name of a file that contains a Tcl script.Tcl_Size objc(in) β how many values live in the arrayobjvpoints to. also = the number of words in the command. two truths, one number.Tcl_Obj **objv(in) β points to an array of pointers to values; each value holds one single word of the command we're executing.int numBytes(in) β how many bytes are inscript, not counting any null terminator. if it's-1, then everything up to the first null byte gets used.const char *script(in) β points to the first byte of the script to execute. it's null-terminated and it's UTF-8.const char *part(in) β a string that forms part of a Tcl script.
π¦ DESCRIPTION π¦
these procedures are how you execute Tcl scripts in literally every form you could want. Tcl_EvalObjEx is the core one, and a whole bunch of the others are just it in a little outfit.
Tcl_EvalObjEx executes the commands in the script stored in objPtr, and it keeps going until either an error happens or it reaches the end of the script. here's the cute part: if this is the first time objPtr has ever been executed, its commands get compiled into bytecode instructions, and then those get executed. the bytecodes get saved inside objPtr so that if that value ever gets evaluated again later, we can just skip the whole compilation step. caching queen. β¨
the return value from Tcl_EvalObjEx (and from every other procedure on this page) is a Tcl completion code, and it's one of TCL_OK, TCL_ERROR, TCL_RETURN, TCL_BREAK, or TCL_CONTINUE β or possibly some other integer value that originated in an extension. plus, a result value or an error message is left in interp's result, and you can grab it with Tcl_GetObjResult.
Tcl_EvalFile reads the file named by fileName and evaluates its contents as a Tcl script. it hands you back the same info as Tcl_EvalObjEx. if the file couldn't be read, you get a Tcl error back describing why it couldn't be read. heads up: the eofchar for files is "\x1A" (^Z) on all platforms. so if you need a "^Z" in code for string comparison, you can use "\x1A" and the Tcl interpreter will safely substitute it into "^Z". π«Ά
Tcl_EvalObjv executes a single preparsed command instead of a whole script. the objc and objv arguments hold the values of the words for the Tcl command β one word per value in objv. it evaluates the command and returns a completion code and result exactly like Tcl_EvalObjEx. β οΈ but bestie, listen: the caller of Tcl_EvalObjv has to manage the reference count of the elements of objv, making sure the values stay valid until Tcl_EvalObjv returns. no letting them evaporate mid-call.
Tcl_Eval is like Tcl_EvalObjEx, except the script comes in as a string instead of a value, and no compilation happens at all. the string should be a proper UTF-8 string as converted by Tcl_ExternalToUtfDString or Tcl_ExternalToUtf when it's known that it might possibly contain upper ASCII characters whose possible combinations might form a UTF-8 special code. the string gets parsed and executed directly (using Tcl_EvalObjv) instead of being compiled and run as bytecodes. and here's a lil tip that's actually in the docs: if you know the script is never gonna be executed again, Tcl_Eval may be faster than Tcl_EvalObjEx. one-shot energy. π« Tcl_Eval returns a completion code and result just like Tcl_EvalObjEx.
Tcl_EvalEx is the extended version of Tcl_Eval that takes the extra numBytes and flags arguments.
Tcl_GlobalEval and Tcl_GlobalEvalObj are the older procedures and they are now deprecated. π¨ they're similar to Tcl_EvalEx and Tcl_EvalObjEx, except the script gets evaluated in the global namespace and its variable context consists of global variables only (it ignores any Tcl procedures that are active). these two are equivalent to using the TCL_EVAL_GLOBAL flag (see below).
Tcl_VarEval takes any number of string arguments of any length, concatenates them all into one single string, then calls Tcl_Eval to execute that string as a Tcl command. it returns the result of the command and also modifies the interpreter result the same way Tcl_Eval does. and the last argument to Tcl_VarEval must be (char *)NULL to mark the end of the arguments. don't forget it, fr fr.
π FLAG BITS π
any OR'ed combination of these values can go in the flags argument of procedures like Tcl_EvalObjEx:
TCL_EVAL_DIRECTβ this flag is only used byTcl_EvalObjEx; every other procedure ignores it. if this bit is set, the script doesn't get compiled into bytecodes at all β instead it's executed directly, the same wayTcl_EvalExdoes it. this flag is useful when the contents of a value are going to change immediately, meaning the bytecodes would never get reused in a future execution anyway. in that case, executing the script directly is faster. efficient queen. πTCL_EVAL_GLOBALβ if this flag is set, the script is evaluated in the global namespace instead of the current namespace, and its variable context consists of global variables only (it ignores any Tcl procedures that are active).
β MISCELLANEOUS DETAILS β
while a Tcl command is being processed, it's totally legal to make nested calls that evaluate other commands β that's literally how procedures and some control structures get implemented. πͺ so if a code other than TCL_OK comes back from a nested Tcl_EvalObjEx invocation, the caller should normally return immediately, passing that same return code back up to its caller, and so on and so on until we hit the top-level application. a few commands, like for, will check for certain return codes, like TCL_BREAK and TCL_CONTINUE, and process them specially without returning. special treatment, deserved.
Tcl_EvalObjEx keeps track of how many nested Tcl_EvalObjEx invocations are in progress for interp. and if a code of TCL_RETURN, TCL_BREAK, or TCL_CONTINUE is about to be returned from the topmost Tcl_EvalObjEx invocation for interp, it converts that return code into TCL_ERROR and sets interp's result to an error message saying the return, break, or continue command was invoked in an inappropriate place. π so basically: top-level applications should never see a return code from Tcl_EvalObjEx other than TCL_OK or TCL_ERROR. periodt.
π REFERENCE COUNT MANAGEMENT π
Tcl_EvalObjEx and Tcl_GlobalEvalObj both increment and decrement the reference count of their objPtr argument β which means you must not pass them any value with a reference count of zero. π« they also manipulate the interpreter result, so you must not count on the interpreter result to hold the reference count of any value across these calls.
Tcl_EvalObjv may increment and decrement the reference count of any value passed via its objv argument β so again, you must not pass any value with a reference count of zero. this function also manipulates the interpreter result, so don't count on the interpreter result to hold the reference count of any value over this call either. π«
π₯ KEYWORDS π₯
execute, file, global, result, script, value
okay that's the whole page, you're officially educated bestie πβ¨ this was the Tcl_Eval(3) page from Tcl Library Procedures, version 8.1 β go forth and evaluate responsibly, mwah ππ¦πΈ
π¦ where this page comes from
- alpine 3.23: tcl9-doc 9.0.3-r0 Β· TCL
- alpine 3.24: tcl9-doc 9.0.3-r2 Β· TCL
- fedora 43: tcl-doc 1:9.0.2-1.fc43 Β· TCL AND GPL-3.0-or-later WITH Bison-exception-2.2 AND BSD-3-Clause
- fedora 44: tcl-doc 1:9.0.2-1.fc44 Β· TCL AND GPL-3.0-or-later WITH Bison-exception-2.2 AND BSD-3-Clause
- nixos 26.05: tcl 9.0.3
- Copyright (c) 1989-1993 The Regents of the University of California
- Copyright (c) 1994-1997 Sun Microsystems, Inc
- Copyright (c) 2000 Scriptics Corporation
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms