Skip to content

Commit fafb666

Browse files
committed
Generate Clang-style error messages
1 parent 53fcaa0 commit fafb666

File tree

6 files changed

+65
-17
lines changed

6 files changed

+65
-17
lines changed

changelog/error-pretty.dd

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
dmd now supports expressive diagnostic error messages with `-verrors=pretty`
2+
3+
With the new CLI option `-verrors=pretty` dmd will now show the offending line directly in its error messages.
4+
Consider this faulty program `test.d`:
5+
6+
---
7+
void foo()
8+
{
9+
10+
a = 1;
11+
}
12+
---
13+
14+
Now run it with `-verrors=pretty`:
15+
16+
$(CONSOLE
17+
> dmd -verrors=pretty test.d
18+
ee.d(5): $(RED Error): undefined identifier a
19+
a = 1;
20+
^
21+
)

src/dmd/cli.d

+3
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,9 @@ dmd -cov -unittest myprog.d
553553
Option("verrors=spec",
554554
"show errors from speculative compiles such as __traits(compiles,...)"
555555
),
556+
Option("verrors=pretty",
557+
"Pretty-print error messages with annotation of the erroring source line"
558+
),
556559
Option("-version",
557560
"print compiler version and exit"
558561
),

src/dmd/errors.d

+21-17
Original file line numberDiff line numberDiff line change
@@ -237,30 +237,34 @@ private void verrorPrint(const ref Loc loc, Color headerColor, const(char)* head
237237
fputs(tmp.peekString(), stderr);
238238
fputc('\n', stderr);
239239

240-
auto fp = fopen(loc.filename, "r");
241-
scope(exit) fclose(fp);
242-
243-
if (fp)
240+
if (global.params.prettyPrintErrors)
244241
{
245-
char* lineptr;
246-
ulong n = 1024;
247-
import core.sys.posix.stdio;
248-
foreach (_; 0 .. loc.linnum)
242+
auto fp = fopen(loc.filename, "r");
243+
scope(exit) fclose(fp);
244+
245+
if (fp)
249246
{
247+
char* lineptr;
248+
ulong n = 1024;
249+
import core.sys.posix.stdio;
250+
foreach (_; 0 .. loc.linnum)
251+
{
252+
assert(getline(&lineptr, &n, fp) > 0);
253+
if (lineptr is null)
254+
goto end;
255+
}
250256
if (lineptr is null)
251257
goto end;
252-
assert(getline(&lineptr, &n, fp) > 0);
253-
}
254-
if (lineptr is null)
255-
goto end;
256-
fprintf(stderr, "%s", lineptr);
258+
fprintf(stderr, "%s", lineptr);
257259

258-
foreach (_; 0 .. loc.charnum)
259-
fputc(' ', stderr);
260+
if (loc.charnum >= 1)
261+
foreach (_; 1 .. loc.charnum)
262+
fputc(' ', stderr);
260263

261-
fputc('^', stderr);
264+
fputc('^', stderr);
265+
}
266+
fputc('\n', stderr);
262267
}
263-
fputc('\n', stderr);
264268
end:
265269
fflush(stderr); // ensure it gets written out in case of compiler aborts
266270
}

src/dmd/globals.d

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ struct Param
158158
*/
159159

160160
bool showGaggedErrors; // print gagged errors anyway
161+
bool prettyPrintErrors; // pretty print errors with the actual line
161162
bool manual; // open browser on compiler manual
162163
bool usage; // print usage and exit
163164
bool mcpuUsage; // print help on -mcpu switch

src/dmd/mars.d

+4
Original file line numberDiff line numberDiff line change
@@ -1732,6 +1732,10 @@ private bool parseCommandLine(const ref Strings arguments, const size_t argc, re
17321732
{
17331733
params.showGaggedErrors = true;
17341734
}
1735+
else if (startsWith(p + 9, "pretty"))
1736+
{
1737+
params.prettyPrintErrors = true;
1738+
}
17351739
else
17361740
goto Lerror;
17371741
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
REQUIRED_ARGS: -verrors=pretty
3+
TEST_OUTPUT:
4+
---
5+
fail_compilation/fail_pretty_errors.d(14): Error: undefined identifier `a`
6+
a = 1;
7+
^
8+
---
9+
*/
10+
11+
void foo()
12+
{
13+
14+
a = 1;
15+
}

0 commit comments

Comments
 (0)