aboutsummaryrefslogtreecommitdiffstats
path: root/eprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'eprintf.c')
-rw-r--r--eprintf.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/eprintf.c b/eprintf.c
new file mode 100644
index 0000000..7a885b3
--- /dev/null
+++ b/eprintf.c
@@ -0,0 +1,106 @@
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "eprintf.h"
+
+char *pname;
+
+/* eprintf: print error and exit, a trailing : in fmt prints strerror(errno) */
+void eprintf(const char *fmt, ...)
+{
+ int errnum = errno;
+ va_list va;
+
+ if (progname() != NULL)
+ fprintf(stderr, "%s: ", progname());
+
+ va_start(va, fmt);
+ vfprintf(stderr, fmt, va);
+ va_end(va);
+
+ if (fmt[0] != '\0' && fmt[strlen(fmt) - 1] == ':')
+ fprintf(stderr, " %s", strerror(errnum));
+ fputc('\n', stderr);
+
+ exit(EXIT_FAILURE);
+}
+
+/* weprintf: print warning, a trailing : in fmt prints strerror(errno) */
+void weprintf(const char *fmt, ...)
+{
+ int errnum = errno;
+ va_list va;
+
+ if (progname() != NULL)
+ fprintf(stderr, "%s: ", progname());
+
+ va_start(va, fmt);
+ vfprintf(stderr, fmt, va);
+ va_end(va);
+
+ if (fmt[0] != '\0' && fmt[strlen(fmt) - 1] == ':')
+ fprintf(stderr, " %s", strerror(errnum));
+ fputc('\n', stderr);
+}
+
+/* estrdup: attempt to strdup a string or exit on error */
+char *estrdup(const char *s)
+{
+ size_t len;
+ char *dup;
+
+ len = strlen(s);
+ if (len == SIZE_MAX)
+ eprintf("estrdup(\"%.20s\") failed: Too long", s);
+ dup = malloc(len + 1);
+ if (dup == NULL)
+ eprintf("estrdup(\"%.20s\") failed:", s);
+ strcpy(dup, s);
+
+ return dup;
+}
+
+/* emalloc: attempt to allocate memory or exit on error */
+void *emalloc(size_t n)
+{
+ void *p;
+
+ p = malloc(n);
+ if (p == NULL)
+ eprintf("emalloc(%zu) failed:", n);
+
+ return p;
+}
+
+/* erealloc: attempt to reallocate memory or exit on error */
+void *erealloc(void *p, size_t n)
+{
+ void *r;
+
+ r = realloc(p, n);
+ if (r == NULL)
+ eprintf("erealloc(%p, %zu) failed:", p, n);
+
+ return r;
+}
+
+/* progname: retrieve stored name of program */
+char *progname(void)
+{
+ return pname;
+}
+
+/* setprogname: set stored name of program */
+void setprogname(const char *s)
+{
+ if (pname != NULL) {
+ weprintf("setprogname(\"%.20s\") called more than once", s);
+ return;
+ }
+
+ pname = estrdup(s);
+}