On Fri, Aug 09, 2019 at 08:31:22AM -0500, Eric Blake wrote:
On 8/9/19 7:59 AM, Richard W.M. Jones wrote:
> In the libguestfs C bindings the handling of optargs is rather
> complex, and I don't intend to replicate that here. Instead they are
> just handled as non-optional arguments appearing after the normal
> arguments.
C can emulate optional arguments via va_args, but with the drawback that
you have to provide some way at the callsite for the implementation to
know which varargs to expect; it gets hairy fast. Keeping things as
non-optional in libnbd C bindings seems reasonable enough.
For interest the way we do this in libguestfs is inspired by Sun's
XView which used va_args like this:
panel_item = xv_create(panel, PANEL_CHOICE_STACK,
XV_WIDTH, 50,
XV_HEIGHT, 25,
PANEL_LABEL_X, 100,
PANEL_LABEL_Y, 100,
PANEL_LABEL_STRING, "Open File",
PANEL_CHOICE_STRINGS, "Append to file",
"Overwrite contents",NULL,
NULL);
(Example from:
ftp://ftp.ora.com/pub/openlook/vol7a.pdf page 23)
However that would break our existing API, and it seems like if you're
using C it's not a big deal to specify all the optional arguments,
particularly for libnbd which is a fairly simple API where we don't
expect to use optargs very much.
In contrast the most optargs used by a libguestfs API is 12 for
guestfs_add_drive_opts:
http://libguestfs.org/guestfs.3.html#guestfs_add_drive_opts
so there (for libguestfs) it does make sense to have a way to supply a
subset from C.
Another possibility is to generate n different function names (each
adding one additional optarg) or even 2^n function names (one for each
combination of which optional args are being provided); in that light,
our existing nbd_aio_pread vs. nbd_aio_pread_callback could be viewed as
two expansions with an optional completion Closure argument, where we
generate 2 C bindings, but where other languages could have just a
single entry point with an optional Closure argument. But that's
obviously ideas for a future patch...
Indeed.
> + | (name, _) ->
> + failwithf "%s: optargs can only be empty list of [OFlags]" name
s/of/or/
Thanks - fixed in my copy.
> @@ -3554,7 +3569,7 @@ let permitted_state_text permitted_states
=
> *)
> let generate_lib_api_c () =
> (* Print the wrapper added around all API calls. *)
> - let rec print_wrapper (name, {args; ret; permitted_states;
> + let rec print_wrapper (name, {args; optargs; ret; permitted_states;
> is_locked; may_set_error}) =
Indentation looks odd to me, but that may be because I'm not familiar
enough with OCaml indentation conventions.
Yes that was wrong too, fixed in my copy.
Thanks,
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW