diff options
author | Guido van Rossum <guido@python.org> | 2000-03-31 00:51:37 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2000-03-31 00:51:37 (GMT) |
commit | a1f0a8f4a4d258ca3636e9e8c8d67146f9af6ee4 (patch) | |
tree | 267257c1d6e73dd0aa75d1602ea468283152f2aa | |
parent | 49679b40b91c30bf6b2ea8aeede9a86c659932b1 (diff) | |
download | cpython-a1f0a8f4a4d258ca3636e9e8c8d67146f9af6ee4.zip cpython-a1f0a8f4a4d258ca3636e9e8c8d67146f9af6ee4.tar.gz cpython-a1f0a8f4a4d258ca3636e9e8c8d67146f9af6ee4.tar.bz2 |
Don't use the object call interface in Tk 8.0 -- the EvalObj* API
changed from 8.0 to 8.1 and I see no big reason to use objects in 8.0.
At least now it works again with all versions from 8.0 - 8.3.
-rw-r--r-- | Modules/_tkinter.c | 205 |
1 files changed, 164 insertions, 41 deletions
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index fa8d589..47edf62 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -425,47 +425,6 @@ 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<PyTuple_Size(value);i++) - argv[i] = AsObj(PyTuple_GetItem(value,i)); - result = Tcl_NewListObj(PyTuple_Size(value), argv); - ckfree(FREECAST argv); - return result; - } - else if (PyUnicode_Check(value)) { - PyObject* utf8 = PyUnicode_AsUTF8String (value); - if (!utf8) - return 0; - return Tcl_NewStringObj (PyString_AS_STRING (utf8), - PyString_GET_SIZE (utf8)); - } - else { - PyObject *v = PyObject_Str(value); - if (!v) - return 0; - result = AsObj(v); - Py_DECREF(v); - return result; - } -} /**** Tkapp Object ****/ @@ -559,6 +518,54 @@ Tkapp_New(screenName, baseName, className, interactive) /** Tcl Eval **/ +#if TKMAJORMINOR >= 8001 +#define USING_OBJECTS +#endif + +#ifdef USING_OBJECTS + +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<PyTuple_Size(value);i++) + argv[i] = AsObj(PyTuple_GetItem(value,i)); + result = Tcl_NewListObj(PyTuple_Size(value), argv); + ckfree(FREECAST argv); + return result; + } + else if (PyUnicode_Check(value)) { + PyObject* utf8 = PyUnicode_AsUTF8String (value); + if (!utf8) + return 0; + return Tcl_NewStringObj (PyString_AS_STRING (utf8), + PyString_GET_SIZE (utf8)); + } + else { + PyObject *v = PyObject_Str(value); + if (!v) + return 0; + result = AsObj(v); + Py_DECREF(v); + return result; + } +} + static PyObject * Tkapp_Call(self, args) PyObject *self; @@ -626,6 +633,122 @@ Tkapp_Call(self, args) return res; } +#else /* !USING_OBJECTS */ + +static PyObject * +Tkapp_Call(self, args) + PyObject *self; + PyObject *args; +{ + /* This is copied from Merge() */ + PyObject *tmp = NULL; + char *argvStore[ARGSZ]; + char **argv = NULL; + int fvStore[ARGSZ]; + int *fv = NULL; + int argc = 0, i; + PyObject *res = NULL; /* except this has a different type */ + Tcl_CmdInfo info; /* and this is added */ + Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */ + + if (!(tmp = PyList_New(0))) + return NULL; + + argv = argvStore; + fv = fvStore; + + if (args == NULL) + argc = 0; + + else if (!PyTuple_Check(args)) { + argc = 1; + fv[0] = 0; + argv[0] = AsString(args, tmp); + } + else { + argc = PyTuple_Size(args); + + if (argc > ARGSZ) { + argv = (char **)ckalloc(argc * sizeof(char *)); + fv = (int *)ckalloc(argc * sizeof(int)); + if (argv == NULL || fv == NULL) { + PyErr_NoMemory(); + goto finally; + } + } + + for (i = 0; i < argc; 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); + } + } + } + /* 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); + } + 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); + Tkinter_Error(self); + } + else { + if (Py_VerboseFlag >= 2) + PySys_WriteStderr("-> '%s'\n", interp->result); + res = PyString_FromString(interp->result); + } + 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); + return res; +} + +#endif /* !USING_OBJECTS */ static PyObject * Tkapp_GlobalCall(self, args) |