output.c

changeset 35
5a71d53d0228
parent 33
3a0064eb9421
child 36
63cd573ffbcf
--- a/output.c	Sun Apr 01 01:43:46 2001 +0200
+++ b/output.c	Sat Jan 19 19:14:36 2002 +0100
@@ -15,7 +15,7 @@
 #include <libtu/output.h>
 #include <libtu/util.h>
 
-#if !defined(LIBTU_NO_ERRMSG) && !defined(HAS_SYSTEM_ASPRINTF)
+#if !defined(HAS_SYSTEM_ASPRINTF)
 #include "../snprintf_2.2/snprintf.h"
 #endif
 
@@ -26,11 +26,14 @@
 static bool verbose_mode=FALSE;
 static int verbose_indent_lvl=0;
 static bool progname_enable=TRUE;
+static WarnHandler *current_warn_handler=NULL;
 
 #define INDENTATOR_LENGTH 4
 
 static char indentator[]={' ', ' ', ' ', ' '};
 
+static void do_dispatch_message(const char *message);
+
 
 void verbose(const char *p, ...)
 {
@@ -99,11 +102,29 @@
 /* warn
  */
 
+
+static void fallback_warn()
+{
+	put_prog_name();
+	fprintf(stderr, "Oops. Error string compilation failed: %s",
+			strerror(errno));
+}
+	
+	
 #define CALL_V(NAME, ARGS) \
-	va_list args; va_start(args, p); NAME ARGS; va_end(args);
+	do { va_list args; va_start(args, p); NAME ARGS; va_end(args); } while(0)
 
+#define DO_DISPATCH(NAME, ARGS) \
+	do{ \
+		char *msg; \
+		if((msg=NAME ARGS)!=NULL){ \
+			do_dispatch_message(msg); \
+			free(msg);\
+		}else{ \
+			fallback_warn(); \
+		} \
+	}while(0)
 
-#ifndef LIBTU_NO_ERRMSG
 
 void libtu_asprintf(char **ret, const char *p, ...)
 {
@@ -116,7 +137,6 @@
 	vasprintf(ret, p, args);
 }
 
-#endif
 
 void warn(const char *p, ...)
 {
@@ -144,69 +164,39 @@
 
 void warn_v(const char *p, va_list args)
 {
-	put_prog_name();
-	vfprintf(stderr, p, args);
-	putc('\n', stderr);
+	DO_DISPATCH(errmsg_v, (p, args));
 }
 
 
 void warn_obj_line_v(const char *obj, int line, const char *p, va_list args)
 {
-	put_prog_name();
-	if(obj!=NULL){
-		if(line>0)
-			fprintf(stderr, TR("%s:%d: "), obj, line);
-		else		
-			fprintf(stderr, "%s: ", obj);
-	}else{
-		if(line>0)
-			fprintf(stderr, TR("%d: "), line);
-	}
-	vfprintf(stderr, p, args);
-	putc('\n', stderr);
+	DO_DISPATCH(errmsg_obj_line_v, (obj, line, p, args));
 }
 
 
 void warn_err()
 {
-	put_prog_name();
-	fprintf(stderr, "%s\n", strerror(errno));
+	DO_DISPATCH(errmsg_err, ());
 }
 
 
 void warn_err_obj(const char *obj)
 {
-	put_prog_name();
-	if(obj!=NULL)
-		fprintf(stderr, "%s: %s\n", obj, strerror(errno));
-	else
-		fprintf(stderr, "%s\n", strerror(errno));
+	DO_DISPATCH(errmsg_err_obj, (obj));
 }
 
 void warn_err_obj_line(const char *obj, int line)
 {
-	put_prog_name();
-	if(obj!=NULL){
-		if(line>0)
-			fprintf(stderr, TR("%s:%d: %s\n"), obj, line, strerror(errno));
-		else
-			fprintf(stderr, "%s: %s\n", obj, strerror(errno));
-	}else{
-		if(line>0)
-			fprintf(stderr, TR("%d: %s\n"), line, strerror(errno));
-		else
-			fprintf(stderr, TR("%s\n"), strerror(errno));
-	}
-
+	DO_DISPATCH(errmsg_err_obj_line, (obj, line));
 }
 
 
 /* errmsg
  */
-#ifndef LIBTU_NO_ERRMSG
 
 #define CALL_V_RET(NAME, ARGS) \
-	char *ret; va_list args; va_start(args, p); ret=NAME ARGS; va_end(args); return ret;
+	char *ret; va_list args; va_start(args, p); ret=NAME ARGS; \
+	va_end(args); return ret;
 
 
 char* errmsg(const char *p, ...)
@@ -244,6 +234,7 @@
 char *errmsg_obj_line_v(const char *obj, int line, const char *p, va_list args)
 {
 	char *res1=NULL, *res2, *res3;
+	
 	if(obj!=NULL){
 		if(line>0)
 			asprintf(&res1, TR("%s:%d: "), obj, line);
@@ -253,7 +244,7 @@
 		if(line>0)
 			asprintf(&res1, TR("%d: "), line);
 	}
-	asprintf(&res2, p, args);
+	vasprintf(&res2, p, args);
 	if(res1!=NULL){
 		if(res2==NULL)
 			return NULL;
@@ -302,20 +293,21 @@
 	return res;
 }
 
-#endif /* LIBTU_NO_ERRMSG */
-
 
 /* die
  */
 
+
 void die(const char *p, ...)
 {
+	set_warn_handler(NULL);
 	CALL_V(die_v, (p, args));
 }
 
 
 void die_v(const char *p, va_list args)
 {
+	set_warn_handler(NULL);
 	warn_v(p, args);
 	exit(EXIT_FAILURE);
 }
@@ -323,18 +315,21 @@
 
 void die_obj(const char *obj, const char *p, ...)
 {
+	set_warn_handler(NULL);
 	CALL_V(die_obj_v, (obj, p, args));
 }
 
 
 void die_obj_line(const char *obj, int line, const char *p, ...)
 {
+	set_warn_handler(NULL);
 	CALL_V(die_obj_line_v, (obj, line, p, args));
 }
 
 
 void die_obj_v(const char *obj, const char *p, va_list args)
 {
+	set_warn_handler(NULL);
 	warn_obj_v(obj, p, args);
 	exit(EXIT_FAILURE);
 }
@@ -342,6 +337,7 @@
 
 void die_obj_line_v(const char *obj, int line, const char *p, va_list args)
 {
+	set_warn_handler(NULL);
 	warn_obj_line_v(obj, line, p, args);
 	exit(EXIT_FAILURE);
 }
@@ -349,6 +345,7 @@
 
 void die_err()
 {
+	set_warn_handler(NULL);
 	warn_err();
 	exit(EXIT_FAILURE);
 }
@@ -356,6 +353,7 @@
 
 void die_err_obj(const char *obj)
 {
+	set_warn_handler(NULL);
 	warn_err_obj(obj);
 	exit(EXIT_FAILURE);
 }
@@ -363,6 +361,32 @@
 
 void die_err_obj_line(const char *obj, int line)
 {
+	set_warn_handler(NULL);
 	warn_err_obj_line(obj, line);
 	exit(EXIT_FAILURE);
 }
+
+
+static void default_warn_handler(const char *message)
+{
+	put_prog_name();
+	fprintf(stderr, "%s", message);
+	putc('\n', stderr);
+}
+
+
+static void do_dispatch_message(const char *message)
+{
+	if(current_warn_handler!=NULL)
+		current_warn_handler(message);
+	else
+		default_warn_handler(message);
+}
+
+
+WarnHandler *set_warn_handler(WarnHandler *handler)
+{
+	WarnHandler *old=current_warn_handler;
+	current_warn_handler=handler;
+	return old;
+}

mercurial