summaryrefslogtreecommitdiffstats
path: root/eprintf.c
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2018-03-01 11:44:02 +0000
committerTomasz Kramkowski <tk@the-tk.com>2018-03-01 11:44:02 +0000
commit7a802c4ff4c715f50825d833fa44f2ad1a5993f4 (patch)
treefe4d734653f6367b516e19f2bf7c8f29870b94b9 /eprintf.c
downloadeprintf-7a802c4ff4c715f50825d833fa44f2ad1a5993f4.tar.gz
eprintf-7a802c4ff4c715f50825d833fa44f2ad1a5993f4.tar.xz
eprintf-7a802c4ff4c715f50825d833fa44f2ad1a5993f4.zip
init commit
Diffstat (limited to 'eprintf.c')
-rw-r--r--eprintf.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/eprintf.c b/eprintf.c
new file mode 100644
index 0000000..9f4aa11
--- /dev/null
+++ b/eprintf.c
@@ -0,0 +1,117 @@
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "eprintf.h"
+
+static char *pname;
+
+// doprintf: print error message
+__attribute__((format(printf, 1, 0)))
+static void doprintf(const char *fmt, va_list va, int errnum)
+{
+ assert(fmt != NULL);
+
+ if (pname != NULL)
+ fprintf(stderr, "%s: ", pname);
+
+ vfprintf(stderr, fmt, va);
+
+ if (fmt[0] != '\0' && fmt[strlen(fmt) - 1] == ':')
+ fprintf(stderr, " %s", strerror(errnum));
+ fputc('\n', stderr);
+}
+
+// eprintf: print error and exit, a trailing : in fmt prints strerror(errno)
+void eprintf(const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ doprintf(fmt, va, errno); // TODO: can va_start set errno
+ va_end(va);
+
+ exit(EXIT_FAILURE);
+}
+
+// weprintf: print warning, a trailing : in fmt prints strerror(errno)
+void weprintf(const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ doprintf(fmt, va, errno); // TODO: Ditto
+ va_end(va);
+}
+
+// estrdup: attempt to strdup a string or exit on error
+char *estrdup(const char *s)
+{
+ size_t len;
+ char *dup;
+
+ assert(s != NULL);
+
+ 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;
+}
+
+// ecalloc: attempt to allocate memory or exit on error
+void *ecalloc(size_t nmemb, size_t size)
+{
+ void *p;
+
+ p = calloc(nmemb, size);
+ if (p == NULL)
+ eprintf("ecalloc(%zu, %zu) failed:", nmemb, size);
+
+ 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;
+}
+
+// setprogname: set stored name of program
+void setprogname(const char *s)
+{
+ assert(s != NULL);
+
+ if (pname != NULL) {
+ weprintf("setprogname(\"%.20s\") called more than once", s);
+ return;
+ }
+
+ pname = estrdup(s);
+}