diff options
author | Tomasz Kramkowski <tk@the-tk.com> | 2018-03-01 11:44:02 +0000 |
---|---|---|
committer | Tomasz Kramkowski <tk@the-tk.com> | 2018-03-01 11:44:02 +0000 |
commit | 7a802c4ff4c715f50825d833fa44f2ad1a5993f4 (patch) | |
tree | fe4d734653f6367b516e19f2bf7c8f29870b94b9 | |
download | eprintf-7a802c4ff4c715f50825d833fa44f2ad1a5993f4.tar.gz eprintf-7a802c4ff4c715f50825d833fa44f2ad1a5993f4.tar.xz eprintf-7a802c4ff4c715f50825d833fa44f2ad1a5993f4.zip |
init commit
-rw-r--r-- | eprintf.c | 117 | ||||
-rw-r--r-- | eprintf.h | 16 | ||||
-rw-r--r-- | module.mk | 3 |
3 files changed, 136 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); +} diff --git a/eprintf.h b/eprintf.h new file mode 100644 index 0000000..0bd662b --- /dev/null +++ b/eprintf.h @@ -0,0 +1,16 @@ +#ifndef EPRINTF_EPRINTF_H +#define EPRINTF_EPRINTF_H +#include <stdnoreturn.h> +#include <stddef.h> + +noreturn void eprintf(const char *fmt, ...) + __attribute__((format(printf, 1, 2))); +void weprintf(const char *fmt, ...) + __attribute__((format(printf, 1, 2))); +char *estrdup(const char *str); +void *emalloc(size_t size); +void *ecalloc(size_t nmemb, size_t size); +void *erealloc(void *p, size_t size); +void setprogname(const char *name); + +#endif // !EPRINTF_EPRINTF_H diff --git a/module.mk b/module.mk new file mode 100644 index 0000000..c27afee --- /dev/null +++ b/module.mk @@ -0,0 +1,3 @@ +EPRINTF_FILES = eprintf.c eprintf.h +$(EPRINTF_FILES): %: $(EPRINTF_PATH)/% + $(LN) $< $@ |