summaryrefslogtreecommitdiff
path: root/gcc/opts-common.c
diff options
context:
space:
mode:
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2010-09-22 20:12:06 +0000
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2010-09-22 20:12:06 +0000
commit5789e05bf0e84052ed8a54b0cd695725f3dfa2ce (patch)
treec66d31c60ecaae93e312d12451c889cde531ce79 /gcc/opts-common.c
parent6c810f5b4a869e0ed1939f4c8ded625bb7e445da (diff)
downloadgcc-5789e05bf0e84052ed8a54b0cd695725f3dfa2ce.tar.gz
* common.opt (-assemble, -compile, -coverage, -debug, -dump,
-dump=, -dumpbase, -dumpdir, -entry, -entry=, -extra-warnings, -for-assembler, -for-assembler=, -for-linker, -for-linker=, -force-link, -force-link=, -language, -language=, -library-directory, -library-directory=, -no-canonical-prefixes, -no-standard-libraries, -no-warnings, -optimize, -output, -output=, -pass-exit-codes, -pedantic, -pedantic-errors, -pie, -pipe, -prefix, -prefix=, -preprocess, -print-file-name, -print-file-name=, -print-libgcc-file-name, -print-multi-directory, -print-multi-lib, -print-multi-os-directory, -print-prog-name, -print-prog-name=, -print-search-dirs, -print-sysroot, -print-sysroot-headers-suffix, -profile, -save-temps, -shared, -specs, -specs=, -static, -symbolic, -time, -verbose, -param=, -sysroot, coverage, e, u, symbolic): New. (fhelp, fhelp=, ftarget-help, fversion): Make into aliases. * gcc.c (A Short Introduction to Adding a Command-Line Option): Remove comment. (cc1_options): Correct specs for passing down --help, --target-help and --help=*. Add spec for passing down --version. (struct option_map, option_map, target_option_translations, translate_options): Remove. (driver_handle_option): Handle OPT__version, OPT__help, OPT__help_ and OPT__target_help instead of OPT_fversion, OPT_fhelp, OPT_fhelp_ and OPT_ftarget_help. (process_command): Don't call translate_options. Call decode_cmdline_options_to_array before checking for -no-canonical-prefixes using decoded options. * opts-common.c (tm.h): Update comment on #include. (find_opt): Allow abbreviations of long options. (struct option_map, option_map): New. (decode_cmdline_option): Use them instead of hardcoding -Wno, -fno and -mno handling. (target_option_translations): New. (decode_cmdline_options_to_array): Handle TARGET_OPTION_TRANSLATE_TABLE in driver. * opts.c (common_handle_option): Don't handle OPT_fhelp, OPT_ftarget_help, OPT_fhelp_ or OPT_fversion. ada: * gcc-interface/lang.opt (-all-warnings, -include-barrier, -include-directory, -include-directory=, -no-standard-includes, -no-standard-libraries): New. c-family: * c.opt (-all-warnings, -ansi, -assert, -assert=, -comments, -comments-in-macros, -define-macro, -define-macro=, -dependencies, -dump, -dump=, -imacros, -imacros=, -include, -include=, -include-barrier, -include-directory, -include-directory=, -include-directory-after, -include-directory-after=, -include-prefix, -include-prefix=, -include-with-prefix, -include-with-prefix=, -include-with-prefix-after, -include-with-prefix-after=, -include-with-prefix-before, -include-with-prefix-before=, -no-integrated-cpp, -no-line-commands, -no-standard-includes, -no-warnings, -output, -output=, -pedantic, -pedantic-errors, -preprocess, -print-missing-file-dependencies, -trace-includes, -traditional, -traditional-cpp, -trigraphs, -undefine-macro, -undefine-macro=, -user-dependencies, -verbose, -write-dependencies, -write-user-dependencies, no-integrated-cpp, traditional): New. fortran: * gfortranspec.c (lang_specific_driver): Handle OPT__version and OPT__help instead of OPT_fversion and OPT_fhelp. * lang.opt (-all-warnings, -assert, -assert=, -comments, -comments-in-macros, -define-macro, -define-macro=, -dependencies, -dump, -dump=, -include-barrier, -include-directory, -include-directory=, -include-directory-after, -include-directory-after=, -include-prefix, -include-prefix=, -no-line-commands, -no-standard-includes, -output, -output=, -preprocess, -print-missing-file-dependencies, -trace-includes, -undefine-macro, -undefine-macro=, -user-dependencies, -verbose, -write-dependencies, -write-user-dependencies): New. java: * jvspec.c (lang_specific_driver): Handle OPT__help instead of OPT_fhelp. * lang.opt (-CLASSPATH, -all-warnings, -bootclasspath, -classpath, -dependencies, -encoding, -extdirs, -include-directory, -include-directory=, -output-class-directory, -output-class-directory=, -resource, -resource=, -user-dependencies): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164531 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/opts-common.c')
-rw-r--r--gcc/opts-common.c259
1 files changed, 225 insertions, 34 deletions
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index 8299edd4ab9..678b60e891b 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -24,7 +24,8 @@ along with GCC; see the file COPYING3. If not see
#include "opts.h"
#include "options.h"
#include "diagnostic.h"
-#include "tm.h" /* For SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG. */
+#include "tm.h" /* For SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG and
+ TARGET_OPTION_TRANSLATE_TABLE. */
/* Perform a binary search to find which option the command-line INPUT
matches. Returns its index in the option array, and
@@ -53,7 +54,7 @@ along with GCC; see the file COPYING3. If not see
size_t
find_opt (const char *input, int lang_mask)
{
- size_t mn, mx, md, opt_len;
+ size_t mn, mn_orig, mx, md, opt_len;
size_t match_wrong_lang;
int comp;
@@ -74,6 +75,8 @@ find_opt (const char *input, int lang_mask)
mn = md;
}
+ mn_orig = mn;
+
/* This is the switch that is the best match but for a different
front end, or OPT_SPECIAL_unknown if there is no match at all. */
match_wrong_lang = OPT_SPECIAL_unknown;
@@ -106,6 +109,40 @@ find_opt (const char *input, int lang_mask)
}
while (mn != cl_options_count);
+ if (match_wrong_lang == OPT_SPECIAL_unknown && input[0] == '-')
+ {
+ /* Long options, starting "--", may be abbreviated if the
+ abbreviation is unambiguous. This only applies to options
+ not taking a joined argument, and abbreviations of "--option"
+ are permitted even if there is a variant "--option=". */
+ size_t mnc = mn_orig + 1;
+ size_t cmp_len = strlen (input);
+ while (mnc < cl_options_count
+ && strncmp (input, cl_options[mnc].opt_text + 1, cmp_len) == 0)
+ {
+ /* Option matching this abbreviation. OK if it is the first
+ match and that does not take a joined argument, or the
+ second match, taking a joined argument and with only '='
+ added to the first match; otherwise considered
+ ambiguous. */
+ if (mnc == mn_orig + 1
+ && !(cl_options[mnc].flags & CL_JOINED))
+ match_wrong_lang = mnc;
+ else if (mnc == mn_orig + 2
+ && match_wrong_lang == mn_orig + 1
+ && (cl_options[mnc].flags & CL_JOINED)
+ && (cl_options[mnc].opt_len
+ == cl_options[mn_orig + 1].opt_len + 1)
+ && strncmp (cl_options[mnc].opt_text + 1,
+ cl_options[mn_orig + 1].opt_text + 1,
+ cl_options[mn_orig + 1].opt_len) == 0)
+ ; /* OK, as long as there are no more matches. */
+ else
+ return OPT_SPECIAL_unknown;
+ mnc++;
+ }
+ }
+
/* Return the best wrong match, or OPT_SPECIAL_unknown if none. */
return match_wrong_lang;
}
@@ -197,6 +234,46 @@ generate_canonical_option (size_t opt_index, const char *arg, int value,
}
}
+/* Structure describing mappings from options on the command line to
+ options to look up with find_opt. */
+struct option_map
+{
+ /* Prefix of the option on the command line. */
+ const char *opt0;
+ /* If two argv elements are considered to be merged into one option,
+ prefix for the second element, otherwise NULL. */
+ const char *opt1;
+ /* The new prefix to map to. */
+ const char *new_prefix;
+ /* Whether at least one character is needed following opt1 or opt0
+ for this mapping to be used. (--optimize= is valid for -O, but
+ --warn- is not valid for -W.) */
+ bool another_char_needed;
+ /* Whether the original option is a negated form of the option
+ resulting from this map. */
+ bool negated;
+};
+static const struct option_map option_map[] =
+ {
+ { "-Wno-", NULL, "-W", false, true },
+ { "-fno-", NULL, "-f", false, true },
+ { "-mno-", NULL, "-m", false, true },
+ { "--debug=", NULL, "-g", false, false },
+ { "--machine-", NULL, "-m", true, false },
+ { "--machine-no-", NULL, "-m", false, true },
+ { "--machine=", NULL, "-m", false, false },
+ { "--machine=no-", NULL, "-m", false, true },
+ { "--machine", "", "-m", false, false },
+ { "--machine", "no-", "-m", false, true },
+ { "--optimize=", NULL, "-O", false, false },
+ { "--std=", NULL, "-std=", false, false },
+ { "--std", "", "-std=", false, false },
+ { "--warn-", NULL, "-W", true, false },
+ { "--warn-no-", NULL, "-W", false, true },
+ { "--", NULL, "-f", true, false },
+ { "--no-", NULL, "-f", false, true }
+ };
+
/* Decode the switch beginning at ARGV for the language indicated by
LANG_MASK (including CL_COMMON and CL_TARGET if applicable), into
the structure *DECODED. Returns the number of switches
@@ -207,10 +284,10 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
struct cl_decoded_option *decoded)
{
size_t opt_index;
- const char *opt, *arg = 0;
- char *dup = 0;
+ const char *arg = 0;
int value = 1;
- unsigned int result = 1, i;
+ unsigned int result = 1, i, extra_args;
+ int adjust_len = 0;
size_t total_len;
char *p;
const struct cl_option *option;
@@ -220,28 +297,50 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
bool joined_arg_flag;
bool have_separate_arg = false;
- opt = argv[0];
+ extra_args = 0;
- opt_index = find_opt (opt + 1, lang_mask);
- if (opt_index == OPT_SPECIAL_unknown
- && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
- && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
+ opt_index = find_opt (argv[0] + 1, lang_mask);
+ i = 0;
+ while (opt_index == OPT_SPECIAL_unknown
+ && i < ARRAY_SIZE (option_map))
{
- /* Drop the "no-" from negative switches. */
- size_t len = strlen (opt) - 3;
-
- dup = XNEWVEC (char, len + 1);
- dup[0] = '-';
- dup[1] = opt[1];
- memcpy (dup + 2, opt + 5, len - 2 + 1);
- opt = dup;
- value = 0;
- opt_index = find_opt (opt + 1, lang_mask);
+ const char *opt0 = option_map[i].opt0;
+ const char *opt1 = option_map[i].opt1;
+ const char *new_prefix = option_map[i].new_prefix;
+ bool another_char_needed = option_map[i].another_char_needed;
+ size_t opt0_len = strlen (opt0);
+ size_t opt1_len = (opt1 == NULL ? 0 : strlen (opt1));
+ size_t optn_len = (opt1 == NULL ? opt0_len : opt1_len);
+ size_t new_prefix_len = strlen (new_prefix);
+
+ extra_args = (opt1 == NULL ? 0 : 1);
+ value = !option_map[i].negated;
+
+ if (strncmp (argv[0], opt0, opt0_len) == 0
+ && (opt1 == NULL
+ || (argv[1] != NULL && strncmp (argv[1], opt1, opt1_len) == 0))
+ && (!another_char_needed
+ || argv[extra_args][optn_len] != 0))
+ {
+ size_t arglen = strlen (argv[extra_args]);
+ char *dup;
+
+ adjust_len = (int) optn_len - (int) new_prefix_len;
+ dup = XNEWVEC (char, arglen + 1 - adjust_len);
+ memcpy (dup, new_prefix, new_prefix_len);
+ memcpy (dup + new_prefix_len, argv[extra_args] + optn_len,
+ arglen - optn_len + 1);
+ opt_index = find_opt (dup + 1, lang_mask);
+ free (dup);
+ }
+ i++;
}
if (opt_index == OPT_SPECIAL_unknown)
{
arg = argv[0];
+ extra_args = 0;
+ value = 1;
goto done;
}
@@ -257,6 +356,7 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
goto done;
}
+ result = extra_args + 1;
warn_message = option->warn_message;
/* Check to see if the option is disabled for this configuration. */
@@ -276,18 +376,16 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
/* Have arg point to the original switch. This is because
some code, such as disable_builtin_function, expects its
argument to be persistent until the program exits. */
- arg = argv[0] + cl_options[opt_index].opt_len + 1;
- if (!value)
- arg += strlen ("no-");
+ arg = argv[extra_args] + cl_options[opt_index].opt_len + 1 + adjust_len;
if (*arg == '\0' && !(option->flags & CL_MISSING_OK))
{
if (separate_arg_flag)
{
- arg = argv[1];
- result = 2;
+ arg = argv[extra_args + 1];
+ result = extra_args + 2;
if (arg == NULL)
- result = 1;
+ result = extra_args + 1;
else
have_separate_arg = true;
}
@@ -298,10 +396,10 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
}
else if (separate_arg_flag)
{
- arg = argv[1];
- result = 2;
+ arg = argv[extra_args + 1];
+ result = extra_args + 2;
if (arg == NULL)
- result = 1;
+ result = extra_args + 1;
else
have_separate_arg = true;
}
@@ -329,7 +427,8 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
const struct cl_option *new_option = &cl_options[new_opt_index];
/* The new option must not be an alias itself. */
- gcc_assert (new_option->alias_target == N_OPTS);
+ gcc_assert (new_option->alias_target == N_OPTS
+ || (new_option->flags & CL_SEPARATE_ALIAS));
if (option->neg_alias_arg)
{
@@ -363,7 +462,11 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
if (!(errors & CL_ERR_MISSING_ARG))
{
if (separate_arg_flag || joined_arg_flag)
- gcc_assert (arg != NULL);
+ {
+ if ((option->flags & CL_MISSING_OK) && arg == NULL)
+ arg = "";
+ gcc_assert (arg != NULL);
+ }
else
gcc_assert (arg == NULL);
}
@@ -392,8 +495,6 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
}
done:
- if (dup)
- free (dup);
decoded->opt_index = opt_index;
decoded->arg = arg;
decoded->value = value;
@@ -455,6 +556,17 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
return result;
}
+#ifdef TARGET_OPTION_TRANSLATE_TABLE
+static const struct {
+ const char *const option_found;
+ const char *const replacements;
+} target_option_translations[] =
+{
+ TARGET_OPTION_TRANSLATE_TABLE,
+ { 0, 0 }
+};
+#endif
+
/* Decode command-line options (ARGC and ARGV being the arguments of
main) into an array, setting *DECODED_OPTIONS to a pointer to that
array and *DECODED_OPTIONS_COUNT to the number of entries in the
@@ -470,9 +582,10 @@ decode_cmdline_options_to_array (unsigned int argc, const char **argv,
struct cl_decoded_option **decoded_options,
unsigned int *decoded_options_count)
{
- unsigned int n, i;
+ unsigned int n, i, target_translate_from;
struct cl_decoded_option *opt_array;
unsigned int num_decoded_options;
+ bool argv_copied = false;
opt_array = XNEWVEC (struct cl_decoded_option, argc);
@@ -489,6 +602,7 @@ decode_cmdline_options_to_array (unsigned int argc, const char **argv,
opt_array[0].errors = 0;
num_decoded_options = 1;
+ target_translate_from = 1;
for (i = 1; i < argc; i += n)
{
const char *opt = argv[i];
@@ -502,11 +616,88 @@ decode_cmdline_options_to_array (unsigned int argc, const char **argv,
continue;
}
+ if (i >= target_translate_from && (lang_mask & CL_DRIVER))
+ {
+#ifdef TARGET_OPTION_TRANSLATE_TABLE
+ int tott_idx;
+
+ for (tott_idx = 0;
+ target_option_translations[tott_idx].option_found;
+ tott_idx++)
+ {
+ if (strcmp (target_option_translations[tott_idx].option_found,
+ argv[i]) == 0)
+ {
+ unsigned int spaces = 0;
+ unsigned int m = 0;
+ const char *sp;
+ char *np;
+
+ for (sp = target_option_translations[tott_idx].replacements;
+ *sp; sp++)
+ {
+ if (*sp == ' ')
+ {
+ spaces++;
+ while (*sp == ' ')
+ sp++;
+ sp--;
+ }
+ }
+
+ if (spaces)
+ {
+ int new_argc = argc + spaces;
+ if (argv_copied)
+ argv = XRESIZEVEC (const char *, argv, new_argc + 1);
+ else
+ {
+ const char **new_argv = XNEWVEC (const char *,
+ new_argc + 1);
+ memcpy (new_argv, argv,
+ (argc + 1) * sizeof (const char *));
+ argv = new_argv;
+ argv_copied = true;
+ }
+ memmove (&argv[i] + spaces, &argv[i],
+ (argc + 1 - i) * sizeof (const char *));
+ argc = new_argc;
+ opt_array = XRESIZEVEC (struct cl_decoded_option,
+ opt_array, argc);
+ }
+
+ sp = target_option_translations[tott_idx].replacements;
+ np = xstrdup (sp);
+
+ while (1)
+ {
+ while (*np == ' ')
+ np++;
+ if (*np == 0)
+ break;
+ argv[i + m++] = np;
+ while (*np != ' ' && *np)
+ np++;
+ if (*np == 0)
+ break;
+ *np++ = 0;
+ }
+
+ target_translate_from = i + m;
+ gcc_assert (m == spaces + 1);
+ break;
+ }
+ }
+#endif
+ }
+
n = decode_cmdline_option (argv + i, lang_mask,
&opt_array[num_decoded_options]);
num_decoded_options++;
}
+ if (argv_copied)
+ free (argv);
opt_array = XRESIZEVEC (struct cl_decoded_option, opt_array,
num_decoded_options);
*decoded_options = opt_array;