📄 tcltest.c
字号:
Tcl_AsyncDelete(asyncPtr->handler); ckfree(asyncPtr->command); ckfree((char *) asyncPtr); break; } } else if (strcmp(argv[1], "mark") == 0) { if (argc != 5) { goto wrongNumArgs; } if ((Tcl_GetInt(interp, argv[2], &id) != TCL_OK) || (Tcl_GetInt(interp, argv[4], &code) != TCL_OK)) { return TCL_ERROR; } for (asyncPtr = firstHandler; asyncPtr != NULL; asyncPtr = asyncPtr->nextPtr) { if (asyncPtr->id == id) { Tcl_AsyncMark(asyncPtr->handler); break; } } Tcl_SetResult(interp, argv[3], TCL_VOLATILE); return code; } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be create, delete, int, or mark", (char *) NULL); return TCL_ERROR; } return TCL_OK;}static intAsyncHandlerProc(clientData, interp, code) ClientData clientData; /* Pointer to TestAsyncHandler structure. */ Tcl_Interp *interp; /* Interpreter in which command was * executed, or NULL. */ int code; /* Current return code from command. */{ TestAsyncHandler *asyncPtr = (TestAsyncHandler *) clientData; char *listArgv[4]; char string[20], *cmd; sprintf(string, "%d", code); listArgv[0] = asyncPtr->command; listArgv[1] = interp->result; listArgv[2] = string; listArgv[3] = NULL; cmd = Tcl_Merge(3, listArgv); code = Tcl_Eval(interp, cmd); ckfree(cmd); return code;}/* *---------------------------------------------------------------------- * * TestcmdinfoCmd -- * * This procedure implements the "testcmdinfo" command. It is used * to test Tcl_GetCommandInfo, Tcl_SetCommandInfo, and command creation * and deletion. * * Results: * A standard Tcl result. * * Side effects: * Creates and deletes various commands and modifies their data. * *---------------------------------------------------------------------- */ /* ARGSUSED */static intTestcmdinfoCmd(dummy, interp, argc, argv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tcl_CmdInfo info; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option cmdName\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[1], "create") == 0) { Tcl_CreateCommand(interp, argv[2], CmdProc1, (ClientData) "original", CmdDelProc1); } else if (strcmp(argv[1], "delete") == 0) { Tcl_DStringInit(&delString); Tcl_DeleteCommand(interp, argv[2]); Tcl_DStringResult(interp, &delString); } else if (strcmp(argv[1], "get") == 0) { if (Tcl_GetCommandInfo(interp, argv[2], &info) ==0) { Tcl_SetResult(interp, "??", TCL_STATIC); return TCL_OK; } if (info.proc == CmdProc1) { Tcl_AppendResult(interp, "CmdProc1", " ", (char *) info.clientData, (char *) NULL); } else if (info.proc == CmdProc2) { Tcl_AppendResult(interp, "CmdProc2", " ", (char *) info.clientData, (char *) NULL); } else { Tcl_AppendResult(interp, "unknown", (char *) NULL); } if (info.deleteProc == CmdDelProc1) { Tcl_AppendResult(interp, " CmdDelProc1", " ", (char *) info.deleteData, (char *) NULL); } else if (info.deleteProc == CmdDelProc2) { Tcl_AppendResult(interp, " CmdDelProc2", " ", (char *) info.deleteData, (char *) NULL); } else { Tcl_AppendResult(interp, " unknown", (char *) NULL); } Tcl_AppendResult(interp, " ", info.namespacePtr->fullName, (char *) NULL); if (info.isNativeObjectProc) { Tcl_AppendResult(interp, " nativeObjectProc", (char *) NULL); } else { Tcl_AppendResult(interp, " stringProc", (char *) NULL); } } else if (strcmp(argv[1], "modify") == 0) { info.proc = CmdProc2; info.clientData = (ClientData) "new_command_data"; info.objProc = NULL; info.objClientData = (ClientData) NULL; info.deleteProc = CmdDelProc2; info.deleteData = (ClientData) "new_delete_data"; if (Tcl_SetCommandInfo(interp, argv[2], &info) == 0) { Tcl_SetResult(interp, "0", TCL_STATIC); } else { Tcl_SetResult(interp, "1", TCL_STATIC); } } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be create, delete, get, or modify", (char *) NULL); return TCL_ERROR; } return TCL_OK;} /*ARGSUSED*/static intCmdProc1(clientData, interp, argc, argv) ClientData clientData; /* String to return. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tcl_AppendResult(interp, "CmdProc1 ", (char *) clientData, (char *) NULL); return TCL_OK;} /*ARGSUSED*/static intCmdProc2(clientData, interp, argc, argv) ClientData clientData; /* String to return. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tcl_AppendResult(interp, "CmdProc2 ", (char *) clientData, (char *) NULL); return TCL_OK;}static voidCmdDelProc1(clientData) ClientData clientData; /* String to save. */{ Tcl_DStringInit(&delString); Tcl_DStringAppend(&delString, "CmdDelProc1 ", -1); Tcl_DStringAppend(&delString, (char *) clientData, -1);}static voidCmdDelProc2(clientData) ClientData clientData; /* String to save. */{ Tcl_DStringInit(&delString); Tcl_DStringAppend(&delString, "CmdDelProc2 ", -1); Tcl_DStringAppend(&delString, (char *) clientData, -1);}/* *---------------------------------------------------------------------- * * TestcmdtokenCmd -- * * This procedure implements the "testcmdtoken" command. It is used * to test Tcl_Command tokens and procedures such as * Tcl_GetCommandFullName. * * Results: * A standard Tcl result. * * Side effects: * Creates and deletes various commands and modifies their data. * *---------------------------------------------------------------------- */ /* ARGSUSED */static intTestcmdtokenCmd(dummy, interp, argc, argv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tcl_Command token; long int l; char buf[30]; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option arg\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[1], "create") == 0) { token = Tcl_CreateCommand(interp, argv[2], CmdProc1, (ClientData) "original", (Tcl_CmdDeleteProc *) NULL); sprintf(buf, "%lx", (long int) token); Tcl_SetResult(interp, buf, TCL_VOLATILE); } else if (strcmp(argv[1], "name") == 0) { Tcl_Obj *objPtr; if (sscanf(argv[2], "%lx", &l) != 1) { Tcl_AppendResult(interp, "bad command token \"", argv[2], "\"", (char *) NULL); return TCL_ERROR; } objPtr = Tcl_NewObj(); Tcl_GetCommandFullName(interp, (Tcl_Command) l, objPtr); Tcl_AppendElement(interp, Tcl_GetCommandName(interp, (Tcl_Command) l)); Tcl_AppendElement(interp, Tcl_GetStringFromObj(objPtr, (int *) NULL)); Tcl_DecrRefCount(objPtr); } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be create or name", (char *) NULL); return TCL_ERROR; } return TCL_OK;}/* *---------------------------------------------------------------------- * * TestcmdtraceCmd -- * * This procedure implements the "testcmdtrace" command. It is used * to test Tcl_CreateTrace and Tcl_DeleteTrace. * * Results: * A standard Tcl result. * * Side effects: * Creates and deletes a command trace, and tests the invocation of * a procedure by the command trace. * *---------------------------------------------------------------------- */ /* ARGSUSED */static intTestcmdtraceCmd(dummy, interp, argc, argv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tcl_DString buffer; int result; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option script\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[1], "tracetest") == 0) { Tcl_DStringInit(&buffer); cmdTrace = Tcl_CreateTrace(interp, 50000, (Tcl_CmdTraceProc *) CmdTraceProc, (ClientData) &buffer); result = Tcl_Eval(interp, argv[2]); if (result == TCL_OK) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, Tcl_DStringValue(&buffer), NULL); } Tcl_DeleteTrace(interp, cmdTrace); Tcl_DStringFree(&buffer); } else if (strcmp(argv[1], "deletetest") == 0) { /* * Create a command trace then eval a script to check whether it is * called. Note that this trace procedure removes itself as a * further check of the robustness of the trace proc calling code in * TclExecuteByteCode. */ cmdTrace = Tcl_CreateTrace(interp, 50000, (Tcl_CmdTraceProc *) CmdTraceDeleteProc, (ClientData) NULL); result = Tcl_Eval(interp, argv[2]); } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be tracetest or deletetest", (char *) NULL); return TCL_ERROR; } return TCL_OK;}static voidCmdTraceProc(clientData, interp, level, command, cmdProc, cmdClientData, argc, argv) ClientData clientData; /* Pointer to buffer in which the * command and arguments are appended. * Accumulates test result. */ Tcl_Interp *interp; /* Current interpreter. */ int level; /* Current trace level. */ char *command; /* The command being traced (after * substitutions). */ Tcl_CmdProc *cmdProc; /* Points to command's command procedure. */ ClientData cmdClientData; /* Client data associated with command * procedure. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tcl_DString *bufPtr = (Tcl_DString *) clientData; int i; Tcl_DStringAppendElement(bufPtr, command); Tcl_DStringStartSublist(bufPtr); for (i = 0; i < argc; i++) { Tcl_DStringAppendElement(bufPtr, argv[i]); } Tcl_DStringEndSublist(bufPtr);}static voidCmdTraceDeleteProc(clientData, interp, level, command, cmdProc, cmdClientData, argc, argv) ClientData clientData; /* Unused. */ Tcl_Interp *interp; /* Current interpreter. */ int level; /* Current trace level. */ char *command; /* The command being traced (after * substitutions). */ Tcl_CmdProc *cmdProc; /* Points to command's command procedure. */ ClientData cmdClientData; /* Client data associated with command * procedure. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ /* * Remove ourselves to test whether calling Tcl_DeleteTrace within * a trace callback causes the for loop in TclExecuteByteCode that * calls traces to reference freed memory. */ Tcl_DeleteTrace(interp, cmdTrace);}/* *---------------------------------------------------------------------- * * TestcreatecommandCmd -- * * This procedure implements the "testcreatecommand" command. It is * used to test that the Tcl_CreateCommand creates a new command in * the namespace specified as part of its name, if any. It also * checks that the namespace code ignore single ":"s in the middle * or end of a command name. * * Results: * A standard Tcl result. * * Side effects: * Creates and deletes two commands ("test_ns_basic::createdcommand" * and "value:at:"). * *---------------------------------------------------------------------- */static intTestcreatecommandCmd(dummy, interp, argc, argv) ClientData dummy; /* Not used. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option\"", (char *) NULL); return TCL_ERROR; } if (strcmp(argv[1], "create") == 0) { Tcl_CreateCommand(interp, "test_ns_basic::createdcommand", CreatedCommandProc, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); } else if (strcmp(argv[1], "delete") == 0) { Tcl_DeleteCommand(interp, "test_ns_basic::createdcommand"); } else if (strcmp(argv[1], "create2") == 0) { Tcl_CreateCommand(interp, "value:at:", CreatedCommandProc2, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); } else if (strcmp(argv[1], "delete2") == 0) { Tcl_DeleteCommand(interp, "value:at:"); } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be create, delete, create2, or delete2", (char *) NULL); return TCL_ERROR; } return TCL_OK;}static intCreatedCommandProc(clientData, interp, argc, argv) ClientData clientData; /* String to return. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tcl_CmdInfo info; int found;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -