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