Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a1f0a8f

Browse files
committed
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.
1 parent 49679b4 commit a1f0a8f

1 file changed

Lines changed: 164 additions & 41 deletions

File tree

Modules/_tkinter.c

Lines changed: 164 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -425,47 +425,6 @@ Split(list)
425425
return v;
426426
}
427427

428-
static Tcl_Obj*
429-
AsObj(value)
430-
PyObject *value;
431-
{
432-
Tcl_Obj *result;
433-
434-
if (PyString_Check(value))
435-
return Tcl_NewStringObj(PyString_AS_STRING(value),
436-
PyString_GET_SIZE(value));
437-
else if (PyInt_Check(value))
438-
return Tcl_NewLongObj(PyInt_AS_LONG(value));
439-
else if (PyFloat_Check(value))
440-
return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
441-
else if (PyTuple_Check(value)) {
442-
Tcl_Obj **argv = (Tcl_Obj**)
443-
ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
444-
int i;
445-
if(!argv)
446-
return 0;
447-
for(i=0;i<PyTuple_Size(value);i++)
448-
argv[i] = AsObj(PyTuple_GetItem(value,i));
449-
result = Tcl_NewListObj(PyTuple_Size(value), argv);
450-
ckfree(FREECAST argv);
451-
return result;
452-
}
453-
else if (PyUnicode_Check(value)) {
454-
PyObject* utf8 = PyUnicode_AsUTF8String (value);
455-
if (!utf8)
456-
return 0;
457-
return Tcl_NewStringObj (PyString_AS_STRING (utf8),
458-
PyString_GET_SIZE (utf8));
459-
}
460-
else {
461-
PyObject *v = PyObject_Str(value);
462-
if (!v)
463-
return 0;
464-
result = AsObj(v);
465-
Py_DECREF(v);
466-
return result;
467-
}
468-
}
469428

470429

471430
/**** Tkapp Object ****/
@@ -559,6 +518,54 @@ Tkapp_New(screenName, baseName, className, interactive)
559518

560519
/** Tcl Eval **/
561520

521+
#if TKMAJORMINOR >= 8001
522+
#define USING_OBJECTS
523+
#endif
524+
525+
#ifdef USING_OBJECTS
526+
527+
static Tcl_Obj*
528+
AsObj(value)
529+
PyObject *value;
530+
{
531+
Tcl_Obj *result;
532+
533+
if (PyString_Check(value))
534+
return Tcl_NewStringObj(PyString_AS_STRING(value),
535+
PyString_GET_SIZE(value));
536+
else if (PyInt_Check(value))
537+
return Tcl_NewLongObj(PyInt_AS_LONG(value));
538+
else if (PyFloat_Check(value))
539+
return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
540+
else if (PyTuple_Check(value)) {
541+
Tcl_Obj **argv = (Tcl_Obj**)
542+
ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*));
543+
int i;
544+
if(!argv)
545+
return 0;
546+
for(i=0;i<PyTuple_Size(value);i++)
547+
argv[i] = AsObj(PyTuple_GetItem(value,i));
548+
result = Tcl_NewListObj(PyTuple_Size(value), argv);
549+
ckfree(FREECAST argv);
550+
return result;
551+
}
552+
else if (PyUnicode_Check(value)) {
553+
PyObject* utf8 = PyUnicode_AsUTF8String (value);
554+
if (!utf8)
555+
return 0;
556+
return Tcl_NewStringObj (PyString_AS_STRING (utf8),
557+
PyString_GET_SIZE (utf8));
558+
}
559+
else {
560+
PyObject *v = PyObject_Str(value);
561+
if (!v)
562+
return 0;
563+
result = AsObj(v);
564+
Py_DECREF(v);
565+
return result;
566+
}
567+
}
568+
562569
static PyObject *
563570
Tkapp_Call(self, args)
564571
PyObject *self;
@@ -626,6 +633,122 @@ Tkapp_Call(self, args)
626633
return res;
627634
}
628635

