[PATCH evemu 3/4] py: Add and use wrapper for libc calls
Daniel Martin
consume.noise at gmail.com
Fri Jan 10 00:30:36 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.
v2: Removed tests if functions can be found in the loaded library and
added tests that the loaded library is static in the class.
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 | 27 +++++++++++++++++++++------
3 files changed, 51 insertions(+), 31 deletions(-)
diff --git a/python/evemu/__init__.py b/python/evemu/__init__.py
index 19b7815..f474036 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 f5268a7..884c861 100644
--- a/python/evemu/base.py
+++ b/python/evemu/base.py
@@ -137,20 +137,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)
@@ -165,8 +180,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..29bdb15 100644
--- a/python/evemu/tests/test_base.py
+++ b/python/evemu/tests/test_base.py
@@ -13,13 +13,28 @@ 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_static_from_load(self):
+ first = evemu.base.LibC._load()
+ self.assertNotEqual(first, None)
+
+ second = evemu.base.LibC._load()
+ self.assertNotEqual(second, None)
+
+ self.assertEqual(first, second)
+
+ def test_libc_static_in_object(self):
+ first = evemu.base.LibC()
+ self.assertNotEqual(first, None)
+
+ second = evemu.base.LibC()
+ self.assertNotEqual(second, None)
+ self.assertEqual(first._loaded_lib, second._loaded_lib)
if __name__ == "__main__":
unittest.main()
--
1.8.5.2
More information about the Input-tools
mailing list