Support escaping special characters in specs

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
This commit is contained in:
Jeff Downs 2017-05-03 15:22:51 +00:00 committed by Rainer Orth
parent 4d0e904fbf
commit 31c830503b
3 changed files with 78 additions and 17 deletions

View 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.

View 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

View file

@ -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: