Skip to content

Commit 64f01dd

Browse files
committed
RF: refactor C code to Michael D's commments
Refactoring for style. Check Python 3 filename encoding result.
1 parent edc80a3 commit 64f01dd

File tree

1 file changed

+63
-46
lines changed

1 file changed

+63
-46
lines changed

src/_tkagg.cpp

+63-46
Original file line numberDiff line numberDiff line change
@@ -273,77 +273,94 @@ static PyMethodDef functions[] = {
273273
#define TKINTER_PKG "tkinter"
274274
#define TKINTER_MOD "_tkinter"
275275
// 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+
}
277284
#else
278285
#define TKINTER_PKG "Tkinter"
279286
#define TKINTER_MOD "tkinter"
280287
// From module __file__ attribute to char *string for dlopen
281-
#define FNAME2CHAR(s) (PyString_AsString(s))
288+
#define fname2char(s) (PyString_AsString(s))
282289
#endif
283290

284291
void *_dfunc(void *lib_handle, const char *func_name)
285292
{
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) {
295301
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);
300303
}
301304
return func;
302305
}
303306

304-
int _func_loader(void *tkinter_lib)
307+
int _func_loader(void *lib)
305308
{
306309
// 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));
315324
}
316325

317326
int load_tkinter_funcs(void)
318327
{
319328
// Load tkinter global funcs from tkinter compiled module.
320329
// Return 0 for success, non-zero for failure.
321330
int ret = -1;
322-
PyObject *pModule, *pSubmodule, *pString;
331+
void *tkinter_lib;
332+
char *tkinter_libname;
333+
PyObject *pModule = NULL, *pSubmodule = NULL, *pString = NULL;
323334

324335
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;
346356
}
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);
347364
return ret;
348365
}
349366
#endif

0 commit comments

Comments
 (0)