[PATCH evemu 16/19] py: Add and use wrapper for libc calls
Peter Hutterer
peter.hutterer at who-t.net
Mon Jan 6 15:53:57 PST 2014
On Mon, Jan 06, 2014 at 06:38:16PM +0100, Daniel Martin wrote:
> Introduce a class LibC in base.py, which wraps fdopen and fflush, and
> replace _call0()s to fdopen and fflush in __init__.py.
>
> Signed-off-by: Daniel Martin <consume.noise at gmail.com>
> ---
> python/evemu/__init__.py | 21 +++++++--------------
> python/evemu/base.py | 34 +++++++++++++++++++++++-----------
> python/evemu/tests/test_base.py | 16 ++++++++++------
> 3 files changed, 40 insertions(+), 31 deletions(-)
>
> diff --git a/python/evemu/__init__.py b/python/evemu/__init__.py
> index f07a8ca..521652b 100644
> --- a/python/evemu/__init__.py
> +++ b/python/evemu/__init__.py
> @@ -54,6 +54,7 @@ class Device(object):
>
> self._is_propfile = self._check_is_propfile(self._file)
> self._evemu = evemu.base.EvEmuBase()
> + self._libc = evemu.base.LibC()
> self._uinput = None
>
> libevemu_new = self._evemu.get_lib().evemu_new
> @@ -61,9 +62,7 @@ class Device(object):
> self._evemu_device = libevemu_new("")
>
> if self._is_propfile:
> - fs = self._evemu._call0(self._evemu.get_c_lib().fdopen,
> - self._file.fileno(),
> - 'r')
> + fs = self._libc.fdopen(self._file.fileno(), b"r")
> self._evemu._call(self._evemu.get_lib().evemu_read,
> self._evemu_device,
> fs)
> @@ -129,13 +128,11 @@ class Device(object):
> if not hasattr(prop_file, "read"):
> raise TypeError("expected file")
>
> - fs = self._evemu._call0(self._evemu.get_c_lib().fdopen,
> - prop_file.fileno(),
> - "w")
> + fs = self._libc.fdopen(prop_file.fileno(), b"w")
> self._evemu._call(self._evemu.get_lib().evemu_write,
> self._evemu_device,
> fs)
> - self._evemu.get_c_lib().fflush(fs)
> + self._libc.fflush(fs)
>
> def play(self, events_file):
> """
> @@ -148,9 +145,7 @@ class Device(object):
> if not hasattr(events_file, "read"):
> raise TypeError("expected file")
>
> - fs = self._evemu._call0(self._evemu.get_c_lib().fdopen,
> - events_file.fileno(),
> - "r")
> + fs = self._libc.fdopen(events_file.fileno(), b"r")
> self._evemu._call(self._evemu.get_lib().evemu_play,
> fs,
> self._file.fileno())
> @@ -167,14 +162,12 @@ class Device(object):
> if not hasattr(events_file, "read"):
> raise TypeError("expected file")
>
> - fs = self._evemu._call0(self._evemu.get_c_lib().fdopen,
> - events_file.fileno(),
> - "w")
> + fs = self._libc.fdopen(events_file.fileno(), b"w")
> self._evemu._call(self._evemu.get_lib().evemu_record,
> fs,
> self._file.fileno(),
> timeout)
> - self._evemu.get_c_lib().fflush(fs)
> + self._libc.fflush(fs)
>
> @property
> def version(self):
> diff --git a/python/evemu/base.py b/python/evemu/base.py
> index 3a9de8d..5f514f3 100644
> --- a/python/evemu/base.py
> +++ b/python/evemu/base.py
> @@ -134,20 +134,35 @@ class LibraryWrapper(object):
> raise NotImplementedError
>
>
> +class LibC(LibraryWrapper):
> + """
> + Wrapper for API calls to the C library.
> + """
> +
> + @staticmethod
> + def _cdll():
> + return ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True)
> +
> + _api_prototypes = {
> + "fdopen": {
> + "argtypes": (c_int, c_char_p),
> + "restype": c_void_p,
> + "errcheck": expect_not_none
> + },
> + "fflush": {
> + "argtypes": (c_void_p,),
> + "restype": c_int,
> + "errcheck": expect_eq_zero
> + },
> + }
> +
> +
> class EvEmuBase(object):
> """
> A base wrapper class for the evemu functions, accessed via ctypes.
> """
> def __init__(self):
> self._lib = ctypes.CDLL(evemu.const.LIB, use_errno=True)
> - self._libc = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True)
> -
> - def _call0(self, api_call, *parameters):
> - result = api_call(*parameters)
> - if result == 0 and self.get_c_errno() != 0:
> - raise evemu.exception.ExecutionError("%s: %s" % (
> - api_call.__name__, self.get_c_error()))
> - return result
>
> def _call(self, api_call, *parameters):
> result = api_call(*parameters)
> @@ -169,8 +184,5 @@ class EvEmuBase(object):
> def get_c_error(self):
> return os.strerror(ctypes.get_errno())
>
> - def get_c_lib(self):
> - return self._libc
> -
> def get_lib(self):
> return self._lib
> diff --git a/python/evemu/tests/test_base.py b/python/evemu/tests/test_base.py
> index 60a05f9..9064d42 100644
> --- a/python/evemu/tests/test_base.py
> +++ b/python/evemu/tests/test_base.py
> @@ -13,13 +13,17 @@ class EvEmuBaseTestCase(evemu.testing.testcase.BaseTestCase):
> self.assertNotEqual(
> wrapper._lib._name.find("libevemu"), -1)
>
> - def test_c_symbols_found(self):
> - # Make sure that the expected functions are present
> - wrapper = evemu.base.EvEmuBase()
> - for function_name in evemu.const.API:
> - function = getattr(wrapper._lib, function_name)
> - self.assertTrue(function is not None)
> + def test_libc_found(self):
> + lib = evemu.base.LibC._load()
> + self.assertNotEqual(lib, None)
> + self.assertTrue(lib._name.startswith("libc"))
>
> + def test_libc_symbols_found(self):
> + lib = evemu.base.LibC._load()
> + for func_name in evemu.base.LibC._api_prototypes.keys():
> + func = getattr(lib, func_name)
> + self.assertNotEqual(func, None)
> + self.assertEqual(func.__name__, func_name)
these two look like they can be integrated into the LibraryWrapper so that we
fail if we can't find the required symbols. it may already do that anyway, I
suspect getattr() will fail on the library for undefined functions so you
can probably drop this bit.
Cheers,
Peter
>
> if __name__ == "__main__":
> unittest.main()
> --
> 1.8.5.2
>
> _______________________________________________
> Input-tools mailing list
> Input-tools at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/input-tools
More information about the Input-tools
mailing list