This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Fwd: More cpplib Work]
- To: Dave Brolley <brolley at cygnus dot com>, law at cygnus dot com
- Subject: Re: [Fwd: More cpplib Work]
- From: Richard Henderson <rth at cygnus dot com>
- Date: Wed, 10 Jun 1998 20:52:34 -0700
- Cc: wilson at cygnus dot com, egcs-patches at cygnus dot com
- References: <13023.897462385@hurl.cygnus.com> <357E9BB5.83D57852@cygnus.com>
- Reply-To: Richard Henderson <rth at cygnus dot com>
On Wed, Jun 10, 1998 at 10:44:05AM -0400, Dave Brolley wrote:
> > > + "%{E:"CPP_FOR_C"}"
> > > + "%{!E:%{M:"CPP_FOR_C"}"
> > > + "%{!M:%{MM:"CPP_FOR_C"}"
> > > + "%{!MM:cc1 %i %1 \
> >
> > So, will CPP_FOR_C get substituted into these expressions, even with
> > the quotes around it? Does it work for both non-ANSI and ANSI compilers?
>
> Actually CPP_FOR_C is *outside* the quotes and will get substituted. This
> relies on concatenation of adjacent literals which works in ANSI. Good point
> about non-ANSI compilers.
You should probably use a new entry down in static_specs, and then
you can write
"%{E:%(cpp_for_c)}
%{!E:%{M:%(cpp_for_c)}
%{!M:%{MM:%(cpp_for_c)}
%{!MM:cc1 ...
> Well, we only want to call cpp once if E or M or MM is specified. I
> couldn't come up with a way to represent OR in this syntax. I would
> love to have a solution where the cpp invocation is only needed once...
Yes, we dreadfully need an OR-type syntax.
How about the following, in which one may use | to separate cases,
binding weaker than !. Note that %{|x:foo} has meaning for pipe,
but that should not be ambiguous with %{x|y:foo}.
So you may now use
"%{E|M|MM:%(cpp_for_c)}%{!E|!M|!MM:cc1 ...}"
or perhaps something more even elaborate now that you have a teeny
bit more power.
r~
Wed Jun 10 20:49:24 1998 Richard Henderson <rth@cygnus.com>
* gcc.c (handle_braces): Recognize | between options as an or.
Index: gcc.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/gcc.c,v
retrieving revision 1.36
diff -u -p -r1.36 gcc.c
--- gcc.c 1998/06/06 10:42:32 1.36
+++ gcc.c 1998/06/11 03:48:55
@@ -363,6 +363,8 @@ or with constant text in a single argume
%{|!S:X} like %{!S:X}, but if there is an S switch, substitute `-'.
%{.S:X} substitutes X, but only if processing a file with suffix S.
%{!.S:X} substitutes X, but only if NOT processing a file with suffix S.
+ %{S|P:X} substitutes X if either -S or -P was given to CC. This maybe
+ combined with ! and . as above.
%(Spec) processes a specification defined in a specs file as *Spec:
%[Spec] as above, but put __ around -D arguments
@@ -4015,11 +4017,10 @@ static char *
handle_braces (p)
register char *p;
{
- register char *q;
- char *filter;
+ char *filter, *body = NULL, *endbody;
int pipe_p = 0;
- int negate = 0;
- int suffix = 0;
+ int negate;
+ int suffix;
int include_blanks = 1;
if (*p == '^')
@@ -4032,6 +4033,9 @@ handle_braces (p)
This is used in %{|!pipe:...}. */
pipe_p = 1, ++p;
+next_member:
+ negate = suffix = 0;
+
if (*p == '!')
/* A `!' after the open-brace negates the condition:
succeed if the specified switch is not present. */
@@ -4048,24 +4052,36 @@ handle_braces (p)
}
filter = p;
- while (*p != ':' && *p != '}') p++;
- if (*p != '}')
+ while (*p != ':' && *p != '}' && *p != '|') p++;
+
+ if (*p == '|' && pipe_p)
+ abort ();
+
+ if (!body)
{
- register int count = 1;
- q = p + 1;
- while (count > 0)
- {
- if (*q == '{')
- count++;
- else if (*q == '}')
- count--;
- else if (*q == 0)
- abort ();
- q++;
+ if (*p != '}')
+ {
+ register int count = 1;
+ register char *q = p;
+
+ while (*q++ != ':') continue;
+ body = q;
+
+ while (count > 0)
+ {
+ if (*q == '{')
+ count++;
+ else if (*q == '}')
+ count--;
+ else if (*q == 0)
+ abort ();
+ q++;
+ }
+ endbody = q;
}
+ else
+ body = p, endbody = p+1;
}
- else
- q = p + 1;
if (suffix)
{
@@ -4073,14 +4089,12 @@ handle_braces (p)
&& strlen (input_suffix) == p - filter
&& strncmp (input_suffix, filter, p - filter) == 0);
- if (p[0] == '}')
+ if (body[0] == '}')
abort ();
if (negate != found
- && do_spec_1 (save_string (p + 1, q - p - 2), 0, NULL_PTR) < 0)
+ && do_spec_1 (save_string (body, endbody-body-1), 0, NULL_PTR) < 0)
return 0;
-
- return q;
}
else if (p[-1] == '*' && p[0] == '}')
{
@@ -4103,11 +4117,11 @@ handle_braces (p)
if (p[-1] == '*' && !negate)
{
int substitution;
- char *r = p;
+ char *r = body;
/* First see whether we have %*. */
substitution = 0;
- while (r < q)
+ while (r < endbody)
{
if (*r == '%' && r[1] == '*')
substitution = 1;
@@ -4121,7 +4135,7 @@ handle_braces (p)
in the text that follows the colon. */
unsigned hard_match_len = p - filter - 1;
- char *string = save_string (p + 1, q - p - 2);
+ char *string = save_string (body, endbody - body - 1);
for (i = 0; i < n_switches; i++)
if (!strncmp (switches[i].part1, filter, hard_match_len)
@@ -4132,7 +4146,10 @@ handle_braces (p)
give_switch (i, 1, 1);
}
- return q;
+ /* We didn't match. Try again. */
+ if (*p++ == '|')
+ goto next_member;
+ return endbody;
}
}
@@ -4166,7 +4183,7 @@ handle_braces (p)
}
}
- /* If it is as desired (present for %{s...}, absent for %{-s...})
+ /* If it is as desired (present for %{s...}, absent for %{!s...})
then substitute either the switch or the specified
conditional text. */
if (present != negate)
@@ -4177,7 +4194,8 @@ handle_braces (p)
}
else
{
- if (do_spec_1 (save_string (p + 1, q - p - 2), 0, NULL_PTR) < 0)
+ if (do_spec_1 (save_string (body, endbody - body - 1),
+ 0, NULL_PTR) < 0)
return 0;
}
}
@@ -4186,10 +4204,15 @@ handle_braces (p)
/* Here if a %{|...} conditional fails: output a minus sign,
which means "standard output" or "standard input". */
do_spec_1 ("-", 0, NULL_PTR);
+ return endbody;
}
}
+
+ /* We didn't match; try again. */
+ if (*p++ == '|')
+ goto next_member;
- return q;
+ return endbody;
}
/* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch