@@ -425,6 +425,47 @@ 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+ }
428469
429470
430471/**** Tkapp Object ****/
@@ -523,111 +564,65 @@ Tkapp_Call(self, args)
523564 PyObject * self ;
524565 PyObject * args ;
525566{
526- /* This is copied from Merge() */
527- PyObject * tmp = NULL ;
528- char * argvStore [ARGSZ ];
529- char * * argv = NULL ;
530- int fvStore [ARGSZ ];
531- int * fv = NULL ;
532- int argc = 0 , i ;
533- PyObject * res = NULL ; /* except this has a different type */
534- Tcl_CmdInfo info ; /* and this is added */
535- Tcl_Interp * interp = Tkapp_Interp (self ); /* and this too */
567+ Tcl_Obj * objStore [ARGSZ ];
568+ Tcl_Obj * * objv = NULL ;
569+ int objc = 0 , i ;
570+ PyObject * res = NULL ;
571+ Tcl_Interp * interp = Tkapp_Interp (self );
572+ /* Could add TCL_EVAL_GLOBAL if wrapped by GlobalCall... */
573+ int flags = TCL_EVAL_DIRECT ;
536574
537- if (!(tmp = PyList_New (0 )))
538- return NULL ;
539-
540- argv = argvStore ;
541- fv = fvStore ;
575+ objv = objStore ;
542576
543577 if (args == NULL )
544- argc = 0 ;
578+ objc = 0 ;
545579
546580 else if (!PyTuple_Check (args )) {
547- argc = 1 ;
548- fv [0 ] = 0 ;
549- argv [0 ] = AsString (args , tmp );
581+ objc = 1 ;
582+ objv [0 ] = AsObj (args );
583+ if (objv [0 ] == 0 )
584+ goto finally ;
585+ Tcl_IncrRefCount (objv [0 ]);
550586 }
551587 else {
552- argc = PyTuple_Size (args );
588+ objc = PyTuple_Size (args );
553589
554- if (argc > ARGSZ ) {
555- argv = (char * * )ckalloc (argc * sizeof (char * ));
556- fv = (int * )ckalloc (argc * sizeof (int ));
557- if (argv == NULL || fv == NULL ) {
590+ if (objc > ARGSZ ) {
591+ objv = (Tcl_Obj * * )ckalloc (objc * sizeof (char * ));
592+ if (objv == NULL ) {
558593 PyErr_NoMemory ();
559594 goto finally ;
560595 }
561596 }
562597
563- for (i = 0 ; i < argc ; i ++ ) {
598+ for (i = 0 ; i < objc ; i ++ ) {
564599 PyObject * v = PyTuple_GetItem (args , i );
565- if (PyTuple_Check (v )) {
566- fv [i ] = 1 ;
567- if (!(argv [i ] = Merge (v )))
568- goto finally ;
569- }
570- else if (v == Py_None ) {
571- argc = i ;
572- break ;
573- }
574- else {
575- fv [i ] = 0 ;
576- argv [i ] = AsString (v , tmp );
577- }
600+ objv [i ] = AsObj (v );
601+ if (!objv [i ])
602+ goto finally ;
603+ Tcl_IncrRefCount (objv [i ]);
578604 }
579605 }
580- /* End code copied from Merge() */
581606
582- /* All this to avoid a call to Tcl_Merge() and the corresponding call
583- to Tcl_SplitList() inside Tcl_Eval()... It can save a bundle! */
584- if (Py_VerboseFlag >= 2 ) {
585- for (i = 0 ; i < argc ; i ++ )
586- PySys_WriteStderr ("%s " , argv [i ]);
587- }
588607 ENTER_TCL
589- info .proc = NULL ;
590- if (argc < 1 ||
591- !Tcl_GetCommandInfo (interp , argv [0 ], & info ) ||
592- info .proc == NULL )
593- {
594- char * cmd ;
595- cmd = Tcl_Merge (argc , argv );
596- i = Tcl_Eval (interp , cmd );
597- ckfree (cmd );
598- }
599- else {
600- Tcl_ResetResult (interp );
601- i = (* info .proc )(info .clientData , interp , argc , argv );
602- }
608+
609+ i = Tcl_EvalObjv (interp , objc , objv , flags );
610+
603611 ENTER_OVERLAP
604- if (info .proc == NULL && Py_VerboseFlag >= 2 )
605- PySys_WriteStderr ("... use TclEval ");
606- if (i == TCL_ERROR ) {
607- if (Py_VerboseFlag >= 2 )
608- PySys_WriteStderr ("... error: '%s'\n" ,
609- interp -> result );
612+ if (i == TCL_ERROR )
610613 Tkinter_Error (self );
611- }
612- else {
613- if (Py_VerboseFlag >= 2 )
614- PySys_WriteStderr ("-> '%s'\n" , interp -> result );
615- res = PyString_FromString (interp -> result );
616- }
614+ else
615+ /* We could request the object result here, but doing
616+ so would confuse applications that expect a string. */
617+ res = PyString_FromString (Tcl_GetStringResult (interp ));
618+
617619 LEAVE_OVERLAP_TCL
618620
619- /* Copied from Merge() again */
620621 finally :
621- for (i = 0 ; i < argc ; i ++ )
622- if (fv [i ]) {
623- ckfree (argv [i ]);
624- }
625- if (argv != argvStore )
626- ckfree (FREECAST argv );
627- if (fv != fvStore )
628- ckfree (FREECAST fv );
629-
630- Py_DECREF (tmp );
622+ for (i = 0 ; i < objc ; i ++ )
623+ Tcl_DecrRefCount (objv [i ]);
624+ if (objv != objStore )
625+ ckfree (FREECAST objv );
631626 return res ;
632627}
633628
0 commit comments