Escape backticks in error messages (#20893)

This commit is contained in:
Dennis 2025-02-19 00:06:47 +01:00 committed by GitHub
parent e082ce247a
commit 0e5c41f799
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 39 additions and 6 deletions

View file

@ -1896,8 +1896,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
const sident = se.toStringz(); const sident = se.toStringz();
if (!sident.length || !Identifier.isValidIdentifier(sident)) if (!sident.length || !Identifier.isValidIdentifier(sident))
{ {
error(ns.exp.loc, "expected valid identifier for C++ namespace but got `%.*s`", error(ns.exp.loc, "expected valid identifier for C++ namespace but got `%s`", se.toErrMsg());
cast(int)sident.length, sident.ptr);
return null; return null;
} }
else else

View file

@ -714,7 +714,10 @@ private void verrorPrint(const(char)* format, va_list ap, ref ErrorInfo info)
writeHighlights(con, tmp); writeHighlights(con, tmp);
} }
else else
{
unescapeBackticks(tmp);
fputs(tmp.peekChars(), stderr); fputs(tmp.peekChars(), stderr);
}
fputc('\n', stderr); fputc('\n', stderr);
__gshared SourceLoc old_loc; __gshared SourceLoc old_loc;
@ -828,6 +831,7 @@ extern (C++) void halt() @safe
* is D source code, and color syntax highlight it. * is D source code, and color syntax highlight it.
* Modify contents of `buf` with highlighted result. * Modify contents of `buf` with highlighted result.
* Many parallels to ddoc.highlightText(). * Many parallels to ddoc.highlightText().
* Double backticks are replaced by a single backtick without coloring.
* Params: * Params:
* buf = text containing `...` code to highlight * buf = text containing `...` code to highlight
*/ */
@ -843,6 +847,13 @@ private void colorSyntaxHighlight(ref OutBuffer buf)
switch (c) switch (c)
{ {
case '`': case '`':
// A double backtick means it's part of the content, don't color
if (i + 1 < buf.length && buf[i + 1] == '`')
{
buf.remove(i, 1);
continue;
}
if (inBacktick) if (inBacktick)
{ {
inBacktick = false; inBacktick = false;
@ -867,6 +878,27 @@ private void colorSyntaxHighlight(ref OutBuffer buf)
} }
} }
/// Replace double backticks in `buf` with a single backtick
void unescapeBackticks(ref OutBuffer buf)
{
for (size_t i = 0; i + 1 < buf.length; ++i)
{
if (buf[i] == '`' && buf[i + 1] == '`')
buf.remove(i, 1);
}
}
unittest
{
OutBuffer buf;
buf.writestring("x````");
unescapeBackticks(buf);
assert(buf.extractSlice() == "x``");
buf.writestring("x````");
colorSyntaxHighlight(buf);
assert(buf.extractSlice() == "x``");
}
/** /**
* Embed these highlighting commands in the text stream. * Embed these highlighting commands in the text stream.

View file

@ -155,13 +155,15 @@ const(char)* toErrMsg(const Dsymbol d)
*/ */
private void truncateForError(ref OutBuffer buf, size_t maxLength) private void truncateForError(ref OutBuffer buf, size_t maxLength)
{ {
// Remove newlines // Remove newlines, escape backticks ` by doubling them
for (size_t i = 0; i < buf.length; i++) for (size_t i = 0; i < buf.length; i++)
{ {
if (buf[i] == '\r') if (buf[i] == '\r')
buf.remove(i, 1); buf.remove(i, 1);
if (buf[i] == '\n') if (buf[i] == '\n')
buf.peekSlice[i] = ' '; buf.peekSlice[i] = ' ';
if (buf[i] == '`')
i = buf.insert(i, "`");
} }
// Strip trailing whitespace // Strip trailing whitespace

View file

@ -1,10 +1,10 @@
/* /*
TEST_OUTPUT: TEST_OUTPUT:
--- ---
fail_compilation/cppmangle.d(11): Error: expected valid identifier for C++ namespace but got `` fail_compilation/cppmangle.d(11): Error: expected valid identifier for C++ namespace but got `""`
fail_compilation/cppmangle.d(15): Error: expected valid identifier for C++ namespace but got `0num` fail_compilation/cppmangle.d(15): Error: expected valid identifier for C++ namespace but got `"0num"`
fail_compilation/cppmangle.d(19): Error: compile time string constant (or sequence) expected, not `2` fail_compilation/cppmangle.d(19): Error: compile time string constant (or sequence) expected, not `2`
fail_compilation/cppmangle.d(23): Error: expected valid identifier for C++ namespace but got `invalid@namespace` fail_compilation/cppmangle.d(23): Error: expected valid identifier for C++ namespace but got `"invalid@namespace"`
--- ---
*/ */