1 /**
2  * Provides an abstraction for what to do with error messages.
3  *
4  * Copyright:   Copyright (C) 2023 by The D Language Foundation, All Rights Reserved
5  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
6  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/errorsink.d, _errorsink.d)
8  * Documentation:  https://dlang.org/phobos/dmd_errorsink.html
9  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/errorsink.d
10  */
11 
12 module dmd.errorsink;
13 
14 import dmd.location;
15 
16 /***************************************
17  * Where error/warning/deprecation messages go.
18  */
19 abstract class ErrorSink
20 {
21   nothrow:
22   extern (C++):
23 
24     void error(const ref Loc loc, const(char)* format, ...);
25 
26     void errorSupplemental(const ref Loc loc, const(char)* format, ...);
27 
28     void warning(const ref Loc loc, const(char)* format, ...);
29 
30     void message(const ref Loc loc, const(char)* format, ...);
31 
32     void deprecation(const ref Loc loc, const(char)* format, ...);
33 
34     void deprecationSupplemental(const ref Loc loc, const(char)* format, ...);
35 }
36 
37 /*****************************************
38  * Just ignores the messages.
39  */
40 class ErrorSinkNull : ErrorSink
41 {
42   nothrow:
43   extern (C++):
44   override:
45 
46     void error(const ref Loc loc, const(char)* format, ...) { }
47 
48     void errorSupplemental(const ref Loc loc, const(char)* format, ...) { }
49 
50     void warning(const ref Loc loc, const(char)* format, ...) { }
51 
52     void message(const ref Loc loc, const(char)* format, ...) { }
53 
54     void deprecation(const ref Loc loc, const(char)* format, ...) { }
55 
56     void deprecationSupplemental(const ref Loc loc, const(char)* format, ...) { }
57 }
58 
59 /*****************************************
60  * Simplest implementation, just sends messages to stderr.
61  */
62 class ErrorSinkStderr : ErrorSink
63 {
64     import core.stdc.stdio;
65     import core.stdc.stdarg;
66 
67   nothrow:
68   extern (C++):
69   override:
70 
71     void error(const ref Loc loc, const(char)* format, ...)
72     {
73         fputs("Error: ", stderr);
74         const p = loc.toChars();
75         if (*p)
76         {
77             fprintf(stderr, "%s: ", p);
78             //mem.xfree(cast(void*)p); // loc should provide the free()
79         }
80 
81         va_list ap;
82         va_start(ap, format);
83         vfprintf(stderr, format, ap);
84         fputc('\n', stderr);
85         va_end(ap);
86     }
87 
88     void errorSupplemental(const ref Loc loc, const(char)* format, ...) { }
89 
90     void warning(const ref Loc loc, const(char)* format, ...)
91     {
92         fputs("Warning: ", stderr);
93         const p = loc.toChars();
94         if (*p)
95         {
96             fprintf(stderr, "%s: ", p);
97             //mem.xfree(cast(void*)p); // loc should provide the free()
98         }
99 
100         va_list ap;
101         va_start(ap, format);
102         vfprintf(stderr, format, ap);
103         fputc('\n', stderr);
104         va_end(ap);
105     }
106 
107     void deprecation(const ref Loc loc, const(char)* format, ...)
108     {
109         fputs("Deprecation: ", stderr);
110         const p = loc.toChars();
111         if (*p)
112         {
113             fprintf(stderr, "%s: ", p);
114             //mem.xfree(cast(void*)p); // loc should provide the free()
115         }
116 
117         va_list ap;
118         va_start(ap, format);
119         vfprintf(stderr, format, ap);
120         fputc('\n', stderr);
121         va_end(ap);
122     }
123 
124     void message(const ref Loc loc, const(char)* format, ...)
125     {
126         const p = loc.toChars();
127         if (*p)
128         {
129             fprintf(stderr, "%s: ", p);
130             //mem.xfree(cast(void*)p); // loc should provide the free()
131         }
132 
133         va_list ap;
134         va_start(ap, format);
135         vfprintf(stderr, format, ap);
136         fputc('\n', stderr);
137         va_end(ap);
138     }
139 
140     void deprecationSupplemental(const ref Loc loc, const(char)* format, ...) { }
141 }