[Fwd: More cpplib Work]

Richard Henderson rth@cygnus.com
Wed Jun 10 20:51:00 GMT 1998


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



More information about the Gcc-patches mailing list