1 /* Declarations for error-reporting functions.
2 Copyright (C) 1995-1997, 2003, 2006, 2008-2023 Free Software Foundation,
3 Inc.
4 This file is part of the GNU C Library.
5
6 This file is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
10
11 This file is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18
19 #ifndef _@GUARD_PREFIX@_ERROR_H
20
21 /* No @PRAGMA_SYSTEM_HEADER@ here, because it would prevent
22 -Wimplicit-fallthrough warnings for missing FALLTHROUGH after error(...)
23 or error_at_line(...) invocations. */
24
25 /* The include_next requires a split double-inclusion guard. */
26 #if @HAVE_ERROR_H@
27 # @INCLUDE_NEXT@ @NEXT_ERROR_H@
28 #endif
29
30 #ifndef _@GUARD_PREFIX@_ERROR_H
31 #define _@GUARD_PREFIX@_ERROR_H
32
33 /* This file uses _GL_ATTRIBUTE_ALWAYS_INLINE, _GL_ATTRIBUTE_FORMAT,
34 _GL_ATTRIBUTE_MAYBE_UNUSED. */
35 #if !_GL_CONFIG_H_INCLUDED
36 #error "Please include config.h first."
37 #endif
38
39 /* Get 'unreachable'. */
40 #include <stddef.h>
41
42 /* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM. */
43 #include <stdio.h>
44
45 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
46
47 #if GNULIB_VFPRINTF_POSIX
48 # define _GL_ATTRIBUTE_SPEC_PRINTF_ERROR _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD
49 #else
50 # define _GL_ATTRIBUTE_SPEC_PRINTF_ERROR _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM
51 #endif
52
53 /* Helper macro for supporting the compiler's control flow analysis better.
54 It evaluates its arguments only once.
55 Test case: Compile copy-file.c with "gcc -Wimplicit-fallthrough". */
56 #if defined __GNUC__ || defined __clang__
57 /* Use 'unreachable' to tell the compiler when the function call does not
58 return. */
59 # define __gl_error_call1(function, status, ...) \
60 ((function) (status, __VA_ARGS__), \
61 (status) != 0 ? unreachable () : (void) 0)
62 /* If STATUS is a not a constant, the function call may or may not return;
63 therefore -Wimplicit-fallthrough will produce a warning. Use a compound
64 statement in order to evaluate STATUS only once.
65 If STATUS is a constant, we don't use a compound statement, because that
66 would trigger a -Wimplicit-fallthrough warning even when STATUS is != 0,
67 when not optimizing. This causes STATUS to be evaluated twice, but
68 that's OK since it does not have side effects. */
69 # define __gl_error_call(function, status, ...) \
70 (__builtin_constant_p (status) \
71 ? __gl_error_call1 (function, status, __VA_ARGS__) \
72 : __extension__ \
73 ({ \
74 int const __errstatus = status; \
75 __gl_error_call1 (function, __errstatus, __VA_ARGS__); \
76 }))
77 #else
78 # define __gl_error_call(function, status, ...) \
79 (function) (status, __VA_ARGS__)
80 #endif
81
82 #if GNULIB_REPLACE_ERROR
83 # undef error_print_progname
84 # undef error_message_count
85 # undef error_one_per_line
86 # define error_print_progname rpl_error_print_progname
87 # define error_message_count rpl_error_message_count
88 # define error_one_per_line rpl_error_one_per_line
89 #endif
90
91 #ifdef __cplusplus
92 extern "C" {
93 #endif
94
95 /* Print a message with 'fprintf (stderr, FORMAT, ...)';
96 if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
97 If STATUS is nonzero, terminate the program with 'exit (STATUS)'. */
98 #if @REPLACE_ERROR@
99 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
100 # undef error
101 # define error rpl_error
102 # endif
103 _GL_FUNCDECL_RPL (error, void,
104 (int __status, int __errnum, const char *__format, ...)
105 _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4)));
106 _GL_CXXALIAS_RPL (error, void,
107 (int __status, int __errnum, const char *__format, ...));
108 # ifndef _GL_NO_INLINE_ERROR
109 # undef error
110 # define error(status, ...) \
111 __gl_error_call (rpl_error, status, __VA_ARGS__)
112 # endif
113 #else
114 # if ! @HAVE_ERROR@
115 _GL_FUNCDECL_SYS (error, void,
116 (int __status, int __errnum, const char *__format, ...)
117 _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4)));
118 # endif
119 _GL_CXXALIAS_SYS (error, void,
120 (int __status, int __errnum, const char *__format, ...));
121 # ifndef _GL_NO_INLINE_ERROR
122 # ifdef error
123 /* Only gcc ≥ 4.7 has __builtin_va_arg_pack. */
124 # if _GL_GNUC_PREREQ (4, 7)
125 # pragma GCC diagnostic push
126 # pragma GCC diagnostic ignored "-Wattributes"
127 _GL_ATTRIBUTE_MAYBE_UNUSED
128 static void
129 _GL_ATTRIBUTE_ALWAYS_INLINE
130 _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4))
131 _gl_inline_error (int __status, int __errnum, const char *__format, ...)
132 {
133 return error (__status, __errnum, __format, __builtin_va_arg_pack ());
134 }
135 # pragma GCC diagnostic pop
136 # undef error
137 # define error(status, ...) \
138 __gl_error_call (_gl_inline_error, status, __VA_ARGS__)
139 # endif
140 # else
141 # define error(status, ...) \
142 __gl_error_call (error, status, __VA_ARGS__)
143 # endif
144 # endif
145 #endif
146 #if __GLIBC__ >= 2
147 _GL_CXXALIASWARN (error);
148 #endif
149
150 /* Likewise. If FILENAME is non-NULL, include FILENAME:LINENO: in the
151 message. */
152 #if @REPLACE_ERROR_AT_LINE@
153 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
154 # undef error_at_line
155 # define error_at_line rpl_error_at_line
156 # endif
157 _GL_FUNCDECL_RPL (error_at_line, void,
158 (int __status, int __errnum, const char *__filename,
159 unsigned int __lineno, const char *__format, ...)
160 _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 5, 6)));
161 _GL_CXXALIAS_RPL (error_at_line, void,
162 (int __status, int __errnum, const char *__filename,
163 unsigned int __lineno, const char *__format, ...));
164 # ifndef _GL_NO_INLINE_ERROR
165 # undef error_at_line
166 # define error_at_line(status, ...) \
167 __gl_error_call (rpl_error_at_line, status, __VA_ARGS__)
168 # endif
169 #else
170 # if ! @HAVE_ERROR_AT_LINE@
171 _GL_FUNCDECL_SYS (error_at_line, void,
172 (int __status, int __errnum, const char *__filename,
173 unsigned int __lineno, const char *__format, ...)
174 _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 5, 6)));
175 # endif
176 _GL_CXXALIAS_SYS (error_at_line, void,
177 (int __status, int __errnum, const char *__filename,
178 unsigned int __lineno, const char *__format, ...));
179 # ifndef _GL_NO_INLINE_ERROR
180 # ifdef error_at_line
181 /* Only gcc ≥ 4.7 has __builtin_va_arg_pack. */
182 # if _GL_GNUC_PREREQ (4, 7)
183 # pragma GCC diagnostic push
184 # pragma GCC diagnostic ignored "-Wattributes"
185 _GL_ATTRIBUTE_MAYBE_UNUSED
186 static void
187 _GL_ATTRIBUTE_ALWAYS_INLINE
188 _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 5, 6))
189 _gl_inline_error_at_line (int __status, int __errnum, const char *__filename,
190 unsigned int __lineno, const char *__format, ...)
191 {
192 return error_at_line (__status, __errnum, __filename, __lineno, __format,
193 __builtin_va_arg_pack ());
194 }
195 # pragma GCC diagnostic pop
196 # undef error_at_line
197 # define error_at_line(status, ...) \
198 __gl_error_call (_gl_inline_error_at_line, status, __VA_ARGS__)
199 # endif
200 # else
201 # define error_at_line(status, ...) \
202 __gl_error_call (error_at_line, status, __VA_ARGS__)
203 # endif
204 # endif
205 #endif
206 _GL_CXXALIASWARN (error_at_line);
207
208 /* If NULL, error will flush stdout, then print on stderr the program
209 name, a colon and a space. Otherwise, error will call this
210 function without parameters instead. */
211 extern DLL_VARIABLE void (*error_print_progname) (void);
212
213 /* This variable is incremented each time 'error' is called. */
214 extern DLL_VARIABLE unsigned int error_message_count;
215
216 /* Sometimes we want to have at most one error per line. This
217 variable controls whether this mode is selected or not. */
218 extern DLL_VARIABLE int error_one_per_line;
219
220 #ifdef __cplusplus
221 }
222 #endif
223
224 #endif /* _@GUARD_PREFIX@_ERROR_H */
225 #endif /* _@GUARD_PREFIX@_ERROR_H */