Support escaping special characters in specs
authorJeff Downs <heydowns@somuchpressure.net>
Wed, 3 May 2017 15:22:51 +0000 (15:22 +0000)
committerRainer Orth <ro@gcc.gnu.org>
Wed, 3 May 2017 15:22:51 +0000 (15:22 +0000)
2017-05-03  Jeff Downs  <heydowns@somuchpressure.net>
    Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

* gcc.c (handle_braces): Support escaping in switch matching
text.
* doc/invoke.texi (Spec Files): Document it.
Remove superfluous @code markup in items.

Co-Authored-By: Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
From-SVN: r247552

gcc/ChangeLog
gcc/doc/invoke.texi
gcc/gcc.c

index dbd170cc47eab63041761bf4c6d41908abc04468..92a4e395ba8680aa7470ba1b5a917eaa9cdffadc 100644 (file)
@@ -1,3 +1,11 @@
+2017-05-03  Jeff Downs  <heydowns@somuchpressure.net>
+           Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
+
+       * gcc.c (handle_braces): Support escaping in switch matching
+       text.
+       * doc/invoke.texi (Spec Files): Document it.
+       Remove superfluous @code markup in items.
+
 2017-05-03  David Malcolm  <dmalcolm@redhat.com>
 
        * diagnostic-show-locus.c (struct column_range): New struct.
index 65308c9d9330f7cb7426f05b1838c02748e47e88..ec7b9aa550e54bea614bc6b530fb3b67a788b786 100644 (file)
@@ -26239,7 +26239,7 @@ Substitute the variable part of a matched option.  See below.
 Note that each comma in the substituted string is replaced by
 a single space.
 
-@item %<@code{S}
+@item %<S
 Remove all occurrences of @code{-S} from the command line.  Note---this
 command is position dependent.  @samp{%} commands in the spec string
 before this one see @code{-S}, @samp{%} commands in the spec string
@@ -26337,7 +26337,7 @@ It is used to separate compiler options from assembler options
 in the @option{--target-help} output.
 @end table
 
-@item %@{@code{S}@}
+@item %@{S@}
 Substitutes the @code{-S} switch, if that switch is given to GCC@.
 If that switch is not specified, this substitutes nothing.  Note that
 the leading dash is omitted when specifying this option, and it is
@@ -26345,11 +26345,11 @@ automatically inserted if the substitution is performed.  Thus the spec
 string @samp{%@{foo@}} matches the command-line option @option{-foo}
 and outputs the command-line option @option{-foo}.
 
-@item %W@{@code{S}@}
+@item %W@{S@}
 Like %@{@code{S}@} but mark last argument supplied within as a file to be
 deleted on failure.
 
-@item %@{@code{S}*@}
+@item %@{S*@}
 Substitutes all the switches specified to GCC whose names start
 with @code{-S}, but which also take an argument.  This is used for
 switches like @option{-o}, @option{-D}, @option{-I}, etc.
@@ -26357,19 +26357,19 @@ GCC considers @option{-o foo} as being
 one switch whose name starts with @samp{o}.  %@{o*@} substitutes this
 text, including the space.  Thus two arguments are generated.
 
-@item %@{@code{S}*&@code{T}*@}
+@item %@{S*&T*@}
 Like %@{@code{S}*@}, but preserve order of @code{S} and @code{T} options
 (the order of @code{S} and @code{T} in the spec is not significant).
 There can be any number of ampersand-separated variables; for each the
 wild card is optional.  Useful for CPP as @samp{%@{D*&U*&A*@}}.
 
-@item %@{@code{S}:@code{X}@}
+@item %@{S:X@}
 Substitutes @code{X}, if the @option{-S} switch is given to GCC@.
 
-@item %@{!@code{S}:@code{X}@}
+@item %@{!S:X@}
 Substitutes @code{X}, if the @option{-S} switch is @emph{not} given to GCC@.
 
-@item %@{@code{S}*:@code{X}@}
+@item %@{S*:X@}
 Substitutes @code{X} if one or more switches whose names start with
 @code{-S} are specified to GCC@.  Normally @code{X} is substituted only
 once, no matter how many such switches appeared.  However, if @code{%*}
@@ -26394,19 +26394,19 @@ when matching an option like @option{-mcu=newchip} produces:
 --script=newchip/memory.ld
 @end smallexample
 
-@item %@{.@code{S}:@code{X}@}
+@item %@{.S:X@}
 Substitutes @code{X}, if processing a file with suffix @code{S}.
 
-@item %@{!.@code{S}:@code{X}@}
+@item %@{!.S:X@}
 Substitutes @code{X}, if @emph{not} processing a file with suffix @code{S}.
 
