* Scan and may produce a new option[] array, which should be used * instead of the original 'options'. * * Right now this is only used to preprocess and substitute * OPTION_ALIAS. * * The returned options should be freed using free_preprocessed_options. */
| 901 | * The returned options should be freed using free_preprocessed_options. |
| 902 | */ |
| 903 | static struct option *preprocess_options(struct parse_opt_ctx_t *ctx, |
| 904 | const struct option *options) |
| 905 | { |
| 906 | struct option *newopt; |
| 907 | int i, nr, alias; |
| 908 | int nr_aliases = 0; |
| 909 | |
| 910 | for (nr = 0; options[nr].type != OPTION_END; nr++) { |
| 911 | if (options[nr].type == OPTION_ALIAS) |
| 912 | nr_aliases++; |
| 913 | } |
| 914 | |
| 915 | if (!nr_aliases) |
| 916 | return NULL; |
| 917 | |
| 918 | DUP_ARRAY(newopt, options, nr + 1); |
| 919 | |
| 920 | /* each alias has two string pointers and NULL */ |
| 921 | CALLOC_ARRAY(ctx->alias_groups, 3 * (nr_aliases + 1)); |
| 922 | |
| 923 | for (alias = 0, i = 0; i < nr; i++) { |
| 924 | int short_name; |
| 925 | const char *long_name; |
| 926 | const char *source; |
| 927 | struct strbuf help = STRBUF_INIT; |
| 928 | int j; |
| 929 | |
| 930 | if (newopt[i].type != OPTION_ALIAS) |
| 931 | continue; |
| 932 | |
| 933 | short_name = newopt[i].short_name; |
| 934 | long_name = newopt[i].long_name; |
| 935 | source = newopt[i].value; |
| 936 | |
| 937 | if (!long_name) |
| 938 | BUG("An alias must have long option name"); |
| 939 | strbuf_addf(&help, _("alias of --%s"), source); |
| 940 | |
| 941 | for (j = 0; j < nr; j++) { |
| 942 | const char *name = options[j].long_name; |
| 943 | |
| 944 | if (!name || strcmp(name, source)) |
| 945 | continue; |
| 946 | |
| 947 | if (options[j].type == OPTION_ALIAS) |
| 948 | BUG("No please. Nested aliases are not supported."); |
| 949 | |
| 950 | memcpy(newopt + i, options + j, sizeof(*newopt)); |
| 951 | newopt[i].short_name = short_name; |
| 952 | newopt[i].long_name = long_name; |
| 953 | newopt[i].help = strbuf_detach(&help, NULL); |
| 954 | newopt[i].flags |= PARSE_OPT_FROM_ALIAS; |
| 955 | break; |
| 956 | } |
| 957 | |
| 958 | if (j == nr) |
| 959 | BUG("could not find source option '%s' of alias '%s'", |
| 960 | source, newopt[i].long_name); |
no test coverage detected