* error.c, internal.h (rb_bug_reporter_add): add a new C-API.

rb_bug_reporter_add() allows to register a function which
  is called at rb_bug() called.
* ext/-test-/bug_reporter/bug_reporter.c: add a test for this C-API.
* ext/-test-/bug_reporter/extconf.rb: ditto.
* test/-ext-/bug_reporter/test_bug_reporter.rb: ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43303 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2013-10-16 08:39:39 +00:00
Родитель c6b599e1b6
Коммит 955a38da08
6 изменённых файлов: 80 добавлений и 1 удалений

Просмотреть файл

@ -1,3 +1,15 @@
Wed Oct 16 17:37:17 2013 Koichi Sasada <ko1@atdot.net>
* error.c, internal.h (rb_bug_reporter_add): add a new C-API.
rb_bug_reporter_add() allows to register a function which
is called at rb_bug() called.
* ext/-test-/bug_reporter/bug_reporter.c: add a test for this C-API.
* ext/-test-/bug_reporter/extconf.rb: ditto.
* test/-ext-/bug_reporter/test_bug_reporter.rb: ditto.
Wed Oct 16 15:14:21 2013 Koichi Sasada <ko1@atdot.net>
* NEWS: add a line into NEWS for last commit.

32
error.c
Просмотреть файл

@ -264,6 +264,29 @@ rb_warn_m(int argc, VALUE *argv, VALUE exc)
return Qnil;
}
#define MAX_BUG_REPORTERS 0x100
static struct bug_reporters {
void (*func)(FILE *out, void *data);
void *data;
} bug_reporters[MAX_BUG_REPORTERS];
static int bug_reporters_size;
int
rb_bug_reporter_add(void (*func)(FILE *, void *), void *data)
{
struct bug_reporters *reporter;
if (bug_reporters_size >= MAX_BUG_REPORTERS) {
rb_bug("rb_bug_reporter_add: overflow");
}
reporter = &bug_reporters[bug_reporters_size++];
reporter->func = func;
reporter->data = data;
return bug_reporters_size;
}
static void
report_bug(const char *file, int line, const char *fmt, va_list args)
{
@ -281,9 +304,16 @@ report_bug(const char *file, int line, const char *fmt, va_list args)
snprintf(buf, 256, "\n%s\n\n", ruby_description);
fputs(buf, out);
rb_vm_bugreport();
/* call additional bug reporters */
{
int i;
for (i=0; i<bug_reporters_size; i++) {
struct bug_reporters *reporter = &bug_reporters[i];
(*reporter->func)(out, reporter->data);
}
}
fprintf(out, REPORTBUG_MSG);
}
}

Просмотреть файл

@ -0,0 +1,24 @@
#include <ruby.h>
#include <stdio.h>
int rb_bug_reporter_add(void (*func)(FILE *, void *), void *data);
static void
sample_bug_reporter(FILE *out, void *ptr)
{
int n = (int)ptr;
fprintf(out, "Sample bug reporter: %d\n", n);
}
static VALUE
register_sample_bug_reporter(VALUE self, VALUE obj)
{
rb_bug_reporter_add(sample_bug_reporter, NUM2INT(obj));
return Qnil;
}
void
Init_bug_reporter(void)
{
rb_define_global_function("register_sample_bug_reporter", register_sample_bug_reporter, 1);
}

Просмотреть файл

@ -0,0 +1 @@
create_makefile("-test-/bug_reporter/bug_reporter")

Просмотреть файл

@ -772,6 +772,9 @@ VALUE rb_big2str_gmp(VALUE x, int base);
VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck);
#endif
/* error.c */
int rb_bug_reporter_add(void (*func)(FILE *, void *), void *data);
/* file.c */
#ifdef __APPLE__
VALUE rb_str_normalize_ospath(const char *ptr, long len);

Просмотреть файл

@ -0,0 +1,9 @@
require 'test/unit'
require_relative "../../ruby/envutil"
class TestBugReporter < Test::Unit::TestCase
def test_bug_reporter_add
expected_stderr = /Sample bug reporter: 12345/
assert_in_out_err(["--disable-gems", "-r-test-/bug_reporter/bug_reporter", "-e", "register_sample_bug_reporter(12345); Process.kill :SEGV, $$"], "", [], expected_stderr, nil)
end
end