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 warningSupplemental(const ref Loc loc, const(char)* format, ...);
31 
32     void message(const ref Loc loc, const(char)* format, ...);
33 
34     void deprecation(const ref Loc loc, const(char)* format, ...);
35 
36     void deprecationSupplemental(const ref Loc loc, const(char)* format, ...);
37 }
38 
39 /*****************************************
40  * Just ignores the messages.
41  */
42 class ErrorSinkNull : ErrorSink
43 {
44   nothrow:
45   extern (C++):
46   override:
47 
48     void error(const ref Loc loc, const(char)* format, ...) { }
49 
50     void errorSupplemental(const ref Loc loc, const(char)* format, ...) { }
51 
52     void warning(const ref Loc loc, const(char)* format, ...) { }
53 
54     void warningSupplemental(const ref Loc loc, const(char)* format, ...) { }
55 
56     void message(const ref Loc loc, const(char)* format, ...) { }
57 
58     void deprecation(const ref Loc loc, const(char)* format, ...) { }
59 
60     void deprecationSupplemental(const ref Loc loc, const(char)* format, ...) { }
61 }
62 
63 /*****************************************
64  * Simplest implementation, just sends messages to stderr.
65  * See also: ErrorSinkCompiler.
66  */
67 class ErrorSinkStderr : ErrorSink
68 {
69     import core.stdc.stdio;
70     import core.stdc.stdarg;
71 
72   nothrow:
73   extern (C++):
74   override:
75 
76     void error(const ref Loc loc, const(char)* format, ...)
77     {
78         fputs("Error: ", stderr);
79         const p = loc.toChars();
80         if (*p)
81         {
82             fprintf(stderr, "%s: ", p);
83             //mem.xfree(cast(void*)p); // loc should provide the free()
84         }
85 
86         va_list ap;
87         va_start(ap, format);
88         vfprintf(stderr, format, ap);
89         fputc('\n', stderr);
90         va_end(ap);
91     }
92 
93     void errorSupplemental(const ref Loc loc, const(char)* format, ...) { }
94 
95     void warning(const ref Loc loc, const(char)* format, ...)
96     {
97         fputs("Warning: ", stderr);
98         const p = loc.toChars();
99         if (*p)
100         {
101             fprintf(stderr, "%s: ", p);
102             //mem.xfree(cast(void*)p); // loc should provide the free()
103         }
104 
105         va_list ap;
106         va_start(ap, format);
107         vfprintf(stderr, format, ap);
108         fputc('\n', stderr);
109         va_end(ap);
110     }
111 
112     void warningSupplemental(const ref Loc loc, const(char)* format, ...) { }
113 
114     void deprecation(const ref Loc loc, const(char)* format, ...)
115     {
116         fputs("Deprecation: ", stderr);
117         const p = loc.toChars();
118         if (*p)
119         {
120             fprintf(stderr, "%s: ", p);
121             //mem.xfree(cast(void*)p); // loc should provide the free()
122         }
123 
124         va_list ap;
125         va_start(ap, format);
126         vfprintf(stderr, format, ap);
127         fputc('\n', stderr);
128         va_end(ap);
129     }
130 
131     void message(const ref Loc loc, const(char)* format, ...)
132     {
133         const p = loc.toChars();
134         if (*p)
135         {
136             fprintf(stderr, "%s: ", p);
137             //mem.xfree(cast(void*)p); // loc should provide the free()
138         }
139 
140         va_list ap;
141         va_start(ap, format);
142         vfprintf(stderr, format, ap);
143         fputc('\n', stderr);
144         va_end(ap);
145     }
146 
147     void deprecationSupplemental(const ref Loc loc, const(char)* format, ...) { }
148 }