{"thread":{"id":"4636","subject":"[PATCH] Customizable error handlers","startedAt":"2006-06-23T13:32:27Z","lastAt":"2006-06-23T23:18:08Z","messageCount":4,"participants":["Petr Baudis","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"22354","messageId":"20060623133227.27854.65567.stgit@machine.or.cz","threadId":"4636","inReplyTo":null,"subject":"[PATCH] Customizable error handlers","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-06-23T13:32:27Z","receivedAt":"2006-06-23T13:32:27Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"This patch makes the usage(), die() and error() handlers customizable.\nNothing in the git code itself uses that but many other libgit users\n(like Git.pm) will.\n\nThis is implemented using the mutator functions primarily because you\ncannot directly modifying global variables of libgit from a program that\ndlopen()ed it, apparently. But having functions for that is a better API\nanyway.\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n---\n\n git-compat-util.h |   10 +++++++---\n usage.c           |   50 +++++++++++++++++++++++++++++++++++++++++++++-----\n 2 files changed, 52 insertions(+), 8 deletions(-)\n\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 5d543d2..e954002 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -36,9 +36,13 @@ #endif\n #endif\n \n /* General helper functions */\n-extern void usage(const char *err) NORETURN;\n-extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n-extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n+void usage(const char *err) NORETURN;\n+void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n+int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n+\n+void set_usage_routine(void (*routine)(const char *err) NORETURN);\n+void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);\n+void set_error_routine(int (*routine)(const char *err, va_list params));\n \n #ifdef NO_MMAP\n \ndiff --git a/usage.c b/usage.c\nindex 1fa924c..445456d 100644\n--- a/usage.c\n+++ b/usage.c\n@@ -12,28 +12,68 @@ static void report(const char *prefix, c\n \tfputs(\"\\n\", stderr);\n }\n \n-void usage(const char *err)\n+void usage_builtin(const char *err)\n {\n \tfprintf(stderr, \"usage: %s\\n\", err);\n \texit(129);\n }\n \n+void die_builtin(const char *err, va_list params)\n+{\n+\treport(\"fatal: \", err, params);\n+\texit(128);\n+}\n+\n+int error_builtin(const char *err, va_list params)\n+{\n+\treport(\"error: \", err, params);\n+\treturn -1;\n+}\n+\n+\n+/* If we are in a dlopen()ed .so write to a global variable would segfault\n+ * (ugh), so keep things static. */\n+static void (*usage_routine)(const char *err) NORETURN = usage_builtin;\n+static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin;\n+static int (*error_routine)(const char *err, va_list params) = error_builtin;\n+\n+void set_usage_routine(void (*routine)(const char *err) NORETURN)\n+{\n+\tusage_routine = routine;\n+}\n+\n+void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN)\n+{\n+\tdie_routine = routine;\n+}\n+\n+void set_error_routine(int (*routine)(const char *err, va_list params))\n+{\n+\terror_routine = routine;\n+}\n+\n+\n+void usage(const char *err)\n+{\n+\tusage_routine(err);\n+}\n+\n void die(const char *err, ...)\n {\n \tva_list params;\n \n \tva_start(params, err);\n-\treport(\"fatal: \", err, params);\n+\tdie_routine(err, params);\n \tva_end(params);\n-\texit(128);\n }\n \n int error(const char *err, ...)\n {\n \tva_list params;\n+\tint ret;\n \n \tva_start(params, err);\n-\treport(\"error: \", err, params);\n+\tret = error_routine(err, params);\n \tva_end(params);\n-\treturn -1;\n+\treturn ret;\n }\n"},{"id":"22355","messageId":"20060623133847.GN21864@pasky.or.cz","threadId":"4636","inReplyTo":"20060623133227.27854.65567.stgit@machine.or.cz","subject":"Re: [PATCH] Customizable error handlers","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-06-23T13:38:47Z","receivedAt":"2006-06-23T13:38:47Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Fri, Jun 23, 2006 at 03:32:27PM CEST, I got a letter\nwhere Petr Baudis <pasky@suse.cz> said that...\n> diff --git a/git-compat-util.h b/git-compat-util.h\n> index 5d543d2..e954002 100644\n> --- a/git-compat-util.h\n> +++ b/git-compat-util.h\n> @@ -36,9 +36,13 @@ #endif\n>  #endif\n>  \n>  /* General helper functions */\n> -extern void usage(const char *err) NORETURN;\n> -extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n> -extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n> +void usage(const char *err) NORETURN;\n> +void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n> +int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n\nWah, this kind of slipped through. Below is a patch without the\nexterns removed. Sorry about the noise.\n\n>  int error(const char *err, ...)\n>  {\n>  \tva_list params;\n> +\tint ret;\n>  \n>  \tva_start(params, err);\n> -\treport(\"error: \", err, params);\n> +\tret = error_routine(err, params);\n>  \tva_end(params);\n> -\treturn -1;\n> +\treturn ret;\n>  }\n\nBTW, I don't mind if you just force the return value to -1 here.\nIt might be saner.\n\n---\n\n[PATCH] Customizable error handlers\n\nThis patch makes the usage(), die() and error() handlers customizable.\nNothing in the git code itself uses that but many other libgit users\n(like Git.pm) will.\n\nThis is implemented using the mutator functions primarily because you\ncannot directly modifying global variables of libgit from a program that\ndlopen()ed it, apparently. But having functions for that is a better API\nanyway.\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n\n---\n\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 5d543d2..0c5ceb3 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -40,6 +40,10 @@ extern void usage(const char *err) NORET\n extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n \n+extern void set_usage_routine(void (*routine)(const char *err) NORETURN);\n+extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);\n+extern void set_error_routine(int (*routine)(const char *err, va_list params));\n+\n #ifdef NO_MMAP\n \n #ifndef PROT_READ\ndiff --git a/usage.c b/usage.c\nindex 1fa924c..445456d 100644\n--- a/usage.c\n+++ b/usage.c\n@@ -12,28 +12,68 @@ static void report(const char *prefix, c\n \tfputs(\"\\n\", stderr);\n }\n \n-void usage(const char *err)\n+void usage_builtin(const char *err)\n {\n \tfprintf(stderr, \"usage: %s\\n\", err);\n \texit(129);\n }\n \n+void die_builtin(const char *err, va_list params)\n+{\n+\treport(\"fatal: \", err, params);\n+\texit(128);\n+}\n+\n+int error_builtin(const char *err, va_list params)\n+{\n+\treport(\"error: \", err, params);\n+\treturn -1;\n+}\n+\n+\n+/* If we are in a dlopen()ed .so write to a global variable would segfault\n+ * (ugh), so keep things static. */\n+static void (*usage_routine)(const char *err) NORETURN = usage_builtin;\n+static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin;\n+static int (*error_routine)(const char *err, va_list params) = error_builtin;\n+\n+void set_usage_routine(void (*routine)(const char *err) NORETURN)\n+{\n+\tusage_routine = routine;\n+}\n+\n+void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN)\n+{\n+\tdie_routine = routine;\n+}\n+\n+void set_error_routine(int (*routine)(const char *err, va_list params))\n+{\n+\terror_routine = routine;\n+}\n+\n+\n+void usage(const char *err)\n+{\n+\tusage_routine(err);\n+}\n+\n void die(const char *err, ...)\n {\n \tva_list params;\n \n \tva_start(params, err);\n-\treport(\"fatal: \", err, params);\n+\tdie_routine(err, params);\n \tva_end(params);\n-\texit(128);\n }\n \n int error(const char *err, ...)\n {\n \tva_list params;\n+\tint ret;\n \n \tva_start(params, err);\n-\treport(\"error: \", err, params);\n+\tret = error_routine(err, params);\n \tva_end(params);\n-\treturn -1;\n+\treturn ret;\n }\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nA person is just about as big as the things that make them angry.\n"},{"id":"22386","messageId":"7vsllv8ny8.fsf@assigned-by-dhcp.cox.net","threadId":"4636","inReplyTo":"20060623133847.GN21864@pasky.or.cz","subject":"Re: [PATCH] Customizable error handlers","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-23T23:14:07Z","receivedAt":"2006-06-23T23:14:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Petr Baudis <pasky@suse.cz> writes:\n\n> Dear diary, on Fri, Jun 23, 2006 at 03:32:27PM CEST, I got a letter\n> where Petr Baudis <pasky@suse.cz> said that...\n>> diff --git a/git-compat-util.h b/git-compat-util.h\n>> index 5d543d2..e954002 100644\n>> --- a/git-compat-util.h\n>> +++ b/git-compat-util.h\n>> @@ -36,9 +36,13 @@ #endif\n>>  #endif\n>>  \n>>  /* General helper functions */\n>> -extern void usage(const char *err) NORETURN;\n>> -extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n>> -extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n>> +void usage(const char *err) NORETURN;\n>> +void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n>> +int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n>\n> Wah, this kind of slipped through. Below is a patch without the\n> externs removed.\n\nOh, I first thought you did that on purpose as a cleanup.  After\nall don't they mean the same thing?\n"},{"id":"22390","messageId":"20060623231807.GO21864@pasky.or.cz","threadId":"4636","inReplyTo":"7vsllv8ny8.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Customizable error handlers","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-06-23T23:18:08Z","receivedAt":"2006-06-23T23:18:08Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Sat, Jun 24, 2006 at 01:14:07AM CEST, I got a letter\nwhere Junio C Hamano <junkio@cox.net> said that...\n> Petr Baudis <pasky@suse.cz> writes:\n> \n> > Dear diary, on Fri, Jun 23, 2006 at 03:32:27PM CEST, I got a letter\n> > where Petr Baudis <pasky@suse.cz> said that...\n> >> diff --git a/git-compat-util.h b/git-compat-util.h\n> >> index 5d543d2..e954002 100644\n> >> --- a/git-compat-util.h\n> >> +++ b/git-compat-util.h\n> >> @@ -36,9 +36,13 @@ #endif\n> >>  #endif\n> >>  \n> >>  /* General helper functions */\n> >> -extern void usage(const char *err) NORETURN;\n> >> -extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n> >> -extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n> >> +void usage(const char *err) NORETURN;\n> >> +void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n> >> +int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n> >\n> > Wah, this kind of slipped through. Below is a patch without the\n> > externs removed.\n> \n> Oh, I first thought you did that on purpose as a cleanup.  After\n> all don't they mean the same thing?\n\nAFAIK they do, but we use extern everywhere and I personally consider\nit good style to externize declarations of, well, external functions.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nA person is just about as big as the things that make them angry.\n"}]}