summaryrefslogtreecommitdiff
path: root/examples/dte/error.c
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2023-11-09 23:19:53 +0100
committerMitja Felicijan <mitja.felicijan@gmail.com>2023-11-09 23:19:53 +0100
commit1566b6faa8534118c3566188181367cd0868468f (patch)
tree1de8d4b369efb5e592685a31088f798a6b63ffa1 /examples/dte/error.c
parent349991bf6efe473ab9a5cbdae0a8114d72b997e3 (diff)
downloadcrep-1566b6faa8534118c3566188181367cd0868468f.tar.gz
Added partial matching and introduced threads
Diffstat (limited to 'examples/dte/error.c')
-rw-r--r--examples/dte/error.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/examples/dte/error.c b/examples/dte/error.c
new file mode 100644
index 0000000..87831c9
--- /dev/null
+++ b/examples/dte/error.c
@@ -0,0 +1,95 @@
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include "error.h"
+#include "command/run.h"
+#include "config.h"
+#include "util/log.h"
+#include "util/xstdio.h"
+
+static char error_buf[512];
+static unsigned int nr_errors;
+static bool msg_is_error;
+static bool print_errors_to_stderr;
+
+void clear_error(void)
+{
+ error_buf[0] = '\0';
+}
+
+bool error_msg(const char *format, ...)
+{
+ const char *cmd = current_command ? current_command->name : NULL;
+ const char *file = current_config.file;
+ const unsigned int line = current_config.line;
+ const size_t size = sizeof(error_buf);
+ int pos = 0;
+
+ if (file && cmd) {
+ pos = snprintf(error_buf, size, "%s:%u: %s: ", file, line, cmd);
+ } else if (file) {
+ pos = snprintf(error_buf, size, "%s:%u: ", file, line);
+ } else if (cmd) {
+ pos = snprintf(error_buf, size, "%s: ", cmd);
+ }
+
+ if (unlikely(pos < 0)) {
+ // Note: POSIX snprintf(3) *does* set errno on failure (unlike ISO C)
+ LOG_ERRNO("snprintf");
+ pos = 0;
+ }
+
+ if (likely(pos < (size - 3))) {
+ va_list ap;
+ va_start(ap, format);
+ vsnprintf(error_buf + pos, size - pos, format, ap);
+ va_end(ap);
+ } else {
+ LOG_WARNING("no buffer space left for error message");
+ }
+
+ msg_is_error = true;
+ nr_errors++;
+
+ if (print_errors_to_stderr) {
+ xfputs(error_buf, stderr);
+ xfputc('\n', stderr);
+ }
+
+ LOG_INFO("%s", error_buf);
+
+ // Always return false, to allow tail-calling as `return error_msg(...);`
+ // from command handlers, instead of `error_msg(...); return false;`
+ return false;
+}
+
+bool error_msg_errno(const char *prefix)
+{
+ return error_msg("%s: %s", prefix, strerror(errno));
+}
+
+void info_msg(const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ vsnprintf(error_buf, sizeof(error_buf), format, ap);
+ va_end(ap);
+ msg_is_error = false;
+}
+
+const char *get_msg(bool *is_error)
+{
+ *is_error = msg_is_error;
+ return error_buf;
+}
+
+unsigned int get_nr_errors(void)
+{
+ return nr_errors;
+}
+
+void set_print_errors_to_stderr(bool enable)
+{
+ print_errors_to_stderr = enable;
+}