Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(10)

Delta Between Two Patch Sets: Modules/_tkinter.c

Issue 16840: Tkinter doesn't support large integers
Left Patch Set: Created 7 years, 1 month ago
Right Patch Set: Created 4 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | Modules/tkinter.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /*********************************************************** 1 /***********************************************************
2 Copyright (C) 1994 Steen Lumholt. 2 Copyright (C) 1994 Steen Lumholt.
3 3
4 All Rights Reserved 4 All Rights Reserved
5 5
6 ******************************************************************/ 6 ******************************************************************/
7 7
8 /* _tkinter.c -- Interface to libtk.a and libtcl.a. */ 8 /* _tkinter.c -- Interface to libtk.a and libtcl.a. */
9 9
10 /* TCL/TK VERSION INFO: 10 /* TCL/TK VERSION INFO:
(...skipping 26 matching lines...) Expand all
37 #ifndef PyDoc_STRVAR 37 #ifndef PyDoc_STRVAR
38 #define PyDoc_STRVAR(name,str) static char name[] = str 38 #define PyDoc_STRVAR(name,str) static char name[] = str
39 #endif 39 #endif
40 40
41 #ifndef PyMODINIT_FUNC 41 #ifndef PyMODINIT_FUNC
42 #define PyMODINIT_FUNC void 42 #define PyMODINIT_FUNC void
43 #endif 43 #endif
44 44
45 #ifndef PyBool_Check 45 #ifndef PyBool_Check
46 #define PyBool_Check(o) 0 46 #define PyBool_Check(o) 0
47 #define PyBool_FromLong PyLong_FromLong 47 #define PyBool_FromLong PyInt_FromLong
48 #endif 48 #endif
49
50 #define CHECK_SIZE(size, elemsize) \
51 ((size_t)(size) <= (size_t)INT_MAX && \
52 (size_t)(size) <= UINT_MAX / (size_t)(elemsize))
49 53
50 /* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately, 54 /* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately,
51 making _tkinter correct for this API means to break earlier 55 making _tkinter correct for this API means to break earlier
52 versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and 56 versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and
53 earlier versions. Once Tcl releases before 8.4 don't need to be supported 57 earlier versions. Once Tcl releases before 8.4 don't need to be supported
54 anymore, this should go. */ 58 anymore, this should go. */
55 #define USE_COMPAT_CONST 59 #define USE_COMPAT_CONST
56 60
57 /* If Tcl is compiled for threads, we must also define TCL_THREAD. We define 61 /* If Tcl is compiled for threads, we must also define TCL_THREAD. We define
58 it always; if Tcl is not threaded, the thread functions in 62 it always; if Tcl is not threaded, the thread functions in
59 Tcl are empty. */ 63 Tcl are empty. */
60 #define TCL_THREADS 64 #define TCL_THREADS
61 65
62 #ifdef TK_FRAMEWORK 66 #ifdef TK_FRAMEWORK
63 #include <Tcl/tcl.h> 67 #include <Tcl/tcl.h>
64 #include <Tk/tk.h> 68 #include <Tk/tk.h>
65 #else 69 #else
66 #include <tcl.h> 70 #include <tcl.h>
67 #include <tk.h> 71 #include <tk.h>
68 #endif 72 #endif
69 #include <tclTomMath.h>
70 73
71 #include "tkinter.h" 74 #include "tkinter.h"
72 75
73 /* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */ 76 /* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
74 #ifndef CONST84_RETURN 77 #ifndef CONST84_RETURN
75 #define CONST84_RETURN 78 #define CONST84_RETURN
76 #undef CONST 79 #undef CONST
77 #define CONST 80 #define CONST
78 #endif 81 #endif
79 82
80 #if TK_VERSION_HEX < 0x08030102 83 #if TK_HEX_VERSION < 0x08030201
81 #error "Tk older than 8.3.1 not supported" 84 #error "Tk older than 8.3.1 not supported"
85 #endif
86
87 /* Unicode conversion assumes that Tcl_UniChar is two bytes.
88 We cannot test this directly, so we test UTF-8 size instead,
89 expecting that TCL_UTF_MAX is changed if Tcl ever supports
90 either UTF-16 or UCS-4.
91 Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for
92 Tcl_Unichar. This is also ok as long as Python uses UCS-4,
93 as well.
94 */
95 #if TCL_UTF_MAX != 3 && !(defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==6)
96 #error "unsupported Tcl configuration"
97 #endif
98
99 #if TK_HEX_VERSION >= 0x08050208 && TK_HEX_VERSION < 0x08060000 || \
100 TK_HEX_VERSION >= 0x08060200
101 #define HAVE_LIBTOMMAMTH
102 #include <tclTomMath.h>
82 #endif 103 #endif
83 104
84 #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) 105 #if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
85 #define HAVE_CREATEFILEHANDLER 106 #define HAVE_CREATEFILEHANDLER
86 #endif 107 #endif
87 108
88 #ifdef HAVE_CREATEFILEHANDLER 109 #ifdef HAVE_CREATEFILEHANDLER
89 110
90 /* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere 111 /* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere
91 with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */ 112 with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */
(...skipping 27 matching lines...) Expand all
119 140
120 #ifdef MS_WINDOWS 141 #ifdef MS_WINDOWS
121 #include <conio.h> 142 #include <conio.h>
122 #define WAIT_FOR_STDIN 143 #define WAIT_FOR_STDIN
123 #endif 144 #endif
124 145
125 #ifdef WITH_THREAD 146 #ifdef WITH_THREAD
126 147
127 /* The threading situation is complicated. Tcl is not thread-safe, except 148 /* The threading situation is complicated. Tcl is not thread-safe, except
128 when configured with --enable-threads. 149 when configured with --enable-threads.
129 150 So we need to use a lock around all uses of Tcl. Previously, the Python
130 So we need to use a lock around all uses of Tcl. Previously, the 151 interpreter lock was used for this. However, this causes problems when
131 Python interpreter lock was used for this. However, this causes 152 other Python threads need to run while Tcl is blocked waiting for events.
132 problems when other Python threads need to run while Tcl is blocked 153
133 waiting for events. 154 To solve this problem, a separate lock for Tcl is introduced. Holding it
134 155 is incompatible with holding Python's interpreter lock. The following four
135 To solve this problem, a separate lock for Tcl is introduced. 156 macros manipulate both locks together.
136 Holding it is incompatible with holding Python's interpreter lock. 157
137 The following four macros manipulate both locks together. 158 ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and
138 159 Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made
139 ENTER_TCL and LEAVE_TCL are brackets, just like 160 that could call an event handler, or otherwise affect the state of a Tcl
140 Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS. They should be 161 interpreter. These assume that the surrounding code has the Python
141 used whenever a call into Tcl is made that could call an event 162 interpreter lock; inside the brackets, the Python interpreter lock has been
142 handler, or otherwise affect the state of a Tcl interpreter. These 163 released and the lock for Tcl has been acquired.
143 assume that the surrounding code has the Python interpreter lock; 164
144 inside the brackets, the Python interpreter lock has been released 165 Sometimes, it is necessary to have both the Python lock and the Tcl lock.
145 and the lock for Tcl has been acquired. 166 (For example, when transferring data from the Tcl interpreter result to a
146 167 Python string object.) This can be done by using different macros to close
147 Sometimes, it is necessary to have both the Python lock and the Tcl 168 the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores
148 lock. (For example, when transferring data from the Tcl 169 the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL
149 interpreter result to a Python string object.) This can be done by 170 releases the Tcl lock.
150 using different macros to close the ENTER_TCL block: ENTER_OVERLAP
151 reacquires the Python lock (and restores the thread state) but
152 doesn't release the Tcl lock; LEAVE_OVERLAP_TCL releases the Tcl
153 lock.
154 171
155 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event 172 By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event
156 handlers when the handler needs to use Python. Such event handlers 173 handlers when the handler needs to use Python. Such event handlers are
157 are entered while the lock for Tcl is held; the event handler 174 entered while the lock for Tcl is held; the event handler presumably needs
158 presumably needs to use Python. ENTER_PYTHON releases the lock for 175 to use Python. ENTER_PYTHON releases the lock for Tcl and acquires
159 Tcl and acquires the Python interpreter lock, restoring the 176 the Python interpreter lock, restoring the appropriate thread state, and
160 appropriate thread state, and LEAVE_PYTHON releases the Python 177 LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock
161 interpreter lock and re-acquires the lock for Tcl. It is okay for 178 for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside
162 ENTER_TCL/LEAVE_TCL pairs to be contained inside the code between 179 the code between ENTER_PYTHON and LEAVE_PYTHON.
163 ENTER_PYTHON and LEAVE_PYTHON. 180
164 181 These locks expand to several statements and brackets; they should not be
165 These locks expand to several statements and brackets; they should 182 used in branches of if statements and the like.
166 not be used in branches of if statements and the like. 183
167 184 If Tcl is threaded, this approach won't work anymore. The Tcl interpreter is
168 If Tcl is threaded, this approach won't work anymore. The Tcl 185 only valid in the thread that created it, and all Tk activity must happen in this
169 interpreter is only valid in the thread that created it, and all Tk 186 thread, also. That means that the mainloop must be invoked in the thread that
170 activity must happen in this thread, also. That means that the 187 created the interpreter. Invoking commands from other threads is possible;
171 mainloop must be invoked in the thread that created the 188 _tkinter will queue an event for the interpreter thread, which will then
172 interpreter. Invoking commands from other threads is possible; 189 execute the command and pass back the result. If the main thread is not in th e
173 _tkinter will queue an event for the interpreter thread, which will 190 mainloop, and invoking commands causes an exception; if the main loop is runn ing
174 then execute the command and pass back the result. If the main 191 but not processing events, the command invocation will block.
175 thread is not in the mainloop, and invoking commands causes an 192
176 exception; if the main loop is running but not processing events, 193 In addition, for a threaded Tcl, a single global tcl_tstate won't be sufficie nt
177 the command invocation will block. 194 anymore, since multiple Tcl interpreters may simultaneously dispatch in diffe rent
178 195 threads. So we use the Tcl TLS API.
179 In addition, for a threaded Tcl, a single global tcl_tstate won't
180 be sufficient anymore, since multiple Tcl interpreters may
181 simultaneously dispatch in different threads. So we use the Tcl TLS
182 API.
183 196
184 */ 197 */
185 198
186 static PyThread_type_lock tcl_lock = 0; 199 static PyThread_type_lock tcl_lock = 0;
187 200
188 #ifdef TCL_THREADS 201 #ifdef TCL_THREADS
189 static Tcl_ThreadDataKey state_key; 202 static Tcl_ThreadDataKey state_key;
190 typedef PyThreadState *ThreadSpecificData; 203 typedef PyThreadState *ThreadSpecificData;
191 #define tcl_tstate \ 204 #define tcl_tstate (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThr eadState*)))
192 (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*)))
193 #else 205 #else
194 static PyThreadState *tcl_tstate = NULL; 206 static PyThreadState *tcl_tstate = NULL;
195 #endif 207 #endif
196 208
197 #define ENTER_TCL \ 209 #define ENTER_TCL \
198 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \ 210 { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \
199 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; 211 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate;
200 212
201 #define LEAVE_TCL \ 213 #define LEAVE_TCL \
202 tcl_tstate = NULL; \ 214 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW _THREADS}
203 if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS}
204 215
205 #define ENTER_OVERLAP \ 216 #define ENTER_OVERLAP \
206 Py_END_ALLOW_THREADS 217 Py_END_ALLOW_THREADS
207 218
208 #define LEAVE_OVERLAP_TCL \ 219 #define LEAVE_OVERLAP_TCL \
209 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); } 220 tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); }
210 221
211 #define ENTER_PYTHON \ 222 #define ENTER_PYTHON \
212 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \ 223 { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \
213 if(tcl_lock) \ 224 if(tcl_lock)PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstat e)); }
214 PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); }
215 225
216 #define LEAVE_PYTHON \ 226 #define LEAVE_PYTHON \
217 { PyThreadState *tstate = PyEval_SaveThread(); \ 227 { PyThreadState *tstate = PyEval_SaveThread(); \
218 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; } 228 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; }
219 229
220 #define CHECK_TCL_APPARTMENT \ 230 #define CHECK_TCL_APPARTMENT \
221 if (((TkappObject *)self)->threaded && \ 231 if (((TkappObject *)self)->threaded && \
222 ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \ 232 ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \
223 PyErr_SetString(PyExc_RuntimeError, \ 233 PyErr_SetString(PyExc_RuntimeError, "Calling Tcl from different appartme nt"); \
224 "Calling Tcl from different appartment"); \
225 return 0; \ 234 return 0; \
226 } 235 }
227 236
228 #else 237 #else
229 238
230 #define ENTER_TCL 239 #define ENTER_TCL
231 #define LEAVE_TCL 240 #define LEAVE_TCL
232 #define ENTER_OVERLAP 241 #define ENTER_OVERLAP
233 #define LEAVE_OVERLAP_TCL 242 #define LEAVE_OVERLAP_TCL
234 #define ENTER_PYTHON 243 #define ENTER_PYTHON
235 #define LEAVE_PYTHON 244 #define LEAVE_PYTHON
236 #define CHECK_TCL_APPARTMENT 245 #define CHECK_TCL_APPARTMENT
237 246
238 #endif 247 #endif
239 248
240 #ifndef FREECAST 249 #ifndef FREECAST
241 #define FREECAST (char *) 250 #define FREECAST (char *)
242 #endif 251 #endif
243 252
244 /**** Tkapp Object Declaration ****/ 253 /**** Tkapp Object Declaration ****/
245 254
246 static PyObject *Tkapp_Type; 255 static PyTypeObject Tkapp_Type;
247 256
248 typedef struct { 257 typedef struct {
249 PyObject_HEAD 258 PyObject_HEAD
250 Tcl_Interp *interp; 259 Tcl_Interp *interp;
251 int wantobjects; 260 int wantobjects;
252 int threaded; /* True if tcl_platform[threaded] */ 261 int threaded; /* True if tcl_platform[threaded] */
253 Tcl_ThreadId thread_id; 262 Tcl_ThreadId thread_id;
254 int dispatching; 263 int dispatching;
255 /* We cannot include tclInt.h, as this is internal. 264 /* We cannot include tclInt.h, as this is internal.
256 So we cache interesting types here. */ 265 So we cache interesting types here. */
257 Tcl_ObjType *BooleanType; 266 const Tcl_ObjType *OldBooleanType;
258 Tcl_ObjType *ByteArrayType; 267 const Tcl_ObjType *BooleanType;
259 Tcl_ObjType *DoubleType; 268 const Tcl_ObjType *ByteArrayType;
260 Tcl_ObjType *IntType; 269 const Tcl_ObjType *DoubleType;
261 Tcl_ObjType *WideIntType; 270 const Tcl_ObjType *IntType;
262 Tcl_ObjType *BignumType; 271 const Tcl_ObjType *WideIntType;
263 Tcl_ObjType *ListType; 272 const Tcl_ObjType *BignumType;
264 Tcl_ObjType *ProcBodyType; 273 const Tcl_ObjType *ListType;
265 Tcl_ObjType *StringType; 274 const Tcl_ObjType *ProcBodyType;
275 const Tcl_ObjType *StringType;
266 } TkappObject; 276 } TkappObject;
267 277
278 #define Tkapp_Check(v) (Py_TYPE(v) == &Tkapp_Type)
268 #define Tkapp_Interp(v) (((TkappObject *) (v))->interp) 279 #define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
269 #define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v)) 280 #define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
270 281
271 #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \ 282 #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
272 (void *) v, Py_REFCNT(v))) 283 (void *) v, Py_REFCNT(v)))
273 284
274 285
275 286
276 /**** Error Handling ****/ 287 /**** Error Handling ****/
277 288
278 static PyObject *Tkinter_TclError; 289 static PyObject *Tkinter_TclError;
279 static int quitMainLoop = 0; 290 static int quitMainLoop = 0;
280 static int errorInCmd = 0; 291 static int errorInCmd = 0;
281 static PyObject *excInCmd; 292 static PyObject *excInCmd;
282 static PyObject *valInCmd; 293 static PyObject *valInCmd;
283 static PyObject *trbInCmd; 294 static PyObject *trbInCmd;
284 295
285 #ifdef TKINTER_PROTECT_LOADTK 296 #ifdef TKINTER_PROTECT_LOADTK
286 static int tk_load_failed = 0; 297 static int tk_load_failed;
287 #endif 298 #endif
288 299
289 300
290 static PyObject * 301 static PyObject *
291 Tkinter_Error(PyObject *v) 302 Tkinter_Error(PyObject *v)
292 { 303 {
293 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v)); 304 PyErr_SetString(Tkinter_TclError, Tkapp_Result(v));
294 return NULL; 305 return NULL;
295 } 306 }
296 307
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 Py_END_ALLOW_THREADS 341 Py_END_ALLOW_THREADS
331 } 342 }
332 if (self->dispatching) 343 if (self->dispatching)
333 return 1; 344 return 1;
334 PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop"); 345 PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
335 return 0; 346 return 0;
336 } 347 }
337 #endif /* WITH_THREAD */ 348 #endif /* WITH_THREAD */
338 349
339 350
351 static char *
352 AsString(PyObject *value, PyObject *tmp)
353 {
354 if (PyString_Check(value))
355 return PyString_AsString(value);
356 #ifdef Py_USING_UNICODE
357 else if (PyUnicode_Check(value)) {
358 PyObject *v = PyUnicode_AsUTF8String(value);
359 if (v == NULL)
360 return NULL;
361 if (PyList_Append(tmp, v) != 0) {
362 Py_DECREF(v);
363 return NULL;
364 }
365 Py_DECREF(v);
366 return PyString_AsString(v);
367 }
368 #endif
369 else {
370 PyObject *v = PyObject_Str(value);
371 if (v == NULL)
372 return NULL;
373 if (PyList_Append(tmp, v) != 0) {
374 Py_DECREF(v);
375 return NULL;
376 }
377 Py_DECREF(v);
378 return PyString_AsString(v);
379 }
380 }
381
382
340 383
341 #define ARGSZ 64 384 #define ARGSZ 64
342 385
386 static char *
387 Merge(PyObject *args)
388 {
389 PyObject *tmp = NULL;
390 char *argvStore[ARGSZ];
391 char **argv = NULL;
392 int fvStore[ARGSZ];
393 int *fv = NULL;
394 Py_ssize_t argc = 0, fvc = 0, i;
395 char *res = NULL;
396
397 if (!(tmp = PyList_New(0)))
398 return NULL;
399
400 argv = argvStore;
401 fv = fvStore;
402
403 if (args == NULL)
404 argc = 0;
405
406 else if (!PyTuple_Check(args)) {
407 argc = 1;
408 fv[0] = 0;
409 if (!(argv[0] = AsString(args, tmp)))
410 goto finally;
411 }
412 else {
413 argc = PyTuple_Size(args);
414
415 if (argc > ARGSZ) {
416 if (!CHECK_SIZE(argc, sizeof(char *))) {
417 PyErr_SetString(PyExc_OverflowError, "tuple is too long");
418 goto finally;
419 }
420 argv = (char **)attemptckalloc((size_t)argc * sizeof(char *));
421 fv = (int *)attemptckalloc((size_t)argc * sizeof(int));
422 if (argv == NULL || fv == NULL) {
423 PyErr_NoMemory();
424 goto finally;
425 }
426 }
427
428 for (i = 0; i < argc; i++) {
429 PyObject *v = PyTuple_GetItem(args, i);
430 if (PyTuple_Check(v)) {
431 fv[i] = 1;
432 if (!(argv[i] = Merge(v)))
433 goto finally;
434 fvc++;
435 }
436 else if (v == Py_None) {
437 argc = i;
438 break;
439 }
440 else {
441 fv[i] = 0;
442 if (!(argv[i] = AsString(v, tmp)))
443 goto finally;
444 fvc++;
445 }
446 }
447 }
448 res = Tcl_Merge(argc, argv);
449 if (res == NULL)
450 PyErr_SetString(Tkinter_TclError, "merge failed");
451
452 finally:
453 for (i = 0; i < fvc; i++)
454 if (fv[i]) {
455 ckfree(argv[i]);
456 }
457 if (argv != argvStore)
458 ckfree(FREECAST argv);
459 if (fv != fvStore)
460 ckfree(FREECAST fv);
461
462 Py_DECREF(tmp);
463 return res;
464 }
465
466
467
468 #ifdef Py_USING_UNICODE
469 static PyObject *
470 unicode_FromTclStringAndSize(const char *s, Py_ssize_t size)
471 {
472 PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL);
473 if (!r && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
474 /* Tcl encodes null character as \xc0\x80 */
475 if (memchr(s, '\xc0', size)) {
476 char *buf, *q;
477 const char *e = s + size;
478 PyErr_Clear();
479 q = buf = (char *)PyMem_Malloc(size);
480 if (buf == NULL) {
481 PyErr_NoMemory();
482 return NULL;
483 }
484 while (s != e) {
485 if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') {
486 *q++ = '\0';
487 s += 2;
488 }
489 else
490 *q++ = *s++;
491 }
492 s = buf;
493 size = q - s;
494 r = PyUnicode_DecodeUTF8(s, size, NULL);
495 PyMem_Free(buf);
496 }
497 }
498 return r;
499 }
500 #endif
501
502 static PyObject *
503 fromTclStringAndSize(const char *s, Py_ssize_t size)
504 {
505 PyObject *r;
506 #ifdef Py_USING_UNICODE
507 Py_ssize_t i;
508 /* If Tcl string contains any bytes with the top bit set,
509 it's UTF-8 and we should decode it to Unicode */
510 for (i = 0; i < size; i++)
511 if (s[i] & 0x80)
512 break;
513 if (i != size) {
514 /* It isn't an ASCII string. */
515 r = unicode_FromTclStringAndSize(s, size);
516 if (r)
517 return r;
518 PyErr_Clear();
519 }
520 #endif
521 r = PyString_FromStringAndSize(s, size);
522 return r;
523 }
524
525 static PyObject *
526 fromTclString(const char *s)
527 {
528 return fromTclStringAndSize(s, strlen(s));
529 }
343 530
344 531
345 static PyObject * 532 static PyObject *
346 Split(char *list) 533 Split(char *list)
347 { 534 {
348 int argc; 535 int argc;
349 char **argv; 536 char **argv;
350 PyObject *v; 537 PyObject *v;
351 538
352 if (list == NULL) { 539 if (list == NULL) {
353 Py_RETURN_NONE; 540 Py_INCREF(Py_None);
541 return Py_None;
354 } 542 }
355 543
356 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { 544 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
357 /* Not a list. 545 /* Not a list.
358 * Could be a quoted string containing funnies, e.g. {"}. 546 * Could be a quoted string containing funnies, e.g. {"}.
359 * Return the string itself. 547 * Return the string itself.
360 */ 548 */
361 return PyUnicode_FromString(list); 549 return PyString_FromString(list);
362 } 550 }
363 551
364 if (argc == 0) 552 if (argc == 0)
365 v = PyUnicode_FromString(""); 553 v = PyString_FromString("");
366 else if (argc == 1) 554 else if (argc == 1)
367 v = PyUnicode_FromString(argv[0]); 555 v = PyString_FromString(argv[0]);
368 else if ((v = PyTuple_New(argc)) != NULL) { 556 else if ((v = PyTuple_New(argc)) != NULL) {
369 int i; 557 int i;
370 PyObject *w; 558 PyObject *w;
371 559
372 for (i = 0; i < argc; i++) { 560 for (i = 0; i < argc; i++) {
373 if ((w = Split(argv[i])) == NULL) { 561 if ((w = Split(argv[i])) == NULL) {
374 Py_DECREF(v); 562 Py_DECREF(v);
375 v = NULL; 563 v = NULL;
376 break; 564 break;
377 } 565 }
378 PyTuple_SetItem(v, i, w); 566 PyTuple_SetItem(v, i, w);
379 } 567 }
380 } 568 }
381 Tcl_Free(FREECAST argv); 569 Tcl_Free(FREECAST argv);
382 return v; 570 return v;
383 } 571 }
384 572
385 /* In some cases, Tcl will still return strings that are supposed to 573 /* In some cases, Tcl will still return strings that are supposed to be
386 be lists. SplitObj walks through a nested tuple, finding string 574 lists. SplitObj walks through a nested tuple, finding string objects that
387 objects that need to be split. */ 575 need to be split. */
388 576
389 static PyObject * 577 static PyObject *
390 SplitObj(PyObject *arg) 578 SplitObj(PyObject *arg)
391 { 579 {
392 if (PyTuple_Check(arg)) { 580 if (PyTuple_Check(arg)) {
393 int i, size; 581 int i, size;
394 PyObject *elem, *newelem, *result; 582 PyObject *elem, *newelem, *result;
395 583
396 size = PyTuple_Size(arg); 584 size = PyTuple_Size(arg);
397 result = NULL; 585 result = NULL;
(...skipping 21 matching lines...) Expand all
419 Py_INCREF(elem); 607 Py_INCREF(elem);
420 PyTuple_SetItem(result, k, elem); 608 PyTuple_SetItem(result, k, elem);
421 } 609 }
422 } 610 }
423 PyTuple_SetItem(result, i, newelem); 611 PyTuple_SetItem(result, i, newelem);
424 } 612 }
425 if (result) 613 if (result)
426 return result; 614 return result;
427 /* Fall through, returning arg. */ 615 /* Fall through, returning arg. */
428 } 616 }
429 else if (PyBytes_Check(arg)) { 617 else if (PyString_Check(arg)) {
430 int argc; 618 int argc;
431 char **argv; 619 char **argv;
432 char *list = PyBytes_AsString(arg); 620 char *list = PyString_AsString(arg);
433 621
434 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { 622 if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
435 Py_INCREF(arg); 623 Py_INCREF(arg);
436 return arg; 624 return arg;
437 } 625 }
438 Tcl_Free(FREECAST argv); 626 Tcl_Free(FREECAST argv);
439 if (argc > 1) 627 if (argc > 1)
440 return Split(PyBytes_AsString(arg)); 628 return Split(PyString_AsString(arg));
629 /* Fall through, returning arg. */
630 }
631 else if (PyUnicode_Check(arg)) {
632 int argc;
633 char **argv;
634 char *list;
635 PyObject *s = PyUnicode_AsUTF8String(arg);
636
637 if (s == NULL) {
638 Py_INCREF(arg);
639 return arg;
640 }
641 list = PyString_AsString(s);
642
643 if (list == NULL ||
644 Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
645 Py_DECREF(s);
646 Py_INCREF(arg);
647 return arg;
648 }
649 Tcl_Free(FREECAST argv);
650 if (argc > 1) {
651 PyObject *v = Split(list);
652 Py_DECREF(s);
653 return v;
654 }
655 Py_DECREF(s);
441 /* Fall through, returning arg. */ 656 /* Fall through, returning arg. */
442 } 657 }
443 Py_INCREF(arg); 658 Py_INCREF(arg);
444 return arg; 659 return arg;
445 } 660 }
446 661
447 662
448 /**** Tkapp Object ****/ 663 /**** Tkapp Object ****/
449 664
450 #ifndef WITH_APPINIT 665 #ifndef WITH_APPINIT
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 703
489 704
490 /* Initialize the Tk application; see the `main' function in 705 /* Initialize the Tk application; see the `main' function in
491 * `tkMain.c'. 706 * `tkMain.c'.
492 */ 707 */
493 708
494 static void EnableEventHook(void); /* Forward */ 709 static void EnableEventHook(void); /* Forward */
495 static void DisableEventHook(void); /* Forward */ 710 static void DisableEventHook(void); /* Forward */
496 711
497 static TkappObject * 712 static TkappObject *
498 Tkapp_New(char *screenName, char *className, 713 Tkapp_New(char *screenName, char *baseName, char *className,
499 int interactive, int wantobjects, int wantTk, int sync, char *use) 714 int interactive, int wantobjects, int wantTk, int sync, char *use)
500 { 715 {
501 TkappObject *v; 716 TkappObject *v;
502 char *argv0; 717 char *argv0;
503 718
504 v = PyObject_New(TkappObject, (PyTypeObject *) Tkapp_Type); 719 v = PyObject_New(TkappObject, &Tkapp_Type);
505 if (v == NULL) 720 if (v == NULL)
506 return NULL; 721 return NULL;
507 722
508 v->interp = Tcl_CreateInterp(); 723 v->interp = Tcl_CreateInterp();
509 v->wantobjects = wantobjects; 724 v->wantobjects = wantobjects;
510 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded", 725 v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
511 TCL_GLOBAL_ONLY) != NULL; 726 TCL_GLOBAL_ONLY) != NULL;
512 v->thread_id = Tcl_GetCurrentThread(); 727 v->thread_id = Tcl_GetCurrentThread();
513 v->dispatching = 0; 728 v->dispatching = 0;
514 729
515 #ifndef TCL_THREADS 730 #ifndef TCL_THREADS
516 if (v->threaded) { 731 if (v->threaded) {
517 PyErr_SetString(PyExc_RuntimeError, 732 PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not ");
518 "Tcl is threaded but _tkinter is not");
519 Py_DECREF(v); 733 Py_DECREF(v);
520 return 0; 734 return 0;
521 } 735 }
522 #endif 736 #endif
523 #ifdef WITH_THREAD 737 #ifdef WITH_THREAD
524 if (v->threaded && tcl_lock) { 738 if (v->threaded && tcl_lock) {
525 /* If Tcl is threaded, we don't need the lock. */ 739 /* If Tcl is threaded, we don't need the lock. */
526 PyThread_free_lock(tcl_lock); 740 PyThread_free_lock(tcl_lock);
527 tcl_lock = NULL; 741 tcl_lock = NULL;
528 } 742 }
529 #endif 743 #endif
530 744
531 v->BooleanType = Tcl_GetObjType("boolean"); 745 v->OldBooleanType = Tcl_GetObjType("boolean");
746 v->BooleanType = Tcl_GetObjType("booleanString");
532 v->ByteArrayType = Tcl_GetObjType("bytearray"); 747 v->ByteArrayType = Tcl_GetObjType("bytearray");
533 v->DoubleType = Tcl_GetObjType("double"); 748 v->DoubleType = Tcl_GetObjType("double");
534 v->IntType = Tcl_GetObjType("int"); 749 v->IntType = Tcl_GetObjType("int");
535 v->WideIntType = Tcl_GetObjType("wideInt"); 750 v->WideIntType = Tcl_GetObjType("wideInt");
536 v->BignumType = Tcl_GetObjType("bignum"); 751 v->BignumType = Tcl_GetObjType("bignum");
537 v->ListType = Tcl_GetObjType("list"); 752 v->ListType = Tcl_GetObjType("list");
538 v->ProcBodyType = Tcl_GetObjType("procbody"); 753 v->ProcBodyType = Tcl_GetObjType("procbody");
539 v->StringType = Tcl_GetObjType("string"); 754 v->StringType = Tcl_GetObjType("string");
540 755
541 /* Delete the 'exit' command, which can screw things up */ 756 /* Delete the 'exit' command, which can screw things up */
542 Tcl_DeleteCommand(v->interp, "exit"); 757 Tcl_DeleteCommand(v->interp, "exit");
543 758
544 if (screenName != NULL) 759 if (screenName != NULL)
545 Tcl_SetVar2(v->interp, "env", "DISPLAY", 760 Tcl_SetVar2(v->interp, "env", "DISPLAY",
546 screenName, TCL_GLOBAL_ONLY); 761 screenName, TCL_GLOBAL_ONLY);
547 762
548 if (interactive) 763 if (interactive)
549 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY); 764 Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
550 else 765 else
551 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); 766 Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
552 767
553 /* This is used to get the application class for Tk 4.1 and up */ 768 /* This is used to get the application class for Tk 4.1 and up */
554 argv0 = (char*)ckalloc(strlen(className) + 1); 769 argv0 = (char*)attemptckalloc(strlen(className) + 1);
555 if (!argv0) { 770 if (!argv0) {
556 PyErr_NoMemory(); 771 PyErr_NoMemory();
557 Py_DECREF(v); 772 Py_DECREF(v);
558 return NULL; 773 return NULL;
559 } 774 }
560 775
561 strcpy(argv0, className); 776 strcpy(argv0, className);
562 if (Py_ISUPPER(Py_CHARMASK(argv0[0]))) 777 if (Py_ISUPPER(Py_CHARMASK(argv0[0])))
563 argv0[0] = Py_TOLOWER(Py_CHARMASK(argv0[0])); 778 argv0[0] = Py_TOLOWER(Py_CHARMASK(argv0[0]));
564 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY); 779 Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
(...skipping 13 matching lines...) Expand all
578 /* some initial arguments need to be in argv */ 793 /* some initial arguments need to be in argv */
579 if (sync || use) { 794 if (sync || use) {
580 char *args; 795 char *args;
581 int len = 0; 796 int len = 0;
582 797
583 if (sync) 798 if (sync)
584 len += sizeof "-sync"; 799 len += sizeof "-sync";
585 if (use) 800 if (use)
586 len += strlen(use) + sizeof "-use "; 801 len += strlen(use) + sizeof "-use ";
587 802
588 args = (char*)ckalloc(len); 803 args = (char*)attemptckalloc(len);
589 if (!args) { 804 if (!args) {
590 PyErr_NoMemory(); 805 PyErr_NoMemory();
591 Py_DECREF(v); 806 Py_DECREF(v);
592 return NULL; 807 return NULL;
593 } 808 }
594 809
595 args[0] = '\0'; 810 args[0] = '\0';
596 if (sync) 811 if (sync)
597 strcat(args, "-sync"); 812 strcat(args, "-sync");
598 if (use) { 813 if (use) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 862
648 863
649 /** Tcl Eval **/ 864 /** Tcl Eval **/
650 865
651 typedef struct { 866 typedef struct {
652 PyObject_HEAD 867 PyObject_HEAD
653 Tcl_Obj *value; 868 Tcl_Obj *value;
654 PyObject *string; /* This cannot cause cycles. */ 869 PyObject *string; /* This cannot cause cycles. */
655 } PyTclObject; 870 } PyTclObject;
656 871
657 static PyObject *PyTclObject_Type; 872 staticforward PyTypeObject PyTclObject_Type;
658 #define PyTclObject_Check(v) ((v)->ob_type == (PyTypeObject *) PyTclObject_Type) 873 #define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type)
659 874
660 static PyObject * 875 static PyObject *
661 newPyTclObject(Tcl_Obj *arg) 876 newPyTclObject(Tcl_Obj *arg)
662 { 877 {
663 PyTclObject *self; 878 PyTclObject *self;
664 self = PyObject_New(PyTclObject, (PyTypeObject *) PyTclObject_Type); 879 self = PyObject_New(PyTclObject, &PyTclObject_Type);
665 if (self == NULL) 880 if (self == NULL)
666 return NULL; 881 return NULL;
667 Tcl_IncrRefCount(arg); 882 Tcl_IncrRefCount(arg);
668 self->value = arg; 883 self->value = arg;
669 self->string = NULL; 884 self->string = NULL;
670 return (PyObject*)self; 885 return (PyObject*)self;
671 } 886 }
672 887
673 static void 888 static void
674 PyTclObject_dealloc(PyTclObject *self) 889 PyTclObject_dealloc(PyTclObject *self)
675 { 890 {
676 Tcl_DecrRefCount(self->value); 891 Tcl_DecrRefCount(self->value);
677 Py_XDECREF(self->string); 892 Py_XDECREF(self->string);
678 PyObject_Del(self); 893 PyObject_Del(self);
679 } 894 }
680 895
896 static PyObject *
897 PyTclObject_str(PyTclObject *self)
898 {
899 if (self->string && PyString_Check(self->string)) {
900 Py_INCREF(self->string);
901 return self->string;
902 }
903 /* XXX Could cache value if it is an ASCII string. */
904 return PyString_FromString(Tcl_GetString(self->value));
905 }
906
681 static char* 907 static char*
682 PyTclObject_TclString(PyObject *self) 908 PyTclObject_TclString(PyObject *self)
683 { 909 {
684 return Tcl_GetString(((PyTclObject*)self)->value); 910 return Tcl_GetString(((PyTclObject*)self)->value);
685 } 911 }
686 912
687 /* Like _str, but create Unicode if necessary. */ 913 /* Like _str, but create Unicode if necessary. */
688 PyDoc_STRVAR(PyTclObject_string__doc__, 914 PyDoc_STRVAR(PyTclObject_string__doc__,
689 "the string representation of this object, either as str or bytes"); 915 "the string representation of this object, either as string or Unicode");
690 916
691 static PyObject * 917 static PyObject *
692 PyTclObject_string(PyTclObject *self, void *ignored) 918 PyTclObject_string(PyTclObject *self, void *ignored)
693 { 919 {
694 char *s;
695 int len;
696 if (!self->string) { 920 if (!self->string) {
697 s = Tcl_GetStringFromObj(self->value, &len); 921 int len;
698 self->string = PyUnicode_FromStringAndSize(s, len); 922 char *s = Tcl_GetStringFromObj(self->value, &len);
923 self->string = fromTclStringAndSize(s, len);
699 if (!self->string) 924 if (!self->string)
700 return NULL; 925 return NULL;
701 } 926 }
702 Py_INCREF(self->string); 927 Py_INCREF(self->string);
703 return self->string; 928 return self->string;
704 } 929 }
705 930
706 static PyObject * 931 #ifdef Py_USING_UNICODE
707 PyTclObject_str(PyTclObject *self, void *ignored) 932 PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode");
933
934 static PyObject *
935 PyTclObject_unicode(PyTclObject *self, void *ignored)
708 { 936 {
709 char *s; 937 char *s;
710 int len; 938 int len;
711 if (self->string && PyUnicode_Check(self->string)) { 939 if (self->string && PyUnicode_Check(self->string)) {
712 Py_INCREF(self->string); 940 Py_INCREF(self->string);
713 return self->string; 941 return self->string;
714 } 942 }
715 /* XXX Could chache result if it is non-ASCII. */ 943 /* XXX Could chache result if it is non-ASCII. */
716 s = Tcl_GetStringFromObj(self->value, &len); 944 s = Tcl_GetStringFromObj(self->value, &len);
717 return PyUnicode_DecodeUTF8(s, len, "strict"); 945 return unicode_FromTclStringAndSize(s, len);
718 } 946 }
947 #endif
719 948
720 static PyObject * 949 static PyObject *
721 PyTclObject_repr(PyTclObject *self) 950 PyTclObject_repr(PyTclObject *self)
722 { 951 {
723 return PyUnicode_FromFormat("<%s object at %p>", 952 char buf[50];
724 self->value->typePtr->name, self->value); 953 PyOS_snprintf(buf, 50, "<%s object at %p>",
725 } 954 self->value->typePtr->name, self->value);
726 955 return PyString_FromString(buf);
727 #define TEST_COND(cond) ((cond) ? Py_True : Py_False) 956 }
728 957
729 static PyObject * 958 static int
730 PyTclObject_richcompare(PyObject *self, PyObject *other, int op) 959 PyTclObject_cmp(PyTclObject *self, PyTclObject *other)
731 { 960 {
732 int result; 961 int res;
733 PyObject *v; 962 res = strcmp(Tcl_GetString(self->value),
734 963 Tcl_GetString(other->value));
735 /* neither argument should be NULL, unless something's gone wrong */ 964 if (res < 0) return -1;
736 if (self == NULL || other == NULL) { 965 if (res > 0) return 1;
737 PyErr_BadInternalCall(); 966 return 0;
738 return NULL;
739 }
740
741 /* both arguments should be instances of PyTclObject */
742 if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) {
743 v = Py_NotImplemented;
744 goto finished;
745 }
746
747 if (self == other)
748 /* fast path when self and other are identical */
749 result = 0;
750 else
751 result = strcmp(Tcl_GetString(((PyTclObject *)self)->value),
752 Tcl_GetString(((PyTclObject *)other)->value));
753 /* Convert return value to a Boolean */
754 switch (op) {
755 case Py_EQ:
756 v = TEST_COND(result == 0);
757 break;
758 case Py_NE:
759 v = TEST_COND(result != 0);
760 break;
761 case Py_LE:
762 v = TEST_COND(result <= 0);
763 break;
764 case Py_GE:
765 v = TEST_COND(result >= 0);
766 break;
767 case Py_LT:
768 v = TEST_COND(result < 0);
769 break;
770 case Py_GT:
771 v = TEST_COND(result > 0);
772 break;
773 default:
774 PyErr_BadArgument();
775 return NULL;
776 }
777 finished:
778 Py_INCREF(v);
779 return v;
780 } 967 }
781 968
782 PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type"); 969 PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type");
783 970
784 static PyObject* 971 static PyObject*
785 get_typename(PyTclObject* obj, void* ignored) 972 get_typename(PyTclObject* obj, void* ignored)
786 { 973 {
787 return PyUnicode_FromString(obj->value->typePtr->name); 974 return PyString_FromString(obj->value->typePtr->name);
788 } 975 }
789 976
790 977
791 static PyGetSetDef PyTclObject_getsetlist[] = { 978 static PyGetSetDef PyTclObject_getsetlist[] = {
792 {"typename", (getter)get_typename, NULL, get_typename__doc__}, 979 {"typename", (getter)get_typename, NULL, get_typename__doc__},
793 {"string", (getter)PyTclObject_string, NULL, 980 {"string", (getter)PyTclObject_string, NULL,
794 PyTclObject_string__doc__}, 981 PyTclObject_string__doc__},
795 {0}, 982 {0},
796 }; 983 };
797 984
798 static PyType_Slot PyTclObject_Type_slots[] = { 985 static PyMethodDef PyTclObject_methods[] = {
799 {Py_tp_dealloc, (destructor)PyTclObject_dealloc}, 986 #ifdef Py_USING_UNICODE
800 {Py_tp_repr, (reprfunc)PyTclObject_repr}, 987 {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS,
801 {Py_tp_str, (reprfunc)PyTclObject_str}, 988 PyTclObject_unicode__doc__},
802 {Py_tp_getattro, PyObject_GenericGetAttr}, 989 #endif
803 {Py_tp_richcompare, PyTclObject_richcompare}, 990 {0}
804 {Py_tp_getset, PyTclObject_getsetlist},
805 {0, 0}
806 }; 991 };
807 992
808 static PyType_Spec PyTclObject_Type_spec = { 993 statichere PyTypeObject PyTclObject_Type = {
809 "_tkinter.Tcl_Obj", 994 PyObject_HEAD_INIT(NULL)
810 sizeof(PyTclObject), 995 0, /*ob_size*/
811 0, 996 "_tkinter.Tcl_Obj", /*tp_name*/
812 Py_TPFLAGS_DEFAULT, 997 sizeof(PyTclObject), /*tp_basicsize*/
813 PyTclObject_Type_slots, 998 0, /*tp_itemsize*/
999 /* methods */
1000 (destructor)PyTclObject_dealloc, /*tp_dealloc*/
1001 0, /*tp_print*/
1002 0, /*tp_getattr*/
1003 0, /*tp_setattr*/
1004 (cmpfunc)PyTclObject_cmp, /*tp_compare*/
1005 (reprfunc)PyTclObject_repr, /*tp_repr*/
1006 0, /*tp_as_number*/
1007 0, /*tp_as_sequence*/
1008 0, /*tp_as_mapping*/
1009 0, /*tp_hash*/
1010 0, /*tp_call*/
1011 (reprfunc)PyTclObject_str, /*tp_str*/
1012 PyObject_GenericGetAttr,/*tp_getattro*/
1013 0, /*tp_setattro*/
1014 0, /*tp_as_buffer*/
1015 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1016 0, /*tp_doc*/
1017 0, /*tp_traverse*/
1018 0, /*tp_clear*/
1019 0, /*tp_richcompare*/
1020 0, /*tp_weaklistoffset*/
1021 0, /*tp_iter*/
1022 0, /*tp_iternext*/
1023 PyTclObject_methods, /*tp_methods*/
1024 0, /*tp_members*/
1025 PyTclObject_getsetlist, /*tp_getset*/
1026 0, /*tp_base*/
1027 0, /*tp_dict*/
1028 0, /*tp_descr_get*/
1029 0, /*tp_descr_set*/
1030 0, /*tp_dictoffset*/
1031 0, /*tp_init*/
1032 0, /*tp_alloc*/
1033 0, /*tp_new*/
1034 0, /*tp_free*/
1035 0, /*tp_is_gc*/
814 }; 1036 };
815 1037
1038 #if PY_SIZE_MAX > INT_MAX
1039 #define CHECK_STRING_LENGTH(s) do { \
1040 if (s != NULL && strlen(s) >= INT_MAX) { \
1041 PyErr_SetString(PyExc_OverflowError, "string is too long"); \
1042 return NULL; \
1043 } } while(0)
1044 #else
1045 #define CHECK_STRING_LENGTH(s)
1046 #endif
1047
1048 #ifdef HAVE_LIBTOMMAMTH
1049 static Tcl_Obj*
1050 asBignumObj(PyObject *value)
1051 {
1052 Tcl_Obj *result;
1053 int neg;
1054 PyObject *hexstr;
1055 char *hexchars;
1056 mp_int bigValue;
1057
1058 neg = Py_SIZE(value) < 0;
1059 hexstr = _PyLong_Format(value, 16, 0, 1);
1060 if (hexstr == NULL)
1061 return NULL;
1062 hexchars = PyString_AsString(hexstr);
1063 if (hexchars == NULL) {
1064 Py_DECREF(hexstr);
1065 return NULL;
1066 }
1067 hexchars += neg + 2; /* skip sign and "0x" */
1068 mp_init(&bigValue);
1069 if (mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) {
1070 mp_clear(&bigValue);
1071 Py_DECREF(hexstr);
1072 PyErr_NoMemory();
1073 return NULL;
1074 }
1075 Py_DECREF(hexstr);
1076 bigValue.sign = neg ? MP_NEG : MP_ZPOS;
1077 result = Tcl_NewBignumObj(&bigValue);
1078 mp_clear(&bigValue);
1079 if (result == NULL) {
1080 PyErr_NoMemory();
1081 return NULL;
1082 }
1083 return result;
1084 }
1085 #endif
816 1086
817 static Tcl_Obj* 1087 static Tcl_Obj*
818 AsObj(PyObject *value) 1088 AsObj(PyObject *value)
819 { 1089 {
820 Tcl_Obj *result; 1090 Tcl_Obj *result;
821 1091
822 if (PyBytes_Check(value)) 1092 if (PyString_Check(value))
823 return Tcl_NewStringObj(PyBytes_AS_STRING(value), 1093 return Tcl_NewStringObj(PyString_AS_STRING(value),
824 PyBytes_GET_SIZE(value)); 1094 PyString_GET_SIZE(value));
1095
825 if (PyBool_Check(value)) 1096 if (PyBool_Check(value))
826 return Tcl_NewBooleanObj(PyObject_IsTrue(value)); 1097 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
1098
1099 if (PyInt_Check(value))
1100 return Tcl_NewLongObj(PyInt_AS_LONG(value));
827 1101
828 if (PyLong_CheckExact(value)) { 1102 if (PyLong_CheckExact(value)) {
829 int overflow; 1103 int overflow;
830 long longValue; 1104 long longValue;
831 #ifdef HAVE_LONG_LONG 1105 #ifdef TCL_WIDE_INT_TYPE
832 PY_LONG_LONG wideValue; 1106 Tcl_WideInt wideValue;
833 #endif 1107 #endif
834 int neg;
835 PyObject *hexstr;
836 char *hexchars;
837 mp_int bigValue;
838
839 longValue = PyLong_AsLongAndOverflow(value, &overflow); 1108 longValue = PyLong_AsLongAndOverflow(value, &overflow);
840 if (!overflow) { 1109 if (!overflow) {
841 /* If there is an overflow in the long conversion,
842 fall through to wideInt handling. */
843 return Tcl_NewLongObj(longValue); 1110 return Tcl_NewLongObj(longValue);
844 } 1111 }
845 1112 /* If there is an overflow in the long conversion,
846 #ifdef HAVE_LONG_LONG 1113 fall through to wideInt handling. */
847 wideValue = PyLong_AsLongLongAndOverflow(value, &overflow); 1114 #ifdef TCL_WIDE_INT_TYPE
848 if (!overflow) { 1115 if (_PyLong_AsByteArray((PyLongObject *)value,
849 /* If there is an overflow in the wideInt conversion, 1116 (unsigned char *)(void *)&wideValue,
850 fall through to bignum handling. */ 1117 sizeof(wideValue),
1118 #ifdef WORDS_BIGENDIAN
1119 0,
1120 #else
1121 1,
1122 #endif
1123 /* signed */ 1) == 0) {
851 return Tcl_NewWideIntObj(wideValue); 1124 return Tcl_NewWideIntObj(wideValue);
852 } 1125 }
853 #endif 1126 PyErr_Clear();
854 1127 #endif
855 neg = Py_SIZE(value) < 0; 1128 /* If there is an overflow in the wideInt conversion,
856 hexstr = _PyLong_Format(value, 16); 1129 fall through to bignum handling. */
857 if (hexstr == NULL) 1130 #ifdef HAVE_LIBTOMMAMTH
858 return NULL; 1131 return asBignumObj(value);
859 hexchars = PyUnicode_AsUTF8(hexstr); 1132 #endif
860 if (hexchars == NULL) { 1133 /* If there is no wideInt or bignum support,
861 Py_DECREF(hexstr); 1134 fall through to default object handling. */
862 return NULL;
863 }
864 hexchars += neg + 2; /* skip sign and "0x" */
865 mp_init(&bigValue);
866 if (mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) {
867 mp_clear(&bigValue);
868 Py_DECREF(hexstr);
869 PyErr_NoMemory();
870 return NULL;
871 }
872 Py_DECREF(hexstr);
873 bigValue.sign = neg ? MP_NEG : MP_ZPOS;
874 result = Tcl_NewBignumObj(&bigValue);
875 mp_clear(&bigValue);
876 if (result == NULL) {
877 PyErr_NoMemory();
878 return NULL;
879 }
880 return result;
881 } 1135 }
882 1136
883 if (PyFloat_Check(value)) 1137 if (PyFloat_Check(value))
884 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); 1138 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
1139
885 if (PyTuple_Check(value)) { 1140 if (PyTuple_Check(value)) {
886 Tcl_Obj **argv = (Tcl_Obj**) 1141 Tcl_Obj **argv;
887 ckalloc(PyTuple_Size(value)*sizeof(Tcl_Obj*)); 1142 Py_ssize_t size, i;
888 int i; 1143
1144 size = PyTuple_Size(value);
1145 if (size == 0)
1146 return Tcl_NewListObj(0, NULL);
1147 if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) {
1148 PyErr_SetString(PyExc_OverflowError, "tuple is too long");
1149 return NULL;
1150 }
1151 argv = (Tcl_Obj **) attemptckalloc(((size_t)size) * sizeof(Tcl_Obj *));
889 if(!argv) 1152 if(!argv)
890 return 0; 1153 return 0;
891 for(i=0;i<PyTuple_Size(value);i++) 1154 for (i = 0; i < size; i++)
892 argv[i] = AsObj(PyTuple_GetItem(value,i)); 1155 argv[i] = AsObj(PyTuple_GetItem(value,i));
893 result = Tcl_NewListObj(PyTuple_Size(value), argv); 1156 result = Tcl_NewListObj(PyTuple_Size(value), argv);
894 ckfree(FREECAST argv); 1157 ckfree(FREECAST argv);
895 return result; 1158 return result;
896 } 1159 }
1160
1161 #ifdef Py_USING_UNICODE
897 if (PyUnicode_Check(value)) { 1162 if (PyUnicode_Check(value)) {
898 void *inbuf; 1163 Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value);
899 Py_ssize_t size; 1164 Py_ssize_t size = PyUnicode_GET_SIZE(value);
900 int kind; 1165 /* This #ifdef assumes that Tcl uses UCS-2.
1166 See TCL_UTF_MAX test above. */
1167 #if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3
901 Tcl_UniChar *outbuf = NULL; 1168 Tcl_UniChar *outbuf = NULL;
902 Py_ssize_t i; 1169 Py_ssize_t i;
903 size_t allocsize; 1170 size_t allocsize;
904 1171 if (size == 0)
905 if (PyUnicode_READY(value) == -1) 1172 return Tcl_NewUnicodeObj((const void *)"", 0);
1173 if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) {
1174 PyErr_SetString(PyExc_OverflowError, "string is too long");
906 return NULL; 1175 return NULL;
907 1176 }
908 inbuf = PyUnicode_DATA(value); 1177 if (sizeof(Py_UNICODE) == sizeof(Tcl_UniChar))
909 size = PyUnicode_GET_LENGTH(value); 1178 return Tcl_NewUnicodeObj(inbuf, size);
910 kind = PyUnicode_KIND(value);
911 allocsize = ((size_t)size) * sizeof(Tcl_UniChar); 1179 allocsize = ((size_t)size) * sizeof(Tcl_UniChar);
912 outbuf = (Tcl_UniChar*)ckalloc(allocsize); 1180 if (allocsize >= size)
1181 outbuf = (Tcl_UniChar*)attemptckalloc(allocsize);
913 /* Else overflow occurred, and we take the next exit */ 1182 /* Else overflow occurred, and we take the next exit */
914 if (!outbuf) { 1183 if (!outbuf) {
915 PyErr_NoMemory(); 1184 PyErr_NoMemory();
916 return NULL; 1185 return NULL;
917 } 1186 }
918 for (i = 0; i < size; i++) { 1187 for (i = 0; i < size; i++) {
919 Py_UCS4 ch = PyUnicode_READ(kind, inbuf, i); 1188 if (inbuf[i] >= 0x10000) {
920 /* We cannot test for sizeof(Tcl_UniChar) directly,
921 so we test for UTF-8 size instead. */
922 #if TCL_UTF_MAX == 3
923 if (ch >= 0x10000) {
924 /* Tcl doesn't do UTF-16, yet. */ 1189 /* Tcl doesn't do UTF-16, yet. */
925 PyErr_Format(PyExc_ValueError, 1190 PyErr_Format(Tkinter_TclError,
926 "character U+%x is above the range " 1191 "character U+%x is above the range "
927 "(U+0000-U+FFFF) allowed by Tcl", 1192 "(U+0000-U+FFFF) allowed by Tcl",
928 ch); 1193 (int)inbuf[i]);
929 ckfree(FREECAST outbuf); 1194 ckfree(FREECAST outbuf);
930 return NULL; 1195 return NULL;
931 } 1196 }
932 #endif 1197 outbuf[i] = inbuf[i];
933 outbuf[i] = ch;
934 } 1198 }
935 result = Tcl_NewUnicodeObj(outbuf, size); 1199 result = Tcl_NewUnicodeObj(outbuf, size);
936 ckfree(FREECAST outbuf); 1200 ckfree(FREECAST outbuf);
937 return result; 1201 return result;
938 } 1202 #else
1203 return Tcl_NewUnicodeObj(inbuf, size);
1204 #endif
1205 }
1206 #endif
1207
939 if(PyTclObject_Check(value)) { 1208 if(PyTclObject_Check(value)) {
940 Tcl_Obj *v = ((PyTclObject*)value)->value; 1209 Tcl_Obj *v = ((PyTclObject*)value)->value;
941 Tcl_IncrRefCount(v); 1210 Tcl_IncrRefCount(v);
942 return v; 1211 return v;
943 } 1212 }
1213
944 { 1214 {
945 PyObject *v = PyObject_Str(value); 1215 PyObject *v = PyObject_Str(value);
946 if (!v) 1216 if (!v)
947 return 0; 1217 return 0;
948 result = AsObj(v); 1218 result = AsObj(v);
949 Py_DECREF(v); 1219 Py_DECREF(v);
950 return result; 1220 return result;
951 } 1221 }
952 } 1222 }
953 1223
1224 static PyObject *
1225 fromBoolean(PyObject* tkapp, Tcl_Obj *value)
1226 {
1227 int boolValue;
1228 if (Tcl_GetBooleanFromObj(Tkapp_Interp(tkapp), value, &boolValue) == TCL_ERR OR)
1229 return Tkinter_Error(tkapp);
1230 return PyBool_FromLong(boolValue);
1231 }
1232
1233 #ifdef TCL_WIDE_INT_TYPE
1234 static PyObject*
1235 fromWideIntObj(PyObject* tkapp, Tcl_Obj *value)
1236 {
1237 Tcl_WideInt wideValue;
1238 if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL _OK) {
1239 #ifdef HAVE_LONG_LONG
1240 if (sizeof(wideValue) <= SIZEOF_LONG_LONG)
1241 return PyLong_FromLongLong(wideValue);
1242 #endif
1243 return _PyLong_FromByteArray((unsigned char *)(void *)&wideValue,
1244 sizeof(wideValue),
1245 #ifdef WORDS_BIGENDIAN
1246 0,
1247 #else
1248 1,
1249 #endif
1250 /* signed */ 1);
1251 }
1252 return NULL;
1253 }
1254 #endif
1255
1256 #ifdef HAVE_LIBTOMMAMTH
1257 static PyObject*
1258 fromBignumObj(PyObject* tkapp, Tcl_Obj *value)
1259 {
1260 mp_int bigValue;
1261 unsigned long numBytes;
1262 unsigned char *bytes;
1263 PyObject *res;
1264
1265 if (Tcl_GetBignumFromObj(Tkapp_Interp(tkapp), value, &bigValue) != TCL_OK)
1266 return Tkinter_Error(tkapp);
1267 numBytes = mp_unsigned_bin_size(&bigValue);
1268 bytes = PyMem_Malloc(numBytes);
1269 if (bytes == NULL) {
1270 mp_clear(&bigValue);
1271 return PyErr_NoMemory();
1272 }
1273 if (mp_to_unsigned_bin_n(&bigValue, bytes,
1274 &numBytes) != MP_OKAY) {
1275 mp_clear(&bigValue);
1276 PyMem_Free(bytes);
1277 return PyErr_NoMemory();
1278 }
1279 res = _PyLong_FromByteArray(bytes, numBytes,
1280 /* big-endian */ 0,
1281 /* unsigned */ 0);
1282 PyMem_Free(bytes);
1283 if (res != NULL && bigValue.sign == MP_NEG) {
1284 PyObject *res2 = PyNumber_Negative(res);
1285 Py_DECREF(res);
1286 res = res2;
1287 }
1288 mp_clear(&bigValue);
1289 return res;
1290 }
1291 #endif
1292
954 static PyObject* 1293 static PyObject*
955 FromObj(PyObject* tkapp, Tcl_Obj *value) 1294 FromObj(PyObject* tkapp, Tcl_Obj *value)
956 { 1295 {
957 PyObject *result = NULL; 1296 PyObject *result = NULL;
958 TkappObject *app = (TkappObject*)tkapp; 1297 TkappObject *app = (TkappObject*)tkapp;
959 Tcl_Interp *interp = Tkapp_Interp(tkapp); 1298 Tcl_Interp *interp = Tkapp_Interp(tkapp);
960 1299
961 if (value->typePtr == NULL) { 1300 if (value->typePtr == NULL) {
962 return PyUnicode_FromStringAndSize(value->bytes, 1301 result = fromTclStringAndSize(value->bytes, value->length);
963 value->length);
964 }
965
966 if (value->typePtr == app->BooleanType) {
967 result = value->internalRep.longValue ? Py_True : Py_False;
968 Py_INCREF(result);
969 return result; 1302 return result;
1303 }
1304
1305 if (value->typePtr == app->BooleanType ||
1306 value->typePtr == app->OldBooleanType) {
1307 return fromBoolean(tkapp, value);
970 } 1308 }
971 1309
972 if (value->typePtr == app->ByteArrayType) { 1310 if (value->typePtr == app->ByteArrayType) {
973 int size; 1311 int size;
974 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); 1312 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
975 return PyBytes_FromStringAndSize(data, size); 1313 return PyString_FromStringAndSize(data, size);
976 } 1314 }
977 1315
978 if (value->typePtr == app->DoubleType) { 1316 if (value->typePtr == app->DoubleType) {
979 return PyFloat_FromDouble(value->internalRep.doubleValue); 1317 return PyFloat_FromDouble(value->internalRep.doubleValue);
980 } 1318 }
981 1319
982 if (value->typePtr == app->IntType) { 1320 if (value->typePtr == app->IntType) {
983 long longValue; 1321 long longValue;
984 if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK) 1322 if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK)
985 return PyLong_FromLong(longValue); 1323 return PyInt_FromLong(longValue);
986 /* If there is an error in the long conversion, 1324 /* If there is an error in the long conversion,
987 fall through to wideInt handling. */ 1325 fall through to wideInt handling. */
988 } 1326 }
989 1327
990 #ifdef HAVE_LONG_LONG 1328 #ifdef TCL_WIDE_INT_TYPE
991 if (value->typePtr == app->IntType || 1329 if (value->typePtr == app->IntType ||
992 value->typePtr == app->WideIntType) { 1330 value->typePtr == app->WideIntType) {
993 Tcl_WideInt wideValue; 1331 result = fromWideIntObj(tkapp, value);
994 if (Tcl_GetWideIntFromObj(interp, value, &wideValue) == TCL_OK) 1332 if (result != NULL || PyErr_Occurred())
995 return PyLong_FromLongLong(wideValue); 1333 return result;
1334 Tcl_ResetResult(interp);
996 /* If there is an error in the wideInt conversion, 1335 /* If there is an error in the wideInt conversion,
997 fall through to bignum handling. */ 1336 fall through to bignum handling. */
998 } 1337 }
999 #endif 1338 #endif
1000 1339
1340 #ifdef HAVE_LIBTOMMAMTH
1001 if (value->typePtr == app->IntType || 1341 if (value->typePtr == app->IntType ||
1002 value->typePtr == app->WideIntType || 1342 value->typePtr == app->WideIntType ||
1003 value->typePtr == app->BignumType || 1343 value->typePtr == app->BignumType) {
1004 (app->BignumType == NULL && 1344 return fromBignumObj(tkapp, value);
1005 strcmp(value->typePtr->name, "bignum") == 0)) { 1345 }
1006 mp_int bigValue; 1346 #endif
1007 /* bignum type is not registered in Tcl */
1008 if (app->BignumType == NULL &&
1009 strcmp(value->typePtr->name, "bignum") == 0) {
1010 app->BignumType = value->typePtr;
1011 }
1012 if (Tcl_GetBignumFromObj(interp, value, &bigValue) == TCL_OK) {
1013 unsigned long numBytes = mp_unsigned_bin_size(&bigValue);
1014 unsigned char *bytes = PyMem_Malloc(numBytes);
1015 PyObject *res;
1016 if (bytes == NULL) {
1017 mp_clear(&bigValue);
1018 return NULL;
1019 }
1020 if (mp_to_unsigned_bin_n(&bigValue, bytes,
1021 &numBytes) != MP_OKAY) {
1022 mp_clear(&bigValue);
1023 PyMem_Free(bytes);
1024 return PyErr_NoMemory();
1025 }
1026 res = _PyLong_FromByteArray(bytes, numBytes,
1027 /* big-endian */ 0,
1028 /* unsigned */ 0);
1029 PyMem_Free(bytes);
1030 if (res != NULL && bigValue.sign == MP_NEG) {
1031 PyObject *res2 = PyNumber_Negative(res);
1032 Py_DECREF(res);
1033 res = res2;
1034 }
1035 mp_clear(&bigValue);
1036 return res;
1037 }
1038 return Tkinter_Error(tkapp);
1039 }
1040 1347
1041 if (value->typePtr == app->ListType) { 1348 if (value->typePtr == app->ListType) {
1042 int size; 1349 int size;
1043 int i, status; 1350 int i, status;
1044 PyObject *elem; 1351 PyObject *elem;
1045 Tcl_Obj *tcl_elem; 1352 Tcl_Obj *tcl_elem;
1046 1353
1047 status = Tcl_ListObjLength(interp, value, &size); 1354 status = Tcl_ListObjLength(interp, value, &size);
1048 if (status == TCL_ERROR) 1355 if (status == TCL_ERROR)
1049 return Tkinter_Error(tkapp); 1356 return Tkinter_Error(tkapp);
(...skipping 14 matching lines...) Expand all
1064 PyTuple_SetItem(result, i, elem); 1371 PyTuple_SetItem(result, i, elem);
1065 } 1372 }
1066 return result; 1373 return result;
1067 } 1374 }
1068 1375
1069 if (value->typePtr == app->ProcBodyType) { 1376 if (value->typePtr == app->ProcBodyType) {
1070 /* fall through: return tcl object. */ 1377 /* fall through: return tcl object. */
1071 } 1378 }
1072 1379
1073 if (value->typePtr == app->StringType) { 1380 if (value->typePtr == app->StringType) {
1074 #if TCL_UTF_MAX==3 1381 #ifdef Py_USING_UNICODE
1075 return PyUnicode_FromKindAndData( 1382 #if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3
1076 PyUnicode_2BYTE_KIND, Tcl_GetUnicode(value), 1383 PyObject *result;
1077 Tcl_GetCharLength(value)); 1384 int size;
1385 Tcl_UniChar *input;
1386 Py_UNICODE *output;
1387
1388 size = Tcl_GetCharLength(value);
1389 result = PyUnicode_FromUnicode(NULL, size);
1390 if (!result)
1391 return NULL;
1392 input = Tcl_GetUnicode(value);
1393 output = PyUnicode_AS_UNICODE(result);
1394 while (size--)
1395 *output++ = *input++;
1396 return result;
1078 #else 1397 #else
1079 return PyUnicode_FromKindAndData( 1398 return PyUnicode_FromUnicode(Tcl_GetUnicode(value),
1080 PyUnicode_4BYTE_KIND, Tcl_GetUnicode(value), 1399 Tcl_GetCharLength(value));
1081 Tcl_GetCharLength(value)); 1400 #endif
1082 #endif 1401 #else
1083 } 1402 int size;
1403 char *c;
1404 c = Tcl_GetStringFromObj(value, &size);
1405 return PyString_FromStringAndSize(c, size);
1406 #endif
1407 }
1408
1409 #if TK_HEX_VERSION >= 0x08050000
1410 if (app->BooleanType == NULL &&
1411 strcmp(value->typePtr->name, "booleanString") == 0) {
1412 /* booleanString type is not registered in Tcl */
1413 app->BooleanType = value->typePtr;
1414 return fromBoolean(tkapp, value);
1415 }
1416 #endif
1417
1418 #ifdef HAVE_LIBTOMMAMTH
1419 if (app->BignumType == NULL &&
1420 strcmp(value->typePtr->name, "bignum") == 0) {
1421 /* bignum type is not registered in Tcl */
1422 app->BignumType = value->typePtr;
1423 return fromBignumObj(tkapp, value);
1424 }
1425 #endif
1084 1426
1085 return newPyTclObject(value); 1427 return newPyTclObject(value);
1086 } 1428 }
1087 1429
1088 #ifdef WITH_THREAD 1430 #ifdef WITH_THREAD
1089 /* This mutex synchronizes inter-thread command calls. */ 1431 /* This mutex synchronizes inter-thread command calls. */
1090 TCL_DECLARE_MUTEX(call_mutex) 1432 TCL_DECLARE_MUTEX(call_mutex)
1091 1433
1092 typedef struct Tkapp_CallEvent { 1434 typedef struct Tkapp_CallEvent {
1093 Tcl_Event ev; /* Must be first */ 1435 Tcl_Event ev; /* Must be first */
(...skipping 16 matching lines...) Expand all
1110 ckfree(FREECAST objv); 1452 ckfree(FREECAST objv);
1111 } 1453 }
1112 1454
1113 /* Convert Python objects to Tcl objects. This must happen in the 1455 /* Convert Python objects to Tcl objects. This must happen in the
1114 interpreter thread, which may or may not be the calling thread. */ 1456 interpreter thread, which may or may not be the calling thread. */
1115 1457
1116 static Tcl_Obj** 1458 static Tcl_Obj**
1117 Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) 1459 Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
1118 { 1460 {
1119 Tcl_Obj **objv = objStore; 1461 Tcl_Obj **objv = objStore;
1120 int objc = 0, i; 1462 Py_ssize_t objc = 0, i;
1121 if (args == NULL) 1463 if (args == NULL)
1122 /* do nothing */; 1464 /* do nothing */;
1123 1465
1124 else if (!PyTuple_Check(args)) { 1466 else if (!PyTuple_Check(args)) {
1125 objv[0] = AsObj(args); 1467 objv[0] = AsObj(args);
1126 if (objv[0] == 0) 1468 if (objv[0] == 0)
1127 goto finally; 1469 goto finally;
1128 objc = 1; 1470 objc = 1;
1129 Tcl_IncrRefCount(objv[0]); 1471 Tcl_IncrRefCount(objv[0]);
1130 } 1472 }
1131 else { 1473 else {
1132 objc = PyTuple_Size(args); 1474 objc = PyTuple_Size(args);
1133 1475
1134 if (objc > ARGSZ) { 1476 if (objc > ARGSZ) {
1135 objv = (Tcl_Obj **)ckalloc(objc * sizeof(char *)); 1477 if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) {
1478 PyErr_SetString(PyExc_OverflowError, "tuple is too long");
1479 return NULL;
1480 }
1481 objv = (Tcl_Obj **)attemptckalloc(((size_t)objc) * sizeof(Tcl_Obj *) );
1136 if (objv == NULL) { 1482 if (objv == NULL) {
1137 PyErr_NoMemory(); 1483 PyErr_NoMemory();
1138 objc = 0; 1484 objc = 0;
1139 goto finally; 1485 goto finally;
1140 } 1486 }
1141 } 1487 }
1142 1488
1143 for (i = 0; i < objc; i++) { 1489 for (i = 0; i < objc; i++) {
1144 PyObject *v = PyTuple_GetItem(args, i); 1490 PyObject *v = PyTuple_GetItem(args, i);
1145 if (v == Py_None) { 1491 if (v == Py_None) {
(...skipping 16 matching lines...) Expand all
1162 Tkapp_CallDeallocArgs(objv, objStore, objc); 1508 Tkapp_CallDeallocArgs(objv, objStore, objc);
1163 return NULL; 1509 return NULL;
1164 } 1510 }
1165 1511
1166 /* Convert the results of a command call into a Python objects. */ 1512 /* Convert the results of a command call into a Python objects. */
1167 1513
1168 static PyObject* 1514 static PyObject*
1169 Tkapp_CallResult(TkappObject *self) 1515 Tkapp_CallResult(TkappObject *self)
1170 { 1516 {
1171 PyObject *res = NULL; 1517 PyObject *res = NULL;
1518 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
1172 if(self->wantobjects) { 1519 if(self->wantobjects) {
1173 Tcl_Obj *value = Tcl_GetObjResult(self->interp);
1174 /* Not sure whether the IncrRef is necessary, but something 1520 /* Not sure whether the IncrRef is necessary, but something
1175 may overwrite the interpreter result while we are 1521 may overwrite the interpreter result while we are
1176 converting it. */ 1522 converting it. */
1177 Tcl_IncrRefCount(value); 1523 Tcl_IncrRefCount(value);
1178 res = FromObj((PyObject*)self, value); 1524 res = FromObj((PyObject*)self, value);
1179 Tcl_DecrRefCount(value); 1525 Tcl_DecrRefCount(value);
1180 } else { 1526 } else {
1181 const char *s = Tcl_GetStringResult(self->interp); 1527 int len;
1182 const char *p = s; 1528 const char *s = Tcl_GetStringFromObj(value, &len);
1183 1529 res = fromTclStringAndSize(s, len);
1184 res = PyUnicode_FromStringAndSize(s, (int)(p-s));
1185 } 1530 }
1186 return res; 1531 return res;
1187 } 1532 }
1188 1533
1189 #ifdef WITH_THREAD 1534 #ifdef WITH_THREAD
1190 1535
1191 /* Tkapp_CallProc is the event procedure that is executed in the context of 1536 /* Tkapp_CallProc is the event procedure that is executed in the context of
1192 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't 1537 the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't
1193 hold the Python lock. */ 1538 hold the Python lock. */
1194 1539
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 } 1609 }
1265 #ifdef WITH_THREAD 1610 #ifdef WITH_THREAD
1266 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { 1611 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
1267 /* We cannot call the command directly. Instead, we must 1612 /* We cannot call the command directly. Instead, we must
1268 marshal the parameters to the interpreter thread. */ 1613 marshal the parameters to the interpreter thread. */
1269 Tkapp_CallEvent *ev; 1614 Tkapp_CallEvent *ev;
1270 Tcl_Condition cond = NULL; 1615 Tcl_Condition cond = NULL;
1271 PyObject *exc_type, *exc_value, *exc_tb; 1616 PyObject *exc_type, *exc_value, *exc_tb;
1272 if (!WaitForMainloop(self)) 1617 if (!WaitForMainloop(self))
1273 return NULL; 1618 return NULL;
1274 ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent)); 1619 ev = (Tkapp_CallEvent*)attemptckalloc(sizeof(Tkapp_CallEvent));
1620 if (ev == NULL) {
1621 PyErr_NoMemory();
1622 return NULL;
1623 }
1275 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc; 1624 ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
1276 ev->self = self; 1625 ev->self = self;
1277 ev->args = args; 1626 ev->args = args;
1278 ev->res = &res; 1627 ev->res = &res;
1279 ev->exc_type = &exc_type; 1628 ev->exc_type = &exc_type;
1280 ev->exc_value = &exc_value; 1629 ev->exc_value = &exc_value;
1281 ev->exc_tb = &exc_tb; 1630 ev->exc_tb = &exc_tb;
1282 ev->done = &cond; 1631 ev->done = &cond;
1283 1632
1284 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex); 1633 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
(...skipping 27 matching lines...) Expand all
1312 1661
1313 LEAVE_OVERLAP_TCL 1662 LEAVE_OVERLAP_TCL
1314 1663
1315 Tkapp_CallDeallocArgs(objv, objStore, objc); 1664 Tkapp_CallDeallocArgs(objv, objStore, objc);
1316 } 1665 }
1317 return res; 1666 return res;
1318 } 1667 }
1319 1668
1320 1669
1321 static PyObject * 1670 static PyObject *
1671 Tkapp_GlobalCall(PyObject *self, PyObject *args)
1672 {
1673 /* Could do the same here as for Tkapp_Call(), but this is not used
1674 much, so I can't be bothered. Unfortunately Tcl doesn't export a
1675 way for the user to do what all its Global* variants do (save and
1676 reset the scope pointer, call the local version, restore the saved
1677 scope pointer). */
1678
1679 char *cmd;
1680 PyObject *res = NULL;
1681
1682 CHECK_TCL_APPARTMENT;
1683
1684 cmd = Merge(args);
1685 if (cmd) {
1686 int err;
1687 ENTER_TCL
1688 err = Tcl_GlobalEval(Tkapp_Interp(self), cmd);
1689 ENTER_OVERLAP
1690 if (err == TCL_ERROR)
1691 res = Tkinter_Error(self);
1692 else
1693 res = PyString_FromString(Tkapp_Result(self));
1694 LEAVE_OVERLAP_TCL
1695 ckfree(cmd);
1696 }
1697
1698 return res;
1699 }
1700
1701 static PyObject *
1322 Tkapp_Eval(PyObject *self, PyObject *args) 1702 Tkapp_Eval(PyObject *self, PyObject *args)
1323 { 1703 {
1324 char *script; 1704 char *script;
1325 PyObject *res = NULL; 1705 PyObject *res = NULL;
1326 int err; 1706 int err;
1327 1707
1328 if (!PyArg_ParseTuple(args, "s:eval", &script)) 1708 if (!PyArg_ParseTuple(args, "s:eval", &script))
1329 return NULL; 1709 return NULL;
1330 1710
1711 CHECK_STRING_LENGTH(script);
1331 CHECK_TCL_APPARTMENT; 1712 CHECK_TCL_APPARTMENT;
1332 1713
1333 ENTER_TCL 1714 ENTER_TCL
1334 err = Tcl_Eval(Tkapp_Interp(self), script); 1715 err = Tcl_Eval(Tkapp_Interp(self), script);
1335 ENTER_OVERLAP 1716 ENTER_OVERLAP
1336 if (err == TCL_ERROR) 1717 if (err == TCL_ERROR)
1337 res = Tkinter_Error(self); 1718 res = Tkinter_Error(self);
1338 else 1719 else
1339 res = PyUnicode_FromString(Tkapp_Result(self)); 1720 res = PyString_FromString(Tkapp_Result(self));
1721 LEAVE_OVERLAP_TCL
1722 return res;
1723 }
1724
1725 static PyObject *
1726 Tkapp_GlobalEval(PyObject *self, PyObject *args)
1727 {
1728 char *script;
1729 PyObject *res = NULL;
1730 int err;
1731
1732 if (!PyArg_ParseTuple(args, "s:globaleval", &script))
1733 return NULL;
1734
1735 CHECK_TCL_APPARTMENT;
1736
1737 ENTER_TCL
1738 err = Tcl_GlobalEval(Tkapp_Interp(self), script);
1739 ENTER_OVERLAP
1740 if (err == TCL_ERROR)
1741 res = Tkinter_Error(self);
1742 else
1743 res = PyString_FromString(Tkapp_Result(self));
1340 LEAVE_OVERLAP_TCL 1744 LEAVE_OVERLAP_TCL
1341 return res; 1745 return res;
1342 } 1746 }
1343 1747
1344 static PyObject * 1748 static PyObject *
1345 Tkapp_EvalFile(PyObject *self, PyObject *args) 1749 Tkapp_EvalFile(PyObject *self, PyObject *args)
1346 { 1750 {
1347 char *fileName; 1751 char *fileName;
1348 PyObject *res = NULL; 1752 PyObject *res = NULL;
1349 int err; 1753 int err;
1350 1754
1351 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName)) 1755 if (!PyArg_ParseTuple(args, "s:evalfile", &fileName))
1352 return NULL; 1756 return NULL;
1353 1757
1758 CHECK_STRING_LENGTH(fileName);
1354 CHECK_TCL_APPARTMENT; 1759 CHECK_TCL_APPARTMENT;
1355 1760
1356 ENTER_TCL 1761 ENTER_TCL
1357 err = Tcl_EvalFile(Tkapp_Interp(self), fileName); 1762 err = Tcl_EvalFile(Tkapp_Interp(self), fileName);
1358 ENTER_OVERLAP 1763 ENTER_OVERLAP
1359 if (err == TCL_ERROR) 1764 if (err == TCL_ERROR)
1360 res = Tkinter_Error(self); 1765 res = Tkinter_Error(self);
1361 1766
1362 else 1767 else
1363 res = PyUnicode_FromString(Tkapp_Result(self)); 1768 res = PyString_FromString(Tkapp_Result(self));
1364 LEAVE_OVERLAP_TCL 1769 LEAVE_OVERLAP_TCL
1365 return res; 1770 return res;
1366 } 1771 }
1367 1772
1368 static PyObject * 1773 static PyObject *
1369 Tkapp_Record(PyObject *self, PyObject *args) 1774 Tkapp_Record(PyObject *self, PyObject *args)
1370 { 1775 {
1371 char *script; 1776 char *script;
1372 PyObject *res = NULL; 1777 PyObject *res = NULL;
1373 int err; 1778 int err;
1374 1779
1375 if (!PyArg_ParseTuple(args, "s", &script)) 1780 if (!PyArg_ParseTuple(args, "s:record", &script))
1376 return NULL; 1781 return NULL;
1377 1782
1783 CHECK_STRING_LENGTH(script);
1378 CHECK_TCL_APPARTMENT; 1784 CHECK_TCL_APPARTMENT;
1379 1785
1380 ENTER_TCL 1786 ENTER_TCL
1381 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL); 1787 err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL);
1382 ENTER_OVERLAP 1788 ENTER_OVERLAP
1383 if (err == TCL_ERROR) 1789 if (err == TCL_ERROR)
1384 res = Tkinter_Error(self); 1790 res = Tkinter_Error(self);
1385 else 1791 else
1386 res = PyUnicode_FromString(Tkapp_Result(self)); 1792 res = PyString_FromString(Tkapp_Result(self));
1387 LEAVE_OVERLAP_TCL 1793 LEAVE_OVERLAP_TCL
1388 return res; 1794 return res;
1389 } 1795 }
1390 1796
1391 static PyObject * 1797 static PyObject *
1392 Tkapp_AddErrorInfo(PyObject *self, PyObject *args) 1798 Tkapp_AddErrorInfo(PyObject *self, PyObject *args)
1393 { 1799 {
1394 char *msg; 1800 char *msg;
1395 1801
1396 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg)) 1802 if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg))
1397 return NULL; 1803 return NULL;
1804 CHECK_STRING_LENGTH(msg);
1398 CHECK_TCL_APPARTMENT; 1805 CHECK_TCL_APPARTMENT;
1399 1806
1400 ENTER_TCL 1807 ENTER_TCL
1401 Tcl_AddErrorInfo(Tkapp_Interp(self), msg); 1808 Tcl_AddErrorInfo(Tkapp_Interp(self), msg);
1402 LEAVE_TCL 1809 LEAVE_TCL
1403 1810
1404 Py_RETURN_NONE; 1811 Py_INCREF(Py_None);
1812 return Py_None;
1405 } 1813 }
1406 1814
1407 1815
1408 1816
1409 /** Tcl Variable **/ 1817 /** Tcl Variable **/
1410 1818
1411 typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags); 1819 typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags);
1412 1820
1413 #ifdef WITH_THREAD 1821 #ifdef WITH_THREAD
1414 TCL_DECLARE_MUTEX(var_mutex) 1822 TCL_DECLARE_MUTEX(var_mutex)
1415 1823
1416 typedef struct VarEvent { 1824 typedef struct VarEvent {
1417 Tcl_Event ev; /* must be first */ 1825 Tcl_Event ev; /* must be first */
1418 PyObject *self; 1826 PyObject *self;
1419 PyObject *args; 1827 PyObject *args;
1420 int flags; 1828 int flags;
1421 EventFunc func; 1829 EventFunc func;
1422 PyObject **res; 1830 PyObject **res;
1423 PyObject **exc_type; 1831 PyObject **exc_type;
1424 PyObject **exc_val; 1832 PyObject **exc_val;
1425 Tcl_Condition *cond; 1833 Tcl_Condition *cond;
1426 } VarEvent; 1834 } VarEvent;
1427 #endif 1835 #endif
1428 1836
1429 static int 1837 static int
1430 varname_converter(PyObject *in, void *_out) 1838 varname_converter(PyObject *in, void *_out)
1431 { 1839 {
1840 char *s;
1432 char **out = (char**)_out; 1841 char **out = (char**)_out;
1433 if (PyBytes_Check(in)) { 1842 if (PyString_Check(in)) {
1434 *out = PyBytes_AsString(in); 1843 if (PyString_Size(in) > INT_MAX) {
1435 return 1; 1844 PyErr_SetString(PyExc_OverflowError, "string is too long");
1436 } 1845 return 0;
1437 if (PyUnicode_Check(in)) { 1846 }
1438 *out = _PyUnicode_AsString(in); 1847 s = PyString_AsString(in);
1848 if (strlen(s) != PyString_Size(in)) {
1849 PyErr_SetString(PyExc_ValueError, "null character in string");
1850 return 0;
1851 }
1852 *out = s;
1439 return 1; 1853 return 1;
1440 } 1854 }
1441 if (PyTclObject_Check(in)) { 1855 if (PyTclObject_Check(in)) {
1442 *out = PyTclObject_TclString(in); 1856 *out = PyTclObject_TclString(in);
1443 return 1; 1857 return 1;
1444 } 1858 }
1445 /* XXX: Should give diagnostics. */ 1859 PyErr_Format(PyExc_TypeError,
1860 "must be str or Tcl_Obj, not %.50s",
1861 in->ob_type->tp_name);
1446 return 0; 1862 return 0;
1447 } 1863 }
1448 1864
1449 #ifdef WITH_THREAD 1865 #ifdef WITH_THREAD
1450 1866
1451 static void 1867 static void
1452 var_perform(VarEvent *ev) 1868 var_perform(VarEvent *ev)
1453 { 1869 {
1454 *(ev->res) = ev->func(ev->self, ev->args, ev->flags); 1870 *(ev->res) = ev->func(ev->self, ev->args, ev->flags);
1455 if (!*(ev->res)) { 1871 if (!*(ev->res)) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 VarEvent *ev; 1903 VarEvent *ev;
1488 PyObject *res, *exc_type, *exc_val; 1904 PyObject *res, *exc_type, *exc_val;
1489 Tcl_Condition cond = NULL; 1905 Tcl_Condition cond = NULL;
1490 1906
1491 /* The current thread is not the interpreter thread. Marshal 1907 /* The current thread is not the interpreter thread. Marshal
1492 the call to the interpreter thread, then wait for 1908 the call to the interpreter thread, then wait for
1493 completion. */ 1909 completion. */
1494 if (!WaitForMainloop(self)) 1910 if (!WaitForMainloop(self))
1495 return NULL; 1911 return NULL;
1496 1912
1497 ev = (VarEvent*)ckalloc(sizeof(VarEvent)); 1913 ev = (VarEvent*)attemptckalloc(sizeof(VarEvent));
1498 1914 if (ev == NULL) {
1915 PyErr_NoMemory();
1916 return NULL;
1917 }
1499 ev->self = selfptr; 1918 ev->self = selfptr;
1500 ev->args = args; 1919 ev->args = args;
1501 ev->flags = flags; 1920 ev->flags = flags;
1502 ev->func = func; 1921 ev->func = func;
1503 ev->res = &res; 1922 ev->res = &res;
1504 ev->exc_type = &exc_type; 1923 ev->exc_type = &exc_type;
1505 ev->exc_val = &exc_val; 1924 ev->exc_val = &exc_val;
1506 ev->cond = &cond; 1925 ev->cond = &cond;
1507 ev->ev.proc = (Tcl_EventProc*)var_proc; 1926 ev->ev.proc = (Tcl_EventProc*)var_proc;
1508 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex); 1927 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
(...skipping 12 matching lines...) Expand all
1521 } 1940 }
1522 1941
1523 static PyObject * 1942 static PyObject *
1524 SetVar(PyObject *self, PyObject *args, int flags) 1943 SetVar(PyObject *self, PyObject *args, int flags)
1525 { 1944 {
1526 char *name1, *name2; 1945 char *name1, *name2;
1527 PyObject *newValue; 1946 PyObject *newValue;
1528 PyObject *res = NULL; 1947 PyObject *res = NULL;
1529 Tcl_Obj *newval, *ok; 1948 Tcl_Obj *newval, *ok;
1530 1949
1531 if (PyArg_ParseTuple(args, "O&O:setvar", 1950 switch (PyTuple_GET_SIZE(args)) {
1532 varname_converter, &name1, &newValue)) { 1951 case 2:
1952 if (!PyArg_ParseTuple(args, "O&O:setvar",
1953 varname_converter, &name1, &newValue))
1954 return NULL;
1533 /* XXX Acquire tcl lock??? */ 1955 /* XXX Acquire tcl lock??? */
1534 newval = AsObj(newValue); 1956 newval = AsObj(newValue);
1535 if (newval == NULL) 1957 if (newval == NULL)
1536 return NULL; 1958 return NULL;
1537 ENTER_TCL 1959 ENTER_TCL
1538 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL, 1960 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL,
1539 newval, flags); 1961 newval, flags);
1540 ENTER_OVERLAP 1962 ENTER_OVERLAP
1541 if (!ok) 1963 if (!ok)
1542 Tkinter_Error(self); 1964 Tkinter_Error(self);
1543 else { 1965 else {
1544 res = Py_None; 1966 res = Py_None;
1545 Py_INCREF(res); 1967 Py_INCREF(res);
1546 } 1968 }
1547 LEAVE_OVERLAP_TCL 1969 LEAVE_OVERLAP_TCL
1548 } 1970 break;
1549 else { 1971 case 3:
1550 PyErr_Clear(); 1972 if (!PyArg_ParseTuple(args, "ssO:setvar",
1551 if (PyArg_ParseTuple(args, "ssO:setvar", 1973 &name1, &name2, &newValue))
1552 &name1, &name2, &newValue)) { 1974 return NULL;
1553 /* XXX must hold tcl lock already??? */ 1975 CHECK_STRING_LENGTH(name1);
1554 newval = AsObj(newValue); 1976 CHECK_STRING_LENGTH(name2);
1555 ENTER_TCL 1977 /* XXX must hold tcl lock already??? */
1556 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags); 1978 newval = AsObj(newValue);
1557 ENTER_OVERLAP 1979 ENTER_TCL
1558 if (!ok) 1980 ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags);
1559 Tkinter_Error(self); 1981 ENTER_OVERLAP
1560 else { 1982 if (!ok)
1561 res = Py_None; 1983 Tkinter_Error(self);
1562 Py_INCREF(res);
1563 }
1564 LEAVE_OVERLAP_TCL
1565 }
1566 else { 1984 else {
1567 return NULL; 1985 res = Py_None;
1568 } 1986 Py_INCREF(res);
1987 }
1988 LEAVE_OVERLAP_TCL
1989 break;
1990 default:
1991 PyErr_SetString(PyExc_TypeError, "setvar requires 2 to 3 arguments");
1992 return NULL;
1569 } 1993 }
1570 return res; 1994 return res;
1571 } 1995 }
1572 1996
1573 static PyObject * 1997 static PyObject *
1574 Tkapp_SetVar(PyObject *self, PyObject *args) 1998 Tkapp_SetVar(PyObject *self, PyObject *args)
1575 { 1999 {
1576 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG); 2000 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG);
1577 } 2001 }
1578 2002
1579 static PyObject * 2003 static PyObject *
1580 Tkapp_GlobalSetVar(PyObject *self, PyObject *args) 2004 Tkapp_GlobalSetVar(PyObject *self, PyObject *args)
1581 { 2005 {
1582 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); 2006 return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
1583 } 2007 }
1584 2008
1585 2009
1586 2010
1587 static PyObject * 2011 static PyObject *
1588 GetVar(PyObject *self, PyObject *args, int flags) 2012 GetVar(PyObject *self, PyObject *args, int flags)
1589 { 2013 {
1590 char *name1, *name2=NULL; 2014 char *name1, *name2=NULL;
1591 PyObject *res = NULL; 2015 PyObject *res = NULL;
1592 Tcl_Obj *tres; 2016 Tcl_Obj *tres;
1593 2017
1594 if (!PyArg_ParseTuple(args, "O&|s:getvar", 2018 if (!PyArg_ParseTuple(args, "O&|s:getvar",
1595 varname_converter, &name1, &name2)) 2019 varname_converter, &name1, &name2))
1596 return NULL; 2020 return NULL;
1597 2021
2022 CHECK_STRING_LENGTH(name2);
1598 ENTER_TCL 2023 ENTER_TCL
1599 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags); 2024 tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags);
1600 ENTER_OVERLAP 2025 ENTER_OVERLAP
1601 if (tres == NULL) { 2026 if (tres == NULL) {
1602 PyErr_SetString(Tkinter_TclError, 2027 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self) ));
1603 Tcl_GetStringResult(Tkapp_Interp(self)));
1604 } else { 2028 } else {
1605 if (((TkappObject*)self)->wantobjects) { 2029 if (((TkappObject*)self)->wantobjects) {
1606 res = FromObj(self, tres); 2030 res = FromObj(self, tres);
1607 } 2031 }
1608 else { 2032 else {
1609 res = PyUnicode_FromString(Tcl_GetString(tres)); 2033 int len;
2034 char *s = Tcl_GetStringFromObj(tres, &len);
2035 res = PyString_FromStringAndSize(s, len);
1610 } 2036 }
1611 } 2037 }
1612 LEAVE_OVERLAP_TCL 2038 LEAVE_OVERLAP_TCL
1613 return res; 2039 return res;
1614 } 2040 }
1615 2041
1616 static PyObject * 2042 static PyObject *
1617 Tkapp_GetVar(PyObject *self, PyObject *args) 2043 Tkapp_GetVar(PyObject *self, PyObject *args)
1618 { 2044 {
1619 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG); 2045 return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG);
(...skipping 10 matching lines...) Expand all
1630 static PyObject * 2056 static PyObject *
1631 UnsetVar(PyObject *self, PyObject *args, int flags) 2057 UnsetVar(PyObject *self, PyObject *args, int flags)
1632 { 2058 {
1633 char *name1, *name2=NULL; 2059 char *name1, *name2=NULL;
1634 int code; 2060 int code;
1635 PyObject *res = NULL; 2061 PyObject *res = NULL;
1636 2062
1637 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2)) 2063 if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2))
1638 return NULL; 2064 return NULL;
1639 2065
2066 CHECK_STRING_LENGTH(name1);
2067 CHECK_STRING_LENGTH(name2);
1640 ENTER_TCL 2068 ENTER_TCL
1641 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags); 2069 code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags);
1642 ENTER_OVERLAP 2070 ENTER_OVERLAP
1643 if (code == TCL_ERROR) 2071 if (code == TCL_ERROR)
1644 res = Tkinter_Error(self); 2072 res = Tkinter_Error(self);
1645 else { 2073 else {
1646 Py_INCREF(Py_None); 2074 Py_INCREF(Py_None);
1647 res = Py_None; 2075 res = Py_None;
1648 } 2076 }
1649 LEAVE_OVERLAP_TCL 2077 LEAVE_OVERLAP_TCL
1650 return res; 2078 return res;
1651 } 2079 }
1652 2080
1653 static PyObject * 2081 static PyObject *
1654 Tkapp_UnsetVar(PyObject *self, PyObject *args) 2082 Tkapp_UnsetVar(PyObject *self, PyObject *args)
1655 { 2083 {
1656 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG); 2084 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG);
1657 } 2085 }
1658 2086
1659 static PyObject * 2087 static PyObject *
1660 Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args) 2088 Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args)
1661 { 2089 {
1662 return var_invoke(UnsetVar, self, args, 2090 return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY) ;
1663 TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
1664 } 2091 }
1665 2092
1666 2093
1667 2094
1668 /** Tcl to Python **/ 2095 /** Tcl to Python **/
1669 2096
1670 static PyObject * 2097 static PyObject *
1671 Tkapp_GetInt(PyObject *self, PyObject *args) 2098 Tkapp_GetInt(PyObject *self, PyObject *args)
1672 { 2099 {
1673 char *s; 2100 char *s;
1674 int v; 2101 #if defined(TCL_WIDE_INT_TYPE) || defined(HAVE_LIBTOMMAMTH)
2102 Tcl_Obj *value;
2103 PyObject *result;
2104 #else
2105 int intValue;
2106 #endif
1675 2107
1676 if (PyTuple_Size(args) == 1) { 2108 if (PyTuple_Size(args) == 1) {
1677 PyObject* o = PyTuple_GetItem(args, 0); 2109 PyObject* o = PyTuple_GetItem(args, 0);
1678 if (PyLong_Check(o)) { 2110 if (PyInt_Check(o) || PyLong_Check(o)) {
1679 Py_INCREF(o); 2111 Py_INCREF(o);
1680 return o; 2112 return o;
1681 } 2113 }
1682 } 2114 }
1683 if (!PyArg_ParseTuple(args, "s:getint", &s)) 2115 if (!PyArg_ParseTuple(args, "s:getint", &s))
1684 return NULL; 2116 return NULL;
1685 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR) 2117 CHECK_STRING_LENGTH(s);
2118 #if defined(TCL_WIDE_INT_TYPE) || defined(HAVE_LIBTOMMAMTH)
2119 value = Tcl_NewStringObj(s, -1);
2120 if (value == NULL)
1686 return Tkinter_Error(self); 2121 return Tkinter_Error(self);
1687 return Py_BuildValue("i", v); 2122 /* Don't use Tcl_GetInt() because it returns ambiguous result for value
2123 in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform).
2124
2125 Prefer bignum because Tcl_GetWideIntFromObj returns ambiguous result for
2126 value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform).
2127 */
2128 #ifdef HAVE_LIBTOMMAMTH
2129 result = fromBignumObj(self, value);
2130 #else
2131 result = fromWideIntObj(self, value);
2132 #endif
2133 Tcl_DecrRefCount(value);
2134 if (result != NULL)
2135 return PyNumber_Int(result);
2136 if (PyErr_Occurred())
2137 return NULL;
2138 #else
2139 if (Tcl_GetInt(Tkapp_Interp(self), s, &intValue) == TCL_OK)
2140 return PyInt_FromLong(intValue);
2141 #endif
2142 return Tkinter_Error(self);
1688 } 2143 }
1689 2144
1690 static PyObject * 2145 static PyObject *
1691 Tkapp_GetDouble(PyObject *self, PyObject *args) 2146 Tkapp_GetDouble(PyObject *self, PyObject *args)
1692 { 2147 {
1693 char *s; 2148 char *s;
1694 double v; 2149 double v;
1695 2150
1696 if (PyTuple_Size(args) == 1) { 2151 if (PyTuple_Size(args) == 1) {
1697 PyObject *o = PyTuple_GetItem(args, 0); 2152 PyObject *o = PyTuple_GetItem(args, 0);
1698 if (PyFloat_Check(o)) { 2153 if (PyFloat_Check(o)) {
1699 Py_INCREF(o); 2154 Py_INCREF(o);
1700 return o; 2155 return o;
1701 } 2156 }
1702 } 2157 }
1703 if (!PyArg_ParseTuple(args, "s:getdouble", &s)) 2158 if (!PyArg_ParseTuple(args, "s:getdouble", &s))
1704 return NULL; 2159 return NULL;
2160 CHECK_STRING_LENGTH(s);
1705 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR) 2161 if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1706 return Tkinter_Error(self); 2162 return Tkinter_Error(self);
1707 return Py_BuildValue("d", v); 2163 return Py_BuildValue("d", v);
1708 } 2164 }
1709 2165
1710 static PyObject * 2166 static PyObject *
1711 Tkapp_GetBoolean(PyObject *self, PyObject *args) 2167 Tkapp_GetBoolean(PyObject *self, PyObject *arg)
1712 { 2168 {
1713 char *s; 2169 char *s;
1714 int v; 2170 int v;
1715 2171
1716 if (PyTuple_Size(args) == 1) { 2172 if (PyInt_Check(arg)) /* int or bool */
1717 PyObject *o = PyTuple_GetItem(args, 0); 2173 return PyBool_FromLong(PyInt_AS_LONG(arg));
1718 if (PyLong_Check(o)) { 2174
1719 Py_INCREF(o); 2175 if (PyLong_Check(arg))
1720 return o; 2176 return PyBool_FromLong(Py_SIZE(arg) != 0);
1721 } 2177
1722 } 2178 if (PyTclObject_Check(arg)) {
1723 if (!PyArg_ParseTuple(args, "s:getboolean", &s)) 2179 if (Tcl_GetBooleanFromObj(Tkapp_Interp(self),
1724 return NULL; 2180 ((PyTclObject*)arg)->value,
2181 &v) == TCL_ERROR)
2182 return Tkinter_Error(self);
2183 return PyBool_FromLong(v);
2184 }
2185
2186 if (!PyArg_Parse(arg, "s:getboolean", &s))
2187 return NULL;
2188 CHECK_STRING_LENGTH(s);
1725 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR) 2189 if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
1726 return Tkinter_Error(self); 2190 return Tkinter_Error(self);
1727 return PyBool_FromLong(v); 2191 return PyBool_FromLong(v);
1728 } 2192 }
1729 2193
1730 static PyObject * 2194 static PyObject *
1731 Tkapp_ExprString(PyObject *self, PyObject *args) 2195 Tkapp_ExprString(PyObject *self, PyObject *args)
1732 { 2196 {
1733 char *s; 2197 char *s;
1734 PyObject *res = NULL; 2198 PyObject *res = NULL;
1735 int retval; 2199 int retval;
1736 2200
1737 if (!PyArg_ParseTuple(args, "s:exprstring", &s)) 2201 if (!PyArg_ParseTuple(args, "s:exprstring", &s))
1738 return NULL; 2202 return NULL;
1739 2203
2204 CHECK_STRING_LENGTH(s);
1740 CHECK_TCL_APPARTMENT; 2205 CHECK_TCL_APPARTMENT;
1741 2206
1742 ENTER_TCL 2207 ENTER_TCL
1743 retval = Tcl_ExprString(Tkapp_Interp(self), s); 2208 retval = Tcl_ExprString(Tkapp_Interp(self), s);
1744 ENTER_OVERLAP 2209 ENTER_OVERLAP
1745 if (retval == TCL_ERROR) 2210 if (retval == TCL_ERROR)
1746 res = Tkinter_Error(self); 2211 res = Tkinter_Error(self);
1747 else 2212 else
1748 res = Py_BuildValue("s", Tkapp_Result(self)); 2213 res = PyString_FromString(Tkapp_Result(self));
1749 LEAVE_OVERLAP_TCL 2214 LEAVE_OVERLAP_TCL
1750 return res; 2215 return res;
1751 } 2216 }
1752 2217
1753 static PyObject * 2218 static PyObject *
1754 Tkapp_ExprLong(PyObject *self, PyObject *args) 2219 Tkapp_ExprLong(PyObject *self, PyObject *args)
1755 { 2220 {
1756 char *s; 2221 char *s;
1757 PyObject *res = NULL; 2222 PyObject *res = NULL;
1758 int retval; 2223 int retval;
1759 long v; 2224 long v;
1760 2225
1761 if (!PyArg_ParseTuple(args, "s:exprlong", &s)) 2226 if (!PyArg_ParseTuple(args, "s:exprlong", &s))
1762 return NULL; 2227 return NULL;
1763 2228
2229 CHECK_STRING_LENGTH(s);
1764 CHECK_TCL_APPARTMENT; 2230 CHECK_TCL_APPARTMENT;
1765 2231
1766 ENTER_TCL 2232 ENTER_TCL
1767 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v); 2233 retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v);
1768 ENTER_OVERLAP 2234 ENTER_OVERLAP
1769 if (retval == TCL_ERROR) 2235 if (retval == TCL_ERROR)
1770 res = Tkinter_Error(self); 2236 res = Tkinter_Error(self);
1771 else 2237 else
1772 res = Py_BuildValue("l", v); 2238 res = Py_BuildValue("l", v);
1773 LEAVE_OVERLAP_TCL 2239 LEAVE_OVERLAP_TCL
1774 return res; 2240 return res;
1775 } 2241 }
1776 2242
1777 static PyObject * 2243 static PyObject *
1778 Tkapp_ExprDouble(PyObject *self, PyObject *args) 2244 Tkapp_ExprDouble(PyObject *self, PyObject *args)
1779 { 2245 {
1780 char *s; 2246 char *s;
1781 PyObject *res = NULL; 2247 PyObject *res = NULL;
1782 double v; 2248 double v;
1783 int retval; 2249 int retval;
1784 2250
1785 if (!PyArg_ParseTuple(args, "s:exprdouble", &s)) 2251 if (!PyArg_ParseTuple(args, "s:exprdouble", &s))
1786 return NULL; 2252 return NULL;
2253 CHECK_STRING_LENGTH(s);
1787 CHECK_TCL_APPARTMENT; 2254 CHECK_TCL_APPARTMENT;
1788 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0) 2255 PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
1789 ENTER_TCL 2256 ENTER_TCL
1790 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v); 2257 retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v);
1791 ENTER_OVERLAP 2258 ENTER_OVERLAP
1792 PyFPE_END_PROTECT(retval) 2259 PyFPE_END_PROTECT(retval)
1793 if (retval == TCL_ERROR) 2260 if (retval == TCL_ERROR)
1794 res = Tkinter_Error(self); 2261 res = Tkinter_Error(self);
1795 else 2262 else
1796 res = Py_BuildValue("d", v); 2263 res = Py_BuildValue("d", v);
1797 LEAVE_OVERLAP_TCL 2264 LEAVE_OVERLAP_TCL
1798 return res; 2265 return res;
1799 } 2266 }
1800 2267
1801 static PyObject * 2268 static PyObject *
1802 Tkapp_ExprBoolean(PyObject *self, PyObject *args) 2269 Tkapp_ExprBoolean(PyObject *self, PyObject *args)
1803 { 2270 {
1804 char *s; 2271 char *s;
1805 PyObject *res = NULL; 2272 PyObject *res = NULL;
1806 int retval; 2273 int retval;
1807 int v; 2274 int v;
1808 2275
1809 if (!PyArg_ParseTuple(args, "s:exprboolean", &s)) 2276 if (!PyArg_ParseTuple(args, "s:exprboolean", &s))
1810 return NULL; 2277 return NULL;
2278 CHECK_STRING_LENGTH(s);
1811 CHECK_TCL_APPARTMENT; 2279 CHECK_TCL_APPARTMENT;
1812 ENTER_TCL 2280 ENTER_TCL
1813 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v); 2281 retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v);
1814 ENTER_OVERLAP 2282 ENTER_OVERLAP
1815 if (retval == TCL_ERROR) 2283 if (retval == TCL_ERROR)
1816 res = Tkinter_Error(self); 2284 res = Tkinter_Error(self);
1817 else 2285 else
1818 res = Py_BuildValue("i", v); 2286 res = Py_BuildValue("i", v);
1819 LEAVE_OVERLAP_TCL 2287 LEAVE_OVERLAP_TCL
1820 return res; 2288 return res;
1821 } 2289 }
1822 2290
1823 2291
1824 2292
1825 static PyObject * 2293 static PyObject *
1826 Tkapp_SplitList(PyObject *self, PyObject *args) 2294 Tkapp_SplitList(PyObject *self, PyObject *args)
1827 { 2295 {
1828 char *list; 2296 char *list;
1829 int argc; 2297 int argc;
1830 char **argv; 2298 char **argv;
1831 PyObject *v; 2299 PyObject *arg, *v;
1832 int i; 2300 int i;
1833 2301
1834 if (PyTuple_Size(args) == 1) { 2302 if (!PyArg_ParseTuple(args, "O:splitlist", &arg))
1835 v = PyTuple_GetItem(args, 0); 2303 return NULL;
1836 if (PyTuple_Check(v)) { 2304 if (PyTclObject_Check(arg)) {
1837 Py_INCREF(v); 2305 int objc;
1838 return v; 2306 Tcl_Obj **objv;
1839 } 2307 if (Tcl_ListObjGetElements(Tkapp_Interp(self),
1840 } 2308 ((PyTclObject*)arg)->value,
2309 &objc, &objv) == TCL_ERROR) {
2310 return Tkinter_Error(self);
2311 }
2312 if (!(v = PyTuple_New(objc)))
2313 return NULL;
2314 for (i = 0; i < objc; i++) {
2315 PyObject *s = FromObj(self, objv[i]);
2316 if (!s || PyTuple_SetItem(v, i, s)) {
2317 Py_DECREF(v);
2318 return NULL;
2319 }
2320 }
2321 return v;
2322 }
2323 if (PyTuple_Check(arg)) {
2324 Py_INCREF(arg);
2325 return arg;
2326 }
2327
1841 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list)) 2328 if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
1842 return NULL; 2329 return NULL;
1843 2330
2331 CHECK_STRING_LENGTH(list);
1844 if (Tcl_SplitList(Tkapp_Interp(self), list, 2332 if (Tcl_SplitList(Tkapp_Interp(self), list,
1845 &argc, &argv) == TCL_ERROR) { 2333 &argc, &argv) == TCL_ERROR) {
1846 PyMem_Free(list); 2334 PyMem_Free(list);
1847 return Tkinter_Error(self); 2335 return Tkinter_Error(self);
1848 } 2336 }
1849 2337
1850 if (!(v = PyTuple_New(argc))) 2338 if (!(v = PyTuple_New(argc)))
1851 goto finally; 2339 goto finally;
1852 2340
1853 for (i = 0; i < argc; i++) { 2341 for (i = 0; i < argc; i++) {
1854 PyObject *s = PyUnicode_FromString(argv[i]); 2342 PyObject *s = PyString_FromString(argv[i]);
1855 if (!s || PyTuple_SetItem(v, i, s)) { 2343 if (!s || PyTuple_SetItem(v, i, s)) {
1856 Py_DECREF(v); 2344 Py_DECREF(v);
1857 v = NULL; 2345 v = NULL;
1858 goto finally; 2346 goto finally;
1859 } 2347 }
1860 } 2348 }
1861 2349
1862 finally: 2350 finally:
1863 ckfree(FREECAST argv); 2351 ckfree(FREECAST argv);
1864 PyMem_Free(list); 2352 PyMem_Free(list);
1865 return v; 2353 return v;
1866 } 2354 }
1867 2355
1868 static PyObject * 2356 static PyObject *
1869 Tkapp_Split(PyObject *self, PyObject *args) 2357 Tkapp_Split(PyObject *self, PyObject *args)
1870 { 2358 {
1871 PyObject *v; 2359 PyObject *arg, *v;
1872 char *list; 2360 char *list;
1873 2361
1874 if (PyTuple_Size(args) == 1) { 2362 if (!PyArg_ParseTuple(args, "O:split", &arg))
1875 PyObject* o = PyTuple_GetItem(args, 0); 2363 return NULL;
1876 if (PyTuple_Check(o)) { 2364 if (PyTclObject_Check(arg)) {
1877 o = SplitObj(o); 2365 Tcl_Obj *value = ((PyTclObject*)arg)->value;
1878 return o; 2366 int objc;
1879 } 2367 Tcl_Obj **objv;
1880 } 2368 int i;
2369 if (Tcl_ListObjGetElements(Tkapp_Interp(self), value,
2370 &objc, &objv) == TCL_ERROR) {
2371 return FromObj(self, value);
2372 }
2373 if (objc == 0)
2374 return PyString_FromString("");
2375 if (objc == 1)
2376 return FromObj(self, objv[0]);
2377 if (!(v = PyTuple_New(objc)))
2378 return NULL;
2379 for (i = 0; i < objc; i++) {
2380 PyObject *s = FromObj(self, objv[i]);
2381 if (!s || PyTuple_SetItem(v, i, s)) {
2382 Py_DECREF(v);
2383 return NULL;
2384 }
2385 }
2386 return v;
2387 }
2388 if (PyTuple_Check(arg))
2389 return SplitObj(arg);
2390
1881 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list)) 2391 if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
1882 return NULL; 2392 return NULL;
2393 CHECK_STRING_LENGTH(list);
1883 v = Split(list); 2394 v = Split(list);
1884 PyMem_Free(list); 2395 PyMem_Free(list);
1885 return v; 2396 return v;
2397 }
2398
2399 static PyObject *
2400 Tkapp_Merge(PyObject *self, PyObject *args)
2401 {
2402 char *s = Merge(args);
2403 PyObject *res = NULL;
2404
2405 if (s) {
2406 res = PyString_FromString(s);
2407 ckfree(s);
2408 }
2409
2410 return res;
1886 } 2411 }
1887 2412
1888 2413
1889 2414
1890 /** Tcl Command **/ 2415 /** Tcl Command **/
1891 2416
1892 /* Client data struct */ 2417 /* Client data struct */
1893 typedef struct { 2418 typedef struct {
1894 PyObject *self; 2419 PyObject *self;
1895 PyObject *func; 2420 PyObject *func;
(...skipping 24 matching lines...) Expand all
1920 /* TBD: no error checking here since we know, via the 2445 /* TBD: no error checking here since we know, via the
1921 * Tkapp_CreateCommand() that the client data is a two-tuple 2446 * Tkapp_CreateCommand() that the client data is a two-tuple
1922 */ 2447 */
1923 func = data->func; 2448 func = data->func;
1924 2449
1925 /* Create argument list (argv1, ..., argvN) */ 2450 /* Create argument list (argv1, ..., argvN) */
1926 if (!(arg = PyTuple_New(argc - 1))) 2451 if (!(arg = PyTuple_New(argc - 1)))
1927 return PythonCmd_Error(interp); 2452 return PythonCmd_Error(interp);
1928 2453
1929 for (i = 0; i < (argc - 1); i++) { 2454 for (i = 0; i < (argc - 1); i++) {
1930 PyObject *s = PyUnicode_FromString(argv[i + 1]); 2455 PyObject *s = fromTclString(argv[i + 1]);
1931 if (!s) { 2456 if (!s || PyTuple_SetItem(arg, i, s)) {
1932 /* Is Tk leaking 0xC080 in %A - a "modified" utf-8 null? */
1933 if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError) &&
1934 !strcmp(argv[i + 1], "\xC0\x80")) {
1935 PyErr_Clear();
1936 /* Convert to "strict" utf-8 null */
1937 s = PyUnicode_FromString("\0");
1938 } else {
1939 Py_DECREF(arg);
1940 return PythonCmd_Error(interp);
1941 }
1942 }
1943 if (PyTuple_SetItem(arg, i, s)) {
1944 Py_DECREF(arg); 2457 Py_DECREF(arg);
1945 return PythonCmd_Error(interp); 2458 return PythonCmd_Error(interp);
1946 } 2459 }
1947 } 2460 }
1948 res = PyEval_CallObject(func, arg); 2461 res = PyEval_CallObject(func, arg);
1949 Py_DECREF(arg); 2462 Py_DECREF(arg);
1950 2463
1951 if (res == NULL) 2464 if (res == NULL)
1952 return PythonCmd_Error(interp); 2465 return PythonCmd_Error(interp);
1953 2466
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2016 Tkapp_CreateCommand(PyObject *selfptr, PyObject *args) 2529 Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
2017 { 2530 {
2018 TkappObject *self = (TkappObject*)selfptr; 2531 TkappObject *self = (TkappObject*)selfptr;
2019 PythonCmd_ClientData *data; 2532 PythonCmd_ClientData *data;
2020 char *cmdName; 2533 char *cmdName;
2021 PyObject *func; 2534 PyObject *func;
2022 int err; 2535 int err;
2023 2536
2024 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func)) 2537 if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func))
2025 return NULL; 2538 return NULL;
2539 CHECK_STRING_LENGTH(cmdName);
2026 if (!PyCallable_Check(func)) { 2540 if (!PyCallable_Check(func)) {
2027 PyErr_SetString(PyExc_TypeError, "command not callable"); 2541 PyErr_SetString(PyExc_TypeError, "command not callable");
2028 return NULL; 2542 return NULL;
2029 } 2543 }
2030 2544
2031 #ifdef WITH_THREAD 2545 #ifdef WITH_THREAD
2032 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() && 2546 if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
2033 !WaitForMainloop(self)) 2547 !WaitForMainloop(self))
2034 return NULL; 2548 return NULL;
2035 #endif 2549 #endif
2036 2550
2037 data = PyMem_NEW(PythonCmd_ClientData, 1); 2551 data = PyMem_NEW(PythonCmd_ClientData, 1);
2038 if (!data) 2552 if (!data)
2039 return PyErr_NoMemory(); 2553 return PyErr_NoMemory();
2040 Py_INCREF(self); 2554 Py_INCREF(self);
2041 Py_INCREF(func); 2555 Py_INCREF(func);
2042 data->self = selfptr; 2556 data->self = selfptr;
2043 data->func = func; 2557 data->func = func;
2558
2044 #ifdef WITH_THREAD 2559 #ifdef WITH_THREAD
2045 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { 2560 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2046 Tcl_Condition cond = NULL; 2561 Tcl_Condition cond = NULL;
2047 CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent)); 2562 CommandEvent *ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent));
2563 if (ev == NULL) {
2564 PyErr_NoMemory();
2565 PyMem_DEL(data);
2566 return NULL;
2567 }
2048 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; 2568 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2049 ev->interp = self->interp; 2569 ev->interp = self->interp;
2050 ev->create = 1; 2570 ev->create = 1;
2051 ev->name = cmdName; 2571 ev->name = cmdName;
2052 ev->data = (ClientData)data; 2572 ev->data = (ClientData)data;
2053 ev->status = &err; 2573 ev->status = &err;
2054 ev->done = &cond; 2574 ev->done = &cond;
2055 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex); 2575 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
2056 Tcl_ConditionFinalize(&cond); 2576 Tcl_ConditionFinalize(&cond);
2057 } 2577 }
2058 else 2578 else
2059 #endif 2579 #endif
2060 { 2580 {
2061 ENTER_TCL 2581 ENTER_TCL
2062 err = Tcl_CreateCommand( 2582 err = Tcl_CreateCommand(
2063 Tkapp_Interp(self), cmdName, PythonCmd, 2583 Tkapp_Interp(self), cmdName, PythonCmd,
2064 (ClientData)data, PythonCmdDelete) == NULL; 2584 (ClientData)data, PythonCmdDelete) == NULL;
2065 LEAVE_TCL 2585 LEAVE_TCL
2066 } 2586 }
2067 if (err) { 2587 if (err) {
2068 PyErr_SetString(Tkinter_TclError, "can't create Tcl command"); 2588 PyErr_SetString(Tkinter_TclError, "can't create Tcl command");
2069 PyMem_DEL(data); 2589 PyMem_DEL(data);
2070 return NULL; 2590 return NULL;
2071 } 2591 }
2072 2592
2073 Py_RETURN_NONE; 2593 Py_INCREF(Py_None);
2594 return Py_None;
2074 } 2595 }
2075 2596
2076 2597
2077 2598
2078 static PyObject * 2599 static PyObject *
2079 Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args) 2600 Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
2080 { 2601 {
2081 TkappObject *self = (TkappObject*)selfptr; 2602 TkappObject *self = (TkappObject*)selfptr;
2082 char *cmdName; 2603 char *cmdName;
2083 int err; 2604 int err;
2084 2605
2085 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName)) 2606 if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
2086 return NULL; 2607 return NULL;
2608 CHECK_STRING_LENGTH(cmdName);
2087 2609
2088 #ifdef WITH_THREAD 2610 #ifdef WITH_THREAD
2089 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { 2611 if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
2090 Tcl_Condition cond = NULL; 2612 Tcl_Condition cond = NULL;
2091 CommandEvent *ev; 2613 CommandEvent *ev;
2092 ev = (CommandEvent*)ckalloc(sizeof(CommandEvent)); 2614 ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent));
2615 if (ev == NULL) {
2616 PyErr_NoMemory();
2617 return NULL;
2618 }
2093 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; 2619 ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
2094 ev->interp = self->interp; 2620 ev->interp = self->interp;
2095 ev->create = 0; 2621 ev->create = 0;
2096 ev->name = cmdName; 2622 ev->name = cmdName;
2097 ev->status = &err; 2623 ev->status = &err;
2098 ev->done = &cond; 2624 ev->done = &cond;
2099 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, 2625 Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
2100 &command_mutex); 2626 &command_mutex);
2101 Tcl_ConditionFinalize(&cond); 2627 Tcl_ConditionFinalize(&cond);
2102 } 2628 }
2103 else 2629 else
2104 #endif 2630 #endif
2105 { 2631 {
2106 ENTER_TCL 2632 ENTER_TCL
2107 err = Tcl_DeleteCommand(self->interp, cmdName); 2633 err = Tcl_DeleteCommand(self->interp, cmdName);
2108 LEAVE_TCL 2634 LEAVE_TCL
2109 } 2635 }
2110 if (err == -1) { 2636 if (err == -1) {
2111 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command"); 2637 PyErr_SetString(Tkinter_TclError, "can't delete Tcl command");
2112 return NULL; 2638 return NULL;
2113 } 2639 }
2114 Py_RETURN_NONE; 2640 Py_INCREF(Py_None);
2641 return Py_None;
2115 } 2642 }
2116 2643
2117 2644
2118 2645
2119 #ifdef HAVE_CREATEFILEHANDLER 2646 #ifdef HAVE_CREATEFILEHANDLER
2120 /** File Handler **/ 2647 /** File Handler **/
2121 2648
2122 typedef struct _fhcdata { 2649 typedef struct _fhcdata {
2123 PyObject *func; 2650 PyObject *func;
2124 PyObject *file; 2651 PyObject *file;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2186 } 2713 }
2187 2714
2188 static PyObject * 2715 static PyObject *
2189 Tkapp_CreateFileHandler(PyObject *self, PyObject *args) 2716 Tkapp_CreateFileHandler(PyObject *self, PyObject *args)
2190 /* args is (file, mask, func) */ 2717 /* args is (file, mask, func) */
2191 { 2718 {
2192 FileHandler_ClientData *data; 2719 FileHandler_ClientData *data;
2193 PyObject *file, *func; 2720 PyObject *file, *func;
2194 int mask, tfile; 2721 int mask, tfile;
2195 2722
2723 if (!self && Py_Py3kWarningFlag) {
2724 if (PyErr_Warn(PyExc_DeprecationWarning,
2725 "_tkinter.createfilehandler is gone in 3.x") < 0 )
2726 return NULL;
2727 }
2728
2196 if (!PyArg_ParseTuple(args, "OiO:createfilehandler", 2729 if (!PyArg_ParseTuple(args, "OiO:createfilehandler",
2197 &file, &mask, &func)) 2730 &file, &mask, &func))
2198 return NULL; 2731 return NULL;
2199 2732
2200 CHECK_TCL_APPARTMENT; 2733 #ifdef WITH_THREAD
2734 if (!self && !tcl_lock) {
2735 /* We don't have the Tcl lock since Tcl is threaded. */
2736 PyErr_SetString(PyExc_RuntimeError,
2737 "_tkinter.createfilehandler not supported "
2738 "for threaded Tcl");
2739 return NULL;
2740 }
2741 #endif
2742
2743 if (self) {
2744 CHECK_TCL_APPARTMENT;
2745 }
2201 2746
2202 tfile = PyObject_AsFileDescriptor(file); 2747 tfile = PyObject_AsFileDescriptor(file);
2203 if (tfile < 0) 2748 if (tfile < 0)
2204 return NULL; 2749 return NULL;
2205 if (!PyCallable_Check(func)) { 2750 if (!PyCallable_Check(func)) {
2206 PyErr_SetString(PyExc_TypeError, "bad argument list"); 2751 PyErr_SetString(PyExc_TypeError, "bad argument list");
2207 return NULL; 2752 return NULL;
2208 } 2753 }
2209 2754
2210 data = NewFHCD(func, file, tfile); 2755 data = NewFHCD(func, file, tfile);
2211 if (data == NULL) 2756 if (data == NULL)
2212 return NULL; 2757 return NULL;
2213 2758
2214 /* Ought to check for null Tcl_File object... */ 2759 /* Ought to check for null Tcl_File object... */
2215 ENTER_TCL 2760 ENTER_TCL
2216 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data); 2761 Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data);
2217 LEAVE_TCL 2762 LEAVE_TCL
2218 Py_RETURN_NONE; 2763 Py_INCREF(Py_None);
2764 return Py_None;
2219 } 2765 }
2220 2766
2221 static PyObject * 2767 static PyObject *
2222 Tkapp_DeleteFileHandler(PyObject *self, PyObject *args) 2768 Tkapp_DeleteFileHandler(PyObject *self, PyObject *args)
2223 { 2769 {
2224 PyObject *file; 2770 PyObject *file;
2225 int tfile; 2771 int tfile;
2226 2772
2773 if (!self && Py_Py3kWarningFlag) {
2774 if (PyErr_Warn(PyExc_DeprecationWarning,
2775 "_tkinter.deletefilehandler is gone in 3.x") < 0 )
2776 return NULL;
2777 }
2778
2227 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file)) 2779 if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file))
2228 return NULL; 2780 return NULL;
2229 2781
2230 CHECK_TCL_APPARTMENT; 2782 #ifdef WITH_THREAD
2783 if (!self && !tcl_lock) {
2784 /* We don't have the Tcl lock since Tcl is threaded. */
2785 PyErr_SetString(PyExc_RuntimeError,
2786 "_tkinter.deletefilehandler not supported "
2787 "for threaded Tcl");
2788 return NULL;
2789 }
2790 #endif
2791
2792 if (self) {
2793 CHECK_TCL_APPARTMENT;
2794 }
2231 2795
2232 tfile = PyObject_AsFileDescriptor(file); 2796 tfile = PyObject_AsFileDescriptor(file);
2233 if (tfile < 0) 2797 if (tfile < 0)
2234 return NULL; 2798 return NULL;
2235 2799
2236 DeleteFHCD(tfile); 2800 DeleteFHCD(tfile);
2237 2801
2238 /* Ought to check for null Tcl_File object... */ 2802 /* Ought to check for null Tcl_File object... */
2239 ENTER_TCL 2803 ENTER_TCL
2240 Tcl_DeleteFileHandler(tfile); 2804 Tcl_DeleteFileHandler(tfile);
2241 LEAVE_TCL 2805 LEAVE_TCL
2242 Py_RETURN_NONE; 2806 Py_INCREF(Py_None);
2807 return Py_None;
2243 } 2808 }
2244 #endif /* HAVE_CREATEFILEHANDLER */ 2809 #endif /* HAVE_CREATEFILEHANDLER */
2245 2810
2246 2811
2247 /**** Tktt Object (timer token) ****/ 2812 /**** Tktt Object (timer token) ****/
2248 2813
2249 static PyObject *Tktt_Type; 2814 static PyTypeObject Tktt_Type;
2250 2815
2251 typedef struct { 2816 typedef struct {
2252 PyObject_HEAD 2817 PyObject_HEAD
2253 Tcl_TimerToken token; 2818 Tcl_TimerToken token;
2254 PyObject *func; 2819 PyObject *func;
2255 } TkttObject; 2820 } TkttObject;
2256 2821
2257 static PyObject * 2822 static PyObject *
2258 Tktt_DeleteTimerHandler(PyObject *self, PyObject *args) 2823 Tktt_DeleteTimerHandler(PyObject *self, PyObject *args)
2259 { 2824 {
2260 TkttObject *v = (TkttObject *)self; 2825 TkttObject *v = (TkttObject *)self;
2261 PyObject *func = v->func; 2826 PyObject *func = v->func;
2262 2827
2263 if (!PyArg_ParseTuple(args, ":deletetimerhandler")) 2828 if (!PyArg_ParseTuple(args, ":deletetimerhandler"))
2264 return NULL; 2829 return NULL;
2265 if (v->token != NULL) { 2830 if (v->token != NULL) {
2266 Tcl_DeleteTimerHandler(v->token); 2831 Tcl_DeleteTimerHandler(v->token);
2267 v->token = NULL; 2832 v->token = NULL;
2268 } 2833 }
2269 if (func != NULL) { 2834 if (func != NULL) {
2270 v->func = NULL; 2835 v->func = NULL;
2271 Py_DECREF(func); 2836 Py_DECREF(func);
2272 Py_DECREF(v); /* See Tktt_New() */ 2837 Py_DECREF(v); /* See Tktt_New() */
2273 } 2838 }
2274 Py_RETURN_NONE; 2839 Py_INCREF(Py_None);
2840 return Py_None;
2275 } 2841 }
2276 2842
2277 static PyMethodDef Tktt_methods[] = 2843 static PyMethodDef Tktt_methods[] =
2278 { 2844 {
2279 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS}, 2845 {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS},
2280 {NULL, NULL} 2846 {NULL, NULL}
2281 }; 2847 };
2282 2848
2283 static TkttObject * 2849 static TkttObject *
2284 Tktt_New(PyObject *func) 2850 Tktt_New(PyObject *func)
2285 { 2851 {
2286 TkttObject *v; 2852 TkttObject *v;
2287 2853
2288 v = PyObject_New(TkttObject, (PyTypeObject *) Tktt_Type); 2854 v = PyObject_New(TkttObject, &Tktt_Type);
2289 if (v == NULL) 2855 if (v == NULL)
2290 return NULL; 2856 return NULL;
2291 2857
2292 Py_INCREF(func); 2858 Py_INCREF(func);
2293 v->token = NULL; 2859 v->token = NULL;
2294 v->func = func; 2860 v->func = func;
2295 2861
2296 /* Extra reference, deleted when called or when handler is deleted */ 2862 /* Extra reference, deleted when called or when handler is deleted */
2297 Py_INCREF(v); 2863 Py_INCREF(v);
2298 return v; 2864 return v;
2299 } 2865 }
2300 2866
2301 static void 2867 static void
2302 Tktt_Dealloc(PyObject *self) 2868 Tktt_Dealloc(PyObject *self)
2303 { 2869 {
2304 TkttObject *v = (TkttObject *)self; 2870 TkttObject *v = (TkttObject *)self;
2305 PyObject *func = v->func; 2871 PyObject *func = v->func;
2306 2872
2307 Py_XDECREF(func); 2873 Py_XDECREF(func);
2308 2874
2309 PyObject_Del(self); 2875 PyObject_Del(self);
2310 } 2876 }
2311 2877
2312 static PyObject * 2878 static PyObject *
2313 Tktt_Repr(PyObject *self) 2879 Tktt_Repr(PyObject *self)
2314 { 2880 {
2315 TkttObject *v = (TkttObject *)self; 2881 TkttObject *v = (TkttObject *)self;
2316 return PyUnicode_FromFormat("<tktimertoken at %p%s>", 2882 char buf[100];
2317 v, 2883
2318 v->func == NULL ? ", handler deleted" : ""); 2884 PyOS_snprintf(buf, sizeof(buf), "<tktimertoken at %p%s>", v,
2319 } 2885 v->func == NULL ? ", handler deleted" : "");
2320 2886 return PyString_FromString(buf);
2321 static PyType_Slot Tktt_Type_slots[] = { 2887 }
2322 {Py_tp_dealloc, Tktt_Dealloc}, 2888
2323 {Py_tp_repr, Tktt_Repr}, 2889 static PyObject *
2324 {Py_tp_methods, Tktt_methods}, 2890 Tktt_GetAttr(PyObject *self, char *name)
2325 {0, 0} 2891 {
2892 return Py_FindMethod(Tktt_methods, self, name);
2893 }
2894
2895 static PyTypeObject Tktt_Type =
2896 {
2897 PyVarObject_HEAD_INIT(NULL, 0)
2898 "tktimertoken", /*tp_name */
2899 sizeof(TkttObject), /*tp_basicsize */
2900 0, /*tp_itemsize */
2901 Tktt_Dealloc, /*tp_dealloc */
2902 0, /*tp_print */
2903 Tktt_GetAttr, /*tp_getattr */
2904 0, /*tp_setattr */
2905 0, /*tp_compare */
2906 Tktt_Repr, /*tp_repr */
2907 0, /*tp_as_number */
2908 0, /*tp_as_sequence */
2909 0, /*tp_as_mapping */
2910 0, /*tp_hash */
2326 }; 2911 };
2327 2912
2328 static PyType_Spec Tktt_Type_spec = {
2329 "tktimertoken",
2330 sizeof(TkttObject),
2331 0,
2332 Py_TPFLAGS_DEFAULT,
2333 Tktt_Type_slots,
2334 };
2335 2913
2336 2914
2337 /** Timer Handler **/ 2915 /** Timer Handler **/
2338 2916
2339 static void 2917 static void
2340 TimerHandler(ClientData clientData) 2918 TimerHandler(ClientData clientData)
2341 { 2919 {
2342 TkttObject *v = (TkttObject *)clientData; 2920 TkttObject *v = (TkttObject *)clientData;
2343 PyObject *func = v->func; 2921 PyObject *func = v->func;
2344 PyObject *res; 2922 PyObject *res;
(...skipping 19 matching lines...) Expand all
2364 LEAVE_PYTHON 2942 LEAVE_PYTHON
2365 } 2943 }
2366 2944
2367 static PyObject * 2945 static PyObject *
2368 Tkapp_CreateTimerHandler(PyObject *self, PyObject *args) 2946 Tkapp_CreateTimerHandler(PyObject *self, PyObject *args)
2369 { 2947 {
2370 int milliseconds; 2948 int milliseconds;
2371 PyObject *func; 2949 PyObject *func;
2372 TkttObject *v; 2950 TkttObject *v;
2373 2951
2952 if (!self && Py_Py3kWarningFlag) {
2953 if (PyErr_Warn(PyExc_DeprecationWarning,
2954 "_tkinter.createtimerhandler is gone in 3.x") < 0)
2955 return NULL;
2956 }
2957
2374 if (!PyArg_ParseTuple(args, "iO:createtimerhandler", 2958 if (!PyArg_ParseTuple(args, "iO:createtimerhandler",
2375 &milliseconds, &func)) 2959 &milliseconds, &func))
2376 return NULL; 2960 return NULL;
2377 if (!PyCallable_Check(func)) { 2961 if (!PyCallable_Check(func)) {
2378 PyErr_SetString(PyExc_TypeError, "bad argument list"); 2962 PyErr_SetString(PyExc_TypeError, "bad argument list");
2379 return NULL; 2963 return NULL;
2380 } 2964 }
2381 2965
2382 CHECK_TCL_APPARTMENT; 2966 #ifdef WITH_THREAD
2967 if (!self && !tcl_lock) {
2968 /* We don't have the Tcl lock since Tcl is threaded. */
2969 PyErr_SetString(PyExc_RuntimeError,
2970 "_tkinter.createtimerhandler not supported "
2971 "for threaded Tcl");
2972 return NULL;
2973 }
2974 #endif
2975
2976 if (self) {
2977 CHECK_TCL_APPARTMENT;
2978 }
2383 2979
2384 v = Tktt_New(func); 2980 v = Tktt_New(func);
2385 if (v) { 2981 if (v) {
2386 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler, 2982 v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler,
2387 (ClientData)v); 2983 (ClientData)v);
2388 } 2984 }
2389 2985
2390 return (PyObject *) v; 2986 return (PyObject *) v;
2391 } 2987 }
2392 2988
2393 2989
2394 /** Event Loop **/ 2990 /** Event Loop **/
2395 2991
2396 static PyObject * 2992 static PyObject *
2397 Tkapp_MainLoop(PyObject *selfptr, PyObject *args) 2993 Tkapp_MainLoop(PyObject *selfptr, PyObject *args)
2398 { 2994 {
2399 int threshold = 0; 2995 int threshold = 0;
2400 TkappObject *self = (TkappObject*)selfptr; 2996 TkappObject *self = (TkappObject*)selfptr;
2401 #ifdef WITH_THREAD 2997 #ifdef WITH_THREAD
2402 PyThreadState *tstate = PyThreadState_Get(); 2998 PyThreadState *tstate = PyThreadState_Get();
2403 #endif 2999 #endif
2404 3000
3001 if (!self && Py_Py3kWarningFlag) {
3002 if (PyErr_Warn(PyExc_DeprecationWarning,
3003 "_tkinter.mainloop is gone in 3.x") < 0)
3004 return NULL;
3005 }
3006
2405 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold)) 3007 if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
2406 return NULL; 3008 return NULL;
2407 3009
2408 CHECK_TCL_APPARTMENT; 3010 #ifdef WITH_THREAD
2409 self->dispatching = 1; 3011 if (!self && !tcl_lock) {
3012 /* We don't have the Tcl lock since Tcl is threaded. */
3013 PyErr_SetString(PyExc_RuntimeError,
3014 "_tkinter.mainloop not supported "
3015 "for threaded Tcl");
3016 return NULL;
3017 }
3018 #endif
3019
3020 if (self) {
3021 CHECK_TCL_APPARTMENT;
3022 self->dispatching = 1;
3023 }
2410 3024
2411 quitMainLoop = 0; 3025 quitMainLoop = 0;
2412 while (Tk_GetNumMainWindows() > threshold && 3026 while (Tk_GetNumMainWindows() > threshold &&
2413 !quitMainLoop && 3027 !quitMainLoop &&
2414 !errorInCmd) 3028 !errorInCmd)
2415 { 3029 {
2416 int result; 3030 int result;
2417 3031
2418 #ifdef WITH_THREAD 3032 #ifdef WITH_THREAD
2419 if (self->threaded) { 3033 if (self && self->threaded) {
2420 /* Allow other Python threads to run. */ 3034 /* Allow other Python threads to run. */
2421 ENTER_TCL 3035 ENTER_TCL
2422 result = Tcl_DoOneEvent(0); 3036 result = Tcl_DoOneEvent(0);
2423 LEAVE_TCL 3037 LEAVE_TCL
2424 } 3038 }
2425 else { 3039 else {
2426 Py_BEGIN_ALLOW_THREADS 3040 Py_BEGIN_ALLOW_THREADS
2427 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); 3041 if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1);
2428 tcl_tstate = tstate; 3042 tcl_tstate = tstate;
2429 result = Tcl_DoOneEvent(TCL_DONT_WAIT); 3043 result = Tcl_DoOneEvent(TCL_DONT_WAIT);
2430 tcl_tstate = NULL; 3044 tcl_tstate = NULL;
2431 if(tcl_lock)PyThread_release_lock(tcl_lock); 3045 if(tcl_lock)PyThread_release_lock(tcl_lock);
2432 if (result == 0) 3046 if (result == 0)
2433 Sleep(Tkinter_busywaitinterval); 3047 Sleep(Tkinter_busywaitinterval);
2434 Py_END_ALLOW_THREADS 3048 Py_END_ALLOW_THREADS
2435 } 3049 }
2436 #else 3050 #else
2437 result = Tcl_DoOneEvent(0); 3051 result = Tcl_DoOneEvent(0);
2438 #endif 3052 #endif
2439 3053
2440 if (PyErr_CheckSignals() != 0) { 3054 if (PyErr_CheckSignals() != 0) {
2441 self->dispatching = 0; 3055 if (self)
3056 self->dispatching = 0;
2442 return NULL; 3057 return NULL;
2443 } 3058 }
2444 if (result < 0) 3059 if (result < 0)
2445 break; 3060 break;
2446 } 3061 }
2447 self->dispatching = 0; 3062 if (self)
3063 self->dispatching = 0;
2448 quitMainLoop = 0; 3064 quitMainLoop = 0;
2449 3065
2450 if (errorInCmd) { 3066 if (errorInCmd) {
2451 errorInCmd = 0; 3067 errorInCmd = 0;
2452 PyErr_Restore(excInCmd, valInCmd, trbInCmd); 3068 PyErr_Restore(excInCmd, valInCmd, trbInCmd);
2453 excInCmd = valInCmd = trbInCmd = NULL; 3069 excInCmd = valInCmd = trbInCmd = NULL;
2454 return NULL; 3070 return NULL;
2455 } 3071 }
2456 Py_RETURN_NONE; 3072 Py_INCREF(Py_None);
3073 return Py_None;
2457 } 3074 }
2458 3075
2459 static PyObject * 3076 static PyObject *
2460 Tkapp_DoOneEvent(PyObject *self, PyObject *args) 3077 Tkapp_DoOneEvent(PyObject *self, PyObject *args)
2461 { 3078 {
2462 int flags = 0; 3079 int flags = 0;
2463 int rv; 3080 int rv;
3081
3082 if (!self && Py_Py3kWarningFlag) {
3083 if (PyErr_Warn(PyExc_DeprecationWarning,
3084 "_tkinter.dooneevent is gone in 3.x") < 0)
3085 return NULL;
3086 }
2464 3087
2465 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags)) 3088 if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags))
2466 return NULL; 3089 return NULL;
2467 3090
2468 ENTER_TCL 3091 ENTER_TCL
2469 rv = Tcl_DoOneEvent(flags); 3092 rv = Tcl_DoOneEvent(flags);
2470 LEAVE_TCL 3093 LEAVE_TCL
2471 return Py_BuildValue("i", rv); 3094 return Py_BuildValue("i", rv);
2472 } 3095 }
2473 3096
2474 static PyObject * 3097 static PyObject *
2475 Tkapp_Quit(PyObject *self, PyObject *args) 3098 Tkapp_Quit(PyObject *self, PyObject *args)
2476 { 3099 {
2477 3100
3101 if (!self && Py_Py3kWarningFlag) {
3102 if (PyErr_Warn(PyExc_DeprecationWarning,
3103 "_tkinter.quit is gone in 3.x") < 0)
3104 return NULL;
3105 }
3106
2478 if (!PyArg_ParseTuple(args, ":quit")) 3107 if (!PyArg_ParseTuple(args, ":quit"))
2479 return NULL; 3108 return NULL;
2480 3109
2481 quitMainLoop = 1; 3110 quitMainLoop = 1;
2482 Py_RETURN_NONE; 3111 Py_INCREF(Py_None);
3112 return Py_None;
2483 } 3113 }
2484 3114
2485 static PyObject * 3115 static PyObject *
2486 Tkapp_InterpAddr(PyObject *self, PyObject *args) 3116 Tkapp_InterpAddr(PyObject *self, PyObject *args)
2487 { 3117 {
2488 3118
2489 if (!PyArg_ParseTuple(args, ":interpaddr")) 3119 if (!PyArg_ParseTuple(args, ":interpaddr"))
2490 return NULL; 3120 return NULL;
2491 3121
2492 return PyLong_FromLong((long)Tkapp_Interp(self)); 3122 return PyLong_FromVoidPtr(Tkapp_Interp(self));
2493 } 3123 }
2494 3124
2495 static PyObject * 3125 static PyObject *
2496 Tkapp_TkInit(PyObject *self, PyObject *args) 3126 Tkapp_TkInit(PyObject *self, PyObject *args)
2497 { 3127 {
2498 Tcl_Interp *interp = Tkapp_Interp(self); 3128 Tcl_Interp *interp = Tkapp_Interp(self);
2499 const char * _tk_exists = NULL; 3129 const char * _tk_exists = NULL;
2500 int err; 3130 int err;
2501 3131
2502 #ifdef TKINTER_PROTECT_LOADTK 3132 #ifdef TKINTER_PROTECT_LOADTK
(...skipping 19 matching lines...) Expand all
2522 Tkinter_Error(self); 3152 Tkinter_Error(self);
2523 } else { 3153 } else {
2524 _tk_exists = Tkapp_Result(self); 3154 _tk_exists = Tkapp_Result(self);
2525 } 3155 }
2526 LEAVE_OVERLAP_TCL 3156 LEAVE_OVERLAP_TCL
2527 if (err == TCL_ERROR) { 3157 if (err == TCL_ERROR) {
2528 return NULL; 3158 return NULL;
2529 } 3159 }
2530 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) { 3160 if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
2531 if (Tk_Init(interp) == TCL_ERROR) { 3161 if (Tk_Init(interp) == TCL_ERROR) {
2532 PyErr_SetString(Tkinter_TclError, 3162 PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(s elf)));
2533 Tcl_GetStringResult(Tkapp_Interp(self)));
2534 #ifdef TKINTER_PROTECT_LOADTK 3163 #ifdef TKINTER_PROTECT_LOADTK
2535 tk_load_failed = 1; 3164 tk_load_failed = 1;
2536 #endif 3165 #endif
2537 return NULL; 3166 return NULL;
2538 } 3167 }
2539 } 3168 }
2540 Py_RETURN_NONE; 3169 Py_INCREF(Py_None);
3170 return Py_None;
2541 } 3171 }
2542 3172
2543 static PyObject * 3173 static PyObject *
2544 Tkapp_WantObjects(PyObject *self, PyObject *args) 3174 Tkapp_WantObjects(PyObject *self, PyObject *args)
2545 { 3175 {
2546 3176
2547 int wantobjects = -1; 3177 int wantobjects = -1;
2548 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects)) 3178 if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects))
2549 return NULL; 3179 return NULL;
2550 if (wantobjects == -1) 3180 if (wantobjects == -1)
2551 return PyBool_FromLong(((TkappObject*)self)->wantobjects); 3181 return PyBool_FromLong(((TkappObject*)self)->wantobjects);
2552 ((TkappObject*)self)->wantobjects = wantobjects; 3182 ((TkappObject*)self)->wantobjects = wantobjects;
2553 3183
2554 Py_RETURN_NONE; 3184 Py_INCREF(Py_None);
3185 return Py_None;
2555 } 3186 }
2556 3187
2557 static PyObject * 3188 static PyObject *
2558 Tkapp_WillDispatch(PyObject *self, PyObject *args) 3189 Tkapp_WillDispatch(PyObject *self, PyObject *args)
2559 { 3190 {
2560 3191
2561 ((TkappObject*)self)->dispatching = 1; 3192 ((TkappObject*)self)->dispatching = 1;
2562 3193
2563 Py_RETURN_NONE; 3194 Py_INCREF(Py_None);
3195 return Py_None;
3196 }
3197
3198 /* Convert Python string or any buffer compatible object to Tcl byte-array
3199 * object. Use it to pass binary data (e.g. image's data) to Tcl/Tk commands.
3200 */
3201 static PyObject *
3202 Tkapp_CreateByteArray(PyObject *self, PyObject *args)
3203 {
3204 Py_buffer view;
3205 Tcl_Obj* obj;
3206 PyObject *res = NULL;
3207
3208 if (!PyArg_ParseTuple(args, "s*:_createbytearray", &view))
3209 return NULL;
3210
3211 if (view.len >= INT_MAX) {
3212 PyErr_SetString(PyExc_OverflowError, "string is too long");
3213 return NULL;
3214 }
3215 obj = Tcl_NewByteArrayObj(view.buf, (int)view.len);
3216 if (obj == NULL) {
3217 PyBuffer_Release(&view);
3218 return Tkinter_Error(self);
3219 }
3220 res = newPyTclObject(obj);
3221 PyBuffer_Release(&view);
3222 return res;
2564 } 3223 }
2565 3224
2566 3225
2567 /**** Tkapp Method List ****/ 3226 /**** Tkapp Method List ****/
2568 3227
2569 static PyMethodDef Tkapp_methods[] = 3228 static PyMethodDef Tkapp_methods[] =
2570 { 3229 {
2571 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS}, 3230 {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
2572 {"wantobjects", Tkapp_WantObjects, METH_VARARGS}, 3231 {"wantobjects", Tkapp_WantObjects, METH_VARARGS},
2573 {"call", Tkapp_Call, METH_VARARGS}, 3232 {"call", Tkapp_Call, METH_VARARGS},
3233 {"globalcall", Tkapp_GlobalCall, METH_VARARGS},
2574 {"eval", Tkapp_Eval, METH_VARARGS}, 3234 {"eval", Tkapp_Eval, METH_VARARGS},
3235 {"globaleval", Tkapp_GlobalEval, METH_VARARGS},
2575 {"evalfile", Tkapp_EvalFile, METH_VARARGS}, 3236 {"evalfile", Tkapp_EvalFile, METH_VARARGS},
2576 {"record", Tkapp_Record, METH_VARARGS}, 3237 {"record", Tkapp_Record, METH_VARARGS},
2577 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS}, 3238 {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS},
2578 {"setvar", Tkapp_SetVar, METH_VARARGS}, 3239 {"setvar", Tkapp_SetVar, METH_VARARGS},
2579 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS}, 3240 {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS},
2580 {"getvar", Tkapp_GetVar, METH_VARARGS}, 3241 {"getvar", Tkapp_GetVar, METH_VARARGS},
2581 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS}, 3242 {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS},
2582 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS}, 3243 {"unsetvar", Tkapp_UnsetVar, METH_VARARGS},
2583 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS}, 3244 {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
2584 {"getint", Tkapp_GetInt, METH_VARARGS}, 3245 {"getint", Tkapp_GetInt, METH_VARARGS},
2585 {"getdouble", Tkapp_GetDouble, METH_VARARGS}, 3246 {"getdouble", Tkapp_GetDouble, METH_VARARGS},
2586 {"getboolean", Tkapp_GetBoolean, METH_VARARGS}, 3247 {"getboolean", Tkapp_GetBoolean, METH_O},
2587 {"exprstring", Tkapp_ExprString, METH_VARARGS}, 3248 {"exprstring", Tkapp_ExprString, METH_VARARGS},
2588 {"exprlong", Tkapp_ExprLong, METH_VARARGS}, 3249 {"exprlong", Tkapp_ExprLong, METH_VARARGS},
2589 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS}, 3250 {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
2590 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS}, 3251 {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS},
2591 {"splitlist", Tkapp_SplitList, METH_VARARGS}, 3252 {"splitlist", Tkapp_SplitList, METH_VARARGS},
2592 {"split", Tkapp_Split, METH_VARARGS}, 3253 {"split", Tkapp_Split, METH_VARARGS},
3254 {"merge", Tkapp_Merge, METH_VARARGS},
2593 {"createcommand", Tkapp_CreateCommand, METH_VARARGS}, 3255 {"createcommand", Tkapp_CreateCommand, METH_VARARGS},
2594 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS}, 3256 {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS},
2595 #ifdef HAVE_CREATEFILEHANDLER 3257 #ifdef HAVE_CREATEFILEHANDLER
2596 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS}, 3258 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
2597 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS}, 3259 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
2598 #endif 3260 #endif
2599 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS}, 3261 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
2600 {"mainloop", Tkapp_MainLoop, METH_VARARGS}, 3262 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
2601 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS}, 3263 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
2602 {"quit", Tkapp_Quit, METH_VARARGS}, 3264 {"quit", Tkapp_Quit, METH_VARARGS},
2603 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS}, 3265 {"interpaddr", Tkapp_InterpAddr, METH_VARARGS},
2604 {"loadtk", Tkapp_TkInit, METH_NOARGS}, 3266 {"loadtk", Tkapp_TkInit, METH_NOARGS},
3267 {"_createbytearray", Tkapp_CreateByteArray, METH_VARARGS},
2605 {NULL, NULL} 3268 {NULL, NULL}
2606 }; 3269 };
2607 3270
2608 3271
2609 3272
2610 /**** Tkapp Type Methods ****/ 3273 /**** Tkapp Type Methods ****/
2611 3274
2612 static void 3275 static void
2613 Tkapp_Dealloc(PyObject *self) 3276 Tkapp_Dealloc(PyObject *self)
2614 { 3277 {
2615 /*CHECK_TCL_APPARTMENT;*/ 3278 /*CHECK_TCL_APPARTMENT;*/
2616 ENTER_TCL 3279 ENTER_TCL
2617 Tcl_DeleteInterp(Tkapp_Interp(self)); 3280 Tcl_DeleteInterp(Tkapp_Interp(self));
2618 LEAVE_TCL 3281 LEAVE_TCL
2619 PyObject_Del(self); 3282 PyObject_Del(self);
2620 DisableEventHook(); 3283 DisableEventHook();
2621 } 3284 }
2622 3285
2623 static PyType_Slot Tkapp_Type_slots[] = { 3286 static PyObject *
2624 {Py_tp_dealloc, Tkapp_Dealloc}, 3287 Tkapp_GetAttr(PyObject *self, char *name)
2625 {Py_tp_methods, Tkapp_methods}, 3288 {
2626 {0, 0} 3289 return Py_FindMethod(Tkapp_methods, self, name);
2627 }; 3290 }
2628 3291
2629 3292 static PyTypeObject Tkapp_Type =
2630 static PyType_Spec Tkapp_Type_spec = { 3293 {
2631 "tkapp", 3294 PyVarObject_HEAD_INIT(NULL, 0)
2632 sizeof(TkappObject), 3295 "tkapp", /*tp_name */
2633 0, 3296 sizeof(TkappObject), /*tp_basicsize */
2634 Py_TPFLAGS_DEFAULT, 3297 0, /*tp_itemsize */
2635 Tkapp_Type_slots, 3298 Tkapp_Dealloc, /*tp_dealloc */
3299 0, /*tp_print */
3300 Tkapp_GetAttr, /*tp_getattr */
3301 0, /*tp_setattr */
3302 0, /*tp_compare */
3303 0, /*tp_repr */
3304 0, /*tp_as_number */
3305 0, /*tp_as_sequence */
3306 0, /*tp_as_mapping */
3307 0, /*tp_hash */
2636 }; 3308 };
2637 3309
2638 3310
2639 3311
2640 /**** Tkinter Module ****/ 3312 /**** Tkinter Module ****/
2641 3313
2642 typedef struct { 3314 typedef struct {
2643 PyObject* tuple; 3315 PyObject* tuple;
2644 int size; /* current size */ 3316 int size; /* current size */
2645 int maxsize; /* allocated size */ 3317 int maxsize; /* allocated size */
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2747 if (_PyTuple_Resize(&context.tuple, context.size)) 3419 if (_PyTuple_Resize(&context.tuple, context.size))
2748 return NULL; 3420 return NULL;
2749 3421
2750 return context.tuple; 3422 return context.tuple;
2751 } 3423 }
2752 3424
2753 static PyObject * 3425 static PyObject *
2754 Tkinter_Create(PyObject *self, PyObject *args) 3426 Tkinter_Create(PyObject *self, PyObject *args)
2755 { 3427 {
2756 char *screenName = NULL; 3428 char *screenName = NULL;
2757 char *baseName = NULL; /* XXX this is not used anymore; 3429 char *baseName = NULL;
2758 try getting rid of it. */
2759 char *className = NULL; 3430 char *className = NULL;
2760 int interactive = 0; 3431 int interactive = 0;
2761 int wantobjects = 0; 3432 int wantobjects = 0;
2762 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */ 3433 int wantTk = 1; /* If false, then Tk_Init() doesn't get called */
2763 int sync = 0; /* pass -sync to wish */ 3434 int sync = 0; /* pass -sync to wish */
2764 char *use = NULL; /* pass -use to wish */ 3435 char *use = NULL; /* pass -use to wish */
2765 3436
3437 baseName = strrchr(Py_GetProgramName(), '/');
3438 if (baseName != NULL)
3439 baseName++;
3440 else
3441 baseName = Py_GetProgramName();
2766 className = "Tk"; 3442 className = "Tk";
2767 3443
2768 if (!PyArg_ParseTuple(args, "|zssiiiiz:create", 3444 if (!PyArg_ParseTuple(args, "|zssiiiiz:create",
2769 &screenName, &baseName, &className, 3445 &screenName, &baseName, &className,
2770 &interactive, &wantobjects, &wantTk, 3446 &interactive, &wantobjects, &wantTk,
2771 &sync, &use)) 3447 &sync, &use))
2772 return NULL; 3448 return NULL;
2773 3449 CHECK_STRING_LENGTH(screenName);
2774 return (PyObject *) Tkapp_New(screenName, className, 3450 CHECK_STRING_LENGTH(baseName);
2775 interactive, wantobjects, wantTk, 3451 CHECK_STRING_LENGTH(className);
3452 CHECK_STRING_LENGTH(use);
3453
3454 return (PyObject *) Tkapp_New(screenName, baseName, className,
3455 interactive, wantobjects, wantTk,
2776 sync, use); 3456 sync, use);
2777 } 3457 }
2778 3458
2779 static PyObject * 3459 static PyObject *
2780 Tkinter_setbusywaitinterval(PyObject *self, PyObject *args) 3460 Tkinter_setbusywaitinterval(PyObject *self, PyObject *args)
2781 { 3461 {
2782 int new_val; 3462 int new_val;
2783 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val)) 3463 if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val))
2784 return NULL; 3464 return NULL;
2785 if (new_val < 0) { 3465 if (new_val < 0) {
2786 PyErr_SetString(PyExc_ValueError, 3466 PyErr_SetString(PyExc_ValueError,
2787 "busywaitinterval must be >= 0"); 3467 "busywaitinterval must be >= 0");
2788 return NULL; 3468 return NULL;
2789 } 3469 }
2790 Tkinter_busywaitinterval = new_val; 3470 Tkinter_busywaitinterval = new_val;
2791 Py_RETURN_NONE; 3471 Py_INCREF(Py_None);
3472 return Py_None;
2792 } 3473 }
2793 3474
2794 static char setbusywaitinterval_doc[] = 3475 static char setbusywaitinterval_doc[] =
2795 "setbusywaitinterval(n) -> None\n\ 3476 "setbusywaitinterval(n) -> None\n\
2796 \n\ 3477 \n\
2797 Set the busy-wait interval in milliseconds between successive\n\ 3478 Set the busy-wait interval in milliseconds between successive\n\
2798 calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\ 3479 calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\
2799 It should be set to a divisor of the maximum time between\n\ 3480 It should be set to a divisor of the maximum time between\n\
2800 frames in an animation."; 3481 frames in an animation.";
2801 3482
2802 static PyObject * 3483 static PyObject *
2803 Tkinter_getbusywaitinterval(PyObject *self, PyObject *args) 3484 Tkinter_getbusywaitinterval(PyObject *self, PyObject *args)
2804 { 3485 {
2805 return PyLong_FromLong(Tkinter_busywaitinterval); 3486 return PyInt_FromLong(Tkinter_busywaitinterval);
2806 } 3487 }
2807 3488
2808 static char getbusywaitinterval_doc[] = 3489 static char getbusywaitinterval_doc[] =
2809 "getbusywaitinterval() -> int\n\ 3490 "getbusywaitinterval() -> int\n\
2810 \n\ 3491 \n\
2811 Return the current busy-wait interval between successive\n\ 3492 Return the current busy-wait interval between successive\n\
2812 calls to Tcl_DoOneEvent in a threaded Python interpreter."; 3493 calls to Tcl_DoOneEvent in a threaded Python interpreter.";
2813 3494
2814 static PyMethodDef moduleMethods[] = 3495 static PyMethodDef moduleMethods[] =
2815 { 3496 {
2816 {"_flatten", Tkinter_Flatten, METH_VARARGS}, 3497 {"_flatten", Tkinter_Flatten, METH_VARARGS},
2817 {"create", Tkinter_Create, METH_VARARGS}, 3498 {"create", Tkinter_Create, METH_VARARGS},
3499 #ifdef HAVE_CREATEFILEHANDLER
3500 {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS},
3501 {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS},
3502 #endif
3503 {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS},
3504 {"mainloop", Tkapp_MainLoop, METH_VARARGS},
3505 {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS},
3506 {"quit", Tkapp_Quit, METH_VARARGS},
2818 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS, 3507 {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS,
2819 setbusywaitinterval_doc}, 3508 setbusywaitinterval_doc},
2820 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval, 3509 {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval,
2821 METH_NOARGS, getbusywaitinterval_doc}, 3510 METH_NOARGS, getbusywaitinterval_doc},
2822 {NULL, NULL} 3511 {NULL, NULL}
2823 }; 3512 };
2824 3513
2825 #ifdef WAIT_FOR_STDIN 3514 #ifdef WAIT_FOR_STDIN
2826 3515
2827 static int stdin_ready = 0; 3516 static int stdin_ready = 0;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2914 DisableEventHook(void) 3603 DisableEventHook(void)
2915 { 3604 {
2916 #ifdef WAIT_FOR_STDIN 3605 #ifdef WAIT_FOR_STDIN
2917 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) { 3606 if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) {
2918 PyOS_InputHook = NULL; 3607 PyOS_InputHook = NULL;
2919 } 3608 }
2920 #endif 3609 #endif
2921 } 3610 }
2922 3611
2923 3612
2924 static struct PyModuleDef _tkintermodule = { 3613 /* all errors will be checked in one fell swoop in init_tkinter() */
2925 PyModuleDef_HEAD_INIT, 3614 static void
2926 "_tkinter", 3615 ins_long(PyObject *d, char *name, long val)
2927 NULL, 3616 {
2928 -1, 3617 PyObject *v = PyInt_FromLong(val);
2929 moduleMethods, 3618 if (v) {
2930 NULL, 3619 PyDict_SetItemString(d, name, v);
2931 NULL, 3620 Py_DECREF(v);
2932 NULL, 3621 }
2933 NULL 3622 }
2934 }; 3623 static void
3624 ins_string(PyObject *d, char *name, char *val)
3625 {
3626 PyObject *v = PyString_FromString(val);
3627 if (v) {
3628 PyDict_SetItemString(d, name, v);
3629 Py_DECREF(v);
3630 }
3631 }
3632
2935 3633
2936 PyMODINIT_FUNC 3634 PyMODINIT_FUNC
2937 PyInit__tkinter(void) 3635 init_tkinter(void)
2938 { 3636 {
2939 PyObject *m, *uexe, *cexe, *o; 3637 PyObject *m, *d;
3638
3639 Py_TYPE(&Tkapp_Type) = &PyType_Type;
2940 3640
2941 #ifdef WITH_THREAD 3641 #ifdef WITH_THREAD
2942 tcl_lock = PyThread_allocate_lock(); 3642 tcl_lock = PyThread_allocate_lock();
2943 if (tcl_lock == NULL) 3643 #endif
2944 return NULL; 3644
2945 #endif 3645 m = Py_InitModule("_tkinter", moduleMethods);
2946
2947 m = PyModule_Create(&_tkintermodule);
2948 if (m == NULL) 3646 if (m == NULL)
2949 return NULL; 3647 return;
2950 3648
2951 o = PyErr_NewException("_tkinter.TclError", NULL, NULL); 3649 d = PyModule_GetDict(m);
2952 if (o == NULL) { 3650 Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
2953 Py_DECREF(m); 3651 PyDict_SetItemString(d, "TclError", Tkinter_TclError);
2954 return NULL; 3652
2955 } 3653 ins_long(d, "READABLE", TCL_READABLE);
2956 Py_INCREF(o); 3654 ins_long(d, "WRITABLE", TCL_WRITABLE);
2957 if (PyModule_AddObject(m, "TclError", o)) { 3655 ins_long(d, "EXCEPTION", TCL_EXCEPTION);
2958 Py_DECREF(o); 3656 ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS);
2959 Py_DECREF(m); 3657 ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS);
2960 return NULL; 3658 ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS);
2961 } 3659 ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS);
2962 Tkinter_TclError = o; 3660 ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS);
2963 3661 ins_long(d, "DONT_WAIT", TCL_DONT_WAIT);
2964 if (PyModule_AddIntConstant(m, "READABLE", TCL_READABLE)) { 3662 ins_string(d, "TK_VERSION", TK_VERSION);
2965 Py_DECREF(m); 3663 ins_string(d, "TCL_VERSION", TCL_VERSION);
2966 return NULL; 3664
2967 } 3665 PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type);
2968 if (PyModule_AddIntConstant(m, "WRITABLE", TCL_WRITABLE)) { 3666
2969 Py_DECREF(m); 3667 Py_TYPE(&Tktt_Type) = &PyType_Type;
2970 return NULL; 3668 PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type);
2971 } 3669
2972 if (PyModule_AddIntConstant(m, "EXCEPTION", TCL_EXCEPTION)) { 3670 Py_TYPE(&PyTclObject_Type) = &PyType_Type;
2973 Py_DECREF(m); 3671 PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type);
2974 return NULL;
2975 }
2976 if (PyModule_AddIntConstant(m, "WINDOW_EVENTS", TCL_WINDOW_EVENTS)) {
2977 Py_DECREF(m);
2978 return NULL;
2979 }
2980 if (PyModule_AddIntConstant(m, "FILE_EVENTS", TCL_FILE_EVENTS)) {
2981 Py_DECREF(m);
2982 return NULL;
2983 }
2984 if (PyModule_AddIntConstant(m, "TIMER_EVENTS", TCL_TIMER_EVENTS)) {
2985 Py_DECREF(m);
2986 return NULL;
2987 }
2988 if (PyModule_AddIntConstant(m, "IDLE_EVENTS", TCL_IDLE_EVENTS)) {
2989 Py_DECREF(m);
2990 return NULL;
2991 }
2992 if (PyModule_AddIntConstant(m, "ALL_EVENTS", TCL_ALL_EVENTS)) {
2993 Py_DECREF(m);
2994 return NULL;
2995 }
2996 if (PyModule_AddIntConstant(m, "DONT_WAIT", TCL_DONT_WAIT)) {
2997 Py_DECREF(m);
2998 return NULL;
2999 }
3000 if (PyModule_AddStringConstant(m, "TK_VERSION", TK_VERSION)) {
3001 Py_DECREF(m);
3002 return NULL;
3003 }
3004 if (PyModule_AddStringConstant(m, "TCL_VERSION", TCL_VERSION)) {
3005 Py_DECREF(m);
3006 return NULL;
3007 }
3008
3009 o = PyType_FromSpec(&Tkapp_Type_spec);
3010 if (o == NULL) {
3011 Py_DECREF(m);
3012 return NULL;
3013 }
3014 if (PyModule_AddObject(m, "TkappType", o)) {
3015 Py_DECREF(o);
3016 Py_DECREF(m);
3017 return NULL;
3018 }
3019 Tkapp_Type = o;
3020
3021 o = PyType_FromSpec(&Tktt_Type_spec);
3022 if (o == NULL) {
3023 Py_DECREF(m);
3024 return NULL;
3025 }
3026 if (PyModule_AddObject(m, "TkttType", o)) {
3027 Py_DECREF(o);
3028 Py_DECREF(m);
3029 return NULL;
3030 }
3031 Tktt_Type = o;
3032
3033 o = PyType_FromSpec(&PyTclObject_Type_spec);
3034 if (o == NULL) {
3035 Py_DECREF(m);
3036 return NULL;
3037 }
3038 if (PyModule_AddObject(m, "Tcl_Obj", o)) {
3039 Py_DECREF(o);
3040 Py_DECREF(m);
3041 return NULL;
3042 }
3043 PyTclObject_Type = o;
3044 3672
3045 #ifdef TK_AQUA 3673 #ifdef TK_AQUA
3046 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems 3674 /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems
3047 * start waking up. Note that Tcl_FindExecutable will do this, this 3675 * start waking up. Note that Tcl_FindExecutable will do this, this
3048 * code must be above it! The original warning from 3676 * code must be above it! The original warning from
3049 * tkMacOSXAppInit.c is copied below. 3677 * tkMacOSXAppInit.c is copied below.
3050 * 3678 *
3051 * NB - You have to swap in the Tk Notifier BEFORE you start up the 3679 * NB - You have to swap in the Tk Notifier BEFORE you start up the
3052 * Tcl interpreter for now. It probably should work to do this 3680 * Tcl interpreter for now. It probably should work to do this
3053 * in the other order, but for now it doesn't seem to. 3681 * in the other order, but for now it doesn't seem to.
3054 * 3682 *
3055 */ 3683 */
3056 Tk_MacOSXSetupTkNotifier(); 3684 Tk_MacOSXSetupTkNotifier();
3057 #endif 3685 #endif
3058 3686
3059 3687
3060 /* This helps the dynamic loader; in Unicode aware Tcl versions 3688 /* This helps the dynamic loader; in Unicode aware Tcl versions
3061 it also helps Tcl find its encodings. */ 3689 it also helps Tcl find its encodings. */
3062 uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1); 3690 Tcl_FindExecutable(Py_GetProgramName());
3063 if (uexe) { 3691
3064 cexe = PyUnicode_EncodeFSDefault(uexe); 3692 if (PyErr_Occurred())
3065 if (cexe) 3693 return;
3066 Tcl_FindExecutable(PyBytes_AsString(cexe));
3067 Py_XDECREF(cexe);
3068 Py_DECREF(uexe);
3069 }
3070
3071 if (PyErr_Occurred()) {
3072 Py_DECREF(m);
3073 return NULL;
3074 }
3075 3694
3076 #if 0 3695 #if 0
3077 /* This was not a good idea; through <Destroy> bindings, 3696 /* This was not a good idea; through <Destroy> bindings,
3078 Tcl_Finalize() may invoke Python code but at that point the 3697 Tcl_Finalize() may invoke Python code but at that point the
3079 interpreter and thread state have already been destroyed! */ 3698 interpreter and thread state have already been destroyed! */
3080 Py_AtExit(Tcl_Finalize); 3699 Py_AtExit(Tcl_Finalize);
3081 #endif 3700 #endif
3082 return m; 3701
3083 } 3702 }
LEFTRIGHT
« no previous file | Modules/tkinter.h » ('j') | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+