This is a small series of i18n factorizations. Again the idea is to: * reduce the number of strings to translate * make life easier for translators by removing constant parts of the strings to translate * uniformize the UI by using a type of message for the a given type of condition. Changes since V1: * factorize checks of more than 2 incompatible options into dedicated functions which list all the incompatible options present on the command line Jean-Noël Avila (4): i18n: factorize more 'incompatible options' messages i18n: factorize "invalid value" messages i18n: remove from i18n strings that do not hold translatable parts i18n: transfer variables into placeholders in command synopsis archive.c | 2 +- builtin/am.c | 7 ++-- builtin/bisect--helper.c | 6 +-- builtin/blame.c | 6 +-- builtin/commit.c | 39 +++++++++--------- builtin/count-objects.c | 2 +- builtin/difftool.c | 5 ++- builtin/fast-export.c | 2 +- builtin/fetch.c | 4 +- builtin/grep.c | 8 ++-- builtin/hash-object.c | 2 +- builtin/help.c | 4 +- builtin/log.c | 5 ++- builtin/merge-base.c | 4 +- builtin/mktag.c | 2 +- builtin/mktree.c | 2 +- builtin/notes.c | 6 +-- builtin/pack-objects.c | 2 +- builtin/prune-packed.c | 2 +- builtin/pull.c | 6 +-- builtin/push.c | 2 +- builtin/rebase.c | 2 +- builtin/reflog.c | 6 +-- builtin/remote.c | 2 +- builtin/replace.c | 2 +- builtin/rev-list.c | 2 +- builtin/send-pack.c | 2 +- builtin/sparse-checkout.c | 8 ++-- builtin/stripspace.c | 4 +- builtin/submodule--helper.c | 2 +- builtin/update-server-info.c | 2 +- diff-merges.c | 2 +- gpg-interface.c | 4 +- ls-refs.c | 2 +- parallel-checkout.c | 3 +- parse-options.c | 50 +++++++++++++++++++++++ parse-options.h | 9 ++++ sequencer.c | 2 +- setup.c | 2 +- submodule-config.c | 2 +- t/t4150-am.sh | 2 +- t/t7500-commit-template-squash-signoff.sh | 2 +- 42 files changed, 145 insertions(+), 85 deletions(-) base-commit: 90d242d36e248acfae0033274b524bfa55a947fd Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1123%2Fjnavila%2Ffactorize_i18n-v2 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1123/jnavila/factorize_i18n-v2 Pull-Request: https://github.com/gitgitgadget/git/pull/1123 Range-diff vs v1: 1: 81ff928567f ! 1: 844e01391e1 i18n: factorize more 'incompatible options' messages @@ Metadata ## Commit message ## i18n: factorize more 'incompatible options' messages + Find more incompatible options to factorize. + When more than two options are mutually exclusive, print the ones which are actually on the command line. @@ Commit message ## builtin/commit.c ## @@ builtin/commit.c: static int parse_and_validate_options(int argc, const char *argv[], + struct commit *current_head, struct wt_status *s) { - int f = 0; -+ char * f_options[4]; - +- int f = 0; +- argc = parse_options(argc, argv, prefix, options, usage, 0); finalize_deferred_config(s); + @@ builtin/commit.c: static int parse_and_validate_options(int argc, const char *argv[], force_author = find_author_by_nickname(force_author); @@ builtin/commit.c: static int parse_and_validate_options(int argc, const char *ar - f++; - if (logfile) - f++; -+ die(_("options '%s' and '%s' cannot be used together"), "--squash", "--fixup"); -+ f_options[f] = "-C"; -+ f+= !!use_message; -+ f_options[f] = "-c"; -+ f+=!!edit_message; -+ f_options[f] = "-F"; -+ f+=!!logfile; -+ f_options[f] = "--fixup"; -+ f+=!!fixup_message; - if (f > 1) +- if (f > 1) - die(_("Only one of -c/-C/-F/--fixup can be used.")); -+ die(_("options '%s' and '%s' cannot be used together"), f_options[0], f_options[1]); - if (have_option_m && (edit_message || use_message || logfile)) +- if (have_option_m && (edit_message || use_message || logfile)) - die((_("Option -m cannot be combined with -c/-C/-F."))); -+ die(_("options '%s' and '%s' cannot be used together"), "-m", f_options[0]); - if (f || have_option_m) +- if (f || have_option_m) ++ die(_("options '%s' and '%s' cannot be used together"), "--squash", "--fixup"); ++ die_if_incompatible_opt4(!!use_message, "-C", ++ !!edit_message, "-c", ++ !!logfile, "-F", ++ !!fixup_message, "--fixup"); ++ if (have_option_m) { ++ if (edit_message) ++ die(_("options '%s' and '%s' cannot be used together"), "-m", "-c"); ++ else if (use_message) ++ die(_("options '%s' and '%s' cannot be used together"), "-m", "-C"); ++ else if (logfile) ++ die(_("options '%s' and '%s' cannot be used together"), "-m", "-F"); ++ } ++ if (use_message || edit_message || logfile ||fixup_message || have_option_m) template_file = NULL; if (edit_message) + use_message = edit_message; @@ builtin/commit.c: static int parse_and_validate_options(int argc, const char *argv[], - if (patch_interactive) interactive = 1; -- + - if (also + only + all + interactive > 1) - die(_("Only one of --include/--only/--all/--interactive/--patch can be used.")); -+ f = 0; -+ f_options[f] = "-i/--include"; -+ f += also; -+ f_options[f] = "-o/--only"; -+ f += only; -+ f_options[f] = "-a/--all"; -+ f += all; -+ f_options[f] = "--interactive/-p/--patch"; -+ f += interactive; -+ if (f > 1) -+ die(_("options '%s' and '%s' cannot be used together"), f_options[0], f_options[1]); - +- ++ die_if_incompatible_opt4(also, "-i/--include", ++ only, "-o/--only", ++ all, "-a/--all", ++ interactive, "--interactive/-p/--patch"); if (fixup_message) { /* + * We limit --fixup's suboptions to only alpha characters. ## builtin/difftool.c ## -@@ builtin/difftool.c: int cmd_difftool(int argc, const char **argv, const char *prefix) - int use_gui_tool = 0, dir_diff = 0, prompt = -1, symlinks = 0, - tool_help = 0, no_index = 0; - static char *difftool_cmd = NULL, *extcmd = NULL; -+ int f = 0; -+ char *f_options[3]; - struct option builtin_difftool_options[] = { - OPT_BOOL('g', "gui", &use_gui_tool, - N_("use `diff.guitool` instead of `diff.tool`")), @@ builtin/difftool.c: int cmd_difftool(int argc, const char **argv, const char *prefix) } else if (dir_diff) die(_("options '%s' and '%s' cannot be used together"), "--dir-diff", "--no-index"); - if (use_gui_tool + !!difftool_cmd + !!extcmd > 1) - die(_("options '%s', '%s', and '%s' cannot be used together"), "--gui", "--tool", "--extcmd"); -+ if (use_gui_tool) { -+ f_options[f] = "--gui"; -+ f++; -+ } -+ if (difftool_cmd) { -+ f_options[f] = "--tool"; -+ f++; -+ } -+ if (extcmd) { -+ f_options[f] = "--extcmd"; -+ f++; -+ } -+ if (f > 1) -+ die(_("options '%s' and '%s' cannot be used together"), f_options[0], f_options[1]); ++ die_if_incompatible_opt3(use_gui_tool, "--gui", ++ !!difftool_cmd, "--tool", ++ !!extcmd, "--extcmd"); if (use_gui_tool) setenv("GIT_MERGETOOL_GUI", "true", 1); ## builtin/grep.c ## @@ builtin/grep.c: int cmd_grep(int argc, const char **argv, const char *prefix) + if (!show_in_pager && !opt.status_only) setup_pager(); - if (!use_index && (untracked || cached)) +- if (!use_index && (untracked || cached)) - die(_("--cached or --untracked cannot be used with --no-index")); -+ die(_("options '%s' and '%s' cannot be used together"),"--cached/--untracked", "--no-index"); - - if (untracked && cached) +- +- if (untracked && cached) - die(_("--untracked cannot be used with --cached")); -+ die(_("options '%s' and '%s' cannot be used together"), "--untracked", "--cached"); ++ die_if_incompatible_opt3(!use_index, "--no-index", ++ untracked, "--untracked", ++ cached, "--cached"); if (!use_index || untracked) { int use_exclude = (opt_exclude < 0) ? use_index : !!opt_exclude; ## builtin/log.c ## -@@ builtin/log.c: int cmd_format_patch(int argc, const char **argv, const char *prefix) - struct strbuf rdiff_title = STRBUF_INIT; - int creation_factor = -1; - -+ int f = 0; -+ char * f_options[4]; -+ - const struct option builtin_format_patch_options[] = { - OPT_CALLBACK_F('n', "numbered", &numbered, NULL, - N_("use [PATCH n/m] even with a single patch"), @@ builtin/log.c: int cmd_format_patch(int argc, const char **argv, const char *prefix) if (rev.show_notes) load_display_notes(&rev.notes_opt); - if (use_stdout + rev.diffopt.close_file + !!output_directory > 1) - die(_("options '%s', '%s', and '%s' cannot be used together"), "--stdout", "--output", "--output-directory"); -+ if (use_stdout) { -+ f_options[f] = "--stdout"; -+ f++; -+ } -+ if (rev.diffopt.close_file) { -+ f_options[f] = "--output"; -+ f++; -+ } -+ if (output_directory) { -+ f_options[f] = "--output-directory"; -+ f++; -+ } -+ -+ if (f > 1) -+ die(_("options '%s'and '%s' cannot be used together"), f_options[0], f_options[1]); ++ die_if_incompatible_opt3(use_stdout, "--stdout", ++ rev.diffopt.close_file, "--output", ++ !!output_directory, "--output-directory"); if (use_stdout) { setup_pager(); @@ builtin/merge-base.c: int cmd_merge_base(int argc, const char **argv, const char if (cmdmode == 'o') return handle_octopus(argc, argv, show_all); + ## parse-options.c ## +@@ parse-options.c: void NORETURN usage_msg_opt(const char *msg, + die_message("%s\n", msg); /* The extra \n is intentional */ + usage_with_options(usagestr, options); + } ++ ++void die_if_incompatible_opt3(int opt1, const char *opt1_name, ++ int opt2, const char *opt2_name, ++ int opt3, const char *opt3_name) ++{ ++ int count = 0; ++ const char *options[3]; ++ ++ if (opt1) ++ options[count++] = opt1_name; ++ if (opt2) ++ options[count++] = opt2_name; ++ if (opt3) ++ options[count++] = opt3_name; ++ if (count > 2) ++ die(_("options '%s', '%s', and '%s' cannot be used together"), opt1_name, opt2_name, opt3_name); ++ else if (count > 1) ++ die(_("options '%s' and '%s' cannot be used together"), options[0], options[1]); ++} ++ ++void die_if_incompatible_opt4(int opt1, const char *opt1_name, ++ int opt2, const char *opt2_name, ++ int opt3, const char *opt3_name, ++ int opt4, const char *opt4_name) ++{ ++ int count = 0; ++ const char *options[4]; ++ ++ if (opt1) ++ options[count++] = opt1_name; ++ if (opt2) ++ options[count++] = opt2_name; ++ if (opt3) ++ options[count++] = opt3_name; ++ if (opt4) ++ options[count++] = opt4_name; ++ switch (count) { ++ case 4: ++ die(_("options '%s', '%s', '%s', and '%s' cannot be used together"), opt1_name, opt2_name, opt3_name, opt4_name); ++ break; ++ case 3: ++ die(_("options '%s', '%s', and '%s' cannot be used together"), options[0], options[1], options[2]); ++ break; ++ case 2: ++ die(_("options '%s' and '%s' cannot be used together"), options[0], options[1]); ++ break; ++ default: ++ break; ++ } ++} + + ## parse-options.h ## +@@ parse-options.h: int parse_opt_tracking_mode(const struct option *, const char *, int); + #define OPT_PATHSPEC_FILE_NUL(v) OPT_BOOL(0, "pathspec-file-nul", v, N_("with --pathspec-from-file, pathspec elements are separated with NUL character")) + #define OPT_AUTOSTASH(v) OPT_BOOL(0, "autostash", v, N_("automatically stash/stash pop before and after")) + ++void die_if_incompatible_opt3(int opt1, const char *opt1_name, ++ int opt2, const char *opt2_name, ++ int opt3, const char *opt3_name); ++ ++void die_if_incompatible_opt4(int opt1, const char *opt1_name, ++ int opt2, const char *opt2_name, ++ int opt3, const char *opt3_name, ++ int opt4, const char *opt4_name); ++ + #endif + ## t/t7500-commit-template-squash-signoff.sh ## @@ t/t7500-commit-template-squash-signoff.sh: test_expect_success '--fixup=reword: give error with pathsec' ' ' 2: ca48e82a6b4 = 2: 4c860698d69 i18n: factorize "invalid value" messages 3: ead191faad9 = 3: 376f8b56908 i18n: remove from i18n strings that do not hold translatable parts 4: 643be0d82de = 4: 8b0057f6180 i18n: transfer variables into placeholders in command synopsis -- gitgitgadget