636+
#else /* !USING_OBJECTS */
637+
638+
static PyObject *
639+
Tkapp_Call(self, args)
640+
PyObject *self;
641+
PyObject *args;
642+
{
643+
/* This is copied from Merge() */
644+
PyObject *tmp = NULL;
645+
char *argvStore[ARGSZ];
646+
char **argv = NULL;
647+
int fvStore[ARGSZ];
648+
int *fv = NULL;
649+
int argc = 0, i;
650+
PyObject *res = NULL; /* except this has a different type */
651+
Tcl_CmdInfo info; /* and this is added */
652+
Tcl_Interp *interp = Tkapp_Interp(self); /* and this too */
653+
654+
if (!(tmp = PyList_New(0)))
655+
return NULL;
656+
657+
argv = argvStore;
658+
fv = fvStore;
659+
660+
if (args == NULL)
661+
argc = 0;
662+
663+
else if (!PyTuple_Check(args)) {
664+
argc = 1;
665+
fv[0] = 0;
666+
argv[0] = AsString(args, tmp);
667+
}
668+
else {
669+
argc = PyTuple_Size(args);
670+
671+
if (argc > ARGSZ) {
672+
argv = (char **)ckalloc(argc * sizeof(char *));
673+
fv = (int *)ckalloc(argc * sizeof(int));
674+
if (argv == NULL || fv == NULL) {
675+
PyErr_NoMemory();
676+
goto finally;
677+
}
678+
}
679+
680+
for (i = 0; i < argc; i++) {
681+
PyObject *v = PyTuple_GetItem(args, i);
682+
if (PyTuple_Check(v)) {
683+
fv[i] = 1;
684+
if (!(argv[i] = Merge(v)))
685+
goto finally;
686+
}
687+
else if (v == Py_None) {
688+
argc = i;
689+
break;
690+
}
691+
else {
692+
fv[i] = 0;
693+
argv[i] = AsString(v, tmp);
694+
}
695+
}
696+
}
697+
/* End code copied from Merge() */
698+
699+
/* All this to avoid a call to Tcl_Merge() and the corresponding call
700+
to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
701+
if (Py_VerboseFlag >= 2) {
702+
for (i = 0; i < argc; i++)
703+
PySys_WriteStderr("%s ", argv[i]);
704+
}
705+
ENTER_TCL
706+
info.proc = NULL;
707+
if (argc < 1 ||
708+
!Tcl_GetCommandInfo(interp, argv[0], &info) ||
709+
info.proc == NULL)
710+
{
711+
char *cmd;
712+
cmd = Tcl_Merge(argc, argv);
713+
i = Tcl_Eval(interp, cmd);
714+
ckfree(cmd);
715+
}
716+
else {
717+
Tcl_ResetResult(interp);
718+
i = (*info.proc)(info.clientData, interp, argc, argv);
719+
}
720+
ENTER_OVERLAP
721+
if (info.proc == NULL && Py_VerboseFlag >= 2)
722+
PySys_WriteStderr("... use TclEval ");
723+
if (i == TCL_ERROR) {
724+
if (Py_VerboseFlag >= 2)
725+
PySys_WriteStderr("... error: '%s'\n",
726+
interp->result);
727+
Tkinter_Error(self);
728+
}
729+
else {
730+
if (Py_VerboseFlag >= 2)
731+
PySys_WriteStderr("-> '%s'\n", interp->result);
732+
res = PyString_FromString(interp->result);
733+
}
734+
LEAVE_OVERLAP_TCL
735+
736+
/* Copied from Merge() again */
737+
finally:
738+
for (i = 0; i < argc; i++)
739+
if (fv[i]) {
740+
ckfree(argv[i]);
741+
}
742+
if (argv != argvStore)
743+
ckfree(FREECAST argv);
744+
if (fv != fvStore)
745+
ckfree(FREECAST fv);
746+
747+
Py_DECREF(tmp);
748+
return res;
749+
}
750+
751+
#endif /* !USING_OBJECTS */
629752

630753
static PyObject *
631754
Tkapp_GlobalCall(self, args)

0 commit comments

Comments
 (0)