#include #include #include #include #include #include "libc.h" 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:", __progname_full); 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); }