X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Fgenerator.ml;h=6ef8e1b3435cd28d1f83abe4001a31d14ca5a507;hb=d268e64fe76944dc042e7ec68a65e59a6cff16ce;hp=84ee90ff77d95149e734039bd3b70efa94b5795b;hpb=2a243cfbe1938d324ac6445aa2917ec3db0d8c50;p=libguestfs.git diff --git a/src/generator.ml b/src/generator.ml index 84ee90f..6ef8e1b 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -950,6 +950,57 @@ Some internal mounts are not unmounted by this call."); This command removes all LVM logical volumes, volume groups and physical volumes."); + ("file", (RString "description", [String "path"]), 49, [], + [InitBasicFS, TestOutput ( + [["touch"; "/new"]; + ["file"; "/new"]], "empty"); + InitBasicFS, TestOutput ( + [["write_file"; "/new"; "some content\n"; "0"]; + ["file"; "/new"]], "ASCII text"); + InitBasicFS, TestLastFail ( + [["file"; "/nofile"]])], + "determine file type", + "\ +This call uses the standard L command to determine +the type or contents of the file. This also works on devices, +for example to find out whether a partition contains a filesystem. + +The exact command which runs is C. Note in +particular that the filename is not prepended to the output +(the C<-b> option)."); + + ("command", (RString "output", [StringList "arguments"]), 50, [], + [], (* XXX how to test? *) + "run a command from the guest filesystem", + "\ +This call runs a command from the guest filesystem. The +filesystem must be mounted, and must contain a compatible +operating system (ie. something Linux, with the same +or compatible processor architecture). + +The single parameter is an argv-style list of arguments. +The first element is the name of the program to run. +Subsequent elements are parameters. The list must be +non-empty (ie. must contain a program name). + +The C<$PATH> environment variable will contain at least +C and C. If you require a program from +another location, you should provide the full path in the +first parameter. + +Shared libraries and data files required by the program +must be available on filesystems which are mounted in the +correct places. It is the caller's responsibility to ensure +all filesystems that are needed are mounted at the right +locations."); + + ("command_lines", (RStringList "lines", [StringList "arguments"]), 51, [], + [], (* XXX how to test? *) + "run a command, returning lines", + "\ +This is the same as C, but splits the +result into a list of lines."); + ] let all_functions = non_daemon_functions @ daemon_functions @@ -1144,7 +1195,9 @@ let check_functions () = failwithf "%s param/ret %s should not contain '-' or '_'" name n; if n = "value" then - failwithf "%s has a param/ret called 'value', which causes conflicts in the OCaml bindings, use something like 'val' or a more descriptive name" n + failwithf "%s has a param/ret called 'value', which causes conflicts in the OCaml bindings, use something like 'val' or a more descriptive name" n; + if n = "argv" || n = "args" then + failwithf "%s has a param/ret called 'argv' or 'args', which will cause some conflicts in the generated code" n in (match fst style with @@ -1282,10 +1335,10 @@ let rec generate_actions_pod () = | RBool _ -> pr "This function returns a C truth value on success or -1 on error.\n\n" | RConstString _ -> - pr "This function returns a string or NULL on error. + pr "This function returns a string, or NULL on error. The string is owned by the guest handle and must I be freed.\n\n" | RString _ -> - pr "This function returns a string or NULL on error. + pr "This function returns a string, or NULL on error. I.\n\n" | RStringList _ -> pr "This function returns a NULL-terminated array of strings @@ -2776,6 +2829,87 @@ and generate_fish_cmds () = pr "}\n"; pr "\n" +(* Readline completion for guestfish. *) +and generate_fish_completion () = + generate_header CStyle GPLv2; + + let all_functions = + List.filter ( + fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags) + ) all_functions in + + pr "\ +#include + +#include +#include +#include + +#ifdef HAVE_LIBREADLINE +#include +#endif + +#include \"fish.h\" + +#ifdef HAVE_LIBREADLINE + +static const char *commands[] = { +"; + + (* Get the commands and sort them, including the aliases. *) + let commands = + List.map ( + fun (name, _, _, flags, _, _, _) -> + let name2 = replace_char name '_' '-' in + let alias = + try find_map (function FishAlias n -> Some n | _ -> None) flags + with Not_found -> name in + + if name <> alias then [name2; alias] else [name2] + ) all_functions in + let commands = List.flatten commands in + let commands = List.sort compare commands in + + List.iter (pr " \"%s\",\n") commands; + + pr " NULL +}; + +static char * +generator (const char *text, int state) +{ + static int index, len; + const char *name; + + if (!state) { + index = 0; + len = strlen (text); + } + + while ((name = commands[index]) != NULL) { + index++; + if (strncasecmp (name, text, len) == 0) + return strdup (name); + } + + return NULL; +} + +#endif /* HAVE_LIBREADLINE */ + +char **do_completion (const char *text, int start, int end) +{ + char **matches = NULL; + +#ifdef HAVE_LIBREADLINE + if (start == 0) + matches = rl_completion_matches (text, generator); +#endif + + return matches; +} +"; + (* Generate the POD documentation for guestfish. *) and generate_fish_actions_pod () = let all_functions_sorted = @@ -3332,20 +3466,22 @@ DESTROY (g) | OptString _ | Bool _ | Int _ -> () - | StringList n -> pr " free (%s);\n" n + | StringList n -> pr " free (%s);\n" n ) (snd style) in (* Code. *) (match fst style with | RErr -> + pr "PREINIT:\n"; + pr " int r;\n"; pr " PPCODE:\n"; - pr " if (guestfs_%s " name; + pr " r = guestfs_%s " name; generate_call_args ~handle:"g" style; - pr " == -1) {\n"; + pr ";\n"; do_cleanups (); + pr " if (r == -1)\n"; pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name; - pr " }\n" | RInt n | RBool n -> pr "PREINIT:\n"; @@ -3354,10 +3490,9 @@ DESTROY (g) pr " %s = guestfs_%s " n name; generate_call_args ~handle:"g" style; pr ";\n"; - pr " if (%s == -1) {\n" n; do_cleanups (); + pr " if (%s == -1)\n" n; pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name; - pr " }\n"; pr " RETVAL = newSViv (%s);\n" n; pr " OUTPUT:\n"; pr " RETVAL\n" @@ -3368,10 +3503,9 @@ DESTROY (g) pr " %s = guestfs_%s " n name; generate_call_args ~handle:"g" style; pr ";\n"; - pr " if (%s == NULL) {\n" n; do_cleanups (); + pr " if (%s == NULL)\n" n; pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name; - pr " }\n"; pr " RETVAL = newSVpv (%s, 0);\n" n; pr " OUTPUT:\n"; pr " RETVAL\n" @@ -3382,10 +3516,9 @@ DESTROY (g) pr " %s = guestfs_%s " n name; generate_call_args ~handle:"g" style; pr ";\n"; - pr " if (%s == NULL) {\n" n; do_cleanups (); + pr " if (%s == NULL)\n" n; pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name; - pr " }\n"; pr " RETVAL = newSVpv (%s, 0);\n" n; pr " free (%s);\n" n; pr " OUTPUT:\n"; @@ -3398,10 +3531,9 @@ DESTROY (g) pr " %s = guestfs_%s " n name; generate_call_args ~handle:"g" style; pr ";\n"; - pr " if (%s == NULL) {\n" n; do_cleanups (); + pr " if (%s == NULL)\n" n; pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name; - pr " }\n"; pr " for (n = 0; %s[n] != NULL; ++n) /**/;\n" n; pr " EXTEND (SP, n);\n"; pr " for (i = 0; i < n; ++i) {\n"; @@ -3416,28 +3548,25 @@ DESTROY (g) pr " r = guestfs_%s " name; generate_call_args ~handle:"g" style; pr ";\n"; - pr " if (r == NULL) {\n"; do_cleanups (); + pr " if (r == NULL)\n"; pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name; - pr " }\n"; pr " EXTEND (SP, 2);\n"; pr " PUSHs (sv_2mortal (newSViv (r->i)));\n"; pr " PUSHs (sv_2mortal (newSViv (r->b)));\n"; pr " guestfs_free_int_bool (r);\n"; | RPVList n -> - generate_perl_lvm_code "pv" pv_cols name style n; + generate_perl_lvm_code "pv" pv_cols name style n do_cleanups; | RVGList n -> - generate_perl_lvm_code "vg" vg_cols name style n; + generate_perl_lvm_code "vg" vg_cols name style n do_cleanups; | RLVList n -> - generate_perl_lvm_code "lv" lv_cols name style n; + generate_perl_lvm_code "lv" lv_cols name style n do_cleanups; ); - do_cleanups (); - pr "\n" ) all_functions -and generate_perl_lvm_code typ cols name style n = +and generate_perl_lvm_code typ cols name style n do_cleanups = pr "PREINIT:\n"; pr " struct guestfs_lvm_%s_list *%s;\n" typ n; pr " int i;\n"; @@ -3446,6 +3575,7 @@ and generate_perl_lvm_code typ cols name style n = pr " %s = guestfs_%s " n name; generate_call_args ~handle:"g" style; pr ";\n"; + do_cleanups (); pr " if (%s == NULL)\n" n; pr " croak (\"%s: %%s\", guestfs_last_error (g));\n" name; pr " EXTEND (SP, %s->len);\n" n; @@ -4023,6 +4153,10 @@ Run it from the top source directory using the command generate_fish_cmds (); close (); + let close = output_to "fish/completion.c" in + generate_fish_completion (); + close (); + let close = output_to "guestfs-structs.pod" in generate_structs_pod (); close ();