musl libc does currently not have an equivalent of GNU Libc's error.h The following is a mix of a workaround from aufs (https://sourceforge.net/p/aufs/aufs-util/ci/aufs4.14/tree/extlib/non-glibc/) and the stranded error.{h,c} implementation https://www.openwall.com/lists/musl/2019/08/06/21 --- a/lib/fmt/xml_test.c +++ b/lib/fmt/xml_test.c @@ -25,7 +25,11 @@ #include #include #include +#ifdef __GNU_LIBRARY__ #include +#else +#include "hidrd/util/error_at_line.h" +#endif #include #include "hidrd/fmt/xml.h" --- a/lib/item/any_test.c +++ b/lib/item/any_test.c @@ -27,7 +27,11 @@ #include #include #include +#ifdef __GNU_LIBRARY__ #include +#else +#include "hidrd/util/error_at_line.h" +#endif #include #include "hidrd/item.h" --- a/lib/opt/test.c +++ b/lib/opt/test.c @@ -26,7 +26,11 @@ #include #include #include +#ifdef __GNU_LIBRARY__ #include +#else +#include "hidrd/util/error_at_line.h" +#endif #include #include "hidrd/opt/spec_list.h" #include "hidrd/opt/list.h" --- a/lib/util/num_test.c +++ b/lib/util/num_test.c @@ -23,7 +23,11 @@ */ #include +#ifdef __GNU_LIBRARY__ #include +#else +#include "hidrd/util/error_at_line.h" +#endif #include #include #include "hidrd/util/num.h" --- a/lib/util/ttbl_test.c +++ b/lib/util/ttbl_test.c @@ -24,7 +24,11 @@ #include #include +#ifdef __GNU_LIBRARY__ #include +#else +#include "hidrd/util/error_at_line.h" +#endif #include #include #include --- a/lib/opt/Makefile.am +++ b/lib/opt/Makefile.am @@ -36,7 +36,7 @@ TESTS = hidrd_opt_test -hidrd_opt_test_SOURCES = test.c +hidrd_opt_test_SOURCES = test.c ../util/error_at_line.c hidrd_opt_test_LDADD = $(lib_LTLIBRARIES) bin_PROGRAMS = --- a/lib/util/Makefile.am +++ b/lib/util/Makefile.am @@ -39,10 +39,10 @@ bin_PROGRAMS = check_PROGRAMS = hidrd_num_test hidrd_ttbl_test -hidrd_num_test_SOURCES = num_test.c +hidrd_num_test_SOURCES = num_test.c error_at_line.c hidrd_num_test_LDADD = $(lib_LTLIBRARIES) -hidrd_ttbl_test_SOURCES = ttbl_test.c +hidrd_ttbl_test_SOURCES = ttbl_test.c error_at_line.c hidrd_ttbl_test_LDADD = $(lib_LTLIBRARIES) TESTS = hidrd_num_test hidrd_ttbl_test --- /dev/null +++ b/lib/util/error_at_line.c @@ -0,0 +1,69 @@ +#include "hidrd/util/error_at_line.h" +#include +#include +#include +#include +#include + +void (*error_print_progname) (void) = 0; +unsigned int error_message_count = 0; +int error_one_per_line = 0; + +static unsigned int saved_linenum = 0; +static const char *saved_file = 0; + +static void errorv(int status, int errnum, const char *file, unsigned int linenum, const char *fmt, va_list ap) +{ + ++error_message_count; + + fflush(stdout); + flockfile(stderr); + + if (error_print_progname) + error_print_progname(); + else { + fprintf(stderr, "%s:", program_invocation_name); + if (!file) + fputc(' ', stderr); + } + + if (file) + fprintf(stderr, "%s:%u: ", file, linenum); + + vfprintf(stderr, fmt, ap); + if (errnum) + fprintf(stderr, ": %s", strerror(errnum)); + fputc('\n', stderr); + + funlockfile(stderr); + + if (status) + exit(status); +} + +void error(int status, int errnum, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + errorv(status, errnum, NULL, 0, fmt, ap); + va_end(ap); +} + +void error_at_line(int status, int errnum, const char *file, unsigned int linenum, const char *fmt, ...) +{ + if (error_one_per_line) { + if(saved_linenum == linenum && file != NULL && + saved_file != NULL && !strcmp(file, saved_file)) + return; + saved_linenum = linenum; + // Assuming that the lifetime of the passed in file name extends + // until the next call is rather questionable, but appears to be + // the expected semantics. + saved_file = file; + } + + va_list ap; + va_start(ap, fmt); + errorv(status, errnum, file, linenum, fmt, ap); + va_end(ap); +} --- /dev/null +++ b/include/hidrd/util/error_at_line.h @@ -0,0 +1,21 @@ +#ifndef _ERROR_H +#define _ERROR_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void (*error_print_progname) (void); +extern unsigned int error_message_count; +extern int error_one_per_line; + +void error(int, int, const char *, ...); +void error_at_line(int, int, const char *, unsigned int, const char *, ...); + +#ifdef __cplusplus +} +#endif + +#endif