diff options
-rw-r--r-- | gpsclient.c | 13 | ||||
-rw-r--r-- | gpspacket.c | 31 | ||||
-rw-r--r-- | python_compatibility.h | 44 |
3 files changed, 66 insertions, 22 deletions
diff --git a/gpsclient.c b/gpsclient.c index 276900e3..7b04ddc0 100644 --- a/gpsclient.c +++ b/gpsclient.c @@ -10,6 +10,7 @@ #include "gps.h" #include "gpsdclient.h" #include "compiler.h" /* for UNUSED */ +#include "python_compatibility.h" /* * Client utility functions @@ -83,13 +84,16 @@ PyDoc_STRVAR(module_doc, /* banishes a pointless compiler warning */ extern PyMODINIT_FUNC initclienthelpers(void); -PyMODINIT_FUNC // cppcheck-suppress unusedFunction -initclienthelpers(void) +GPSD_PY_MODULE_INIT(clienthelpers) { PyObject *m; - m = Py_InitModule3("gps.clienthelpers", gpsclient_methods, module_doc); + /* Create the module and add the functions */ + GPSD_PY_MODULE_DEF(m, "clienthelpers", module_doc, gpsclient_methods) + + if (m == NULL) + return GPSD_PY_MODULE_ERROR_VAL; PyModule_AddIntConstant(m, "deg_dd", deg_dd); PyModule_AddIntConstant(m, "deg_ddmm", deg_ddmm); @@ -99,5 +103,6 @@ initclienthelpers(void) PyModule_AddIntConstant(m, "imperial", imperial); PyModule_AddIntConstant(m, "nautical", nautical); PyModule_AddIntConstant(m, "metric", metric); -} + return GPSD_PY_MODULE_SUCCESS_VAL(m); +} diff --git a/gpspacket.c b/gpspacket.c index 06a41d36..0c9ade28 100644 --- a/gpspacket.c +++ b/gpspacket.c @@ -9,6 +9,7 @@ #include <stdio.h> #include "gpsd.h" +#include "python_compatibility.h" static PyObject *ErrorObject = NULL; @@ -94,7 +95,7 @@ Lexer_get(LexerObject *self, PyObject *args) if (PyErr_Occurred()) return NULL; - return Py_BuildValue("(i, i, s#, i)", + return Py_BuildValue("(i, i, " GPSD_PY_BYTE_FORMAT ", i)", len, self->lexer.type, self->lexer.outbuffer, @@ -125,12 +126,6 @@ static PyMethodDef Lexer_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyObject * -Lexer_getattr(LexerObject *self, char *name) -{ - return Py_FindMethod(Lexer_methods, (PyObject *)self, name); -} - PyDoc_STRVAR(Lexer__doc__, "GPS packet lexer object\n\ \n\ @@ -139,15 +134,14 @@ Fetch a single packet from file descriptor"); static PyTypeObject Lexer_Type = { /* The ob_type field must be initialized in the module init function * to be portable to Windows without using C++. */ - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT(NULL, 0) "gps.packet.lexer", /*tp_name*/ sizeof(LexerObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)Lexer_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - (getattrfunc)Lexer_getattr, /*tp_getattr*/ + 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ @@ -157,11 +151,11 @@ static PyTypeObject Lexer_Type = { 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ - 0, /*tp_getattro*/ + PyObject_GenericGetAttr, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ - Lexer__doc__, /*tp_doc*/ + Lexer__doc__, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ @@ -255,17 +249,16 @@ level of the message and the message itself.\n\ /* banishes a pointless compiler warning */ extern PyMODINIT_FUNC initpacket(void); -PyMODINIT_FUNC // cppcheck-suppress unusedFunction -initpacket(void) +GPSD_PY_MODULE_INIT(packet) { PyObject *m; - if (PyType_Ready(&Lexer_Type) < 0) - return; - /* Create the module and add the functions */ - m = Py_InitModule3("packet", packet_methods, module_doc); + GPSD_PY_MODULE_DEF(m, "packet", module_doc, packet_methods) + + if (m == NULL || PyType_Ready(&Lexer_Type) < 0) + return GPSD_PY_MODULE_ERROR_VAL; PyModule_AddIntConstant(m, "BAD_PACKET", BAD_PACKET); PyModule_AddIntConstant(m, "COMMENT_PACKET", COMMENT_PACKET); @@ -298,4 +291,6 @@ initpacket(void) PyModule_AddIntConstant(m, "LOG_DATA", LOG_DATA); PyModule_AddIntConstant(m, "LOG_SPIN", LOG_SPIN); PyModule_AddIntConstant(m, "LOG_RAW", LOG_RAW); + + return GPSD_PY_MODULE_SUCCESS_VAL(m); } diff --git a/python_compatibility.h b/python_compatibility.h new file mode 100644 index 00000000..635cd06c --- /dev/null +++ b/python_compatibility.h @@ -0,0 +1,44 @@ +/* + * python_compatibility.h -- macros for Python 2/3 compatibility + * + * This file is Copyright (c) 2016 by the GPSD project + * BSD terms apply: see the file COPYING in the distribution root for details. + * + * Definitions based on examples in "Supporting Python 3 - The Book Site" + * http://python3porting.com/cextensions.html + */ + +#ifndef _PYTHON_COMPATIBILITY_H_ +#define _PYTHON_COMPATIBILITY_H_ + +#include <Python.h> + +#if PY_MAJOR_VERSION >= 3 + +#define GPSD_PY_MODULE_INIT(name) PyMODINIT_FUNC PyInit_##name(void) + +#define GPSD_PY_MODULE_DEF(mod, name, doc, methods) \ + static struct PyModuleDef moduledef = { \ + PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \ + mod = PyModule_Create(&moduledef); + +#define GPSD_PY_MODULE_ERROR_VAL NULL +#define GPSD_PY_MODULE_SUCCESS_VAL(val) val + +#define GPSD_PY_BYTE_FORMAT "y#" + +#else /* !Python 3 */ + +#define GPSD_PY_MODULE_INIT(name) PyMODINIT_FUNC init##name(void) + +#define GPSD_PY_MODULE_DEF(mod, name, doc, methods) \ + mod = Py_InitModule3(name, methods, doc); + +#define GPSD_PY_MODULE_ERROR_VAL +#define GPSD_PY_MODULE_SUCCESS_VAL(val) + +#define GPSD_PY_BYTE_FORMAT "s#" + +#endif /* !Python 3 */ + +#endif /* _PYTHON_COMPATIBILITY_H_ */ |