Richard W.M. Jones
2015-Sep-15 13:54 UTC
[Libguestfs] [PATCH 3/3] python: Allow bindings to be compiled with different version of libguestfs (RHBZ#1262983).
Patch to fix: https://bugzilla.redhat.com/show_bug.cgi?id=1262983 Note this won't help until the first two patches get backported to the stable branches, since <guestfs.h> won't define the necessary GUESTFS_HAVE_* macros. Rich.
Richard W.M. Jones
2015-Sep-15 13:54 UTC
[Libguestfs] [PATCH 1/3] header: Define GUESTFS_HAVE_* for every function.
Previously we only defined GUESTFS_HAVE_* macros for functions that
were not deprecated, test or debug functions. The reasoning for that
is given in this commit message [note that 'LIBGUESTFS_HAVE_' is the
old/deprecated macro]:
commit 2d8fd7dacd77361bc385be42112289faafb5c60d
Author: Richard Jones <rjones@redhat.com>
Date: Thu Sep 2 22:45:54 2010 +0100
Define LIBGUESTFS_HAVE_<shortname> for C API functions.
The actions each have a corresponding define, eg:
#define LIBGUESTFS_HAVE_VGUUID 1
extern char *guestfs_vguuid (guestfs_h *g, const char *vgname);
However functions which are for testing, debugging or deprecated do
not have the corresponding define. Also a few functions are so
basic (eg. guestfs_create) that there is no point defining a symbol
for them.
This wasn't in fact carried through very consistently, since when we
replaced s/LIBGUESTFS_HAVE_/GUESTFS_HAVE_/, we kept the old
LIBGUESTFS_HAVE_* macros, but defined them for every function. Oops.
This commit defines GUESTFS_HAVE_* for every function in <guestfs.h>,
making it easier to write the Python language bindings (see following
commits).
---
generator/c.ml | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/generator/c.ml b/generator/c.ml
index a2b9c94..ae8e933 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -645,13 +645,7 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private
(guestfs_h *g, const char *
let generate_action_header { name = shortname;
style = ret, args, optargs as style;
deprecated_by = deprecated_by } - let test -
String.length shortname >= 13 &&
- String.sub shortname 0 13 = "internal_test" in
- let debug - String.length shortname >= 5 && String.sub
shortname 0 5 = "debug" in
- if deprecated_by = None && not test && not debug then
- pr "#define GUESTFS_HAVE_%s 1\n" (String.uppercase shortname);
+ pr "#define GUESTFS_HAVE_%s 1\n" (String.uppercase shortname);
if optargs <> [] then (
iteri (
--
2.5.0
Richard W.M. Jones
2015-Sep-15 13:54 UTC
[Libguestfs] [PATCH 2/3] header: Define GUESTFS_HAVE_STRUCT_* for each struct defined in the header.
---
generator/c.ml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/generator/c.ml b/generator/c.ml
index ae8e933..055b683 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -603,6 +603,8 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private
(guestfs_h *g, const char *
(* Public structures. *)
let generate_all_structs = List.iter (
fun { s_name = typ; s_cols = cols } ->
+ pr "#define GUESTFS_HAVE_STRUCT_%s 1\n" (String.uppercase typ);
+ pr "\n";
pr "struct guestfs_%s {\n" typ;
List.iter (
function
--
2.5.0
Richard W.M. Jones
2015-Sep-15 13:54 UTC
[Libguestfs] [PATCH 3/3] python: Allow bindings to be compiled with different version of libguestfs (RHBZ#1262983).
When compiling the libguestfs bindings as a pip module, it's helpful
if you can compile the bindings with a different version of libguestfs
(eg. installed 1.28, pip module 1.30).
That broke the previous assumption that we were always compiling
against precisely the same version of libguestfs (which made sense
because the python bindings are part of the libguestfs source tree).
Python distutils has no way to check a C library to find out if
functions are defined. Therefore we have to rely on GUESTFS_HAVE_*
macros from <guestfs.h>.
---
generator/python.ml | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/generator/python.ml b/generator/python.ml
index 637f22d..c1128f8 100644
--- a/generator/python.ml
+++ b/generator/python.ml
@@ -140,6 +140,7 @@ put_table (char * const * const argv)
";
let emit_put_list_function typ + pr "#ifdef
GUESTFS_HAVE_STRUCT_%s\n" (String.uppercase typ);
pr "static PyObject *\n";
pr "put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ;
pr "{\n";
@@ -151,12 +152,14 @@ put_table (char * const * const argv)
pr " PyList_SetItem (list, i, put_%s
(&%ss->val[i]));\n" typ typ;
pr " return list;\n";
pr "};\n";
+ pr "#endif\n";
pr "\n"
in
(* Structures, turned into Python dictionaries. *)
List.iter (
fun { s_name = typ; s_cols = cols } ->
+ pr "#ifdef GUESTFS_HAVE_STRUCT_%s\n" (String.uppercase typ);
pr "static PyObject *\n";
pr "put_%s (struct guestfs_%s *%s)\n" typ typ typ;
pr "{\n";
@@ -228,6 +231,7 @@ put_table (char * const * const argv)
) cols;
pr " return dict;\n";
pr "};\n";
+ pr "#endif\n";
pr "\n";
) external_structs;
@@ -246,6 +250,7 @@ put_table (char * const * const argv)
fun { name = name; style = (ret, args, optargs as style);
blocking = blocking;
c_function = c_function; c_optarg_prefix = c_optarg_prefix } ->
+ pr "#ifdef GUESTFS_HAVE_%s\n" (String.uppercase name);
pr "static PyObject *\n";
pr "py_guestfs_%s (PyObject *self, PyObject *args)\n" name;
pr "{\n";
@@ -381,6 +386,7 @@ put_table (char * const * const argv)
fun optarg ->
let n = name_of_optargt optarg in
let uc_n = String.uppercase n in
+ pr "#ifdef %s_%s_BITMASK\n" c_optarg_prefix uc_n;
pr " if (py_%s != Py_None) {\n" n;
pr " optargs_s.bitmask |= %s_%s_BITMASK;\n"
c_optarg_prefix uc_n;
(match optarg with
@@ -403,6 +409,7 @@ put_table (char * const * const argv)
pr " if (!optargs_s.%s) goto out;\n" n;
);
pr " }\n";
+ pr "#endif\n"
) optargs;
pr "\n"
);
@@ -524,13 +531,16 @@ put_table (char * const * const argv)
| OBool _ | OInt _ | OInt64 _ | OString _ -> ()
| OStringList n ->
let uc_n = String.uppercase n in
+ pr "#ifdef %s_%s_BITMASK\n" c_optarg_prefix uc_n;
pr " if (py_%s != Py_None && (optargs_s.bitmask &
%s_%s_BITMASK) != 0)\n"
n c_optarg_prefix uc_n;
- pr " free ((char **) optargs_s.%s);\n" n
+ pr " free ((char **) optargs_s.%s);\n" n;
+ pr "#endif\n"
) optargs;
pr " return py_r;\n";
pr "}\n";
+ pr "#endif\n";
pr "\n"
) external_functions_sorted;
@@ -546,8 +556,10 @@ put_table (char * const * const argv)
pr " py_guestfs_event_to_string, METH_VARARGS, NULL },\n";
List.iter (
fun { name = name } ->
+ pr "#ifdef GUESTFS_HAVE_%s\n" (String.uppercase name);
pr " { (char *) \"%s\", py_guestfs_%s, METH_VARARGS, NULL
},\n"
- name name
+ name name;
+ pr "#endif\n"
) external_functions_sorted;
pr " { NULL, NULL, 0, NULL }\n";
pr "};\n";
--
2.5.0
Reasonably Related Threads
- [PATCH] python: fix possible free on uninit memory with OStringList optargs
- [PATCH 0/7] Add tar compress, numericowner, excludes flags.
- [PATCH 1/4] php: fix invalid memory access with OptString
- [PATCH 0/6] Allow non-optargs functions to gain optional arguments.
- [PATCH] generator: Share Common_utils code.