summaryrefslogtreecommitdiffstats
path: root/src/kmk/kmkbuiltin/err.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kmk/kmkbuiltin/err.c')
-rw-r--r--src/kmk/kmkbuiltin/err.c340
1 files changed, 340 insertions, 0 deletions
diff --git a/src/kmk/kmkbuiltin/err.c b/src/kmk/kmkbuiltin/err.c
new file mode 100644
index 0000000..bbab335
--- /dev/null
+++ b/src/kmk/kmkbuiltin/err.c
@@ -0,0 +1,340 @@
+/* $Id: err.c 3237 2018-12-25 04:11:26Z bird $ */
+/** @file
+ * Override err.h so we get the program name right.
+ */
+
+/*
+ * Copyright (c) 2005-2016 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
+ *
+ * This file is part of kBuild.
+ *
+ * kBuild is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * kBuild is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with kBuild. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+# ifdef HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#else
+# include <stdlib.h>
+# define snprintf _snprintf
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include "err.h"
+#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
+# include "../output.h"
+#endif
+
+#ifdef KBUILD_OS_WINDOWS
+/* This is a trick to speed up console output on windows. */
+# include "console.h"
+# undef fwrite
+# define fwrite maybe_con_fwrite
+#endif
+
+int err(PKMKBUILTINCTX pCtx, int eval, const char *fmt, ...)
+{
+ /*
+ * We format into a buffer and pass that onto output.c or fwrite.
+ */
+ int error = errno;
+ char *pszToFree = NULL;
+ char szMsgStack[4096];
+ char *pszMsg = szMsgStack;
+ size_t cbMsg = sizeof(szMsgStack);
+ for (;;)
+ {
+ int cchMsg = snprintf(pszMsg, cbMsg, "%s: error: ", pCtx->pszProgName);
+ if (cchMsg < (int)cbMsg - 1 && cchMsg > 0)
+ {
+ int cchMsg2;
+ va_list va;
+ va_start(va, fmt);
+ cchMsg += cchMsg2 = vsnprintf(&pszMsg[cchMsg], cbMsg - cchMsg, fmt, va);
+ va_end(va);
+
+ if ( cchMsg < (int)cbMsg - 1
+ && cchMsg2 >= 0)
+ {
+ cchMsg += cchMsg2 = snprintf(&pszMsg[cchMsg], cbMsg - cchMsg, ": %s\n", strerror(error));
+ if ( cchMsg < (int)cbMsg - 1
+ && cchMsg2 >= 0)
+ {
+#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
+ if (pCtx->pOut)
+ output_write_text(pCtx->pOut, 1 /*is_err*/, pszMsg, cchMsg);
+ else
+#endif
+ {
+ fflush(stdout);
+ fwrite(pszMsg, cchMsg, 1, stderr);
+ fflush(stderr); /* paranoia */
+ }
+ if (pszToFree)
+ free(pszToFree);
+ errno = error;
+ return eval;
+ }
+ }
+ }
+
+ /* double the buffer size and retry */
+ if (pszToFree)
+ free(pszToFree);
+ cbMsg *= 2;
+ pszToFree = malloc(cbMsg);
+ if (!pszToFree)
+ {
+ fprintf(stderr, "out of memory!\n");
+ errno = error;
+ return eval;
+ }
+ }
+}
+
+
+int errx(PKMKBUILTINCTX pCtx, int eval, const char *fmt, ...)
+{
+ /*
+ * We format into a buffer and pass that onto output.c or fwrite.
+ */
+ char *pszToFree = NULL;
+ char szMsgStack[4096];
+ char *pszMsg = szMsgStack;
+ size_t cbMsg = sizeof(szMsgStack);
+ for (;;)
+ {
+ int cchMsg = snprintf(pszMsg, cbMsg, "%s: error: ", pCtx->pszProgName);
+ if (cchMsg < (int)cbMsg - 1 && cchMsg > 0)
+ {
+ int cchMsg2;
+ va_list va;
+ va_start(va, fmt);
+ cchMsg += cchMsg2 = vsnprintf(&pszMsg[cchMsg], cbMsg - cchMsg, fmt, va);
+ va_end(va);
+
+ if ( cchMsg < (int)cbMsg - 2
+ && cchMsg2 >= 0)
+ {
+ /* ensure newline */
+ if (pszMsg[cchMsg - 1] != '\n')
+ {
+ pszMsg[cchMsg++] = '\n';
+ pszMsg[cchMsg] = '\0';
+ }
+
+#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
+ if (pCtx->pOut)
+ output_write_text(pCtx->pOut, 1 /*is_err*/, pszMsg, cchMsg);
+ else
+#endif
+ {
+ fflush(stdout);
+ fwrite(pszMsg, cchMsg, 1, stderr);
+ fflush(stderr); /* paranoia */
+ }
+ if (pszToFree)
+ free(pszToFree);
+ return eval;
+ }
+ }
+
+ /* double the buffer size and retry */
+ if (pszToFree)
+ free(pszToFree);
+ cbMsg *= 2;
+ pszToFree = malloc(cbMsg);
+ if (!pszToFree)
+ {
+ fprintf(stderr, "out of memory!\n");
+ return eval;
+ }
+ }
+}
+
+void warn(PKMKBUILTINCTX pCtx, const char *fmt, ...)
+{
+ /*
+ * We format into a buffer and pass that onto output.c or fwrite.
+ */
+ int error = errno;
+ char *pszToFree = NULL;
+ char szMsgStack[4096];
+ char *pszMsg = szMsgStack;
+ size_t cbMsg = sizeof(szMsgStack);
+ for (;;)
+ {
+ int cchMsg = snprintf(pszMsg, cbMsg, "%s: ", pCtx->pszProgName);
+ if (cchMsg < (int)cbMsg - 1 && cchMsg > 0)
+ {
+ int cchMsg2;
+ va_list va;
+ va_start(va, fmt);
+ cchMsg += cchMsg2 = vsnprintf(&pszMsg[cchMsg], cbMsg - cchMsg, fmt, va);
+ va_end(va);
+
+ if ( cchMsg < (int)cbMsg - 1
+ && cchMsg2 >= 0)
+ {
+ cchMsg += cchMsg2 = snprintf(&pszMsg[cchMsg], cbMsg - cchMsg, ": %s\n", strerror(error));
+ if ( cchMsg < (int)cbMsg - 1
+ && cchMsg2 >= 0)
+ {
+#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
+ if (pCtx->pOut)
+ output_write_text(pCtx->pOut, 1 /*is_err*/, pszMsg, cchMsg);
+ else
+#endif
+ {
+ fflush(stdout);
+ fwrite(pszMsg, cchMsg, 1, stderr);
+ fflush(stderr); /* paranoia */
+ }
+ if (pszToFree)
+ free(pszToFree);
+ errno = error;
+ return;
+ }
+ }
+ }
+
+ /* double the buffer size and retry */
+ if (pszToFree)
+ free(pszToFree);
+ cbMsg *= 2;
+ pszToFree = malloc(cbMsg);
+ if (!pszToFree)
+ {
+ fprintf(stderr, "out of memory!\n");
+ errno = error;
+ return;
+ }
+ }
+}
+
+void warnx(PKMKBUILTINCTX pCtx, const char *fmt, ...)
+{
+ /*
+ * We format into a buffer and pass that onto output.c or fwrite.
+ */
+ char *pszToFree = NULL;
+ char szMsgStack[4096];
+ char *pszMsg = szMsgStack;
+ size_t cbMsg = sizeof(szMsgStack);
+ for (;;)
+ {
+ int cchMsg = snprintf(pszMsg, cbMsg, "%s: ", pCtx->pszProgName);
+ if (cchMsg < (int)cbMsg - 1 && cchMsg > 0)
+ {
+ int cchMsg2;
+ va_list va;
+ va_start(va, fmt);
+ cchMsg += cchMsg2 = vsnprintf(&pszMsg[cchMsg], cbMsg - cchMsg, fmt, va);
+ va_end(va);
+
+ if ( cchMsg < (int)cbMsg - 2
+ && cchMsg2 >= 0)
+ {
+ /* ensure newline */
+ if (pszMsg[cchMsg - 1] != '\n')
+ {
+ pszMsg[cchMsg++] = '\n';
+ pszMsg[cchMsg] = '\0';
+ }
+
+#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
+ if (pCtx->pOut)
+ output_write_text(pCtx->pOut, 1 /*is_err*/, pszMsg, cchMsg);
+ else
+#endif
+ {
+ fflush(stdout);
+ fwrite(pszMsg, cchMsg, 1, stderr);
+ fflush(stderr); /* paranoia */
+ }
+ if (pszToFree)
+ free(pszToFree);
+ return;
+ }
+ }
+
+ /* double the buffer size and retry */
+ if (pszToFree)
+ free(pszToFree);
+ cbMsg *= 2;
+ pszToFree = malloc(cbMsg);
+ if (!pszToFree)
+ {
+ fprintf(stderr, "out of memory!\n");
+ return;
+ }
+ }
+}
+
+void kmk_builtin_ctx_printf(PKMKBUILTINCTX pCtx, int fIsErr, const char *pszFormat, ...)
+{
+ /*
+ * We format into a buffer and pass that onto output.c or fwrite.
+ */
+ char *pszToFree = NULL;
+ char szMsgStack[4096];
+ char *pszMsg = szMsgStack;
+ size_t cbMsg = sizeof(szMsgStack);
+ for (;;)
+ {
+ int cchMsg;
+ va_list va;
+ va_start(va, pszFormat);
+ cchMsg = vsnprintf(pszMsg, cbMsg, pszFormat, va);
+ va_end(va);
+ if (cchMsg < (int)cbMsg - 1 && cchMsg > 0)
+ {
+#if !defined(KMK_BUILTIN_STANDALONE) && !defined(KWORKER)
+ if (pCtx->pOut)
+ output_write_text(pCtx->pOut, fIsErr, pszMsg, cchMsg);
+ else
+#endif
+ {
+ fwrite(pszMsg, cchMsg, 1, fIsErr ? stderr : stdout);
+ fflush(fIsErr ? stderr : stdout);
+ }
+ if (pszToFree)
+ free(pszToFree);
+ return;
+ }
+
+ /* double the buffer size and retry */
+ if (pszToFree)
+ free(pszToFree);
+ cbMsg *= 2;
+ pszToFree = malloc(cbMsg);
+ if (!pszToFree)
+ {
+ fprintf(stderr, "out of memory!\n");
+ return;
+ }
+ }
+}
+