[PATCH evemu 16/19] py: Add and use wrapper for libc calls

Daniel Martin consume.noise at gmail.com
Mon Jan 6 09:38:16 PST 2014


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)
 
 if __name__ == "__main__":
     unittest.main()
-- 
1.8.5.2



More information about the Input-tools mailing list