Files
libguestfs/generator/actions.ml
2017-02-21 17:23:21 +00:00

184 lines
6.5 KiB
OCaml

(* libguestfs
* Copyright (C) 2009-2017 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*)
(* Please read generator/README first. *)
open Common_utils
open Types
open Utils
(* non_daemon_functions are any functions which don't get processed
* in the daemon, eg. functions for setting and getting local
* configuration values.
*)
let non_daemon_functions =
Actions_internal_tests.test_functions @
Actions_internal_tests.test_support_functions @
Actions_core.non_daemon_functions @
Actions_core_deprecated.non_daemon_functions @
Actions_debug.non_daemon_functions @
Actions_hivex.non_daemon_functions @
Actions_inspection.non_daemon_functions @
Actions_inspection_deprecated.non_daemon_functions @
Actions_properties.non_daemon_functions @
Actions_properties_deprecated.non_daemon_functions @
Actions_tsk.non_daemon_functions
(* daemon_functions are any functions which cause some action
* to take place in the daemon.
*)
let daemon_functions =
Actions_augeas.daemon_functions @
Actions_core.daemon_functions @
Actions_core_deprecated.daemon_functions @
Actions_debug.daemon_functions @
Actions_hivex.daemon_functions @
Actions_tsk.daemon_functions
(* Some post-processing of the basic lists of actions. *)
(* Add the name of the C function:
* c_name = short name, used by C bindings so we know what to export
* c_function = full name that non-C bindings should call
* c_optarg_prefix = prefix for optarg / bitmask names
*)
let test_functions, non_daemon_functions, daemon_functions =
let make_c_function f =
match f with
| { style = _, _, [] } ->
{ f with
c_name = f.name;
c_function = "guestfs_" ^ f.name;
c_optarg_prefix = "GUESTFS_" ^ String.uppercase_ascii f.name }
| { style = _, _, (_::_); once_had_no_optargs = false } ->
{ f with
c_name = f.name;
c_function = "guestfs_" ^ f.name ^ "_argv";
c_optarg_prefix = "GUESTFS_" ^ String.uppercase_ascii f.name }
| { style = _, _, (_::_); once_had_no_optargs = true } ->
{ f with
c_name = f.name ^ "_opts";
c_function = "guestfs_" ^ f.name ^ "_opts_argv";
c_optarg_prefix = "GUESTFS_" ^ String.uppercase_ascii f.name
^ "_OPTS";
non_c_aliases = [ f.name ^ "_opts" ] }
in
let test_functions =
List.map make_c_function Actions_internal_tests.test_functions in
let non_daemon_functions = List.map make_c_function non_daemon_functions in
let daemon_functions = List.map make_c_function daemon_functions in
test_functions, non_daemon_functions, daemon_functions
(* Create a camel-case version of each name, unless the camel_name
* field was set above.
*)
let non_daemon_functions, daemon_functions =
let make_camel_case name =
List.fold_left (
fun a b ->
a ^ String.uppercase_ascii (Str.first_chars b 1) ^ Str.string_after b 1
) "" (Str.split (Str.regexp "_") name)
in
let make_camel_case_if_not_set f =
if f.camel_name = "" then
{ f with camel_name = make_camel_case f.name }
else
f
in
let non_daemon_functions =
List.map make_camel_case_if_not_set non_daemon_functions in
let daemon_functions =
List.map make_camel_case_if_not_set daemon_functions in
non_daemon_functions, daemon_functions
(* Before we add the non_daemon_functions and daemon_functions to
* a single list, verify the proc_nr field which should be the only
* difference between them. (Note more detailed checking is done
* in checks.ml).
*)
let () =
List.iter (
function
| { name = name; proc_nr = None } ->
failwithf "daemon function %s should have proc_nr = Some n > 0" name
| { name = name; proc_nr = Some n } when n <= 0 ->
failwithf "daemon function %s should have proc_nr = Some n > 0" name
| { proc_nr = Some _ } -> ()
) daemon_functions;
List.iter (
function
| { name = name; proc_nr = Some _ } ->
failwithf "non-daemon function %s should have proc_nr = None" name
| { proc_nr = None } -> ()
) non_daemon_functions
(* This is used to generate the lib/MAX_PROC_NR file which
* contains the maximum procedure number, a surrogate for the
* ABI version number. See lib/Makefile.am for the details.
*)
let max_proc_nr =
let proc_nrs = List.map (
function { proc_nr = Some n } -> n | { proc_nr = None } -> assert false
) daemon_functions in
List.fold_left max 0 proc_nrs
(* All functions. *)
let actions = non_daemon_functions @ daemon_functions
(* Filters which can be applied. *)
let is_non_daemon_function = function
| { proc_nr = None } -> true
| { proc_nr = Some _ } -> false
let non_daemon_functions = List.filter is_non_daemon_function
let is_daemon_function f = not (is_non_daemon_function f)
let daemon_functions = List.filter is_daemon_function
let is_external { visibility = v } = match v with
| VPublic | VPublicNoFish | VStateTest | VBindTest | VDebug -> true
| VInternal -> false
let external_functions = List.filter is_external
let is_internal f = not (is_external f)
let internal_functions = List.filter is_internal
let is_documented { visibility = v } = match v with
| VPublic | VPublicNoFish | VStateTest -> true
| VBindTest | VDebug | VInternal -> false
let documented_functions = List.filter is_documented
let is_fish { visibility = v; style = (_, args, _) } =
(* Internal functions are not exported to guestfish. *)
match v with
| VPublicNoFish | VStateTest | VBindTest | VInternal -> false
| VPublic | VDebug ->
(* Functions that take Pointer parameters cannot be used in
* guestfish, since there is no way the user could safely
* generate a pointer.
*)
not (List.exists (function Pointer _ -> true | _ -> false) args)
let fish_functions = List.filter is_fish
(* In some places we want the functions to be displayed sorted
* alphabetically, so this is useful:
*)
let sort = List.sort action_compare