Author: Armin Rigo <ar...@tunes.org> Branch: cffi-1.0 Changeset: r2019:eea21524de0a Date: 2015-05-17 09:22 +0200 http://bitbucket.org/cffi/cffi/changeset/eea21524de0a/
Log: Best-effort attempt at supporting C++. There is still one issue shown in test_recompiler if we replace "if 0:" with "if 1:". diff --git a/cffi/_cffi_include.h b/cffi/_cffi_include.h --- a/cffi/_cffi_include.h +++ b/cffi/_cffi_include.h @@ -1,4 +1,7 @@ #include <Python.h> +#ifdef __cplusplus +extern "C" { +#endif #include <stddef.h> #include "parse_c_type.h" @@ -145,7 +148,7 @@ assert((((uintptr_t)_cffi_types[index]) & 1) == 0), \ (CTypeDescrObject *)_cffi_types[index]) -static PyObject *_cffi_init(char *module_name, Py_ssize_t version, +static PyObject *_cffi_init(const char *module_name, Py_ssize_t version, const struct _cffi_type_context_s *ctx) { PyObject *module, *o_arg, *new_module; @@ -165,7 +168,7 @@ goto failure; new_module = PyObject_CallMethod( - module, "_init_cffi_1_0_external_module", "O", o_arg); + module, (char *)"_init_cffi_1_0_external_module", (char *)"O", o_arg); Py_DECREF(o_arg); Py_DECREF(module); @@ -200,3 +203,7 @@ #else # define _CFFI_UNUSED_FN /* nothing */ #endif + +#ifdef __cplusplus +} +#endif diff --git a/cffi/api.py b/cffi/api.py --- a/cffi/api.py +++ b/cffi/api.py @@ -475,13 +475,14 @@ ('_UNICODE', '1')] kwds['define_macros'] = defmacros - def set_source(self, module_name, source, **kwds): + def set_source(self, module_name, source, source_extension='.c', **kwds): if hasattr(self, '_assigned_source'): raise ValueError("set_source() cannot be called several times " "per ffi object") if not isinstance(module_name, basestring): raise TypeError("'module_name' must be a string") - self._assigned_source = (source, kwds, str(module_name)) + self._assigned_source = (str(module_name), source, + source_extension, kwds) def distutils_extension(self, tmpdir='build', verbose=True): from distutils.dir_util import mkpath @@ -492,7 +493,7 @@ return self.verifier.get_extension() raise ValueError("set_source() must be called before" " distutils_extension()") - source, kwds, module_name = self._assigned_source + module_name, source, source_extension, kwds = self._assigned_source if source is None: raise TypeError("distutils_extension() is only for C extension " "modules, not for dlopen()-style pure Python " @@ -500,6 +501,7 @@ mkpath(tmpdir) ext, updated = recompile(self, module_name, source, tmpdir=tmpdir, + source_extension=source_extension, call_c_compiler=False, **kwds) if verbose: if updated: @@ -513,7 +515,7 @@ # if not hasattr(self, '_assigned_source'): raise ValueError("set_source() must be called before emit_c_code()") - source, kwds, module_name = self._assigned_source + module_name, source, source_extension, kwds = self._assigned_source if source is None: raise TypeError("emit_c_code() is only for C extension modules, " "not for dlopen()-style pure Python modules") @@ -525,7 +527,7 @@ # if not hasattr(self, '_assigned_source'): raise ValueError("set_source() must be called before emit_c_code()") - source, kwds, module_name = self._assigned_source + module_name, source, source_extension, kwds = self._assigned_source if source is not None: raise TypeError("emit_python_code() is only for dlopen()-style " "pure Python modules, not for C extension modules") @@ -537,9 +539,9 @@ # if not hasattr(self, '_assigned_source'): raise ValueError("set_source() must be called before compile()") - source, kwds, module_name = self._assigned_source - return recompile(self, module_name, - source, tmpdir=tmpdir, **kwds) + module_name, source, source_extension, kwds = self._assigned_source + return recompile(self, module_name, source, tmpdir=tmpdir, + source_extension=source_extension, **kwds) def _load_backend_lib(backend, name, flags): diff --git a/cffi/recompiler.py b/cffi/recompiler.py --- a/cffi/recompiler.py +++ b/cffi/recompiler.py @@ -17,7 +17,7 @@ self.check_value = check_value def as_c_expr(self): - return ' { "%s", %s, %s, %s },' % ( + return ' { "%s", (void *)%s, %s, %s },' % ( self.name, self.address, self.type_op.as_c_expr(), self.size) def as_python_expr(self): @@ -333,8 +333,8 @@ prnt('static const char * const _cffi_includes[] = {') for ffi_to_include in self.ffi._included_ffis: try: - included_source, _, included_module_name = ( - ffi_to_include._assigned_source) + included_module_name, included_source = ( + ffi_to_include._assigned_source[:2]) except AttributeError: raise ffiplatform.VerificationError( "ffi object %r includes %r, but the latter has not " @@ -428,8 +428,8 @@ for i in range(num_includes): ffi_to_include = self.ffi._included_ffis[i] try: - included_source, _, included_module_name = ( - ffi_to_include._assigned_source) + included_module_name, included_source = ( + ffi_to_include._assigned_source[:2]) except AttributeError: raise ffiplatform.VerificationError( "ffi object %r includes %r, but the latter has not " @@ -516,7 +516,8 @@ self._prnt(' if (datasize != 0) {') self._prnt(' if (datasize < 0)') self._prnt(' %s;' % errcode) - self._prnt(' %s = alloca((size_t)datasize);' % (tovar,)) + self._prnt(' %s = (%s)alloca((size_t)datasize);' % ( + tovar, tp.get_c_name(''))) self._prnt(' memset((void *)%s, 0, (size_t)datasize);' % (tovar,)) self._prnt(' if (_cffi_convert_array_from_object(' '(char *)%s, _cffi_type(%d), %s) < 0)' % ( @@ -1122,15 +1123,15 @@ source_name = ffiplatform.maybe_relative_path(c_file) return ffiplatform.get_extension(source_name, module_name, **kwds) -def recompile(ffi, module_name, preamble, tmpdir='.', - call_c_compiler=True, c_file=None, **kwds): +def recompile(ffi, module_name, preamble, tmpdir='.', call_c_compiler=True, + c_file=None, source_extension='.c', **kwds): if not isinstance(module_name, str): module_name = module_name.encode('ascii') if ffi._windows_unicode: ffi._apply_windows_unicode(kwds) if preamble is not None: if c_file is None: - c_file = os.path.join(tmpdir, module_name + '.c') + c_file = os.path.join(tmpdir, module_name + source_extension) ext = _get_extension(module_name, c_file, kwds) updated = make_c_source(ffi, module_name, preamble, c_file) if call_c_compiler: diff --git a/demo/bsdopendirtype_build.py b/demo/bsdopendirtype_build.py --- a/demo/bsdopendirtype_build.py +++ b/demo/bsdopendirtype_build.py @@ -15,9 +15,11 @@ """) ffi.set_source("_bsdopendirtype", """ +extern "C" { #include <sys/types.h> #include <dirent.h> -""") +} +""", source_extension='.cpp') if __name__ == '__main__': ffi.compile() diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py --- a/testing/cffi1/test_recompiler.py +++ b/testing/cffi1/test_recompiler.py @@ -20,6 +20,9 @@ kwds.setdefault('undef_macros', ['NDEBUG']) module_name = '_CFFI_' + module_name ffi.set_source(module_name, source) + if 0: # test the .cpp mode too + kwds.setdefault('source_extension', '.cpp') + source = 'extern "C" {\n%s\n}' % (source,) return recompiler._verify(ffi, module_name, source, *args, **kwds) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit