open Generator_structs
open Generator_prepopts
open Generator_c
+open Generator_events
+
+let doc_opttype_of = function
+ | Bool n -> "true|false"
+ | Int n
+ | Int64 n -> "N"
+ | String n -> ".."
+ | _ -> assert false
(* Generate a lot of different functions for guestfish. *)
let generate_fish_cmds () =
pr "#include <config.h>\n";
pr "\n";
+ pr "/* It is safe to call deprecated functions from this file. */\n";
+ pr "#undef GUESTFS_WARN_DEPRECATED\n";
+ pr "\n";
pr "#include <stdio.h>\n";
pr "#include <stdlib.h>\n";
pr "#include <string.h>\n";
pr "#include <inttypes.h>\n";
pr "\n";
- pr "#include <guestfs.h>\n";
pr "#include \"c-ctype.h\"\n";
pr "#include \"full-write.h\"\n";
pr "#include \"xstrtol.h\"\n";
+ pr "\n";
+ pr "#include <guestfs.h>\n";
pr "#include \"fish.h\"\n";
+ pr "#include \"fish-cmds.h\"\n";
pr "#include \"options.h\"\n";
pr "#include \"cmds_gperf.h\"\n";
pr "\n";
(String.concat ""
(List.map (fun arg -> " " ^ name_of_argt arg) args))
(String.concat ""
- (List.map (fun arg -> sprintf " [%s:..]" (name_of_argt arg)) optargs)) in
+ (List.map (fun arg ->
+ sprintf " [%s:%s]" (name_of_argt arg) (doc_opttype_of arg)
+ ) optargs)) in
let warnings =
if List.exists (function Key _ -> true | _ -> false) args then
("\n\n" ^ protocol_limit_warning)
else "" in
- (* For DangerWillRobinson commands, we should probably have
- * guestfish prompt before allowing you to use them (especially
- * in interactive mode). XXX
- *)
- let warnings =
- warnings ^
- if List.mem DangerWillRobinson flags then
- ("\n\n" ^ danger_will_robinson)
- else "" in
-
let warnings =
warnings ^
match deprecation_notice flags with
) all_functions;
(* list_commands function, which implements guestfish -h *)
- pr "void list_commands (void)\n";
+ pr "void\n";
+ pr "list_commands (void)\n";
pr "{\n";
pr " printf (\" %%-16s %%s\\n\", _(\"Command\"), _(\"Description\"));\n";
pr " list_builtin_commands ();\n";
pr "\n";
(* display_command function, which implements guestfish -h cmd *)
- pr "int display_command (const char *cmd)\n";
+ pr "int\n";
+ pr "display_command (const char *cmd)\n";
pr "{\n";
pr " const struct command_table *ct;\n";
pr "\n";
pr "\n";
let emit_print_list_function typ =
- pr "static void print_%s_list (struct guestfs_%s_list *%ss)\n"
+ pr "static void\n";
+ pr "print_%s_list (struct guestfs_%s_list *%ss)\n"
typ typ typ;
pr "{\n";
pr " unsigned int i;\n";
let needs_i =
List.exists (function (_, (FUUID|FBuffer)) -> true | _ -> false) cols in
- pr "static void print_%s_indent (struct guestfs_%s *%s, const char *indent)\n" typ typ typ;
+ pr "static void\n";
+ pr "print_%s_indent (struct guestfs_%s *%s, const char *indent)\n" typ typ typ;
pr "{\n";
if needs_i then (
pr " unsigned int i;\n";
pr " printf (\"%%s%s: %%c\\n\", indent, %s->%s);\n"
name typ name
| name, FOptPercent ->
- pr " if (%s->%s >= 0) printf (\"%%s%s: %%g %%%%\\n\", indent, %s->%s);\n"
- typ name name typ name;
- pr " else printf (\"%%s%s: \\n\", indent);\n" name
+ pr " if (%s->%s >= 0)\n" typ name;
+ pr " printf (\"%%s%s: %%g %%%%\\n\", indent, (double) %s->%s);\n"
+ name typ name;
+ pr " else\n";
+ pr " printf (\"%%s%s: \\n\", indent);\n" name
) cols;
pr "}\n";
pr "\n";
List.iter (
function
| typ, (RStructOnly | RStructAndList) ->
- pr "static void print_%s (struct guestfs_%s *%s)\n" typ typ typ;
+ pr "static void\n";
+ pr "print_%s (struct guestfs_%s *%s)\n" typ typ typ;
pr "{\n";
pr " print_%s_indent (%s, \"\");\n" typ typ;
pr "}\n";
pr " %s = argv[i++];\n" name
| Pathname name
| Dev_or_Path name ->
- pr " %s = resolve_win_path (argv[i++]);\n" name;
+ pr " %s = win_prefix (argv[i++]); /* process \"win:\" prefix */\n" name;
pr " if (%s == NULL) return -1;\n" name
| OptString name ->
pr " %s = STRNEQ (argv[i], \"\") ? argv[i] : NULL;\n" name;
pr " if (%s == NULL) return -1;\n" name
| Key name ->
pr " %s = read_key (\"%s\");\n" name name;
+ pr " if (keys_from_stdin)\n";
+ pr " input_lineno++;\n";
pr " if (%s == NULL) return -1;\n" name
| Bool name ->
pr " %s = is_true (argv[i++]) ? 1 : 0;\n" name
pr " }\n";
pr "}\n"
+and generate_fish_cmds_h () =
+ generate_header CStyle GPLv2plus;
+
+ pr "#ifndef FISH_CMDS_H\n";
+ pr "#define FISH_CMDS_H\n";
+ pr "\n";
+
+ List.iter (
+ fun (shortname, _, _, _, _, _, _) ->
+ pr "extern int run_%s (const char *cmd, size_t argc, char *argv[]);\n"
+ shortname
+ ) fish_commands;
+
+ pr "\n";
+ pr "#endif /* FISH_CMDS_H */\n"
+
(* gperf code to do fast lookups of commands. *)
and generate_fish_cmds_gperf () =
generate_header CStyle GPLv2plus;
) args;
List.iter (
function
- | Bool n | Int n | Int64 n | String n -> pr " [%s:..]" n
+ | (Bool n | Int n | Int64 n | String n) as arg ->
+ pr " [%s:%s]" n (doc_opttype_of arg)
| _ -> assert false
) optargs;
pr "\n";
if List.mem ProtocolLimitWarning flags then
pr "%s\n\n" protocol_limit_warning;
- if List.mem DangerWillRobinson flags then
- pr "%s\n\n" danger_will_robinson;
-
match deprecation_notice flags with
| None -> ()
| Some txt -> pr "%s\n\n" txt
name name;
) prepopts;
pr "};\n"
+
+and generate_fish_event_names () =
+ generate_header CStyle GPLv2plus;
+
+ pr "\
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include \"fish.h\"
+
+const char *
+event_name_of_event_bitmask (uint64_t ev)
+{
+ switch (ev) {
+";
+
+ List.iter (
+ fun (name, _) ->
+ pr " case GUESTFS_EVENT_%s:\n" (String.uppercase name);
+ pr " return \"%s\";\n" name
+ ) events;
+
+ pr " default:
+ abort (); /* should not happen */
+ }
+}
+
+void
+print_event_set (uint64_t event_bitmask, FILE *fp)
+{
+ int comma = 0;
+
+ if (event_bitmask == GUESTFS_EVENT_ALL) {
+ fputs (\"*\", fp);
+ return;
+ }
+
+";
+
+ List.iter (
+ fun (name, _) ->
+ pr " if (event_bitmask & GUESTFS_EVENT_%s) {\n" (String.uppercase name);
+ pr " if (comma) fputc (',', fp);\n";
+ pr " comma = 1;\n";
+ pr " fputs (\"%s\", fp);\n" name;
+ pr " }\n"
+ ) events;
+
+ pr "\
+}
+
+int
+event_bitmask_of_event_set (const char *arg, uint64_t *eventset_r)
+{
+ size_t n;
+
+ if (STREQ (arg, \"*\")) {
+ *eventset_r = GUESTFS_EVENT_ALL;
+ return 0;
+ }
+
+ *eventset_r = 0;
+
+ while (*arg) {
+ n = strcspn (arg, \",\");
+
+ ";
+
+ List.iter (
+ fun (name, _) ->
+ pr "if (STREQLEN (arg, \"%s\", n))\n" name;
+ pr " *eventset_r |= GUESTFS_EVENT_%s;\n" (String.uppercase name);
+ pr " else ";
+ ) events;
+
+ pr "\
+{
+ fprintf (stderr, _(\"unknown event name: %%s\\n\"), arg);
+ return -1;
+ }
+
+ arg += n;
+ if (*arg == ',')
+ arg++;
+ }
+
+ return 0;
+}
+"