Tcl_SetChannelError(3tcl)

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

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

ok so like. this is a page from the Tcl Library Procedures manual, and it's all about Tcl_SetChannelError, Tcl_SetChannelErrorInterp, Tcl_GetChannelError and Tcl_GetChannelErrorInterp β€” the little squad of functions that let channel drivers create and intercept Tcl errors. it's giving ✨backstage pass✨ energy, iykyk.


🌸 NAME 🌸

Tcl_SetChannelError, Tcl_SetChannelErrorInterp, Tcl_GetChannelError, Tcl_GetChannelErrorInterp β€” functions to create/intercept Tcl errors by channel drivers.

like. that's the whole vibe. four functions, one mission: getting your custom error messages out of a channel driver and into the world πŸ¦‹


✨ SYNOPSIS ✨

#include <tcl.h>

Tcl_SetChannelError(chan, msg)

Tcl_SetChannelErrorInterp(interp, msg)

Tcl_GetChannelError(chan, msgPtr)

Tcl_GetChannelErrorInterp(interp, msgPtr)

no cap, that's it. that's the whole handshake 🀝


πŸŽ€ ARGUMENTS πŸŽ€

  • Tcl_Channel chan (in) β€” this is the Tcl channel whose bypass area we're poking at. yes, "bypass area" is the real name, it's iconic, we love her πŸ’…
  • Tcl_Interp* interp (in) β€” the Tcl interpreter whose bypass area we're accessing. same deal, different host πŸ’œ
  • Tcl_Obj* msg (in) β€” the error message that gets put into a bypass area. it's a list of return options and values, followed by a string message. and listen: both the message AND the option/value info are optional. but it must be a well-formed list. no malformed lists in this house πŸ™ˆ
  • Tcl_Obj** msgPtr (out) β€” a reference to a place where the message stored in the accessed bypass area can be stored in. yes bestie, it's a pointer to a pointer, we're doing that today 😭

🌈 DESCRIPTION 🌈

ok so here's the lore. the standard definition of a Tcl channel driver does not permit the direct return of arbitrary error messages, except for the setting and retrieval of channel options. every other function is restricted to POSIX error codes. kinda cringe, ngl πŸ˜”

the functions described here overcome this limitation. channel drivers are allowed to use Tcl_SetChannelError and Tcl_SetChannelErrorInterp to place arbitrary error messages in bypass areas defined for channels and interpreters. and the generic I/O layer uses Tcl_GetChannelError and Tcl_GetChannelErrorInterp to look for messages in the bypass areas and arrange for their return as errors. and here's the key part, bestie β€” the POSIX error codes set by a driver are used now if and only if no messages are present. if and only if. periodt. πŸ”₯

Tcl_SetChannelError stores error information in the bypass area of the specified channel. the number of references to the msg value goes up by one. previously stored information will be discarded, by releasing the reference held by the channel. and the channel reference must not be NULL. like, don't even try it πŸ™…β™€οΈ

Tcl_SetChannelErrorInterp stores error information in the bypass area of the specified interpreter. the number of references to the msg value goes up by one. previously stored information will be discarded, by releasing the reference held by the interpreter. and the interpreter reference must not be NULL. same rules, different area πŸ’«

Tcl_GetChannelError places either the error message held in the bypass area of the specified channel into msgPtr, or NULL; and resets the bypass. that means: after an invocation, all following invocations will return NULL, until an intervening invocation of Tcl_SetChannelError with a non-NULL message. the msgPtr must not be NULL. the reference count of the message is not touched. the reference previously held by the channel is now held by the caller of the function, and it is the caller's responsibility to release that reference when it is done with the value. so like, you own it now. don't forget about it 🫢

Tcl_GetChannelErrorInterp places either the error message held in the bypass area of the specified interpreter into msgPtr, or NULL; and resets the bypass. so again β€” after an invocation, all following invocations will return NULL, until an intervening invocation of Tcl_SetChannelErrorInterp with a non-NULL message. the msgPtr must not be NULL. the reference count of the message is not touched. the reference previously held by the interpreter is now held by the caller of the function, and it is the caller's responsibility to release that reference when it is done with the value. yes you, bestie. it's yours now πŸ‘‘


πŸ’… which driver functions get to use which bypass function πŸ’…

which functions of a channel driver are allowed to use which bypass function is listed below, as is which functions of the public channel API may leave a message in the bypass areas.

  • Tcl_DriverInputProc β€” may use Tcl_SetChannelError, and only this function.
  • Tcl_DriverOutputProc β€” may use Tcl_SetChannelError, and only this function.
  • Tcl_DriverWideSeekProc β€” may use Tcl_SetChannelError, and only this function.
  • Tcl_DriverSetOptionProc β€” has already the ability to pass arbitrary error messages. must not use any of the new functions.
  • Tcl_DriverGetOptionProc β€” has already the ability to pass arbitrary error messages. must not use any of the new functions.
  • Tcl_DriverWatchProc β€” must not use any of the new functions. it is internally called and has no ability to return any type of error whatsoever. so like, no.
  • Tcl_DriverBlockModeProc β€” may use Tcl_SetChannelError, and only this function.
  • Tcl_DriverGetHandleProc β€” must not use any of the new functions. it is only a low-level function, and not used by Tcl commands.
  • Tcl_DriverHandlerProc β€” must not use any of the new functions. it is internally called and has no ability to return any type of error whatsoever. same energy as Tcl_DriverWatchProc, honestly πŸ’€

πŸ¦‹ the public functions that are now lowkey different πŸ¦‹

given the information above, the following public functions of the Tcl C API are affected by these changes; when these functions are called, the channel may now contain a stored arbitrary error message requiring processing by the caller.

Tcl_Flush          Tcl_GetsObj          Tcl_Gets
Tcl_ReadChars      Tcl_ReadRaw          Tcl_Read
Tcl_Seek           Tcl_StackChannel     Tcl_Tell
Tcl_WriteChars     Tcl_WriteObj         Tcl_WriteRaw
Tcl_Write

all other API functions are unchanged. in particular, the functions below leave all their error information in the interpreter result. they're the chill ones 😌

Tcl_Close          Tcl_UnstackChannel   Tcl_UnregisterChannel

🧚 REFERENCE COUNT MANAGEMENT 🧚

the msg argument to Tcl_SetChannelError and Tcl_SetChannelErrorInterp, if not NULL, may have any reference count; these functions will copy. so don't stress about it 🌸

Tcl_GetChannelError and Tcl_GetChannelErrorInterp write a value reference into their msgPtr, but do not manipulate its reference count. the reference count will be at least 1 (unless the reference is NULL). at least one, bestie. at minimum. πŸ’–


πŸ‘‘ SEE ALSO πŸ‘‘

go read those too, they're part of the same friend group πŸ«‚


⭐ KEYWORDS ⭐

channel driver, error messages, channel type


and that's the whole page, bestie πŸ’… this was Tcl 8.5, from the Tcl_SetChannelError(3tcl) manual page in the Tcl Library Procedures section β€” mwah, go slay some channel drivers βœ¨πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from