Tcl_TraceCommand(3tcl)

πŸ“¦
version 9.0.4 Β· 2 versions
, in debian trixie, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– Tcl_TraceCommand β€” bestie edition πŸ’–

okay so this is a page from the 3tcl manual, and it's all about Tcl_CommandTraceInfo, Tcl_TraceCommand and Tcl_UntraceCommand β€” the three functions that let your C code keep an eye on when a Tcl command gets renamed or yeeted into the void. monitoring renames and deletes, that's the whole vibe πŸ¦‹


✨ NAME ✨

Tcl_CommandTraceInfo, Tcl_TraceCommand, Tcl_UntraceCommand β€” monitor renames and deletes of a command πŸ‘€


πŸŽ€ SYNOPSIS πŸŽ€

#include <tcl.h>

void *
Tcl_CommandTraceInfo(interp, cmdName, flags, proc, prevClientData)

int
Tcl_TraceCommand(interp, cmdName, flags, proc, clientData)

Tcl_UntraceCommand(interp, cmdName, flags, proc, clientData)

🌸 ARGUMENTS 🌸

  • Tcl_Interp *interp (in) β€” the interpreter that's holding the command, periodt.
  • const char *cmdName (in) β€” the name of the command. literally just the name.
  • int flags (in) β€” an OR'ed-together collection of the values TCL_TRACE_RENAME and TCL_TRACE_DELETE.
  • Tcl_CommandTraceProc *proc (in) β€” the procedure that gets called when the specified operations happen to cmdName.
  • void *clientData (in) β€” arbitrary argument, gets passed straight through to proc.
  • void *prevClientData (in) β€” if it's non-NULL, it's the last value that Tcl_CommandTraceInfo returned, so this call gives you info about the next trace. if it's NULL, you get info about the first trace. ✨

πŸ’… DESCRIPTION πŸ’…

Tcl_TraceCommand lets a C procedure monitor what happens to a Tcl command, so your C code gets invoked whenever that command is renamed or deleted. if the trace gets created successfully, Tcl_TraceCommand returns TCL_OK. if something went wrong (say, cmdName points at a command that doesn't even exist, embarrassing for it) then TCL_ERROR comes back and an error message gets dropped into the interpreter's result. πŸ’€

the flags argument to Tcl_TraceCommand is what tells it when to call your trace procedure. it's an OR'ed combination of any of these values:

  • TCL_TRACE_RENAME β€” invoke proc whenever the command is renamed.
  • TCL_TRACE_DELETE β€” invoke proc when the command is deleted.

whenever one of the specified operations happens to the command, proc gets invoked. it should have arguments and a result matching the type Tcl_CommandTraceProc:

typedef void Tcl_CommandTraceProc(
        void *clientData,
        Tcl_Interp *interp,
        const char *oldName,
        const char *newName,
        int flags);

the clientData and interp parameters will have the same values as the ones you passed to Tcl_TraceCommand when you made the trace. clientData usually points at an application-specific data structure that describes what to do when proc fires. OldName is the name of the command being renamed, and newName is the name it's being renamed to (or NULL when the command is being deleted). Flags is an OR'ed combination of bits that can carry several pieces of info at once: one of the bits TCL_TRACE_RENAME and TCL_TRACE_DELETE will be set in flags to show which operation is happening to the command. the bit TCL_TRACE_DESTROYED gets set in flags if the trace is about to be destroyed β€” that's useful to proc so it can clean up its own internal data structures (peep the TCL_TRACE_DESTROYED section below for more). and because deleting commands can happen as part of deleting the interp that contains them, proc has to be careful about what the passed-in interp value can be asked to do. the routine Tcl_InterpDeleted is a big deal for this. when Tcl_InterpDeleted returns 1, proc won't be able to invoke any scripts in interp. in that situation, proc's whole job is limited to cleaning up its own data structures. no cap. πŸ™ˆ

Tcl_UntraceCommand is how you remove a trace. if the command specified by interp, cmdName and flags has a trace set with flags, proc and clientData, then that matching trace gets removed. if no such trace exists, the call to Tcl_UntraceCommand just does nothing at all, no drama. the same bits are valid for flags as for calls to Tcl_TraceCommand.

Tcl_CommandTraceInfo is how you retrieve info about traces set on a given command. the return value from Tcl_CommandTraceInfo is the clientData associated with a particular trace. the trace has to be on the command specified by the interp, cmdName and flags arguments (heads up: currently the flags are ignored; set flags to 0 for future compatibility 🫢) and its trace procedure has to be the same as the proc argument. if prevClientData is NULL, the return value corresponds to the first (most recently created) matching trace, or NULL if there are no matching traces. if prevClientData isn't NULL, then it should be the return value from a previous call to Tcl_CommandTraceInfo. in that case the new return value corresponds to the next matching trace after the one whose clientData matches prevClientData, or NULL if no trace matches prevClientData or if there are no more matching traces after it. this mechanism is what makes it possible to step through all the traces for a given command that share the same proc. iconic honestly. πŸ‘‘


🌈 CALLING COMMANDS DURING TRACES 🌈

during rename traces, the command being renamed is visible under both names at the same time, and the command still exists during delete traces β€” unless the interp that contains it is being deleted. however, there is no mechanism for signaling that an error occurred inside a trace procedure, so take great care that errors don't get silently lost. 😭


πŸ”₯ MULTIPLE TRACES πŸ”₯

it's totally possible for multiple traces to exist on the same command. when that happens, all of the trace procedures get invoked on each access, in order from most-recently-created to least-recently-created. attempts to delete the command during a delete trace will fail silently, since the command is already scheduled for deletion anyway. if the command being renamed gets renamed by one of its rename traces, that renaming takes precedence over the one that triggered the trace, and the collection of traces will not be reexecuted; if several traces rename the command, the last renaming takes precedence. πŸ’«


πŸ’œ TCL_TRACE_DESTROYED FLAG πŸ’œ

in a delete callback to proc, the TCL_TRACE_DESTROYED bit is set in flags.


⭐ KEYWORDS ⭐

clientData, trace, command


and that's the whole page bestie πŸ₯° this one comes to you from the Tcl 7.4 era, filed under section 3tcl β€” go forth and trace responsibly πŸ’–βœ¨πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from