+---------- On Feb 15, Dossy said: > In 3.x, it seems the ClientData parameter is either 's' or 'g' to > indicate setter or getter. Evil hackery. :-)
Actually, in 3.x, the 's' has no meaning to the code. NsTclVSetCmd does not look at its ClientData (which is why it's named "dummy" in that function). NsTclVGetCmd, on the other hand, looks at its ClientData. If ClientData is 'g', the function implements nsv_get; if ClientData is 'e', the function implements nsv_exists. In 4.0, nsv_get and nsv_exists are implemented by separate C functions, so no argument is needed to determine which command was invoked. I speculate (having looked at the 4.0 source but not having run 4.0) that 4.0 gives each virtual server its own set of NSVs. So when a virtual server invokes an some NsTclNsv*ObjCmd function, the function needs access to the NSV data structures specific to that virtual server. The ClientData contains a pointer to an NsInterp, and the NsInterp's servPtr points to the invoking NsServer. The NsServer contains the virtual server's NSV data structures. So if you're invoking some NsTclNsv*ObjCmd directly, you should pass an NsInterp pointer as its ClientData. Note that those functions do not appear to be part of the AOLserver C API. If you had a Tcl_Interp that belongs to the appropriate virtual serve, you could legally fish out a pointer to an NsTclNsv*ObjCmd using Tcl_GetCommandInfo. You'd get both the pointer to the function (in infoPtr->objProc) and the appropriate ClientData to pass to it (in infoPtr->objClientData).
