Move main option loop to opts.c
Neil Booth
neil@daikokuya.co.uk
Tue Jun 24 23:04:00 GMT 2003
This moves the main loop over argv[] to opts.c, fixes a few missing
"break;"s that were pointed out, and pulls the warning about the
wrong front end to the generic code out of c-opts.c. We now
get messages like:
$ ./cc1 -fbackslash /tmp/foo.c
cc1: warning: command line option "-fbackslash" is valid for F77 but not for C
Neil.
* c-opts.c (complain_wrong_lang, write_langs): Remove.
(c_common_handle_option): Complaints about wrong language are
handled in opts.c now.
* opts.c (complain_wrong_lang, write_langs, handle_options): New.
(find_opt): Fix thinko.
(handle_option): Update prototype. Complain about switches for
a different front end.
(common_handle_option): Add missing breaks.
* opts.h (lang_names, handle_options): New.
(handle_option): Remove.
* opts.sh: Write out language names array.
* topelv.c (parse_options_and_default_flags): Use handle_options.
f:
* top.c (ffe_handle_option): Add missing break.
Index: c-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-opts.c,v
retrieving revision 1.62
diff -u -p -r1.62 c-opts.c
--- c-opts.c 22 Jun 2003 13:41:24 -0000 1.62
+++ c-opts.c 24 Jun 2003 22:15:00 -0000
@@ -102,8 +102,6 @@ static size_t include_cursor;
static void missing_arg (enum opt_code);
static void set_Wimplicit (int);
-static void complain_wrong_lang (size_t, int);
-static void write_langs (char *, int);
static void print_help (void);
static void handle_OPT_d (const char *);
static void set_std_cxx98 (int);
@@ -245,7 +243,7 @@ c_common_handle_option (size_t scode, co
{
const struct cl_option *option = &cl_options[scode];
enum opt_code code = (enum opt_code) scode;
- int result = 1, lang_mask;
+ int result = 1;
if (code == N_OPTS)
{
@@ -259,13 +257,6 @@ c_common_handle_option (size_t scode, co
return 1;
}
- lang_mask = lang_flags[(c_language << 1) + flag_objc];
- if (!(option->flags & lang_mask))
- {
- complain_wrong_lang (code, value);
- return 1;
- }
-
if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
{
missing_arg (code);
@@ -1509,42 +1500,6 @@ handle_OPT_d (const char *arg)
flag_dump_includes = 1;
break;
}
-}
-
-/* Write a slash-separated list of languages in FLAGS to BUF. */
-static void
-write_langs (char *buf, int flags)
-{
- *buf = '\0';
- if (flags & CL_C)
- strcat (buf, "C");
- if (flags & CL_ObjC)
- {
- if (*buf)
- strcat (buf, "/");
- strcat (buf, "ObjC");
- }
- if (flags & CL_CXX)
- {
- if (*buf)
- strcat (buf, "/");
- strcat (buf, "C++");
- }
-}
-
-/* Complain that switch OPT_INDEX does not apply to this front end. */
-static void
-complain_wrong_lang (size_t opt_index, int on)
-{
- char ok_langs[60], bad_langs[60];
- int ok_flags = cl_options[opt_index].flags;
-
- write_langs (ok_langs, ok_flags);
- write_langs (bad_langs, ~ok_flags);
- /* Eventually this should become a hard error. */
- warning ("\"-%c%s%s\" is valid for %s but not for %s",
- cl_options[opt_index].opt_text[0], on ? "" : "no-",
- cl_options[opt_index].opt_text + 1, ok_langs, bad_langs);
}
/* Handle --help output. */
Index: opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/opts.c,v
retrieving revision 1.14
diff -u -p -r1.14 opts.c
--- opts.c 22 Jun 2003 20:21:34 -0000 1.14
+++ opts.c 24 Jun 2003 22:15:01 -0000
@@ -129,6 +129,10 @@ static size_t find_opt (const char *, in
static int common_handle_option (size_t scode, const char *arg, int value);
static void handle_param (const char *);
static void set_Wextra (int);
+static unsigned int handle_option (char **argv, unsigned int lang_mask);
+static char *write_langs (unsigned int lang_mask);
+static void complain_wrong_lang (const char *, const struct cl_option *,
+ unsigned int lang_mask);
/* Perform a binary search to find which option the command-line INPUT
matches. Returns its index in the option array, and N_OPTS
@@ -200,7 +204,7 @@ find_opt (const char *input, int lang_ma
/* If we haven't remembered a prior match, remember this
one. Any prior match is necessarily better. */
- if (match_wrong_lang != cl_options_count)
+ if (match_wrong_lang == cl_options_count)
match_wrong_lang = mn;
}
@@ -230,15 +234,62 @@ integral_argument (const char *arg)
return -1;
}
-/* Handle the switch beginning at ARGV, with ARGC remaining. */
-int
-handle_option (int argc ATTRIBUTE_UNUSED, char **argv, int lang_mask)
+/* Return a malloced slash-separated list of languages in MASK. */
+static char *
+write_langs (unsigned int mask)
+{
+ unsigned int n = 0, len = 0;
+ const char *lang_name;
+ char *result;
+
+ for (n = 0; (lang_name = lang_names[n]) != 0; n++)
+ if (mask & (1U << n))
+ len += strlen (lang_name) + 1;
+
+ result = xmalloc (len);
+ len = 0;
+ for (n = 0; (lang_name = lang_names[n]) != 0; n++)
+ if (mask & (1U << n))
+ {
+ if (len)
+ result[len++] = '/';
+ strcpy (result + len, lang_name);
+ len += strlen (lang_name);
+ }
+
+ result[len] = 0;
+
+ return result;
+}
+
+/* Complain that switch OPT_INDEX does not apply to this front end. */
+static void
+complain_wrong_lang (const char *text, const struct cl_option *option,
+ unsigned int lang_mask)
+{
+ char *ok_langs, *bad_lang;
+
+ ok_langs = write_langs (option->flags);
+ bad_lang = write_langs (lang_mask);
+
+ /* Eventually this should become a hard error IMO. */
+ warning ("command line option \"%s\" is valid for %s but not for %s",
+ text, ok_langs, bad_lang);
+
+ free (ok_langs);
+ free (bad_lang);
+}
+
+/* Handle the switch beginning at ARGV for the language indicated by
+ LANG_MASK. Returns the number of switches consumed. */
+static unsigned int
+handle_option (char **argv, unsigned int lang_mask)
{
size_t opt_index;
const char *opt, *arg = 0;
char *dup = 0;
int value = 1;
- int result = 0;
+ unsigned int result = 0;
const struct cl_option *option;
opt = argv[0];
@@ -273,7 +324,8 @@ handle_option (int argc ATTRIBUTE_UNUSED
option = &cl_options[opt_index];
- /* Reject negative form of switches that don't take negatives. */
+ /* Reject negative form of switches that don't take negatives as
+ unrecognized. */
if (!value && (option->flags & CL_REJECT_NEGATIVE))
goto done;
@@ -308,6 +360,14 @@ handle_option (int argc ATTRIBUTE_UNUSED
result = 2;
}
+ /* Now we've swallowed any potential argument, complain if this
+ is a switch for a different front end. */
+ if (!(option->flags & (lang_mask | CL_COMMON)))
+ {
+ complain_wrong_lang (argv[0], option, lang_mask);
+ goto done;
+ }
+
/* If the switch takes an integer, convert it. */
if (arg && (option->flags & CL_UINTEGER))
{
@@ -335,6 +395,26 @@ handle_option (int argc ATTRIBUTE_UNUSED
return result;
}
+/* Decode and handle the vector of command line options. LANG_MASK
+ contains has a single bit set representing the current
+ language. */
+void
+handle_options (unsigned int argc, char **argv, unsigned int lang_mask)
+{
+ unsigned int n, i;
+
+ for (i = 1; i < argc; i += n)
+ {
+ n = handle_option (argv + i, lang_mask);
+
+ if (!n)
+ {
+ n = 1;
+ error ("unrecognized command line option \"%s\"", argv[i]);
+ }
+ }
+}
+
/* Handle target- and language-independent options. Return zero to
generate an "unknown option" message. */
static int
@@ -399,6 +479,7 @@ common_handle_option (size_t scode, cons
case OPT_Wdeprecated_declarations:
warn_deprecated_decl = value;
+ break;
case OPT_Wdisabled_optimization:
warn_disabled_optimization = value;
@@ -1015,6 +1096,7 @@ common_handle_option (size_t scode, cons
case OPT_ftime_report:
time_report = value;
+ break;
case OPT_ftls_model_:
if (!strcmp (arg, "global-dynamic"))
Index: opts.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/opts.h,v
retrieving revision 1.6
diff -u -p -r1.6 opts.h
--- opts.h 22 Jun 2003 09:04:57 -0000 1.6
+++ opts.h 24 Jun 2003 22:15:01 -0000
@@ -21,7 +21,8 @@ Software Foundation, 59 Temple Place - S
#ifndef GCC_OPTS_H
#define GCC_OPTS_H
-extern int handle_option (int argc, char **argv, int lang_mask);
+extern void handle_options (unsigned int argc, char **argv,
+ unsigned int lang_mask);
struct cl_option
{
@@ -33,6 +34,7 @@ struct cl_option
extern const struct cl_option cl_options[];
extern const unsigned int cl_options_count;
+extern const char *const lang_names[];
#define CL_JOINED (1 << 24) /* If takes joined argument. */
#define CL_SEPARATE (1 << 25) /* If takes a separate argument. */
Index: opts.sh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/opts.sh,v
retrieving revision 1.18
diff -u -p -r1.18 opts.sh
--- opts.sh 22 Jun 2003 20:21:35 -0000 1.18
+++ opts.sh 24 Jun 2003 22:15:01 -0000
@@ -85,20 +85,25 @@ ${AWK} '
h_file = "'${H_FILE}'"
comma = ","
+ print "/* This file is auto-generated by opts.sh. */\n" > c_file
+ print "#include \"" h_file "\"" >> c_file
+ print "#include \"opts.h\"\n" >> c_file
+ print "const char * const lang_names[] =\n{" >> c_file
+
print "/* This file is auto-generated by opts.sh. */\n" > h_file
for (i = 0; i < n_langs; i++) {
macros[i] = "CL_" langs[i]
gsub( "[^A-Za-z0-9_]", "X", macros[i] )
s = substr(" ", length (macros[i]))
print "#define " macros[i] s " (1 << " i ")" >> h_file
+ print " \"" langs[i] "\"," >> c_file
}
- print "\nenum opt_code\n{" >> h_file
- print "/* This file is auto-generated by opts.sh. */\n" > c_file
- print "#include \"" h_file "\"" >> c_file
- print "#include \"opts.h\"\n" >> c_file
+ print " 0\n};\n" >> c_file
print "const unsigned int cl_options_count = N_OPTS;\n" >> c_file
print "const struct cl_option cl_options[] =\n{" >> c_file
+
+ print "\nenum opt_code\n{" >> h_file
for (i = 0; i < n_opts; i++)
back_chain[i] = "N_OPTS";
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.786
diff -u -p -r1.786 toplev.c
--- toplev.c 24 Jun 2003 16:50:28 -0000 1.786
+++ toplev.c 24 Jun 2003 22:15:02 -0000
@@ -4735,58 +4735,7 @@ parse_options_and_default_flags (int arg
OPTIMIZATION_OPTIONS (optimize, optimize_size);
#endif
- /* Perform normal command line switch decoding. */
- for (i = 1; i < argc;)
- {
- int processed;
-
- /* Give the language a chance to decode the option for itself. */
- processed = handle_option (argc - i, argv + i, lang_mask);
-
- if (processed)
- i += processed;
- else
- {
- const char *option = NULL;
- const char *lang = NULL;
- unsigned int j;
-
- /* It is possible that the command line switch is not valid for the
- current language, but it is valid for another language. In order
- to be compatible with previous versions of the compiler (which
- did not issue an error message in this case) we check for this
- possibility here. If we do find a match, then if extra_warnings
- is set we generate a warning message, otherwise we will just
- ignore the option. */
- for (j = 0; j < ARRAY_SIZE (documented_lang_options); j++)
- {
- option = documented_lang_options[j].option;
-
- if (option == NULL)
- lang = documented_lang_options[j].description;
- else if (! strncmp (argv[i], option, strlen (option)))
- break;
- }
-
- if (j != ARRAY_SIZE (documented_lang_options))
- {
- if (extra_warnings)
- {
- warning ("ignoring command line option '%s'", argv[i]);
- if (lang)
- warning
- ("(it is valid for %s but not the selected language)",
- lang);
- }
- }
- else if (argv[i][0] == '-' && argv[i][1] == 'g')
- warning ("`%s': unknown or unsupported -g option", &argv[i][2]);
- else
- error ("unrecognized option `%s'", argv[i]);
-
- i++;
- }
- }
+ handle_options (argc, argv, lang_mask);
if (flag_pie)
flag_pic = flag_pie;
Index: f/top.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/f/top.c,v
retrieving revision 1.34
diff -u -p -r1.34 top.c
--- f/top.c 21 Jun 2003 20:28:18 -0000 1.34
+++ f/top.c 24 Jun 2003 22:15:03 -0000
@@ -440,6 +440,7 @@ ffe_handle_option (size_t scode, const c
ffe_set_case_match (FFE_caseNONE);
ffe_set_case_source (FFE_caseLOWER);
ffe_set_case_symbol (FFE_caseNONE);
+ break;
case OPT_fcase_preserve:
ffe_set_case_intrin (FFE_caseNONE);
More information about the Gcc-patches
mailing list