On 8/9/19 7:59 AM, Richard W.M. Jones wrote: > In libguestfs generator we have the concept of optargs which is > different from plain arguments. These are mapped to optional > arguments in languages that support them such as Python. > > This commit adds a new concept of optargs. At the moment it is simply > limited to handling the optional (in some bindings) flags parameter > which is used to handle the NBD_CMD_FLAG_* flags. > > If present, the old Flags parameter becomes OFlags and is moved into > the optargs list. > > For the OCaml generation this change simplifies things considerably as > we no longer need the mapping from C arg to ocaml_arg (they are now > the same). > > 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.
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...
>
> Note this commit does not change the API in any language.
> ---
> generator/generator | 505 +++++++++++++++++++++++---------------------
> 1 file changed, 259 insertions(+), 246 deletions(-)
>
> @@ -3157,17 +3169,14 @@ end = struct
>
> (* Check the API definition. *)
> let () =
> - (* Flags must only appear once in the final argument position. *)
> + (* Currently optargs can only be [] or [OFlags]. This condition
> + * will be relaxed later when we support more optional arguments.
> + *)
...and you even mention that we might have more optional arguments in
the future.
> List.iter (
> - fun (name, { args }) ->
> - let args = List.rev args in
> - match args with
> - | [] -> ()
> - | Flags _ :: xs
> - | xs ->
> - if List.exists (function Flags _ -> true | _ -> false) xs then
> - failwithf "%s: Flags must appear in final argument position only"
> - name
> + function
> + | _, { optargs = [] } | _, { optargs = [OFlags _] } -> ()
> + | (name, _) ->
> + failwithf "%s: optargs can only be empty list of [OFlags]" name
s/of/or/
> @@ -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.
ACK with the typo fix.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization: qemu.org | libvirt.org
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Libguestfs mailing list [email protected] https://www.redhat.com/mailman/listinfo/libguestfs
