/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2011-2019 Ruby-GNOME Project Team * Copyright (C) 2002-2005 Masao Mutoh * Copyright (C) 1998-2000 Yukihiro Matsumoto, * Daisuke Kanda, * Hiroshi Igarashi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA */ #include "rbgprivate.h" #define RG_TARGET_NAMESPACE mLog static VALUE rbglib_log_handler_procs; static gboolean log_canceled; static const gchar * logmessage(GLogLevelFlags level) { if (level & G_LOG_LEVEL_ERROR){ return "ERROR"; } else if (level & G_LOG_LEVEL_CRITICAL){ return "CRITICAL"; } else if (level & G_LOG_LEVEL_WARNING){ return "WARNING"; } else if (level & G_LOG_LEVEL_MESSAGE){ return "MESSAGE"; } else if (level & G_LOG_LEVEL_INFO){ return "INFO"; } else if (level & G_LOG_LEVEL_DEBUG){ return "DEBUG"; } return "UNKNOWN"; } static VALUE rbg_printerr(VALUE message, G_GNUC_UNUSED VALUE user_data, G_GNUC_UNUSED int argc, G_GNUC_UNUSED const VALUE *argv, G_GNUC_UNUSED VALUE block) { g_printerr("\tfrom %.*s\n", (int)RSTRING_LEN(message), RSTRING_PTR(message)); return Qnil; } static void rbglib_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { if (!log_canceled) { g_printerr("%s-%s **: %s\n", log_domain, logmessage(log_level), message); if (rb_during_gc()) { g_printerr("\tfrom %s:%d\n", rb_sourcefile(), rb_sourceline()); } else { VALUE backtrace = rb_funcall(rb_mKernel, rb_intern("caller"), 0); ID id_each; CONST_ID(id_each, "each"); rb_block_call(backtrace, id_each, 0, NULL, rbg_printerr, Qnil); } } else { g_log_default_handler(log_domain, log_level, message, user_data); } } /* Use Internal only */ static VALUE rg_s_cancel_handler(G_GNUC_UNUSED VALUE self) { log_canceled = TRUE; return Qnil; } static VALUE rg_s_set_handler(VALUE self, VALUE domain, VALUE levels) { guint handler_id = g_log_set_handler(RVAL2CSTR_ACCEPT_NIL(domain), NUM2INT(levels), (GLogFunc)rbglib_log_handler, (gpointer)self); return UINT2NUM(handler_id); } static VALUE rg_s_remove_handler(VALUE self, VALUE domain, VALUE handler_id) { g_log_remove_handler(RVAL2CSTR_ACCEPT_NIL(domain), NUM2UINT(handler_id)); G_REMOVE_RELATIVE(self, handler_id, rbglib_log_handler_procs); return Qnil; } static VALUE rg_s_set_always_fatal(G_GNUC_UNUSED VALUE self, VALUE fatal_mask) { return INT2NUM(g_log_set_always_fatal(NUM2INT(fatal_mask))); } static VALUE rg_s_set_fatal_mask(G_GNUC_UNUSED VALUE self, VALUE domain, VALUE fatal_mask) { return INT2NUM(g_log_set_fatal_mask(RVAL2CSTR_ACCEPT_NIL(domain), NUM2INT(fatal_mask))); } static VALUE rg_s_log(G_GNUC_UNUSED VALUE self, VALUE domain, VALUE level, VALUE str) { g_log(RVAL2CSTR_ACCEPT_NIL(domain), NUM2INT(level), "%s", RVAL2CSTR(str)); return Qnil; } void Init_glib_messages(void) { VALUE RG_TARGET_NAMESPACE = rb_define_module_under(rbg_mGLib(), "Log"); log_canceled = FALSE; rb_global_variable(&rbglib_log_handler_procs); rbglib_log_handler_procs = rb_hash_new(); RG_DEF_SMETHOD(set_handler, 2); RG_DEF_SMETHOD(remove_handler, 2); RG_DEF_SMETHOD(cancel_handler, 0); RG_DEF_SMETHOD(set_always_fatal, 1); RG_DEF_SMETHOD(set_fatal_mask, 2); RG_DEF_SMETHOD(log, 3); rb_define_const(RG_TARGET_NAMESPACE, "FATAL_MASK", INT2NUM(G_LOG_FATAL_MASK)); rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_USER_SHIFT", INT2NUM(G_LOG_LEVEL_USER_SHIFT)); /* GLogLevelFlags */ rb_define_const(RG_TARGET_NAMESPACE, "FLAG_RECURSION", INT2NUM(G_LOG_FLAG_RECURSION)); rb_define_const(RG_TARGET_NAMESPACE, "FLAG_FATAL", INT2NUM(G_LOG_FLAG_FATAL)); rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_ERROR", INT2NUM(G_LOG_LEVEL_ERROR)); rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_CRITICAL", INT2NUM(G_LOG_LEVEL_CRITICAL)); rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_WARNING", INT2NUM(G_LOG_LEVEL_WARNING)); rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_MESSAGE", INT2NUM(G_LOG_LEVEL_MESSAGE)); rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_INFO", INT2NUM(G_LOG_LEVEL_INFO)); rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_DEBUG", INT2NUM(G_LOG_LEVEL_DEBUG)); rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_MASK", INT2NUM(G_LOG_LEVEL_MASK)); }