This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch: %{<flag} spec syntax
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Subject: Patch: %{<flag} spec syntax
- From: Tom Tromey <tromey at cygnus dot com>
- Date: 26 Mar 2000 15:27:32 -0700
- Reply-To: tromey at cygnus dot com
A while back I asked a question about removing options while doing
spec processing; see
http://gcc.gnu.org/ml/gcc/2000-03/msg00119.html
Nick answered with a suggestion for how to change gcc.c to allow this:
http://gcc.gnu.org/ml/gcc/2000-03/msg00125.html
I've implemented his suggestion. Here is the patch. This patch also
includes a minor fix to make some code conform to the coding
standards, and adds some new defines which I think make the
`live_cond' code a bit clearer.
I tried this by changing jvspec.c to include a %{<...} for each
Java-specific `-f' option. Before this patch, each such -f was passed
to the cc1 invocation. After this patch, such options were correctly
omitted.
Is this ok?
2000-03-26 Tom Tromey <tromey@cygnus.com>
* gcc.c (handle_braces): Recognize `%{<S}' construct.
(SWITCH_OK, SWITCH_FALSE, SWITCH_IGNORE, SWITCH_LIVE): New
defines.
(process_command): Use them.
(check_live_switch): Likewise.
(give_switch): Skip ignored switches.
Tom
Index: gcc.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gcc.c,v
retrieving revision 1.134
diff -u -c -r1.134 gcc.c
*** gcc.c 2000/03/14 18:08:35 1.134
--- gcc.c 2000/03/26 22:19:29
***************
*** 366,371 ****
--- 366,375 ----
specified to CC. Note that the tail part of the -S option
(i.e. the part matched by the `*') will be substituted for each
occurrence of %* within X.
+ %{<S} remove all occurances of S from the command line.
+ Note - this option is position dependent. % commands in the
+ spec string before this option will see S, % commands in the
+ spec string after this option will not.
%{S:X} substitutes X, but only if the -S switch was given to CC.
%{!S:X} substitutes X, but only if the -S switch was NOT given to CC.
%{|S:X} like %{S:X}, but if no S switch, substitute `-'.
***************
*** 2639,2649 ****
If a switch uses following arguments, then the `part1' field
is the switch itself and the `args' field
is a null-terminated vector containing the following arguments.
! The `live_cond' field is 1 if the switch is true in a conditional spec,
! -1 if false (overridden by a later switch), and is initialized to zero.
The `validated' field is nonzero if any spec has looked at this switch;
if it remains zero at the end of the run, it must be meaningless. */
struct switchstr
{
const char *part1;
--- 2643,2661 ----
If a switch uses following arguments, then the `part1' field
is the switch itself and the `args' field
is a null-terminated vector containing the following arguments.
! The `live_cond' field is:
! 0 when initialized
! 1 if the switch is true in a conditional spec,
! -1 if false (overridden by a later switch)
! -2 if this switch should be ignored (used in %{<S})
The `validated' field is nonzero if any spec has looked at this switch;
if it remains zero at the end of the run, it must be meaningless. */
+ #define SWITCH_OK 0
+ #define SWITCH_FALSE -1
+ #define SWITCH_IGNORE -2
+ #define SWITCH_LIVE 1
+
struct switchstr
{
const char *part1;
***************
*** 3465,3471 ****
cc1 spec string. */
switches[n_switches].part1 = "--help";
switches[n_switches].args = 0;
! switches[n_switches].live_cond = 0;
switches[n_switches].validated = 0;
n_switches++;
--- 3477,3483 ----
cc1 spec string. */
switches[n_switches].part1 = "--help";
switches[n_switches].args = 0;
! switches[n_switches].live_cond = SWITCH_OK;
switches[n_switches].validated = 0;
n_switches++;
***************
*** 3480,3486 ****
-e0 or -e1 down into the linker. */
switches[n_switches].part1 = &argv[i][0];
switches[n_switches].args = 0;
! switches[n_switches].live_cond = 0;
switches[n_switches].validated = 0;
n_switches++;
}
--- 3492,3498 ----
-e0 or -e1 down into the linker. */
switches[n_switches].part1 = &argv[i][0];
switches[n_switches].args = 0;
! switches[n_switches].live_cond = SWITCH_OK;
switches[n_switches].validated = 0;
n_switches++;
}
***************
*** 3589,3595 ****
else
switches[n_switches].args = 0;
! switches[n_switches].live_cond = 0;
switches[n_switches].validated = 0;
/* This is always valid, since gcc.c itself understands it. */
if (!strcmp (p, "save-temps"))
--- 3601,3607 ----
else
switches[n_switches].args = 0;
! switches[n_switches].live_cond = SWITCH_OK;
switches[n_switches].validated = 0;
/* This is always valid, since gcc.c itself understands it. */
if (!strcmp (p, "save-temps"))
***************
*** 4601,4617 ****
int negate;
int suffix;
int include_blanks = 1;
if (*p == '^')
! /* A '^' after the open-brace means to not give blanks before args. */
! include_blanks = 0, ++p;
if (*p == '|')
! /* A `|' after the open-brace means,
! if the test fails, output a single minus sign rather than nothing.
! This is used in %{|!pipe:...}. */
! pipe_p = 1, ++p;
next_member:
negate = suffix = 0;
--- 4613,4644 ----
int negate;
int suffix;
int include_blanks = 1;
+ int elide_switch = 0;
if (*p == '^')
! {
! /* A '^' after the open-brace means to not give blanks before args. */
! include_blanks = 0;
! ++p;
! }
if (*p == '|')
! {
! /* A `|' after the open-brace means,
! if the test fails, output a single minus sign rather than nothing.
! This is used in %{|!pipe:...}. */
! pipe_p = 1;
! ++p;
! }
+ if (*p == '<')
+ {
+ /* A `<' after the open-brace means that the switch should be
+ removed from the command-line. */
+ elide_switch = 1;
+ ++p;
+ }
+
next_member:
negate = suffix = 0;
***************
*** 4630,4635 ****
--- 4657,4669 ----
++p;
}
+ if (elide_switch && (negate || pipe_p || suffix))
+ {
+ /* It doesn't make sense to mix elision with other flags. We
+ could fatal() here, but the standard seems to be to abort. */
+ abort ();
+ }
+
filter = p;
while (*p != ':' && *p != '}' && *p != '|') p++;
***************
*** 4767,4773 ****
conditional text. */
if (present != negate)
{
! if (*p == '}')
{
give_switch (i, 0, include_blanks);
}
--- 4801,4812 ----
conditional text. */
if (present != negate)
{
! if (elide_switch)
! {
! switches[i].live_cond = SWITCH_IGNORE;
! switches[i].validated = 1;
! }
! else if (*p == '}')
{
give_switch (i, 0, include_blanks);
}
***************
*** 4829,4835 ****
if (switches[i].part1[0] == 'O')
{
switches[switchnum].validated = 1;
! switches[switchnum].live_cond = -1;
return 0;
}
break;
--- 4868,4874 ----
if (switches[i].part1[0] == 'O')
{
switches[switchnum].validated = 1;
! switches[switchnum].live_cond = SWITCH_FALSE;
return 0;
}
break;
***************
*** 4843,4849 ****
&& ! strcmp (&switches[i].part1[1], &name[4]))
{
switches[switchnum].validated = 1;
! switches[switchnum].live_cond = -1;
return 0;
}
}
--- 4882,4888 ----
&& ! strcmp (&switches[i].part1[1], &name[4]))
{
switches[switchnum].validated = 1;
! switches[switchnum].live_cond = SWITCH_FALSE;
return 0;
}
}
***************
*** 4858,4864 ****
&& !strcmp (&switches[i].part1[4], &name[1]))
{
switches[switchnum].validated = 1;
! switches[switchnum].live_cond = -1;
return 0;
}
}
--- 4897,4903 ----
&& !strcmp (&switches[i].part1[4], &name[1]))
{
switches[switchnum].validated = 1;
! switches[switchnum].live_cond = SWITCH_FALSE;
return 0;
}
}
***************
*** 4866,4872 ****
}
/* Otherwise the switch is live. */
! switches[switchnum].live_cond = 1;
return 1;
}
--- 4905,4911 ----
}
/* Otherwise the switch is live. */
! switches[switchnum].live_cond = SWITCH_LIVE;
return 1;
}
***************
*** 4887,4892 ****
--- 4926,4934 ----
int omit_first_word;
int include_blanks;
{
+ if (switches[switchnum].live_cond == SWITCH_IGNORE)
+ return;
+
if (!omit_first_word)
{
do_spec_1 ("-", 0, NULL_PTR);