[Python-checkins] CVS: python/dist/src/Modules _tkinter.c,1.92,1.93

Guido van Rossum python-dev@python.org
Tue, 28 Mar 2000 19:19:53 -0500 (EST)


Update of /projects/cvsroot/python/dist/src/Modules
In directory eric:/projects/python/develop/guido/src/Modules

Modified Files:
	_tkinter.c 
Log Message:
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).


Index: _tkinter.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Modules/_tkinter.c,v
retrieving revision 1.92
retrieving revision 1.93
diff -C2 -r1.92 -r1.93
*** _tkinter.c	2000/03/28 20:07:05	1.92
--- _tkinter.c	2000/03/29 00:19:50	1.93
***************
*** 426,429 ****
--- 426,470 ----
  }
  
+ 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;
+ 	}
+ }
  
  
***************
*** 524,559 ****
  	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;
--- 565,594 ----
  	PyObject *args;
  {
! 	Tcl_Obj *objStore[ARGSZ];
! 	Tcl_Obj **objv = NULL;
! 	int objc = 0, i;
! 	PyObject *res = NULL;
! 	Tcl_Interp *interp = Tkapp_Interp(self);
! 	/* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
! 	int flags = TCL_EVAL_DIRECT;
  
! 	objv = objStore;
  
  	if (args == NULL)
! 		objc = 0;
  
  	else if (!PyTuple_Check(args)) {
! 		objc = 1;
! 		objv[0] = AsObj(args);
! 		if (objv[0] == 0)
! 			goto finally;
! 		Tcl_IncrRefCount(objv[0]);
  	}
  	else {
! 		objc = PyTuple_Size(args);
  
! 		if (objc > ARGSZ) {
! 			objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *));
! 			if (objv == NULL) {
  				PyErr_NoMemory();
  				goto finally;
***************
*** 561,632 ****
  		}
  
! 		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;
  }
--- 596,627 ----
  		}
  
! 		for (i = 0; i < objc; i++) {
  			PyObject *v = PyTuple_GetItem(args, i);
! 			objv[i] = AsObj(v);
! 			if (!objv[i])
! 				goto finally;
! 			Tcl_IncrRefCount(objv[i]);
  		}
  	}
  
  	ENTER_TCL
! 
! 	i = Tcl_EvalObjv(interp, objc, objv, flags);
! 
  	ENTER_OVERLAP
! 	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. */
! 		res = PyString_FromString(Tcl_GetStringResult(interp));
! 
  	LEAVE_OVERLAP_TCL
  
    finally:
! 	for (i = 0; i < objc; i++)
! 		Tcl_DecrRefCount(objv[i]);
! 	if (objv != objStore)
! 		ckfree(FREECAST objv);
  	return res;
  }