From 632de2702183468721ef98e2a2ded249baa663b3 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 29 Mar 2000 00:19:50 +0000 Subject: [PATCH] The Tcl_Obj patch discussed on the patches list. This was originally submitted by Martin von Loewis as part of his Unicode patch; all I did was add special cases for Python int and float objects and rearrange the object type tests somewhat to speed up the common cases (string, int, float, tuple, unicode, object). --- Modules/_tkinter.c | 159 ++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 82 deletions(-) diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 92226633abb..fa8d589663b 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -425,6 +425,47 @@ Split(list) return v; } +static Tcl_Obj* +AsObj(value) + PyObject *value; +{ + Tcl_Obj *result; + + if (PyString_Check(value)) + return Tcl_NewStringObj(PyString_AS_STRING(value), + PyString_GET_SIZE(value)); + else if (PyInt_Check(value)) + return Tcl_NewLongObj(PyInt_AS_LONG(value)); + else if (PyFloat_Check(value)) + return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); + else if (PyTuple_Check(value)) { + Tcl_Obj **argv = (Tcl_Obj**) + ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*)); + int i; + if(!argv) + return 0; + for(i=0;i ARGSZ) { - argv = (char **)ckalloc(argc * sizeof(char *)); - fv = (int *)ckalloc(argc * sizeof(int)); - if (argv == NULL || fv == NULL) { + if (objc > ARGSZ) { + objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *)); + if (objv == NULL) { PyErr_NoMemory(); goto finally; } } - for (i = 0; i < argc; i++) { + for (i = 0; i < objc; i++) { PyObject *v = PyTuple_GetItem(args, i); - if (PyTuple_Check(v)) { - fv[i] = 1; - if (!(argv[i] = Merge(v))) - goto finally; - } - else if (v == Py_None) { - argc = i; - break; - } - else { - fv[i] = 0; - argv[i] = AsString(v, tmp); - } + objv[i] = AsObj(v); + if (!objv[i]) + goto finally; + Tcl_IncrRefCount(objv[i]); } } - /* End code copied from Merge() */ - /* All this to avoid a call to Tcl_Merge() and the corresponding call - to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */ - if (Py_VerboseFlag >= 2) { - for (i = 0; i < argc; i++) - PySys_WriteStderr("%s ", argv[i]); - } ENTER_TCL - info.proc = NULL; - if (argc < 1 || - !Tcl_GetCommandInfo(interp, argv[0], &info) || - info.proc == NULL) - { - char *cmd; - cmd = Tcl_Merge(argc, argv); - i = Tcl_Eval(interp, cmd); - ckfree(cmd); - } - else { - Tcl_ResetResult(interp); - i = (*info.proc)(info.clientData, interp, argc, argv); - } + + i = Tcl_EvalObjv(interp, objc, objv, flags); + ENTER_OVERLAP - if (info.proc == NULL && Py_VerboseFlag >= 2) - PySys_WriteStderr("... use TclEval "); - if (i == TCL_ERROR) { - if (Py_VerboseFlag >= 2) - PySys_WriteStderr("... error: '%s'\n", - interp->result); + if (i == TCL_ERROR) Tkinter_Error(self); - } - else { - if (Py_VerboseFlag >= 2) - PySys_WriteStderr("-> '%s'\n", interp->result); - res = PyString_FromString(interp->result); - } + else + /* We could request the object result here, but doing + so would confuse applications that expect a string. */ + res = PyString_FromString(Tcl_GetStringResult(interp)); + LEAVE_OVERLAP_TCL - /* Copied from Merge() again */ finally: - for (i = 0; i < argc; i++) - if (fv[i]) { - ckfree(argv[i]); - } - if (argv != argvStore) - ckfree(FREECAST argv); - if (fv != fvStore) - ckfree(FREECAST fv); - - Py_DECREF(tmp); + for (i = 0; i < objc; i++) + Tcl_DecrRefCount(objv[i]); + if (objv != objStore) + ckfree(FREECAST objv); return res; }