Make parallel compiles faster in this directory (about 8s down to 3s).
---
.gitignore | 3 +
fish/Makefile.am | 17 ++-
generator/fish.ml | 348 ++++++++++++++++++++++++++++++-----------------------
generator/fish.mli | 3 +
generator/main.ml | 3 +
5 files changed, 220 insertions(+), 154 deletions(-)
diff --git a/.gitignore b/.gitignore
index fc0d065..8312d99 100644
--- a/.gitignore
+++ b/.gitignore
@@ -204,6 +204,7 @@ Makefile.in
/fish/cmds-gperf.c
/fish/cmds-gperf.gperf
/fish/completion.c
+/fish/entries-?.c
/fish/event-names.c
/fish/fish-cmds.h
/fish/guestfish
@@ -216,6 +217,8 @@ Makefile.in
/fish/prepopts.h
/fish/rc_protocol.c
/fish/rc_protocol.h
+/fish/run-?.c
+/fish/run.h
/fish/stamp-guestfish.pod
/fish/stamp-libguestfs-tools.conf.pod
/fish/stamp-virt-copy-in.pod
diff --git a/fish/Makefile.am b/fish/Makefile.am
index a6de568..e1bc210 100644
--- a/fish/Makefile.am
+++ b/fish/Makefile.am
@@ -23,13 +23,28 @@ generator_built = \
cmds.c \
cmds-gperf.gperf \
completion.c \
+ entries-0.c \
+ entries-1.c \
+ entries-2.c \
+ entries-3.c \
+ entries-4.c \
+ entries-5.c \
+ entries-6.c \
event-names.c \
fish-cmds.h \
guestfish-actions.pod \
guestfish-commands.pod \
guestfish-prepopts.pod \
prepopts.h \
- prepopts.c
+ prepopts.c \
+ run-0.c \
+ run-1.c \
+ run-2.c \
+ run-3.c \
+ run-4.c \
+ run-5.c \
+ run-6.c \
+ run.h
BUILT_SOURCES = \
$(generator_built) \
diff --git a/generator/fish.ml b/generator/fish.ml
index 2acd484..b16326b 100644
--- a/generator/fish.ml
+++ b/generator/fish.ml
@@ -76,11 +76,10 @@ let c_quoted_indented ~indent str =
let str = replace_str str "\\n" ("\\n\"\n" ^ indent ^
"\"") in
str
-(* Generate a lot of different functions for guestfish. *)
-let generate_fish_cmds () =
+(* Generate run_* functions and header for libguestfs API functions. *)
+let generate_fish_run_cmds actions () =
generate_header CStyle GPLv2plus;
-
pr "#include <config.h>\n";
pr "\n";
pr "/* It is safe to call deprecated functions from this file. */\n";
@@ -93,7 +92,6 @@ let generate_fish_cmds () =
pr "#include <libintl.h>\n";
pr "#include <errno.h>\n";
pr "\n";
- pr "#include \"c-ctype.h\"\n";
pr "#include \"full-write.h\"\n";
pr "#include \"xstrtol.h\"\n";
pr "\n";
@@ -102,157 +100,16 @@ let generate_fish_cmds () =
pr "#include \"structs-print.h\"\n";
pr "\n";
pr "#include \"fish.h\"\n";
- pr "#include \"fish-cmds.h\"\n";
pr "#include \"options.h\"\n";
- pr "#include \"cmds-gperf.h\"\n";
+ pr "#include \"fish-cmds.h\"\n";
+ pr "#include \"run.h\"\n";
pr "\n";
pr "/* Valid suffixes allowed for numbers. See Gnulib xstrtol function.
*/\n";
pr "static const char xstrtol_suffixes[] = \"0kKMGTPEZY\";\n";
pr "\n";
- pr "/* Return these errors from run_* functions. */\n";
- pr "#define RUN_ERROR -1\n";
- pr "#define RUN_WRONG_ARGS -2\n";
- pr "\n";
-
- List.iter (
- fun { name = name } ->
- pr "static int run_%s (const char *cmd, size_t argc, char *argv[]);\n"
- name
- ) (actions |> fish_functions |> sort);
-
- pr "\n";
-
- (* List of command_entry structs. *)
- List.iter (
- fun ({ name = name; shortdesc = shortdesc; longdesc = longdesc } as f) ->
- let aliases = get_aliases f in
-
- let name2 = replace_char name '_' '-' in
- let describe_alias =
- if aliases <> [] then
- sprintf "\n\nYou can use %s as an alias for this command."
- (String.concat " or " (List.map (fun s -> "'" ^ s
^ "'") aliases))
- else "" in
-
- let pod =
- sprintf "%s - %s\n\n=head1 DESCRIPTION\n\n%s\n\n%s"
- name2 shortdesc longdesc describe_alias in
- let text =
- String.concat "\n" (pod2text ~trim:false ~discard:false
"NAME" pod)
- ^ "\n" in
-
- pr "struct command_entry %s_cmd_entry = {\n" name;
- pr " .name = \"%s\",\n" name2;
- pr " .help = \"%s\",\n" (c_quoted_indented ~indent:"
" text);
- pr " .synopsis = NULL,\n";
- pr " .run = run_%s\n" name;
- pr "};\n";
- pr "\n";
- ) fish_commands;
-
- List.iter (
- fun ({ name = name; style = _, args, optargs;
- shortdesc = shortdesc; longdesc = longdesc } as f) ->
- let aliases = get_aliases f in
-
- let name2 = replace_char name '_' '-' in
-
- let longdesc = replace_str longdesc "C<guestfs_" "C<" in
- let synopsis =
- match args with
- | [] -> name2
- | args ->
- let args = List.filter (function Key _ -> false | _ -> true) args in
- sprintf "%s%s%s"
- name2
- (String.concat ""
- (List.map (fun arg -> " " ^ name_of_argt arg) args))
- (String.concat ""
- (List.map (fun arg ->
- sprintf " [%s:%s]" (name_of_optargt arg) (doc_opttype_of
arg)
- ) optargs)) in
-
- let warnings =
- if List.exists (function Key _ -> true | _ -> false) args then
- "\n\nThis command has one or more key or passphrase parameters.
-Guestfish will prompt for these separately."
- else "" in
-
- let warnings =
- warnings ^
- if f.protocol_limit_warning then
- "\n\n" ^ protocol_limit_warning
- else "" in
-
- let warnings =
- warnings ^
- match deprecation_notice ~replace_underscores:true f with
- | None -> ""
- | Some txt -> "\n\n" ^ txt in
-
- let describe_alias =
- if aliases <> [] then
- sprintf "\n\nYou can use %s as an alias for this command."
- (String.concat " or " (List.map (fun s -> "'" ^ s
^ "'") aliases))
- else "" in
-
- let pod =
- sprintf "%s - %s\n\n=head1 SYNOPSIS\n\n %s\n\n=head1
DESCRIPTION\n\n%s%s%s"
- name2 shortdesc synopsis longdesc warnings describe_alias in
- let text =
- String.concat "\n" (pod2text ~trim:false ~discard:false
"NAME" pod)
- ^ "\n" in
-
- pr "struct command_entry %s_cmd_entry = {\n" name;
- pr " .name = \"%s\",\n" name2;
- pr " .help = \"%s\",\n" (c_quoted_indented ~indent:"
" text);
- pr " .synopsis = \"%s\",\n" (c_quote synopsis);
- pr " .run = run_%s\n" name;
- pr "};\n";
- pr "\n";
- ) (actions |> fish_functions |> sort);
-
- (* list_commands function, which implements guestfish -h *)
- pr "void\n";
- pr "list_commands (void)\n";
- pr "{\n";
- pr " printf (\" %%-16s %%s\\n\", _(\"Command\"),
_(\"Description\"));\n";
- pr " list_builtin_commands ();\n";
- List.iter (
- fun (name, f) ->
- let name = replace_char name '_' '-' in
- match f with
- | Function shortdesc ->
- pr " printf (\"%%-20s %%s\\n\", \"%s\",
_(\"%s\"));\n"
- name shortdesc
- | Alias f ->
- let f = replace_char f '_' '-' in
- pr " printf (\"%%-20s \", \"%s\");\n" name;
- pr " printf (_(\"alias for '%%s'\"),
\"%s\");\n" f;
- pr " putchar ('\\n');\n"
- ) all_functions_commands_and_aliases_sorted;
- pr " printf (\" %%s\\n\",";
- pr " _(\"Use -h <cmd> / help <cmd> to show detailed help
for a command.\"));\n";
- pr "}\n";
- pr "\n";
-
- (* display_command function, which implements guestfish -h cmd *)
- pr "int\n";
- pr "display_command (const char *cmd)\n";
- pr "{\n";
- pr " const struct command_table *ct;\n";
- pr "\n";
- pr " ct = lookup_fish_command (cmd, strlen (cmd));\n";
- pr " if (ct) {\n";
- pr " fputs (ct->entry->help, stdout);\n";
- pr " return 0;\n";
- pr " }\n";
- pr " else\n";
- pr " return display_builtin_command (cmd);\n";
- pr "}\n";
- pr "\n";
let emit_print_list_function typ =
+ pr "\n";
pr "static void\n";
pr "print_%s_list (struct guestfs_%s_list *%ss)\n"
typ typ typ;
@@ -266,7 +123,6 @@ Guestfish will prompt for these separately."
pr " printf (\"}\\n\");\n";
pr " }\n";
pr "}\n";
- pr "\n";
in
(* Emit a print_TYPE_list function definition only if that function is used. *)
@@ -282,22 +138,22 @@ Guestfish will prompt for these separately."
List.iter (
function
| typ, (RStructOnly | RStructAndList) ->
+ pr "\n";
pr "static void\n";
pr "print_%s (struct guestfs_%s *%s)\n" typ typ typ;
pr "{\n";
pr " guestfs_int_print_%s_indent (%s, stdout, \"\\n\",
\"\");\n"
typ typ;
pr "}\n";
- pr "\n";
| typ, _ -> () (* empty *)
) (rstructs_used_by (actions |> fish_functions));
- (* run_<action> actions *)
List.iter (
fun { name = name; style = (ret, args, optargs as style);
fish_output = fish_output; c_function = c_function;
c_optarg_prefix = c_optarg_prefix } ->
- pr "static int\n";
+ pr "\n";
+ pr "int\n";
pr "run_%s (const char *cmd, size_t argc, char *argv[])\n" name;
pr "{\n";
pr " int ret = RUN_ERROR;\n";
@@ -642,9 +498,195 @@ Guestfish will prompt for these separately."
pr " out_noargs:\n";
pr " return ret;\n";
pr "}\n";
- pr "\n"
+ ) (actions |> fish_functions |> sort)
+
+let generate_fish_run_header () =
+ generate_header CStyle GPLv2plus;
+
+ pr "#ifndef FISH_RUN_H\n";
+ pr "#define FISH_RUN_H\n";
+ pr "\n";
+
+ pr "/* Return these errors from run_* functions. */\n";
+ pr "#define RUN_ERROR -1\n";
+ pr "#define RUN_WRONG_ARGS -2\n";
+ pr "\n";
+
+ List.iter (
+ fun { name = name } ->
+ pr "extern int run_%s (const char *cmd, size_t argc, char *argv[]);\n"
+ name
) (actions |> fish_functions |> sort);
+ pr "\n";
+ pr "#endif /* FISH_RUN_H */\n"
+
+let generate_fish_cmd_entries actions () =
+ generate_header CStyle GPLv2plus;
+
+ pr "#include <config.h>\n";
+ pr "\n";
+ pr "#include <stdio.h>\n";
+ pr "#include <stdlib.h>\n";
+ pr "\n";
+ pr "#include \"cmds-gperf.h\"\n";
+ pr "#include \"run.h\"\n";
+ pr "\n";
+
+ List.iter (
+ fun ({ name = name; style = _, args, optargs;
+ shortdesc = shortdesc; longdesc = longdesc } as f) ->
+ let aliases = get_aliases f in
+
+ let name2 = replace_char name '_' '-' in
+
+ let longdesc = replace_str longdesc "C<guestfs_" "C<" in
+ let synopsis =
+ match args with
+ | [] -> name2
+ | args ->
+ let args = List.filter (function Key _ -> false | _ -> true) args in
+ sprintf "%s%s%s"
+ name2
+ (String.concat ""
+ (List.map (fun arg -> " " ^ name_of_argt arg) args))
+ (String.concat ""
+ (List.map (fun arg ->
+ sprintf " [%s:%s]" (name_of_optargt arg) (doc_opttype_of
arg)
+ ) optargs)) in
+
+ let warnings =
+ if List.exists (function Key _ -> true | _ -> false) args then
+ "\n\nThis command has one or more key or passphrase parameters.
+Guestfish will prompt for these separately."
+ else "" in
+
+ let warnings =
+ warnings ^
+ if f.protocol_limit_warning then
+ "\n\n" ^ protocol_limit_warning
+ else "" in
+
+ let warnings =
+ warnings ^
+ match deprecation_notice ~replace_underscores:true f with
+ | None -> ""
+ | Some txt -> "\n\n" ^ txt in
+
+ let describe_alias =
+ if aliases <> [] then
+ sprintf "\n\nYou can use %s as an alias for this command."
+ (String.concat " or " (List.map (fun s -> "'" ^ s
^ "'") aliases))
+ else "" in
+
+ let pod =
+ sprintf "%s - %s\n\n=head1 SYNOPSIS\n\n %s\n\n=head1
DESCRIPTION\n\n%s%s%s"
+ name2 shortdesc synopsis longdesc warnings describe_alias in
+ let text =
+ String.concat "\n" (pod2text ~trim:false ~discard:false
"NAME" pod)
+ ^ "\n" in
+
+ pr "struct command_entry %s_cmd_entry = {\n" name;
+ pr " .name = \"%s\",\n" name2;
+ pr " .help = \"%s\",\n" (c_quoted_indented ~indent:"
" text);
+ pr " .synopsis = \"%s\",\n" (c_quote synopsis);
+ pr " .run = run_%s\n" name;
+ pr "};\n";
+ pr "\n";
+ ) (actions |> fish_functions |> sort)
+
+(* Generate a lot of different functions for guestfish. *)
+let generate_fish_cmds () =
+ generate_header CStyle GPLv2plus;
+
+ pr "#include <config.h>\n";
+ pr "\n";
+ pr "#include <stdio.h>\n";
+ pr "#include <stdlib.h>\n";
+ pr "#include <string.h>\n";
+ pr "#include <inttypes.h>\n";
+ pr "#include <libintl.h>\n";
+ pr "#include <errno.h>\n";
+ pr "\n";
+ pr "#include \"guestfs.h\"\n";
+ pr "#include \"guestfs-internal-frontend.h\"\n";
+ pr "#include \"structs-print.h\"\n";
+ pr "\n";
+ pr "#include \"fish.h\"\n";
+ pr "#include \"fish-cmds.h\"\n";
+ pr "#include \"options.h\"\n";
+ pr "#include \"cmds-gperf.h\"\n";
+ pr "#include \"run.h\"\n";
+ pr "\n";
+
+ (* List of command_entry structs for pure guestfish commands. *)
+ List.iter (
+ fun ({ name = name; shortdesc = shortdesc; longdesc = longdesc } as f) ->
+ let aliases = get_aliases f in
+
+ let name2 = replace_char name '_' '-' in
+ let describe_alias =
+ if aliases <> [] then
+ sprintf "\n\nYou can use %s as an alias for this command."
+ (String.concat " or " (List.map (fun s -> "'" ^ s
^ "'") aliases))
+ else "" in
+
+ let pod =
+ sprintf "%s - %s\n\n=head1 DESCRIPTION\n\n%s\n\n%s"
+ name2 shortdesc longdesc describe_alias in
+ let text =
+ String.concat "\n" (pod2text ~trim:false ~discard:false
"NAME" pod)
+ ^ "\n" in
+
+ pr "struct command_entry %s_cmd_entry = {\n" name;
+ pr " .name = \"%s\",\n" name2;
+ pr " .help = \"%s\",\n" (c_quoted_indented ~indent:"
" text);
+ pr " .synopsis = NULL,\n";
+ pr " .run = run_%s\n" name;
+ pr "};\n";
+ pr "\n";
+ ) fish_commands;
+
+ (* list_commands function, which implements guestfish -h *)
+ pr "void\n";
+ pr "list_commands (void)\n";
+ pr "{\n";
+ pr " printf (\" %%-16s %%s\\n\", _(\"Command\"),
_(\"Description\"));\n";
+ pr " list_builtin_commands ();\n";
+ List.iter (
+ fun (name, f) ->
+ let name = replace_char name '_' '-' in
+ match f with
+ | Function shortdesc ->
+ pr " printf (\"%%-20s %%s\\n\", \"%s\",
_(\"%s\"));\n"
+ name shortdesc
+ | Alias f ->
+ let f = replace_char f '_' '-' in
+ pr " printf (\"%%-20s \", \"%s\");\n" name;
+ pr " printf (_(\"alias for '%%s'\"),
\"%s\");\n" f;
+ pr " putchar ('\\n');\n"
+ ) all_functions_commands_and_aliases_sorted;
+ pr " printf (\" %%s\\n\",";
+ pr " _(\"Use -h <cmd> / help <cmd> to show detailed help
for a command.\"));\n";
+ pr "}\n";
+ pr "\n";
+
+ (* display_command function, which implements guestfish -h cmd *)
+ pr "int\n";
+ pr "display_command (const char *cmd)\n";
+ pr "{\n";
+ pr " const struct command_table *ct;\n";
+ pr "\n";
+ pr " ct = lookup_fish_command (cmd, strlen (cmd));\n";
+ pr " if (ct) {\n";
+ pr " fputs (ct->entry->help, stdout);\n";
+ pr " return 0;\n";
+ pr " }\n";
+ pr " else\n";
+ pr " return display_builtin_command (cmd);\n";
+ pr "}\n";
+ pr "\n";
+
(* run_action function *)
pr "int\n";
pr "run_action (const char *cmd, size_t argc, char *argv[])\n";
diff --git a/generator/fish.mli b/generator/fish.mli
index bb4376a..ed52d90 100644
--- a/generator/fish.mli
+++ b/generator/fish.mli
@@ -17,6 +17,9 @@
*)
val generate_fish_actions_pod : unit -> unit
+val generate_fish_run_cmds : Types.action list -> unit -> unit
+val generate_fish_run_header : unit -> unit
+val generate_fish_cmd_entries : Types.action list -> unit -> unit
val generate_fish_cmds : unit -> unit
val generate_fish_cmds_gperf : unit -> unit
val generate_fish_cmds_h : unit -> unit
diff --git a/generator/main.ml b/generator/main.ml
index edf106a..52b77b4 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -126,6 +126,9 @@ Run it from the top source directory using the command
output_to "tests/c-api/tests.c" generate_c_api_tests;
output_to "fish/cmds-gperf.gperf" generate_fish_cmds_gperf;
output_to "fish/cmds.c" generate_fish_cmds;
+ output_to_subset "fish/entries-%d.c" generate_fish_cmd_entries;
+ output_to_subset "fish/run-%d.c" generate_fish_run_cmds;
+ output_to "fish/run.h" generate_fish_run_header;
output_to "fish/completion.c" generate_fish_completion;
output_to "fish/event-names.c" generate_fish_event_names;
output_to "fish/fish-cmds.h" generate_fish_cmds_h;
--
2.9.3