-@item %@{,@code{S}:@code{X}@}
+@item %@{,S:X@}
 Substitutes @code{X}, if processing a file for language @code{S}.
 
-@item %@{!,@code{S}:@code{X}@}
+@item %@{!,S:X@}
 Substitutes @code{X}, if not processing a file for language @code{S}.
 
-@item %@{@code{S}|@code{P}:@code{X}@}
+@item %@{S|P:X@}
 Substitutes @code{X} if either @code{-S} or @code{-P} is given to
 GCC@.  This may be combined with @samp{!}, @samp{.}, @samp{,}, and
 @code{*} sequences as well, although they have a stronger binding than
@@ -26441,7 +26441,14 @@ be as many clauses as you need.  This may be combined with @code{.},
 
 @end table
 
-The conditional text @code{X} in a %@{@code{S}:@code{X}@} or similar
+The switch matching text @code{S} in a @samp{%@{S@}}, @samp{%@{S:X@}}
+or similar construct can use a backslash to ignore the special meaning
+of the character following it, thus allowing literal matching of a
+character that is otherwise specially treated.  For example,
+@samp{%@{std=iso9899\:1999:X@}} substitutes @code{X} if the
+@option{-std=iso9899:1999} option is given.
+
+The conditional text @code{X} in a @samp{%@{S:X@}} or similar
 construct may contain other nested @samp{%} constructs or spaces, or
 even newlines.  They are processed as usual, as described above.
 Trailing white space in @code{X} is ignored.  White space may also
index 826b012cd77384031e2cdef49fd314fe7879decd..120c5c0792a38afe06f7ddb5bd13209eb08a8a2c 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -584,6 +584,12 @@ or with constant text in a single argument.
 
  %(Spec) processes a specification defined in a specs file as *Spec:
 
+The switch matching text S in a %{S}, %{S:X}, or similar construct can use
+a backslash to ignore the special meaning of the character following it,
+thus allowing literal matching of a character that is otherwise specially
+treated.  For example, %{std=iso9899\:1999:X} substitutes X if the
+-std=iso9899:1999 option is given.
+
 The conditional text X in a %{S:X} or similar construct may contain
 other nested % constructs or spaces, or even newlines.  They are
 processed as usual, as described above.  Trailing white space in X is
@@ -6237,6 +6243,8 @@ handle_braces (const char *p)
 {
   const char *atom, *end_atom;
   const char *d_atom = NULL, *d_end_atom = NULL;
+  char *esc_buf = NULL, *d_esc_buf = NULL;
+  int esc;
   const char *orig = p;
 
   bool a_is_suffix;
@@ -6287,11 +6295,42 @@ handle_braces (const char *p)
            p++, a_is_spectype = true;
 
          atom = p;
+         esc = 0;
          while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
-                || *p == ',' || *p == '.' || *p == '@')
-           p++;
+                || *p == ',' || *p == '.' || *p == '@' || *p == '\\')
+           {
+             if (*p == '\\')
+               {
+                 p++;
+                 if (!*p)
+                   fatal_error (input_location,
+                                "braced spec %qs ends in escape", orig);
+                 esc++;
+               }
+             p++;
+           }
          end_atom = p;
 
+         if (esc)
+           {
+             const char *ap;
+             char *ep;
+
+             if (esc_buf && esc_buf != d_esc_buf)
+               free (esc_buf);
+             esc_buf = NULL;
+             ep = esc_buf = (char *) xmalloc (end_atom - atom - esc + 1);
+             for (ap = atom; ap != end_atom; ap++, ep++)
+               {
+                 if (*ap == '\\')
+                   ap++;
+                 *ep = *ap;
+               }
+             *ep = '\0';
+             atom = esc_buf;
+             end_atom = ep;
+           }
+
          if (*p == '*')
            p++, a_is_starred = 1;
        }
@@ -6358,6 +6397,7 @@ handle_braces (const char *p)
                      disj_matched = true;
                      d_atom = atom;
                      d_end_atom = end_atom;
+                     d_esc_buf = esc_buf;
                    }
                }
            }
@@ -6369,7 +6409,7 @@ handle_braces (const char *p)
              p = process_brace_body (p + 1, d_atom, d_end_atom, disj_starred,
                                      disj_matched && !n_way_matched);
              if (p == 0)
-               return 0;
+               goto done;
 
              /* If we have an N-way choice, reset state for the next
                 disjunction.  */
@@ -6390,6 +6430,12 @@ handle_braces (const char *p)
     }
   while (*p++ != '}');
 
+ done:
+  if (d_esc_buf && d_esc_buf != esc_buf)
+    free (d_esc_buf);
+  if (esc_buf)
+    free (esc_buf);
+
   return p;
 
  invalid: