Tcl_Eval(3tcl)

πŸ’– Tcl_Eval β€” the "pls just run this script bestie" page πŸ’–

okay so welcome to Tcl_Eval(3tcl), aka one of the Tcl Library Procedures, and honestly? it's giving the moment. we're talking all the ways to make Tcl actually execute your script: eight whole functions, no cap. grab a boba, this one's long but it's worth it πŸ§‹βœ¨


✨ NAME ✨

Tcl_EvalObjEx, Tcl_EvalFile, Tcl_EvalObjv, Tcl_Eval, Tcl_EvalEx, Tcl_GlobalEval, Tcl_GlobalEvalObj, Tcl_VarEval β€” every single one of these is here to execute Tcl scripts. that's the whole vibe. πŸ’…


πŸŽ€ 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 your script is gonna run. heads up: the interpreter's result gets overwritten with whatever result or error message comes out of the script. 🫢
  • Tcl_Obj *objPtr (in) β€” a Tcl value holding the script you wanna execute.
  • int flags (in) β€” an OR'ed combo of flag bits for extra options. currently the supported girls are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. πŸ‘‘
  • const char *fileName (in) β€” name of a file that has a Tcl script in it.
  • Tcl_Size objc (in) β€” how many values live in the array objv points at; also literally the number of words in the command. ✨
  • Tcl_Obj **objv (in) β€” points to an array of pointers to values; each value holds one single word of the command you're about to execute.
  • int numBytes (in) β€” number of bytes in script, not counting any null terminating character. 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 (a null-terminated TUTF-8 byte sequence).
  • const char *part (in) β€” a string that forms part of a Tcl script.

πŸ’œ DESCRIPTION πŸ’œ

N.B. go read the Tcl_UniChar documentation page for the tea on the TUTF-8 encoding and all the related terms we reference here. not optional bestie, it's the lore. πŸ“–

so the procedures described here get invoked to execute Tcl scripts in various forms. Tcl_EvalObjEx is the core one, the main character, and lots of the others are lowkey using it under the hood. it executes the commands in the script stored in objPtr until either an error happens or the end of the script is reached. and here's the slay: if this is the first time objPtr has been executed, its commands get compiled into bytecode instructions which are then executed. those bytecodes are saved in objPtr, so the compilation step can be skipped if the value gets evaluated again later. caching? we love to see it. πŸ”₯

the return value from Tcl_EvalObjEx (and from literally all the other procedures described here) is a Tcl completion code with one of the values TCL_OK, TCL_ERROR, TCL_RETURN, TCL_BREAK, or TCL_CONTINUE, or possibly some other integer value originating in an extension. also, a result value or error message is left in interp's result β€” you can grab it with Tcl_GetObjResult. πŸ’–

Tcl_EvalFile reads the file given by fileName and evaluates its contents as a Tcl script. it returns the same info as Tcl_EvalObjEx. if the file couldn't be read, a Tcl error gets returned to explain why it couldn't be read. the eofchar for files is β€œ\x1A” (^Z) for all platforms. if you need a β€œ^Z” in code for string comparison, you can use β€œ\x1A”, which the Tcl interpreter will safely substitute into β€œ^Z”. πŸŽ€

Tcl_EvalObjv executes a single preparsed command instead of a whole script. the objc and objv arguments contain the values of the words for the Tcl command, one word in each value in objv. Tcl_EvalObjv evaluates the command and returns a completion code and result just like Tcl_EvalObjEx. but 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. that's on you, bestie. πŸ™ˆ

Tcl_Eval is similar to Tcl_EvalObjEx except the script to execute comes in as a string instead of a value, and no compilation occurs. the string should be a proper TUTF-8 byte sequence as converted by Tcl_ExternalToUtfDString or Tcl_ExternalToUtf when it's known to possibly contain upper ASCII characters whose possible combinations might be a UTF-8 special code. the string gets parsed and executed directly (using Tcl_EvalObjv) instead of compiled-then-bytecode-executed. in situations where it's known that the script will never be executed again, Tcl_Eval may be faster than Tcl_EvalObjEx. and Tcl_Eval returns a completion code and result just like Tcl_EvalObjEx. ⭐

Tcl_EvalEx is an extended version of Tcl_Eval that takes the additional arguments numBytes and flags. extra options, extra power. ✨

Tcl_GlobalEval and Tcl_GlobalEvalObj are older procedures that are now deprecated β€” yes, they're the vintage ones in the back of the closet. they're similar to Tcl_EvalEx and Tcl_EvalObjEx except the script is evaluated in the global namespace and its variable context consists of global variables only (it ignores any Tcl procedures that are active). these functions are equivalent to using the TCL_EVAL_GLOBAL flag (see below). πŸ’€

Tcl_VarEval takes any number of string arguments of any length, concatenates them 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 arguments β€” do not forget it, fr fr. 🌈


🌟 FLAG BITS 🌟

any OR'ed combination of these values may be used for the flags argument to procedures like Tcl_EvalObjEx:

  • TCL_EVAL_DIRECT β€” this flag is only used by Tcl_EvalObjEx; other procedures ignore it. if this bit is set, the script is not compiled to bytecodes; instead it's executed directly, the way Tcl_EvalEx does it. it's useful when the contents of a value are going to change immediately, so the bytecodes won't be reused in a future execution β€” in that case, executing the script directly is faster. πŸ’…
  • TCL_EVAL_GLOBAL β€” if this 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). periodt. πŸ‘‘

🌸 MISCELLANEOUS DETAILS 🌸

during the processing of a Tcl command it's legal to make nested calls to evaluate other commands β€” that's literally how procedures and some control structures are implemented. so if a code other than TCL_OK gets returned from a nested Tcl_EvalObjEx invocation, the caller should normally return immediately, passing that same return code back to its caller, and so on and so on until the top-level application is reached. a few commands, like for, will check for certain return codes β€” like TCL_BREAK and TCL_CONTINUE β€” and process them specially without returning. 🧚

Tcl_EvalObjEx keeps track of how many nested Tcl_EvalObjEx invocations are in progress for interp. 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 to TCL_ERROR and sets interp's result to an error message saying the return, break, or continue command was invoked in an inappropriate place. πŸ‘€ which means top-level applications should never see a return code from Tcl_EvalObjEx other than TCL_OK or TCL_ERROR. that's the rule!!


🫢 REFERENCE COUNT MANAGEMENT 🫢

Tcl_EvalObjEx and Tcl_GlobalEvalObj both increment and decrement the reference count of their objPtr argument β€” so you must not pass them any value with a reference count of zero. they also manipulate the interpreter result; you must not count on the interpreter result to hold the reference count of any value over 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; you must not count on the interpreter result to hold the reference count of any value over this call. βœ‹


πŸ‘‘ KEYWORDS πŸ‘‘

execute, file, global, result, script, value


and that's the page, bestie!! ✨ this was Tcl 8.1, dated back in the day, and it's the Tcl_Eval(3tcl) page from the Tcl Library Procedures β€” tysm for reading, you ate that, mwah πŸ’–πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from
  • ubuntu stonking: tcl9.0-doc 9.0.4+dfsg-1
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms