source: trunk/src/kmk/kmkbuiltin/err.c

Last change on this file was 3636, checked in by bird, 9 months ago

kmk/kmkbuiltins: Some UCRT & VC++ 2022 adjustments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 KB
RevLine 
[370]1/* $Id: err.c 3636 2024-11-02 01:52:45Z bird $ */
2/** @file
3 * Override err.h so we get the program name right.
[2019]4 */
5
6/*
[2911]7 * Copyright (c) 2005-2016 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
[370]8 *
[2019]9 * This file is part of kBuild.
[370]10 *
[2019]11 * kBuild is free software; you can redistribute it and/or modify
[370]12 * it under the terms of the GNU General Public License as published by
[2019]13 * the Free Software Foundation; either version 3 of the License, or
[370]14 * (at your option) any later version.
15 *
[2019]16 * kBuild is distributed in the hope that it will be useful,
[370]17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
[2019]22 * along with kBuild. If not, see <http://www.gnu.org/licenses/>
[370]23 *
24 */
25
[2019]26/*******************************************************************************
27* Header Files *
28*******************************************************************************/
[3192]29#ifdef HAVE_CONFIG_H
30# include "config.h"
[3237]31# ifdef HAVE_STDLIB_H
32# include <stdlib.h>
33# endif
34# ifdef HAVE_STDINT_H
35# include <stdint.h>
36# endif
[3192]37#else
38# include <stdlib.h>
[3636]39# if _MSC_VER < 1400
40# define snprintf _snprintf
41# endif
[3192]42#endif
[370]43#include <stdio.h>
44#include <stdarg.h>
45#include <string.h>
46#include <errno.h>
47#include "err.h"
[3192]48#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
49# include "../output.h"
50#endif
[370]51
[2911]52#ifdef KBUILD_OS_WINDOWS
53/* This is a trick to speed up console output on windows. */
[3188]54# include "console.h"
[2911]55# undef fwrite
56# define fwrite maybe_con_fwrite
57#endif
[370]58
[3192]59int err(PKMKBUILTINCTX pCtx, int eval, const char *fmt, ...)
60{
61 /*
62 * We format into a buffer and pass that onto output.c or fwrite.
63 */
64 int error = errno;
65 char *pszToFree = NULL;
66 char szMsgStack[4096];
67 char *pszMsg = szMsgStack;
68 size_t cbMsg = sizeof(szMsgStack);
69 for (;;)
70 {
71 int cchMsg = snprintf(pszMsg, cbMsg, "%s: error: ", pCtx->pszProgName);
72 if (cchMsg < (int)cbMsg - 1 && cchMsg > 0)
73 {
74 int cchMsg2;
75 va_list va;
76 va_start(va, fmt);
77 cchMsg += cchMsg2 = vsnprintf(&pszMsg[cchMsg], cbMsg - cchMsg, fmt, va);
78 va_end(va);
[2911]79
[3192]80 if ( cchMsg < (int)cbMsg - 1
81 && cchMsg2 >= 0)
82 {
83 cchMsg += cchMsg2 = snprintf(&pszMsg[cchMsg], cbMsg - cchMsg, ": %s\n", strerror(error));
84 if ( cchMsg < (int)cbMsg - 1
85 && cchMsg2 >= 0)
86 {
87#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
88 if (pCtx->pOut)
89 output_write_text(pCtx->pOut, 1 /*is_err*/, pszMsg, cchMsg);
90 else
91#endif
92 {
93 fflush(stdout);
94 fwrite(pszMsg, cchMsg, 1, stderr);
95 fflush(stderr); /* paranoia */
96 }
97 if (pszToFree)
98 free(pszToFree);
99 errno = error;
100 return eval;
101 }
102 }
103 }
[370]104
[3192]105 /* double the buffer size and retry */
106 if (pszToFree)
107 free(pszToFree);
108 cbMsg *= 2;
109 pszToFree = malloc(cbMsg);
110 if (!pszToFree)
111 {
112 fprintf(stderr, "out of memory!\n");
113 errno = error;
114 return eval;
115 }
116 }
117}
[370]118
[3192]119
120int errx(PKMKBUILTINCTX pCtx, int eval, const char *fmt, ...)
[370]121{
[3192]122 /*
123 * We format into a buffer and pass that onto output.c or fwrite.
124 */
125 char *pszToFree = NULL;
126 char szMsgStack[4096];
127 char *pszMsg = szMsgStack;
128 size_t cbMsg = sizeof(szMsgStack);
129 for (;;)
[2911]130 {
[3192]131 int cchMsg = snprintf(pszMsg, cbMsg, "%s: error: ", pCtx->pszProgName);
132 if (cchMsg < (int)cbMsg - 1 && cchMsg > 0)
133 {
134 int cchMsg2;
135 va_list va;
136 va_start(va, fmt);
137 cchMsg += cchMsg2 = vsnprintf(&pszMsg[cchMsg], cbMsg - cchMsg, fmt, va);
138 va_end(va);
[2911]139
[3192]140 if ( cchMsg < (int)cbMsg - 2
[2911]141 && cchMsg2 >= 0)
142 {
[3192]143 /* ensure newline */
144 if (pszMsg[cchMsg - 1] != '\n')
145 {
146 pszMsg[cchMsg++] = '\n';
147 pszMsg[cchMsg] = '\0';
148 }
149
150#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
151 if (pCtx->pOut)
152 output_write_text(pCtx->pOut, 1 /*is_err*/, pszMsg, cchMsg);
153 else
154#endif
155 {
156 fflush(stdout);
157 fwrite(pszMsg, cchMsg, 1, stderr);
158 fflush(stderr); /* paranoia */
159 }
160 if (pszToFree)
161 free(pszToFree);
[2911]162 return eval;
163 }
[3192]164 }
[2911]165
[3192]166 /* double the buffer size and retry */
167 if (pszToFree)
168 free(pszToFree);
169 cbMsg *= 2;
170 pszToFree = malloc(cbMsg);
171 if (!pszToFree)
172 {
173 fprintf(stderr, "out of memory!\n");
174 return eval;
[2911]175 }
176 }
[370]177}
178
[3192]179void warn(PKMKBUILTINCTX pCtx, const char *fmt, ...)
[370]180{
[3192]181 /*
182 * We format into a buffer and pass that onto output.c or fwrite.
183 */
184 int error = errno;
185 char *pszToFree = NULL;
186 char szMsgStack[4096];
187 char *pszMsg = szMsgStack;
188 size_t cbMsg = sizeof(szMsgStack);
189 for (;;)
[2911]190 {
[3192]191 int cchMsg = snprintf(pszMsg, cbMsg, "%s: ", pCtx->pszProgName);
192 if (cchMsg < (int)cbMsg - 1 && cchMsg > 0)
193 {
194 int cchMsg2;
195 va_list va;
196 va_start(va, fmt);
197 cchMsg += cchMsg2 = vsnprintf(&pszMsg[cchMsg], cbMsg - cchMsg, fmt, va);
198 va_end(va);
[2911]199
[3192]200 if ( cchMsg < (int)cbMsg - 1
201 && cchMsg2 >= 0)
202 {
203 cchMsg += cchMsg2 = snprintf(&pszMsg[cchMsg], cbMsg - cchMsg, ": %s\n", strerror(error));
204 if ( cchMsg < (int)cbMsg - 1
205 && cchMsg2 >= 0)
206 {
207#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
208 if (pCtx->pOut)
209 output_write_text(pCtx->pOut, 1 /*is_err*/, pszMsg, cchMsg);
210 else
211#endif
212 {
213 fflush(stdout);
214 fwrite(pszMsg, cchMsg, 1, stderr);
215 fflush(stderr); /* paranoia */
216 }
217 if (pszToFree)
218 free(pszToFree);
219 errno = error;
220 return;
221 }
222 }
223 }
224
225 /* double the buffer size and retry */
226 if (pszToFree)
227 free(pszToFree);
228 cbMsg *= 2;
229 pszToFree = malloc(cbMsg);
230 if (!pszToFree)
[2911]231 {
[3192]232 fprintf(stderr, "out of memory!\n");
233 errno = error;
234 return;
[2911]235 }
236 }
[370]237}
238
[3192]239void warnx(PKMKBUILTINCTX pCtx, const char *fmt, ...)
[370]240{
[3192]241 /*
242 * We format into a buffer and pass that onto output.c or fwrite.
243 */
244 char *pszToFree = NULL;
245 char szMsgStack[4096];
246 char *pszMsg = szMsgStack;
247 size_t cbMsg = sizeof(szMsgStack);
248 for (;;)
[2911]249 {
[3192]250 int cchMsg = snprintf(pszMsg, cbMsg, "%s: ", pCtx->pszProgName);
251 if (cchMsg < (int)cbMsg - 1 && cchMsg > 0)
252 {
253 int cchMsg2;
254 va_list va;
255 va_start(va, fmt);
256 cchMsg += cchMsg2 = vsnprintf(&pszMsg[cchMsg], cbMsg - cchMsg, fmt, va);
257 va_end(va);
[2911]258
[3192]259 if ( cchMsg < (int)cbMsg - 2
[2911]260 && cchMsg2 >= 0)
261 {
[3192]262 /* ensure newline */
263 if (pszMsg[cchMsg - 1] != '\n')
264 {
265 pszMsg[cchMsg++] = '\n';
266 pszMsg[cchMsg] = '\0';
267 }
268
269#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
270 if (pCtx->pOut)
271 output_write_text(pCtx->pOut, 1 /*is_err*/, pszMsg, cchMsg);
272 else
273#endif
274 {
275 fflush(stdout);
276 fwrite(pszMsg, cchMsg, 1, stderr);
277 fflush(stderr); /* paranoia */
278 }
279 if (pszToFree)
280 free(pszToFree);
[2911]281 return;
282 }
[3192]283 }
[2911]284
[3192]285 /* double the buffer size and retry */
286 if (pszToFree)
287 free(pszToFree);
288 cbMsg *= 2;
289 pszToFree = malloc(cbMsg);
290 if (!pszToFree)
291 {
292 fprintf(stderr, "out of memory!\n");
293 return;
[2911]294 }
295 }
[370]296}
297
[3192]298void kmk_builtin_ctx_printf(PKMKBUILTINCTX pCtx, int fIsErr, const char *pszFormat, ...)
[370]299{
[3192]300 /*
301 * We format into a buffer and pass that onto output.c or fwrite.
302 */
303 char *pszToFree = NULL;
304 char szMsgStack[4096];
305 char *pszMsg = szMsgStack;
306 size_t cbMsg = sizeof(szMsgStack);
307 for (;;)
[2911]308 {
[3192]309 int cchMsg;
310 va_list va;
311 va_start(va, pszFormat);
312 cchMsg = vsnprintf(pszMsg, cbMsg, pszFormat, va);
313 va_end(va);
314 if (cchMsg < (int)cbMsg - 1 && cchMsg > 0)
315 {
316#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
317 if (pCtx->pOut)
318 output_write_text(pCtx->pOut, fIsErr, pszMsg, cchMsg);
319 else
320#endif
321 {
322 fwrite(pszMsg, cchMsg, 1, fIsErr ? stderr : stdout);
323 fflush(fIsErr ? stderr : stdout);
324 }
325 if (pszToFree)
326 free(pszToFree);
327 return;
328 }
[2911]329
[3192]330 /* double the buffer size and retry */
331 if (pszToFree)
332 free(pszToFree);
333 cbMsg *= 2;
334 pszToFree = malloc(cbMsg);
335 if (!pszToFree)
[2911]336 {
[3192]337 fprintf(stderr, "out of memory!\n");
[2911]338 return;
339 }
340 }
[370]341}
342
Note: See TracBrowser for help on using the repository browser.