X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=generator%2Fgenerator_fish.ml;h=3d52421b9e255690c23789959e128c2eca847225;hp=76b4c7aad3d3283ee7bbb27d55f66b3b2867ecb6;hb=9b102aae65449a8d321e8cf44a3993af558291db;hpb=a232e62dcf508517a32b9a8d7e4529e827be721b diff --git a/generator/generator_fish.ml b/generator/generator_fish.ml index 76b4c7a..3d52421 100644 --- a/generator/generator_fish.ml +++ b/generator/generator_fish.ml @@ -30,6 +30,13 @@ open Generator_structs open Generator_prepopts open Generator_c +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 () = generate_header CStyle GPLv2plus; @@ -48,16 +55,21 @@ let generate_fish_cmds () = pr "#include \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 \n"; pr "#include \n"; pr "#include \n"; pr "#include \n"; pr "\n"; - pr "#include \n"; pr "#include \"c-ctype.h\"\n"; pr "#include \"full-write.h\"\n"; pr "#include \"xstrtol.h\"\n"; + pr "\n"; + pr "#include \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"; @@ -76,11 +88,7 @@ let generate_fish_cmds () = (* List of command_entry structs. *) List.iter ( fun (name, _, _, flags, _, shortdesc, longdesc) -> - pr "struct command_entry %s_cmd_entry = {\n" name; - let name2 = replace_char name '_' '-' in - pr " .name = \"%s\",\n" name2; - let aliases = filter_map (function FishAlias n -> Some n | _ -> None) flags in let describe_alias = @@ -89,10 +97,16 @@ let generate_fish_cmds () = (String.concat " or " (List.map (fun s -> "'" ^ s ^ "'") aliases)) else "" in - pr " .shortdesc = \"%s\",\n" shortdesc; - pr " .podbody = %S,\n" - ("=head1 DESCRIPTION\n\n" ^ longdesc ^ describe_alias); + 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_quote text); pr " .run = run_%s\n" name; pr "};\n"; pr "\n"; @@ -100,11 +114,7 @@ let generate_fish_cmds () = List.iter ( fun (name, (_, args, optargs), _, flags, _, shortdesc, longdesc) -> - pr "struct command_entry %s_cmd_entry = {\n" name; - let name2 = replace_char name '_' '-' in - pr " .name = \"%s\",\n" name2; - let aliases = filter_map (function FishAlias n -> Some n | _ -> None) flags in @@ -119,7 +129,9 @@ let generate_fish_cmds () = (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 @@ -133,16 +145,6 @@ Guestfish will prompt for these separately." ("\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 @@ -155,19 +157,24 @@ Guestfish will prompt for these separately." (String.concat " or " (List.map (fun s -> "'" ^ s ^ "'") aliases)) else "" in - pr " .shortdesc = \"%s\",\n" shortdesc; - pr " .podbody = %S,\n" - ("=head1 SYNOPSIS\n\n " ^ synopsis ^ "\n\n" ^ - "=head1 DESCRIPTION\n\n" ^ - longdesc ^ warnings ^ describe_alias); + 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_quote text); pr " .run = run_%s\n" name; pr "};\n"; pr "\n"; ) 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"; @@ -183,13 +190,14 @@ Guestfish will prompt for these separately." 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 " ct = lookup_fish_command (cmd, strlen (cmd));\n"; pr " if (ct) {\n"; - pr " pod2text (ct->entry->name, ct->entry->shortdesc, ct->entry->podbody);\n"; + pr " fputs (ct->entry->help, stdout);\n"; pr " return 0;\n"; pr " }\n"; pr " else\n"; @@ -198,7 +206,8 @@ Guestfish will prompt for these separately." 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"; @@ -218,7 +227,8 @@ Guestfish will prompt for these separately." 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"; @@ -257,9 +267,11 @@ Guestfish will prompt for these separately." 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"; @@ -278,7 +290,8 @@ Guestfish will prompt for these separately." 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"; @@ -323,6 +336,7 @@ Guestfish will prompt for these separately." | Bool n -> pr " int %s;\n" n | Int n -> pr " int %s;\n" n | Int64 n -> pr " int64_t %s;\n" n + | Pointer _ -> assert false ) args; if optargs <> [] then ( @@ -390,7 +404,7 @@ Guestfish will prompt for these separately." 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; @@ -410,6 +424,8 @@ Guestfish will prompt for these separately." 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 @@ -423,6 +439,7 @@ Guestfish will prompt for these separately." parse_integer "argv[i++]" "xstrtoll" "long long" "int" range name | Int64 name -> parse_integer "argv[i++]" "xstrtoll" "long long" "int64_t" None name + | Pointer _ -> assert false ) args; (* Optional arguments are prefixed with : and @@ -455,10 +472,12 @@ Guestfish will prompt for these separately." "The Int type in the generator is a signed 31 bit int." in Some (min, max, comment) in let expr = sprintf "&argv[i][%d]" (len+1) in - parse_integer expr "xstrtoll" "long long" "int" range name + parse_integer expr "xstrtoll" "long long" "int" range + (sprintf "optargs_s.%s" n) | Int64 n -> let expr = sprintf "&argv[i][%d]" (len+1) in - parse_integer expr "xstrtoll" "long long" "int64_t" None name + parse_integer expr "xstrtoll" "long long" "int64_t" None + (sprintf "optargs_s.%s" n) | String n -> pr " optargs_s.%s = &argv[i][%d];\n" n (len+1); | _ -> assert false @@ -506,6 +525,7 @@ Guestfish will prompt for these separately." pr " free_file_in (%s);\n" name | StringList name | DeviceList name -> pr " free_strings (%s);\n" name + | Pointer _ -> assert false ) args; (* Any output flags? *) @@ -609,6 +629,22 @@ Guestfish will prompt for these separately." 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; @@ -810,10 +846,12 @@ and generate_fish_actions_pod () = | FileIn n | FileOut n -> pr " (%s|-)" n | BufferIn n -> pr " %s" n | Key _ -> () (* keys are entered at a prompt *) + | Pointer _ -> assert false ) 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"; @@ -834,9 +872,6 @@ Guestfish will prompt for these separately.\n\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 @@ -905,6 +940,8 @@ and generate_fish_prep_options_c () = generate_header CStyle GPLv2plus; pr "\ +#include + #include \"fish.h\" #include \"prepopts.h\"