for (const char *p = format; *p;)
{
- while (*p != '\0' && *p != '%' && *p != '`')
+ while (*p != '\0' && *p != '\\' && *p != '%' && *p != '`')
{
obstack_1grow (&buf, *p);
p++;
if (*p == '\0')
break;
+ if (*p == '\\')
+ {
+ if (p[1] == '`')
+ {
+ /* Escaped backtick, don't expand it as a quoted string. */
+ obstack_1grow (&buf, '`');
+ p++;;
+ }
+ else
+ obstack_1grow (&buf, *p);
+
+ p++;
+ continue;
+ }
+
if (*p == '`')
{
/* Text enclosed by `...` are translated as a quoted string. */
return (char *) obstack_finish (&buf);
}
+/* Rewrite the format string FORMAT to deal with any characters that require
+ escaping before expand_d_format expands it. */
+
+static char *
+escape_d_format (const char *format)
+{
+ obstack buf;
+
+ gcc_obstack_init (&buf);
+
+ for (const char *p = format; *p; p++)
+ {
+ switch (*p)
+ {
+ case '%':
+ /* Escape `%' characters so that pp_format does not confuse them
+ for actual format specifiers. */
+ obstack_1grow (&buf, '%');
+ break;
+
+ case '`':
+ /* Escape '`' characters so that expand_d_format does not confuse them
+ for a quoted string. */
+ obstack_1grow (&buf, '\\');
+ break;
+
+ default:
+ break;
+ }
+
+ obstack_1grow (&buf, *p);
+ }
+
+ obstack_1grow (&buf, '\0');
+ return (char *) obstack_finish (&buf);
+}
+
/* Helper routine for all error routines. Reports a diagnostic specified by
KIND at the explicit location LOC. The message FORMAT comes from the dmd
front-end, which does not get translated by the gcc diagnostic routines. */
/* Build string and emit. */
if (prefix2 != NULL)
- xformat = xasprintf ("%s %s %s", prefix1, prefix2, format);
+ xformat = xasprintf ("%s %s %s", escape_d_format (prefix1),
+ escape_d_format (prefix2), format);
else if (prefix1 != NULL)
- xformat = xasprintf ("%s %s", prefix1, format);
+ xformat = xasprintf ("%s %s", escape_d_format (prefix1), format);
else
xformat = xasprintf ("%s", format);
/* Build string and emit. */
if (prefix2 != NULL)
- xformat = xasprintf ("%s %s %s", prefix1, prefix2, format);
+ xformat = xasprintf ("%s %s %s", escape_d_format (prefix1),
+ escape_d_format (prefix2), format);
else if (prefix1 != NULL)
- xformat = xasprintf ("%s %s", prefix1, format);
+ xformat = xasprintf ("%s %s", escape_d_format (prefix1), format);
else
xformat = xasprintf ("%s", format);