@@ -273,77 +273,94 @@ static PyMethodDef functions[] = {
273
273
#define TKINTER_PKG " tkinter"
274
274
#define TKINTER_MOD " _tkinter"
275
275
// From module __file__ attribute to char *string for dlopen.
276
- #define FNAME2CHAR (s ) (PyBytes_AsString(PyUnicode_EncodeFSDefault(s)))
276
+ char *fname2char (PyObject *fname)
277
+ {
278
+ PyObject *bytes = PyUnicode_EncodeFSDefault (fname);
279
+ if (bytes == NULL ) {
280
+ return NULL ;
281
+ }
282
+ return PyBytes_AsString (bytes);
283
+ }
277
284
#else
278
285
#define TKINTER_PKG " Tkinter"
279
286
#define TKINTER_MOD " tkinter"
280
287
// From module __file__ attribute to char *string for dlopen
281
- #define FNAME2CHAR (s ) (PyString_AsString(s))
288
+ #define fname2char (s ) (PyString_AsString(s))
282
289
#endif
283
290
284
291
void *_dfunc (void *lib_handle, const char *func_name)
285
292
{
286
- // Load function, unless there has been a previous error. If so, then
287
- // return NULL. If there is an error loading the function, return NULL
288
- // and set error flag.
289
- static int have_error = 0 ;
290
- void *func = NULL ;
291
- if (have_error == 0 ) {
292
- // reset errors
293
- dlerror ();
294
- func = dlsym (lib_handle, func_name);
293
+ // Load function `func_name` from `lib_handle`.
294
+ // Set Python exception if we can't find `func_name` in `lib_handle`.
295
+ // Returns function pointer or NULL if not present.
296
+
297
+ // Reset errors.
298
+ dlerror ();
299
+ void *func = dlsym (lib_handle, func_name);
300
+ if (func == NULL ) {
295
301
const char *error = dlerror ();
296
- if (error != NULL ) {
297
- PyErr_SetString (PyExc_RuntimeError, error);
298
- have_error = 1 ;
299
- }
302
+ PyErr_SetString (PyExc_RuntimeError, error);
300
303
}
301
304
return func;
302
305
}
303
306
304
- int _func_loader (void *tkinter_lib )
307
+ int _func_loader (void *lib )
305
308
{
306
309
// Fill global function pointers from dynamic lib.
307
- // Return 0 fur success; 1 otherwise.
308
- TCL_CREATE_COMMAND = (tcl_cc) _dfunc (tkinter_lib, " Tcl_CreateCommand" );
309
- TCL_APPEND_RESULT = (tcl_app_res) _dfunc (tkinter_lib, " Tcl_AppendResult" );
310
- TK_MAIN_WINDOW = (tk_mw) _dfunc (tkinter_lib, " Tk_MainWindow" );
311
- TK_FIND_PHOTO = (tk_fp) _dfunc (tkinter_lib, " Tk_FindPhoto" );
312
- TK_PHOTO_PUTBLOCK = (tk_ppb_nc) _dfunc (tkinter_lib, " Tk_PhotoPutBlock_NoComposite" );
313
- TK_PHOTO_BLANK = (tk_pb) _dfunc (tkinter_lib, " Tk_PhotoBlank" );
314
- return (TK_PHOTO_BLANK == NULL );
310
+ // Return 1 if any pointer is NULL, 0 otherwise.
311
+ return (
312
+ ((TCL_CREATE_COMMAND = (tcl_cc)
313
+ _dfunc (lib, " Tcl_CreateCommand" )) == NULL ) ||
314
+ ((TCL_APPEND_RESULT = (tcl_app_res)
315
+ _dfunc (lib, " Tcl_AppendResult" )) == NULL ) ||
316
+ ((TK_MAIN_WINDOW = (tk_mw)
317
+ _dfunc (lib, " Tk_MainWindow" )) == NULL ) ||
318
+ ((TK_FIND_PHOTO = (tk_fp)
319
+ _dfunc (lib, " Tk_FindPhoto" )) == NULL ) ||
320
+ ((TK_PHOTO_PUTBLOCK = (tk_ppb_nc)
321
+ _dfunc (lib, " Tk_PhotoPutBlock_NoComposite" )) == NULL ) ||
322
+ ((TK_PHOTO_BLANK = (tk_pb)
323
+ _dfunc (lib, " Tk_PhotoBlank" )) == NULL ));
315
324
}
316
325
317
326
int load_tkinter_funcs (void )
318
327
{
319
328
// Load tkinter global funcs from tkinter compiled module.
320
329
// Return 0 for success, non-zero for failure.
321
330
int ret = -1 ;
322
- PyObject *pModule, *pSubmodule, *pString;
331
+ void *tkinter_lib;
332
+ char *tkinter_libname;
333
+ PyObject *pModule = NULL , *pSubmodule = NULL , *pString = NULL ;
323
334
324
335
pModule = PyImport_ImportModule (TKINTER_PKG);
325
- if (pModule != NULL ) {
326
- pSubmodule = PyObject_GetAttrString (pModule, TKINTER_MOD);
327
- if (pSubmodule != NULL ) {
328
- pString = PyObject_GetAttrString (pSubmodule, " __file__" );
329
- if (pString != NULL ) {
330
- char *tkinter_libname = FNAME2CHAR (pString);
331
- void *tkinter_lib = dlopen (tkinter_libname, RTLD_LAZY);
332
- if (tkinter_lib == NULL ) {
333
- PyErr_SetString (PyExc_RuntimeError,
334
- " Cannot dlopen tkinter module file" );
335
- } else {
336
- ret = _func_loader (tkinter_lib);
337
- // dlclose probably safe because tkinter has been
338
- // imported.
339
- dlclose (tkinter_lib);
340
- }
341
- Py_DECREF (pString);
342
- }
343
- Py_DECREF (pSubmodule);
344
- }
345
- Py_DECREF (pModule);
336
+ if (pModule == NULL ) {
337
+ goto exit ;
338
+ }
339
+ pSubmodule = PyObject_GetAttrString (pModule, TKINTER_MOD);
340
+ if (pSubmodule == NULL ) {
341
+ goto exit ;
342
+ }
343
+ pString = PyObject_GetAttrString (pSubmodule, " __file__" );
344
+ if (pString == NULL ) {
345
+ goto exit ;
346
+ }
347
+ tkinter_libname = fname2char (pString);
348
+ if (tkinter_libname == NULL ) {
349
+ goto exit ;
350
+ }
351
+ tkinter_lib = dlopen (tkinter_libname, RTLD_LAZY);
352
+ if (tkinter_lib == NULL ) {
353
+ PyErr_SetString (PyExc_RuntimeError,
354
+ " Cannot dlopen tkinter module file" );
355
+ goto exit ;
346
356
}
357
+ ret = _func_loader (tkinter_lib);
358
+ // dlclose probably safe because tkinter has been imported.
359
+ dlclose (tkinter_lib);
360
+ exit :
361
+ Py_XDECREF (pModule);
362
+ Py_XDECREF (pSubmodule);
363
+ Py_XDECREF (pString);
347
364
return ret;
348
365
}
349
366
#endif
0 commit comments