[Python-checkins] python/dist/src/Modules _tkinter.c,1.130,1.131
loewis@users.sourceforge.net
loewis@users.sourceforge.net
Tue, 26 Nov 2002 01:28:07 -0800
Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv30260/Modules
Modified Files:
_tkinter.c
Log Message:
Patch #518625: Return objects in Tkinter.
Index: _tkinter.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v
retrieving revision 1.130
retrieving revision 1.131
diff -C2 -d -r1.130 -r1.131
*** _tkinter.c 1 Oct 2002 18:50:56 -0000 1.130
--- _tkinter.c 26 Nov 2002 09:28:05 -0000 1.131
***************
*** 51,57 ****
--- 51,59 ----
#ifdef TK_FRAMEWORK
#include <Tcl/tcl.h>
+ #include <Tcl/tclInt.h>
#include <Tk/tk.h>
#else
#include <tcl.h>
+ #include <tclInt.h>
#include <tk.h>
#endif
***************
*** 220,223 ****
--- 222,226 ----
PyObject_HEAD
Tcl_Interp *interp;
+ int want_objects;
} TkappObject;
***************
*** 425,428 ****
--- 428,492 ----
}
+ /* In some cases, Tcl will still return strings that are supposed to be
+ lists. SplitObj walks through a nested tuple, finding string objects that
+ need to be split. */
+
+ PyObject *
+ SplitObj(PyObject *arg)
+ {
+ if (PyTuple_Check(arg)) {
+ int i, size;
+ PyObject *elem, *newelem, *result;
+
+ size = PyTuple_Size(arg);
+ result = NULL;
+ /* Recursively invoke SplitObj for all tuple items.
+ If this does not return a new object, no action is
+ needed. */
+ for(i = 0; i < size; i++) {
+ elem = PyTuple_GetItem(arg, i);
+ newelem = SplitObj(elem);
+ if (!newelem) {
+ Py_XDECREF(result);
+ return NULL;
+ }
+ if (!result) {
+ int k;
+ if (newelem == elem) {
+ Py_DECREF(newelem);
+ continue;
+ }
+ result = PyTuple_New(size);
+ if (!result)
+ return NULL;
+ for(k = 0; k < i; k++) {
+ elem = PyTuple_GetItem(arg, k);
+ Py_INCREF(elem);
+ PyTuple_SetItem(result, k, elem);
+ }
+ }
+ PyTuple_SetItem(result, i, newelem);
+ }
+ if (result)
+ return result;
+ /* Fall through, returning arg. */
+ }
+ else if (PyString_Check(arg)) {
+ int argc;
+ char **argv;
+ char *list = PyString_AsString(arg);
+
+ if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
+ Py_INCREF(arg);
+ return arg;
+ }
+ Tcl_Free(FREECAST argv);
+ if (argc > 1)
+ return Split(PyString_AsString(arg));
+ /* Fall through, returning arg. */
+ }
+ Py_INCREF(arg);
+ return arg;
+ }
***************
*** 459,463 ****
static TkappObject *
! Tkapp_New(char *screenName, char *baseName, char *className, int interactive)
{
TkappObject *v;
--- 523,528 ----
static TkappObject *
! Tkapp_New(char *screenName, char *baseName, char *className,
! int interactive, int want_objects)
{
TkappObject *v;
***************
*** 469,472 ****
--- 534,538 ----
v->interp = Tcl_CreateInterp();
+ v->want_objects = want_objects;
#if defined(macintosh)
***************
*** 514,517 ****
--- 580,681 ----
/** Tcl Eval **/
+ typedef struct {
+ PyObject_HEAD
+ Tcl_Obj *value;
+ } PyTclObject;
+
+ staticforward PyTypeObject PyTclObject_Type;
+ #define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
+
+ static PyObject *
+ newPyTclObject(Tcl_Obj *arg)
+ {
+ PyTclObject *self;
+ self = PyObject_New(PyTclObject, &PyTclObject_Type);
+ if (self == NULL)
+ return NULL;
+ Tcl_IncrRefCount(arg);
+ self->value = arg;
+ return (PyObject*)self;
+ }
+
+ static void
+ PyTclObject_dealloc(PyTclObject *self)
+ {
+ Tcl_DecrRefCount(self->value);
+ PyObject_Del(self);
+ }
+
+ static PyObject *
+ PyTclObject_str(PyTclObject *self)
+ {
+ return PyString_FromString(Tcl_GetString(self->value));
+ }
+
+ static PyObject *
+ PyTclObject_repr(PyTclObject *self)
+ {
+ char buf[50];
+ PyOS_snprintf(buf, 50, "<%s object at 0x%.8x>",
+ self->value->typePtr->name, (int)self->value);
+ return PyString_FromString(buf);
+ }
+
+ static PyObject*
+ get_typename(PyTclObject* obj, void* ignored)
+ {
+ return PyString_FromString(obj->value->typePtr->name);
+ }
+
+ static PyGetSetDef PyTclObject_getsetlist[] = {
+ {"typename", (getter)get_typename, NULL, "name of the Tcl type"},
+ {0},
+ };
+
+ statichere PyTypeObject PyTclObject_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "_tkinter.Tcl_Obj", /*tp_name*/
+ sizeof(PyTclObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)PyTclObject_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ (reprfunc)PyTclObject_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ (reprfunc)PyTclObject_str, /*tp_str*/
+ PyObject_GenericGetAttr,/*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ PyTclObject_getsetlist, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ 0, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ };
+
static Tcl_Obj*
AsObj(PyObject *value)
***************
*** 571,574 ****
--- 735,743 ----
}
#endif
+ else if(PyTclObject_Check(value)) {
+ Tcl_Obj *v = ((PyTclObject*)value)->value;
+ Tcl_IncrRefCount(v);
+ return v;
+ }
else {
PyObject *v = PyObject_Str(value);
***************
*** 581,584 ****
--- 750,846 ----
}
+ static PyObject*
+ FromObj(PyObject* tkapp, Tcl_Obj *value)
+ {
+ PyObject *result = NULL;
+
+ if (value->typePtr == NULL)
+ return PyString_FromStringAndSize(value->bytes, value->length);
+
+ if (value->typePtr == &tclBooleanType) {
+ result = value->internalRep.longValue ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+ }
+
+ if (value->typePtr == &tclByteArrayType) {
+ int size;
+ char *data = Tcl_GetByteArrayFromObj(value, &size);
+ return PyString_FromStringAndSize(data, size);
+ }
+
+ if (value->typePtr == &tclDoubleType) {
+ return PyFloat_FromDouble(value->internalRep.doubleValue);
+ }
+
+ if (value->typePtr == &tclIntType) {
+ return PyInt_FromLong(value->internalRep.longValue);
+ }
+
+ if (value->typePtr == &tclListType) {
+ int size;
+ int i, status;
+ PyObject *elem;
+ Tcl_Obj *tcl_elem;
+
+ status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size);
+ if (status == TCL_ERROR)
+ return Tkinter_Error(tkapp);
+ result = PyTuple_New(size);
+ if (!result)
+ return NULL;
+ for (i = 0; i < size; i++) {
+ status = Tcl_ListObjIndex(Tkapp_Interp(tkapp),
+ value, i, &tcl_elem);
+ if (status == TCL_ERROR) {
+ Py_DECREF(result);
+ return Tkinter_Error(tkapp);
+ }
+ elem = FromObj(tkapp, tcl_elem);
+ if (!elem) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SetItem(result, i, elem);
+ }
+ return result;
+ }
+
+ if (value->typePtr == &tclProcBodyType) {
+ // fall through: return tcl object
+ }
+
+ if (value->typePtr == &tclStringType) {
+ #ifdef Py_USING_UNICODE
+ #ifdef Py_UNICODE_WIDE
+ PyObject *result;
+ int size;
+ Tcl_UniChar *input;
+ Py_UNICODE *output;
+
+ size = Tcl_GetCharLength(value);
+ result = PyUnicode_FromUnicode(NULL, size);
+ if (!result)
+ return NULL;
+ input = Tcl_GetUnicode(value);
+ output = PyUnicode_AS_UNICODE(result);
+ while (size--)
+ *output++ = *input++;
+ return result;
+ #else
+ return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
+ Tcl_GetCharLength(value));
+ #endif
+ #else
+ int size;
+ char *c;
+ c = Tcl_GetStringFromObj(value, &size);
+ return PyString_FromStringAndSize(c, size);
+ #endif
+ }
+
+ return newPyTclObject(value);
+ }
+
static PyObject *
Tkapp_Call(PyObject *self, PyObject *args)
***************
*** 640,646 ****
if (i == TCL_ERROR)
Tkinter_Error(self);
! else {
! /* We could request the object result here, but doing
! so would confuse applications that expect a string. */
const char *s = Tcl_GetStringResult(interp);
const char *p = s;
--- 902,914 ----
if (i == TCL_ERROR)
Tkinter_Error(self);
! else if(((TkappObject*)self)->want_objects) {
! Tcl_Obj *value = Tcl_GetObjResult(interp);
! /* Not sure whether the IncrRef is necessary, but something
! may overwrite the interpreter result while we are
! converting it. */
! Tcl_IncrRefCount(value);
! res = FromObj(self, value);
! Tcl_DecrRefCount(value);
! } else {
const char *s = Tcl_GetStringResult(interp);
const char *p = s;
***************
*** 965,968 ****
--- 1233,1243 ----
int v;
+ if (PyTuple_Size(args) == 1) {
+ PyObject* o = PyTuple_GetItem(args, 0);
+ if (PyInt_Check(o)) {
+ Py_INCREF(o);
+ return o;
+ }
+ }
if (!PyArg_ParseTuple(args, "s:getint", &s))
return NULL;
***************
*** 978,981 ****
--- 1253,1263 ----
double v;
+ if (PyTuple_Size(args) == 1) {
+ PyObject *o = PyTuple_GetItem(args, 0);
+ if (PyFloat_Check(o)) {
+ Py_INCREF(o);
+ return o;
+ }
+ }
if (!PyArg_ParseTuple(args, "s:getdouble", &s))
return NULL;
***************
*** 991,994 ****
--- 1273,1283 ----
int v;
+ if (PyTuple_Size(args) == 1) {
+ PyObject *o = PyTuple_GetItem(args, 0);
+ if (PyInt_Check(o)) {
+ Py_INCREF(o);
+ return o;
+ }
+ }
if (!PyArg_ParseTuple(args, "s:getboolean", &s))
return NULL;
***************
*** 1094,1097 ****
--- 1383,1393 ----
int i;
+ if (PyTuple_Size(args) == 1) {
+ v = PyTuple_GetItem(args, 0);
+ if (PyTuple_Check(v)) {
+ Py_INCREF(v);
+ return v;
+ }
+ }
if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
return NULL;
***************
*** 1122,1125 ****
--- 1418,1428 ----
char *list;
+ if (PyTuple_Size(args) == 1) {
+ PyObject* o = PyTuple_GetItem(args, 0);
+ if (PyTuple_Check(o)) {
+ o = SplitObj(o);
+ return o;
+ }
+ }
if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
return NULL;
***************
*** 1661,1664 ****
--- 1964,1981 ----
+ static PyObject *
+ Tkapp_WantObjects(PyObject *self, PyObject *args)
+ {
+
+ int want_objects;
+ if (!PyArg_ParseTuple(args, "i:wantobjects", &want_objects))
+ return NULL;
+ ((TkappObject*)self)->want_objects = want_objects;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+
/**** Tkapp Method List ****/
***************
*** 1666,1669 ****
--- 1983,1987 ----
static PyMethodDef Tkapp_methods[] =
{
+ {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
{"call", Tkapp_Call, METH_OLDARGS},
{"globalcall", Tkapp_GlobalCall, METH_OLDARGS},
***************
*** 1862,1865 ****
--- 2180,2184 ----
char *className = NULL;
int interactive = 0;
+ int want_objects = 0;
baseName = strrchr(Py_GetProgramName(), '/');
***************
*** 1872,1880 ****
if (!PyArg_ParseTuple(args, "|zssi:create",
&screenName, &baseName, &className,
! &interactive))
return NULL;
return (PyObject *) Tkapp_New(screenName, baseName, className,
! interactive);
}
--- 2191,2199 ----
if (!PyArg_ParseTuple(args, "|zssi:create",
&screenName, &baseName, &className,
! &interactive, &want_objects))
return NULL;
return (PyObject *) Tkapp_New(screenName, baseName, className,
! interactive, want_objects);
}
***************
*** 2046,2049 ****
--- 2365,2370 ----
PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
+ PyTclObject_Type.ob_type = &PyType_Type;
+ PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
#ifdef TK_AQUA