os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclTestProcBodyObj.c
Update contrib.
2 * tclTestProcBodyObj.c --
4 * Implements the "procbodytest" package, which contains commands
5 * to test creation of Tcl procedures whose body argument is a
6 * Tcl_Obj of type "procbody" rather than a string.
8 * Copyright (c) 1998 by Scriptics Corporation.
10 * See the file "license.terms" for information on usage and redistribution
11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 * RCS: @(#) $Id: tclTestProcBodyObj.c,v 1.2 1998/11/10 06:54:44 jingham Exp $
19 * name and version of this package
22 static char packageName[] = "procbodytest";
23 static char packageVersion[] = "1.0";
26 * Name of the commands exported by this package
29 static char procCommand[] = "proc";
32 * this struct describes an entry in the table of command names and command
36 typedef struct CmdTable
38 char *cmdName; /* command name */
39 Tcl_ObjCmdProc *proc; /* command proc */
40 int exportIt; /* if 1, export the command */
44 * Declarations for functions defined in this file.
47 static int ProcBodyTestProcObjCmd _ANSI_ARGS_((ClientData dummy,
48 Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
49 static int ProcBodyTestInitInternal _ANSI_ARGS_((Tcl_Interp *interp,
51 static int RegisterCommand _ANSI_ARGS_((Tcl_Interp* interp,
52 char *namespace, CONST CmdTable *cmdTablePtr));
53 int Procbodytest_Init _ANSI_ARGS_((Tcl_Interp * interp));
54 int Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp * interp));
57 * List of commands to create when the package is loaded; must go after the
58 * declarations of the enable command procedure.
61 static CONST CmdTable commands[] =
63 { procCommand, ProcBodyTestProcObjCmd, 1 },
68 static CONST CmdTable safeCommands[] =
70 { procCommand, ProcBodyTestProcObjCmd, 1 },
76 *----------------------------------------------------------------------
78 * Procbodytest_Init --
80 * This procedure initializes the "procbodytest" package.
83 * A standard Tcl result.
88 *----------------------------------------------------------------------
92 Procbodytest_Init(interp)
93 Tcl_Interp *interp; /* the Tcl interpreter for which the package
96 return ProcBodyTestInitInternal(interp, 0);
100 *----------------------------------------------------------------------
102 * Procbodytest_SafeInit --
104 * This procedure initializes the "procbodytest" package.
107 * A standard Tcl result.
112 *----------------------------------------------------------------------
116 Procbodytest_SafeInit(interp)
117 Tcl_Interp *interp; /* the Tcl interpreter for which the package
120 return ProcBodyTestInitInternal(interp, 1);
124 *----------------------------------------------------------------------
128 * This procedure registers a command in the context of the given namespace.
131 * A standard Tcl result.
136 *----------------------------------------------------------------------
139 static int RegisterCommand(interp, namespace, cmdTablePtr)
140 Tcl_Interp* interp; /* the Tcl interpreter for which the
141 * operation is performed */
142 char *namespace; /* the namespace in which the command
144 CONST CmdTable *cmdTablePtr; /* the command to register */
148 if (cmdTablePtr->exportIt) {
149 sprintf(buf, "namespace eval %s { namespace export %s }",
150 namespace, cmdTablePtr->cmdName);
151 if (Tcl_Eval(interp, buf) != TCL_OK)
155 sprintf(buf, "%s::%s", namespace, cmdTablePtr->cmdName);
156 Tcl_CreateObjCommand(interp, buf, cmdTablePtr->proc, 0, 0);
162 *----------------------------------------------------------------------
164 * ProcBodyTestInitInternal --
166 * This procedure initializes the Loader package.
167 * The isSafe flag is 1 if the interpreter is safe, 0 otherwise.
170 * A standard Tcl result.
175 *----------------------------------------------------------------------
179 ProcBodyTestInitInternal(interp, isSafe)
180 Tcl_Interp *interp; /* the Tcl interpreter for which the package
182 int isSafe; /* 1 if this is a safe interpreter */
184 CONST CmdTable *cmdTablePtr;
186 cmdTablePtr = (isSafe) ? &safeCommands[0] : &commands[0];
187 for ( ; cmdTablePtr->cmdName ; cmdTablePtr++) {
188 if (RegisterCommand(interp, packageName, cmdTablePtr) != TCL_OK) {
193 return Tcl_PkgProvide(interp, packageName, packageVersion);
197 *----------------------------------------------------------------------
199 * ProcBodyTestProcObjCmd --
201 * Implements the "procbodytest::proc" command. Here is the command
203 * procbodytest::proc newName argList bodyName
204 * Looks up a procedure called $bodyName and, if the procedure exists,
205 * constructs a Tcl_Obj of type "procbody" and calls Tcl_ProcObjCmd.
207 * newName the name of the procedure to be created
208 * argList the argument list for the procedure
209 * bodyName the name of an existing procedure from which the
210 * body is to be copied.
211 * This command can be used to trigger the branches in Tcl_ProcObjCmd that
212 * construct a proc from a "procbody", for example:
213 * proc a {x} {return $x}
215 * procbodytest::proc b {x} a
216 * Note the call to "a 123", which is necessary so that the Proc pointer
217 * for "a" is filled in by the internal compiler; this is a hack.
220 * Returns a standard Tcl code.
223 * A new procedure is created.
224 * Leaves an error message in the interp's result on error.
226 *----------------------------------------------------------------------
230 ProcBodyTestProcObjCmd (dummy, interp, objc, objv)
231 ClientData dummy; /* context; not used */
232 Tcl_Interp *interp; /* the current interpreter */
233 int objc; /* argument count */
234 Tcl_Obj *CONST objv[]; /* arguments */
239 Proc *procPtr = (Proc *) NULL;
245 Tcl_WrongNumArgs(interp, 1, objv, "newName argsList bodyName");
250 * Find the Command pointer to this procedure
253 fullName = Tcl_GetStringFromObj(objv[3], (int *) NULL);
254 procCmd = Tcl_FindCommand(interp, fullName, (Tcl_Namespace *) NULL,
256 if (procCmd == NULL) {
260 cmdPtr = (Command *) procCmd;
263 * check that this is a procedure and not a builtin command:
264 * If a procedure, cmdPtr->objProc is either 0 or TclObjInterpProc,
265 * and cmdPtr->proc is either 0 or TclProcInterpProc.
266 * Also, the compile proc should be 0, but we don't check for that.
269 if (((cmdPtr->objProc != NULL)
270 && (cmdPtr->objProc != TclGetObjInterpProc()))
271 || ((cmdPtr->proc != NULL)
272 && (cmdPtr->proc != TclGetInterpProc()))) {
273 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
274 "command \"", fullName,
275 "\" is not a Tcl procedure", (char *) NULL);
280 * it is a Tcl procedure: the client data is the Proc structure
283 if (cmdPtr->objProc != NULL) {
284 procPtr = (Proc *) cmdPtr->objClientData;
285 } else if (cmdPtr->proc != NULL) {
286 procPtr = (Proc *) cmdPtr->clientData;
289 if (procPtr == NULL) {
290 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
291 "procedure \"", fullName,
292 "\" does not have a Proc struct!", (char *) NULL);
297 * create a new object, initialize our argument vector, call into Tcl
300 bodyObjPtr = TclNewProcBodyObj(procPtr);
301 if (bodyObjPtr == NULL) {
302 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
303 "failed to create a procbody object for procedure \"",
304 fullName, "\"", (char *) NULL);
307 Tcl_IncrRefCount(bodyObjPtr);
312 myobjv[3] = bodyObjPtr;
313 myobjv[4] = (Tcl_Obj *) NULL;
315 result = Tcl_ProcObjCmd((ClientData) NULL, interp, objc, myobjv);
316 Tcl_DecrRefCount(bodyObjPtr);