Skip to content

Commit

Permalink
Generate Clang-style error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
wilzbach committed Jul 11, 2018
1 parent 53fcaa0 commit fafb666
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 17 deletions.
21 changes: 21 additions & 0 deletions changelog/error-pretty.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
dmd now supports expressive diagnostic error messages with `-verrors=pretty`

With the new CLI option `-verrors=pretty` dmd will now show the offending line directly in its error messages.
Consider this faulty program `test.d`:

---
void foo()
{

a = 1;
}
---

Now run it with `-verrors=pretty`:

$(CONSOLE
> dmd -verrors=pretty test.d
ee.d(5): $(RED Error): undefined identifier a
a = 1;
^
)
3 changes: 3 additions & 0 deletions src/dmd/cli.d
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,9 @@ dmd -cov -unittest myprog.d
Option("verrors=spec",
"show errors from speculative compiles such as __traits(compiles,...)"
),
Option("verrors=pretty",
"Pretty-print error messages with annotation of the erroring source line"
),
Option("-version",
"print compiler version and exit"
),
Expand Down
38 changes: 21 additions & 17 deletions src/dmd/errors.d
Original file line number Diff line number Diff line change
Expand Up @@ -237,30 +237,34 @@ private void verrorPrint(const ref Loc loc, Color headerColor, const(char)* head
fputs(tmp.peekString(), stderr);
fputc('\n', stderr);

auto fp = fopen(loc.filename, "r");
scope(exit) fclose(fp);

if (fp)
if (global.params.prettyPrintErrors)
{
char* lineptr;
ulong n = 1024;
import core.sys.posix.stdio;
foreach (_; 0 .. loc.linnum)
auto fp = fopen(loc.filename, "r");
scope(exit) fclose(fp);

if (fp)
{
char* lineptr;
ulong n = 1024;
import core.sys.posix.stdio;
foreach (_; 0 .. loc.linnum)
{
assert(getline(&lineptr, &n, fp) > 0);
if (lineptr is null)
goto end;
}
if (lineptr is null)
goto end;
assert(getline(&lineptr, &n, fp) > 0);
}
if (lineptr is null)
goto end;
fprintf(stderr, "%s", lineptr);
fprintf(stderr, "%s", lineptr);

foreach (_; 0 .. loc.charnum)
fputc(' ', stderr);
if (loc.charnum >= 1)
foreach (_; 1 .. loc.charnum)
fputc(' ', stderr);

fputc('^', stderr);
fputc('^', stderr);
}
fputc('\n', stderr);
}
fputc('\n', stderr);
end:
fflush(stderr); // ensure it gets written out in case of compiler aborts
}
Expand Down
1 change: 1 addition & 0 deletions src/dmd/globals.d
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ struct Param
*/

bool showGaggedErrors; // print gagged errors anyway
bool prettyPrintErrors; // pretty print errors with the actual line
bool manual; // open browser on compiler manual
bool usage; // print usage and exit
bool mcpuUsage; // print help on -mcpu switch
Expand Down
4 changes: 4 additions & 0 deletions src/dmd/mars.d
Original file line number Diff line number Diff line change
Expand Up @@ -1732,6 +1732,10 @@ private bool parseCommandLine(const ref Strings arguments, const size_t argc, re
{
params.showGaggedErrors = true;
}
else if (startsWith(p + 9, "pretty"))
{
params.prettyPrintErrors = true;
}
else
goto Lerror;
}
Expand Down
15 changes: 15 additions & 0 deletions test/fail_compilation/fail_pretty_errors.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
REQUIRED_ARGS: -verrors=pretty
TEST_OUTPUT:
---
fail_compilation/fail_pretty_errors.d(14): Error: undefined identifier `a`
a = 1;
^
---
*/

void foo()
{

a = 1;
}

0 comments on commit fafb666

Please sign in to comment.