For a very long time we have maintained two sets of utility functions,
in mllib/common_utils.ml and generator/utils.ml. This changes things
so that the same set of utility functions can be shared with both
directories.
It's not possible to use common_utils.ml directly in the generator
because it provides several functions that use modules outside the
OCaml stdlib. Therefore we add some lightweight post-processing which
extracts the functions using only the stdlib:
(*<stdlib>*)
...
(*</stdlib>*)
and creates generator/common_utils.ml and generator/common_utils.mli
from that. The effect is we only need to write utility functions
once.
As with other tools, we still have generator-specific utility
functions in generator/utils.ml.
Also in this change:
- Use String.uppercase_ascii and String.lowercase_ascii in place
of deprecated String.uppercase/String.lowercase.
- Implement String.capitalize_ascii to replace deprecated
String.capitalize.
- Move isspace, isdigit, isxdigit functions to Char module.
Previously we used an awkward hack to split up the large src/actions.c
into smaller files (which can benefit from being compiled in
parallel). This commit generalizes that code, so that we pass a
subsetted actions list to certain generator functions.
The output of the generator is identical after this commit and the
previous commit, except for the UUID encoded into tests/c-api/tests.c
since that is derived from the MD5 hash of generator/actions.ml.
This mostly mechanical change moves all of the libguestfs API
lists of functions into a struct in the Actions module.
It also adds filter functions to be used elsewhere to get
subsets of these functions.
Original code Replacement
all_functions actions
daemon_functions actions |> daemon_functions
non_daemon_functions actions |> non_daemon_functions
external_functions actions |> external_functions
internal_functions actions |> internal_functions
documented_functions actions |> documented_functions
fish_functions actions |> fish_functions
*_functions_sorted ... replacement as above ... |> sort
Document which feature, if any, is needed for a function; this should
help users in properly checking feature availability when using certain
functions.
Extend the generator to generate a source (and the header for it) with
functions that print the content of a guestfs struct. The code is
modelled after the code for it in fish.ml, although made a bit more
generic (destination FILE*, line separator) so it can be used also in
the library, when tracing.
This just introduces the new code and builds it as part of the helper
libutils.la.
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 2d8fd7dacd
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).
libguestfs has used double and triple underscores in identifiers.
These aren't valid for global names in C++.
The second step is to replace all guestfs__* (2 underscores) with
guestfs_impl_*.
These functions are used where a libguestfs API call is implemented on
the library side. The generator creates a wrapper function which
calls guestfs_impl_* to do the work. (Libguestfs APIs which are
passed directly by the daemon work differently and don't require a
guestfs_impl_* function).
This is an entirely mechanical change done using:
git ls-files | xargs perl -pi.bak -e 's/guestfs___/guestfs_impl_/g'
Reference: http://stackoverflow.com/a/228797
libguestfs has used double and triple underscores in identifiers.
These aren't valid for global names in C++.
The first step is to replace all guestfs___* (3 underscores) with
guestfs_int_*. We've used guestfs_int_* elsewhere already as a prefix
for internal identifiers.
This is an entirely mechanical change done using:
git ls-files | xargs perl -pi.bak -e 's/guestfs___/guestfs_int_/g'
Reference: http://stackoverflow.com/a/228797
This API already existed (as guestfs___add_libvirt_dom), and was used
by a few tools.
This commit changes it to a public API.
Note that for reasons outlined in the previous commit message, it is
impossible to call this from guestfish or from non-C language
bindings.
This implements Pointer arguments properly, at least for certain
limited definitions of "implements" and "properly".
'Pointer' as an argument type is meant to indicate a pointer passed to
an API. The canonical example is the following proposed API:
int guestfs_add_libvirt_dom (guestfs_h *g, virDomainPtr dom, ...);
where 'dom' is described in the generator as:
Pointer ("virDomainPtr", "dom")
Pointer existed already in the generator, but the implementation was
broken. It is not used by any existing API.
There are two basic difficulties of implementing Pointer:
(1) In language bindings there is no portable way to turn (eg.) a Perl
Sys::Virt 'dom' object into a C virDomainPtr.
(2) We can't rely on <libvirt/libvirt.h> being included (since it's an
optional dependency).
In this commit, we solve (2) by using a 'void *'.
We don't solve (1), really. Instead we have a macro
POINTER_NOT_IMPLEMENTED which is used by currently all the non-C
language bindings. It complains loudly and passes a NULL to the
underlying function. The underlying function detects the NULL and
safely returns an error. It is to be hoped that people will
contribute patches to make each language binding work, although in
some bindings it will always remain impossible to implement.
The FileIn/FileOut parameters are not passed through to the daemon.
Previously we generated incorrect RPC code (an empty 'struct
guestfs_<fn>_args') because we didn't account for these FileIn/FileOut
parameters correctly.
This function is now generated, so bindings in various languages
are made automatically.
Note that the function previously returned void, but now it returns
int (although always 0). We don't believe that this is an ABI break
since existing programs will continue to work.
Non-daemon functions normally have a wrapper function called
eg. guestfs_name. The "real" (ie. hand-written) function is called
eg. guestfs__name. The wrapper deals with checking parameters and
doing trace messages.
This commit allows the wrapper function to be omitted. The reason is
so that we can handle a few functions that have to be thread-safe
(currently just: guestfs_user_cancel). The wrapper is not thread safe
because it can call events and/or the error handler.
The libutils convenience library is a place for code shared between
the main library, language bindings and virt tools. Note that the
code is statically linked into both the library, each binding and each
tool, but this is an improvement because (a) the source is shared and
(b) libguestfs.so can export fewer private functions.
Currently it contains the cleanup functions, and the functions
guestfs___free_string_list function and guestfs___for_each_disk.
guestfs___for_each_disk has changed so that it no longer
unconditionally sets the error in the guestfs handle. Instead callers
can control error handling.
These are internal functions. Very old versions of libguestfs used to
export them, but they haven't been (and shouldn't be) exported for a
long time.
Also remove the unused guestfs_error function.
Note that you have to use this as follows:
#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= x0y0z /* gcc >= x.y.z */
since GUESTFS_GCC_VERSION is not defined unless it's GCC.
A Mountable is passed from the library to the daemon as a string. The daemon
stub parses it into a mountable_t, which it passes to the implementation.
Update all implementations which now take a mountable_t.