From bb8244c99752e9ce7822a19fedc34c0edff21d39 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Sat, 27 Dec 2014 22:19:06 +0200 Subject: [PATCH] [glibutil] Initial commit --- .gitignore | 15 + Makefile | 190 ++++++++++++ README | 1 + debian/changelog | 5 + debian/compat | 1 + debian/control | 18 ++ debian/copyright | 29 ++ debian/libglibutil-dev.install | 3 + debian/libglibutil.install | 1 + debian/rules | 11 + include/gutil_log.h | 343 +++++++++++++++++++++ include/gutil_macros.h | 59 ++++ include/gutil_types.h | 51 ++++ libglibutil.pc.in | 10 + rpm/libglibutil.spec | 46 +++ src/gutil_log.c | 527 +++++++++++++++++++++++++++++++++ 16 files changed, 1310 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/libglibutil-dev.install create mode 100644 debian/libglibutil.install create mode 100755 debian/rules create mode 100644 include/gutil_log.h create mode 100644 include/gutil_macros.h create mode 100644 include/gutil_types.h create mode 100644 libglibutil.pc.in create mode 100644 rpm/libglibutil.spec create mode 100644 src/gutil_log.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c9e6100 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*~ +debian/files +debian/libglibutil-dev.debhelper.log +debian/libglibutil-dev.substvars +debian/libglibutil-dev +debian/libglibutil.debhelper.log +debian/libglibutil.postinst.debhelper +debian/libglibutil.postrm.debhelper +debian/libglibutil.substvars +debian/libglibutil +debian/tmp +documentation.list +installroot +build +RPMS diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b8ceee0 --- /dev/null +++ b/Makefile @@ -0,0 +1,190 @@ +# -*- Mode: makefile-gmake -*- + +.PHONY: clean all debug release + +# +# Required packages +# + +PKGS = glib-2.0 + +# +# Default target +# + +all: debug release pkgconfig + +# +# Library version +# + +VERSION_MAJOR = 1 +VERSION_MINOR = 0 +VERSION_RELEASE = 0 + +NAME = glibutil +LIB_NAME = lib$(NAME) +LIB_DEV_SYMLINK = $(LIB_NAME).so +LIB_SYMLINK1 = $(LIB_DEV_SYMLINK).$(VERSION_MAJOR) +LIB_SYMLINK2 = $(LIB_SYMLINK1).$(VERSION_MINOR) +LIB_SONAME = $(LIB_SYMLINK1) +LIB = $(LIB_SONAME).$(VERSION_MINOR).$(VERSION_RELEASE) + +# +# Sources +# + +SRC = gutil_log.c + +# +# Directories +# + +SRC_DIR = src +INCLUDE_DIR = include +BUILD_DIR = build +DEBUG_BUILD_DIR = $(BUILD_DIR)/debug +RELEASE_BUILD_DIR = $(BUILD_DIR)/release + +# +# Tools and flags +# + +CC = $(CROSS_COMPILE)gcc +LD = $(CC) +WARNINGS = -Wall +INCLUDES = -I$(INCLUDE_DIR) +BASE_FLAGS = -fPIC +FULL_CFLAGS = $(BASE_FLAGS) $(CFLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) \ + -MMD -MP $(shell pkg-config --cflags $(PKGS)) +FULL_LDFLAGS = $(BASE_FLAGS) $(LDFLAGS) -shared -Wl,-soname,$(LIB_SONAME) \ + $(shell pkg-config --libs $(PKGS)) +DEBUG_FLAGS = -g +RELEASE_FLAGS = + +ifndef KEEP_SYMBOLS +KEEP_SYMBOLS = 0 +endif + +ifneq ($(KEEP_SYMBOLS),0) +RELEASE_FLAGS += -g +endif + +DEBUG_LDFLAGS = $(FULL_LDFLAGS) $(DEBUG_FLAGS) +RELEASE_LDFLAGS = $(FULL_LDFLAGS) $(RELEASE_FLAGS) +DEBUG_CFLAGS = $(FULL_CFLAGS) $(DEBUG_FLAGS) -DDEBUG +RELEASE_CFLAGS = $(FULL_CFLAGS) $(RELEASE_FLAGS) -O2 + +# +# Files +# + +PKGCONFIG = $(BUILD_DIR)/$(LIB_NAME).pc +DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o) +RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o) + +# +# Dependencies +# + +DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d) +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(DEPS)),) +-include $(DEPS) +endif +endif + +$(DEBUG_OBJS) $(DEBUG_LIB): | $(DEBUG_BUILD_DIR) +$(RELEASE_OBJS) $(RELEASE_LIB): | $(RELEASE_BUILD_DIR) + +# +# Rules +# + +DEBUG_LIB = $(DEBUG_BUILD_DIR)/$(LIB) +RELEASE_LIB = $(RELEASE_BUILD_DIR)/$(LIB) +DEBUG_LINK = $(DEBUG_BUILD_DIR)/$(LIB_SYMLINK1) +RELEASE_LINK = $(RELEASE_BUILD_DIR)/$(LIB_SYMLINK1) + +debug: $(DEBUG_LIB) $(DEBUG_LINK) + +release: $(RELEASE_LIB) $(RELEASE_LINK) + +pkgconfig: $(PKGCONFIG) + +clean: + rm -f *~ $(SRC_DIR)/*~ $(INCLUDE_DIR)/*~ + rm -fr $(BUILD_DIR) RPMS installroot + rm -fr debian/tmp debian/libglibutil debian/libglibutil-dev + rm -f documentation.list debian/files debian/*.substvars + rm -f debian/*.debhelper.log debian/*.debhelper debian/*~ + +$(GEN_DIR): + mkdir -p $@ + +$(DEBUG_BUILD_DIR): + mkdir -p $@ + +$(RELEASE_BUILD_DIR): + mkdir -p $@ + +$(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c + $(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@ + +$(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c + $(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@ + +$(DEBUG_LIB): $(DEBUG_OBJS) + $(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) -o $@ + +$(RELEASE_LIB): $(RELEASE_OBJS) + $(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) -o $@ +ifeq ($(KEEP_SYMBOLS),0) + strip $@ +endif + +$(DEBUG_LINK): + ln -sf $(LIB) $@ + +$(RELEASE_LINK): + ln -sf $(LIB) $@ + +$(PKGCONFIG): $(LIB_NAME).pc.in + sed -e 's/\[version\]/'$(VERSION_MAJOR).$(VERSION_MINOR)/g $< > $@ + +# +# Install +# + +INSTALL_PERM = 644 +INSTALL_OWNER = $(shell id -u) +INSTALL_GROUP = $(shell id -g) + +INSTALL = install +INSTALL_DIRS = $(INSTALL) -d +INSTALL_FILES = $(INSTALL) -m $(INSTALL_PERM) + +INSTALL_LIB_DIR = $(DESTDIR)/usr/lib +INSTALL_INCLUDE_DIR = $(DESTDIR)/usr/include/$(NAME) +INSTALL_PKGCONFIG_DIR = $(DESTDIR)/usr/lib/pkgconfig + +INSTALL_ALIAS = $(INSTALL_LIB_DIR)/$(LIB_SHORTCUT) + +install: $(INSTALL_LIB_DIR) + $(INSTALL_FILES) $(RELEASE_LIB) $(INSTALL_LIB_DIR) + ln -sf $(LIB) $(INSTALL_LIB_DIR)/$(LIB_SYMLINK2) + ln -sf $(LIB_SYMLINK2) $(INSTALL_LIB_DIR)/$(LIB_SYMLINK1) + +install-dev: install $(INSTALL_INCLUDE_DIR) $(INSTALL_PKGCONFIG_DIR) + $(INSTALL_FILES) $(INCLUDE_DIR)/*.h $(INSTALL_INCLUDE_DIR) + $(INSTALL_FILES) $(PKGCONFIG) $(INSTALL_PKGCONFIG_DIR) + ln -sf $(LIB_SYMLINK1) $(INSTALL_LIB_DIR)/$(LIB_DEV_SYMLINK) + +$(INSTALL_LIB_DIR): + $(INSTALL_DIRS) $@ + +$(INSTALL_INCLUDE_DIR): + $(INSTALL_DIRS) $@ + +$(INSTALL_PKGCONFIG_DIR): + $(INSTALL_DIRS) $@ diff --git a/README b/README new file mode 100644 index 0000000..1f92e18 --- /dev/null +++ b/README @@ -0,0 +1 @@ +Library of glib utilities. diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..29ea13a --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +libglibutil (1.0.0) unstable; urgency=low + + * Initial release + + -- Slava Monich Sat, 27 Dec 2014 22:36:32 +0200 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..fbfadf2 --- /dev/null +++ b/debian/control @@ -0,0 +1,18 @@ +Source: libglibutil +Section: libs +Priority: optional +Maintainer: Slava Monich +Build-Depends: debhelper (>= 7), libglib2.0-dev (>= 2.0) +Standards-Version: 3.8.4 + +Package: libglibutil +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Library of glib utilities + +Package: libglibutil-dev +Section: libdevel +Architecture: any +Depends: libglibutil (= ${binary:Version}), ${misc:Depends} +Description: Development files for libglibutil diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..bda404d --- /dev/null +++ b/debian/copyright @@ -0,0 +1,29 @@ +Copyright (C) 2014-2015 Jolla Ltd. +Contact: Slava Monich + +You may use this file under the terms of BSD license as follows: + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the Jolla Ltd nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. diff --git a/debian/libglibutil-dev.install b/debian/libglibutil-dev.install new file mode 100644 index 0000000..68a82f9 --- /dev/null +++ b/debian/libglibutil-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/libglibutil.so usr/lib +include/*.h usr/include/glibutil +build/libglibutil.pc usr/lib/pkgconfig diff --git a/debian/libglibutil.install b/debian/libglibutil.install new file mode 100644 index 0000000..1f37dfd --- /dev/null +++ b/debian/libglibutil.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/libglibutil.so.* usr/lib diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..3a92007 --- /dev/null +++ b/debian/rules @@ -0,0 +1,11 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +override_dh_auto_install: + dh_auto_install -- install-dev + +%: + dh $@ diff --git a/include/gutil_log.h b/include/gutil_log.h new file mode 100644 index 0000000..5fe36c4 --- /dev/null +++ b/include/gutil_log.h @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2014-2015 Jolla Ltd. + * Contact: Slava Monich + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Jolla Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GUTIL_LOG_H +#define GUTIL_LOG_H + +#include "gutil_types.h" +#include + +G_BEGIN_DECLS + +/* Log levels */ +#define GLOG_LEVEL_ALWAYS (-2) +#define GLOG_LEVEL_INHERIT (-1) +#define GLOG_LEVEL_NONE (0) +#define GLOG_LEVEL_ERR (1) +#define GLOG_LEVEL_WARN (2) +#define GLOG_LEVEL_INFO (3) +#define GLOG_LEVEL_DEBUG (4) +#define GLOG_LEVEL_VERBOSE (5) + +/* Allow these to be redefined */ +#ifndef GLOG_LEVEL_MAX +# ifdef DEBUG +# define GLOG_LEVEL_MAX GLOG_LEVEL_VERBOSE +# else +# define GLOG_LEVEL_MAX GLOG_LEVEL_DEBUG +# endif +#endif /* GLOG_LEVEL_MAX */ + +#ifndef GLOG_LEVEL_DEFAULT +# ifdef DEBUG +# define GLOG_LEVEL_DEFAULT GLOG_LEVEL_DEBUG +# else +# define GLOG_LEVEL_DEFAULT GLOG_LEVEL_INFO +# endif +#endif /* GLOG_LEVEL_DEFAULT */ + +/* Do we need a separate log level for ASSERTs? */ +#ifndef GLOG_LEVEL_ASSERT +# ifdef DEBUG +# define GLOG_LEVEL_ASSERT GLOG_LEVEL_ERR +# else + /* No asserts in release build */ +# define GLOG_LEVEL_ASSERT (GLOG_LEVEL_MAX+1) +# endif +#endif + +/* Log module */ +struct glog_module { + const char* name; /* Name (used as prefix) */ + const GLogModule* parent; /* Parent log module (optional) */ + void* reserved; /* Reserved for future expansion */ + const int max_level; /* Maximum level defined at compile time */ + int level; /* Current log level */ + int flags; /* Flags (should be zero) */ + int reserved2; /* Reserved for future expansion */ +}; + +/* Command line parsing helper. Option format is [module]:level + * where level can be either a number or log level name ("none", err etc.) */ +gboolean +gutil_log_parse_option( + const char* opt, /* String to parse */ + GLogModule** modules, /* Known modules */ + int count, /* Number of known modules */ + GError** error); /* Optional error message */ + +/* Set log type by name ("syslog", "stdout" or "glib"). This is also + * primarily for parsing command line options */ +gboolean +gutil_log_set_type( + const char* type, + const char* default_name); + +const char* +gutil_log_get_type( + void); + +/* Generates the string containg description of log levels and list of + * log modules. The caller must deallocate the string with g_free */ +char* +gutil_log_description( + GLogModule** modules, /* Known modules */ + int count); /* Number of known modules */ + +/* Logging function */ +void +gutil_log( + const GLogModule* module, /* Calling module (NULL for default) */ + int level, /* Message log level */ + const char* format, /* Message format */ + ...) G_GNUC_PRINTF(3,4); /* Followed by arguments */ + +void +gutil_logv( + const GLogModule* module, + int level, + const char* format, + va_list va); + +/* Check if logging is enabled for the specified log level */ +gboolean +gutil_log_enabled( + const GLogModule* module, + int level); + +/* Known log types */ +extern const char GLOG_TYPE_STDOUT[]; +extern const char GLOG_TYPE_STDERR[]; +extern const char GLOG_TYPE_GLIB[]; +extern const char GLOG_TYPE_CUSTOM[]; +extern const char GLOG_TYPE_SYSLOG[]; + +/* Available log handlers */ +#define GUTIL_DEFINE_LOG_FN(fn) void fn(const char* name, int level, \ + const char* format, va_list va) +GUTIL_DEFINE_LOG_FN(gutil_log_stdout); +GUTIL_DEFINE_LOG_FN(gutil_log_stderr); +GUTIL_DEFINE_LOG_FN(gutil_log_glib); +GUTIL_DEFINE_LOG_FN(gutil_log_syslog); + +/* Log configuration */ +#define GLOG_MODULE_DECL(m) extern GLogModule m; +GLOG_MODULE_DECL(gutil_log_default) +typedef GUTIL_DEFINE_LOG_FN((*GLogProc)); +extern GLogProc gutil_log_func; +extern gboolean gutil_log_timestamp; /* Only affects stdout and stderr */ + +/* Log module (optional) */ +#define GLOG_MODULE_DEFINE_(var,name) \ + GLogModule var = {name, NULL, NULL, \ + GLOG_LEVEL_MAX, GLOG_LEVEL_INHERIT, 0, 0} +#define GLOG_MODULE_DEFINE2_(var,name,parent) \ + GLogModule var = {name, &(parent), NULL, \ + GLOG_LEVEL_MAX, GLOG_LEVEL_INHERIT, 0, 0} +#ifdef GLOG_MODULE_NAME +extern GLogModule GLOG_MODULE_NAME; +# define GLOG_MODULE_CURRENT (&GLOG_MODULE_NAME) +# define GLOG_MODULE_DEFINE(name) \ + GLOG_MODULE_DEFINE_(GLOG_MODULE_NAME,name) +# define GLOG_MODULE_DEFINE2(name,parent) \ + GLOG_MODULE_DEFINE2_(GLOG_MODULE_NAME,name,parent) +#else +# define GLOG_MODULE_CURRENT NULL +#endif + +/* Logging macros */ + +#define GLOG_NOTHING ((void)0) +#define GLOG_ENABLED(level) gutil_log_enabled(GLOG_MODULE_CURRENT,level) +#define GERRMSG(err) (((err) && (err)->message) ? (err)->message : \ + "Unknown error") + +#if !defined(GLOG_VARARGS) && defined(__GNUC__) +# define GLOG_VARARGS +#endif + +#ifndef GLOG_VARARGS +# define GLOG_VA_NONE(x) static inline void GUTIL_##x(const char* f, ...) {} +# define GLOG_VA(x) static inline void GUTIL_##x(const char* f, ...) { \ + if (f && f[0]) { \ + va_list va; va_start(va,f); \ + gutil_logv(GLOG_MODULE_CURRENT, GLOG_LEVEL_##x, f, va); \ + va_end(va); \ + } \ +} +#endif /* GLOG_VARARGS */ + +#define GUTIL_LOG_ANY (GLOG_LEVEL_MAX >= GLOG_LEVEL_NONE) +#define GUTIL_LOG_ERR (GLOG_LEVEL_MAX >= GLOG_LEVEL_ERR) +#define GUTIL_LOG_WARN (GLOG_LEVEL_MAX >= GLOG_LEVEL_WARN) +#define GUTIL_LOG_INFO (GLOG_LEVEL_MAX >= GLOG_LEVEL_INFO) +#define GUTIL_LOG_DEBUG (GLOG_LEVEL_MAX >= GLOG_LEVEL_DEBUG) +#define GUTIL_LOG_VERBOSE (GLOG_LEVEL_MAX >= GLOG_LEVEL_VERBOSE) +#define GUTIL_LOG_ASSERT (GLOG_LEVEL_MAX >= GLOG_LEVEL_ASSERT) + +#if GUTIL_LOG_ASSERT +void +gutil_log_assert( + const GLogModule* module, /* Calling module (NULL for default) */ + int level, /* Assert log level */ + const char* expr, /* Assert expression */ + const char* file, /* File name */ + int line); /* Line number */ +# define GASSERT(expr) ((expr) ? GLOG_NOTHING : \ + gutil_log_assert(GLOG_MODULE_CURRENT, GLOG_LEVEL_ASSERT, \ + #expr, __FILE__, __LINE__)) +# define GVERIFY(expr) GASSERT(expr) +# define GVERIFY_FALSE(expr) GASSERT(!(expr)) +# define GVERIFY_EQ(expr,val) GASSERT((expr) == (val)) +# define GVERIFY_NE(expr,val) GASSERT((expr) != (val)) +# define GVERIFY_GE(expr,val) GASSERT((expr) >= (val)) +# define GVERIFY_GT(expr,val) GASSERT((expr) > (val)) +# define GVERIFY_LE(expr,val) GASSERT((expr) <= (val)) +# define GVERIFY_LT(expr,val) GASSERT((expr) < (val)) +#else +# define GASSERT(expr) +# define GVERIFY(expr) (expr) +# define GVERIFY_FALSE(expr) (expr) +# define GVERIFY_EQ(expr,val) (expr) +# define GVERIFY_NE(expr,val) (expr) +# define GVERIFY_GE(expr,val) (expr) +# define GVERIFY_GT(expr,val) (expr) +# define GVERIFY_LE(expr,val) (expr) +# define GVERIFY_LT(expr,val) (expr) +#endif + +#ifdef GLOG_VARARGS +# if GUTIL_LOG_ERR +# define GERR(f,args...) gutil_log(GLOG_MODULE_CURRENT, \ + GLOG_LEVEL_ERR, f, ##args) +# define GERR_(f,args...) gutil_log(GLOG_MODULE_CURRENT, \ + GLOG_LEVEL_ERR, "%s() " f, __FUNCTION__, ##args) +# else +# define GERR(f,args...) GLOG_NOTHING +# define GERR_(f,args...) GLOG_NOTHING +# endif /* GUTIL_LOG_ERR */ +#else +# define GERR_ GERR +# if GUTIL_LOG_ERR + GLOG_VA(ERR) +# else + GLOG_VA_NONE(ERR) +# endif /* GUTIL_LOG_ERR */ +#endif /* GLOG_VARARGS */ + +#ifdef GLOG_VARARGS +# if GUTIL_LOG_WARN +# define GWARN(f,args...) gutil_log(GLOG_MODULE_CURRENT, \ + GLOG_LEVEL_WARN, f, ##args) +# define GWARN_(f,args...) gutil_log(GLOG_MODULE_CURRENT, \ + GLOG_LEVEL_WARN, "%s() " f, __FUNCTION__, ##args) +# else +# define GWARN(f,args...) GLOG_NOTHING +# define GWARN_(f,args...) GLOG_NOTHING +# endif /* GUTIL_LOGL_WARN */ +#else +# define GWARN_ GWARN +# if GUTIL_LOG_WARN + GLOG_VA(WARN) +# else + GLOG_VA_NONE(WARN) +# endif /* GUTIL_LOGL_WARN */ +# endif /* GLOG_VARARGS */ + +#ifdef GLOG_VARARGS +# if GUTIL_LOG_INFO +# define GINFO(f,args...) gutil_log(GLOG_MODULE_CURRENT, \ + GLOG_LEVEL_INFO, f, ##args) +# define GINFO_(f,args...) gutil_log(GLOG_MODULE_CURRENT, \ + GLOG_LEVEL_INFO, "%s() " f, __FUNCTION__, ##args) +# else +# define GINFO(f,args...) GLOG_NOTHING +# define GINFO_(f,args...) GLOG_NOTHING +# endif /* GUTIL_LOG_INFO */ +#else +# define GINFO_ GINFO +# if GUTIL_LOG_INFO + GLOG_VA(INFO) +# else + GLOG_VA_NONE(INFO) +# endif /* GUTIL_LOG_INFO */ +#endif /* GLOG_VARARGS */ + +#ifdef GLOG_VARARGS +# if GUTIL_LOG_DEBUG +# define GDEBUG(f,args...) gutil_log(GLOG_MODULE_CURRENT, \ + GLOG_LEVEL_DEBUG, f, ##args) +# define GDEBUG_(f,args...) gutil_log(GLOG_MODULE_CURRENT, \ + GLOG_LEVEL_DEBUG, "%s() " f, __FUNCTION__, ##args) +# else +# define GDEBUG(f,args...) GLOG_NOTHING +# define GDEBUG_(f,args...) GLOG_NOTHING +# endif /* GUTIL_LOG_DEBUG */ +#else +# define GDEBUG_ GDEBUG +# if GUTIL_LOG_DEBUG + GLOG_VA(DEBUG) +# else + GLOG_VA_NONE(DEBUG) +# endif /* GUTIL_LOG_DEBUG */ +#endif /* GLOG_VARARGS */ + +#ifdef GLOG_VARARGS +# if GUTIL_LOG_VERBOSE +# define GVERBOSE(f,args...) gutil_log(GLOG_MODULE_CURRENT, \ + GLOG_LEVEL_VERBOSE, f, ##args) +# define GVERBOSE_(f,args...) gutil_log(GLOG_MODULE_CURRENT, \ + GLOG_LEVEL_VERBOSE, "%s() " f, __FUNCTION__, ##args) +# else +# define GVERBOSE(f,args...) GLOG_NOTHING +# define GVERBOSE_(f,args...) GLOG_NOTHING +# endif /* GUTIL_LOG_VERBOSE */ +#else +# define GVERBOSE_ GVERBOSE +# if GUTIL_LOG_VERBOSE + GLOG_VA(VERBOSE) +# else + GLOG_VA_NONE(VERBOSE) +# endif /* GUTIL_LOG_VERBOSE */ +#endif /* GLOG_VARARGS */ + +G_END_DECLS + +#endif /* GUTIL_LOG_H */ + +/* + * Local Variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/gutil_macros.h b/include/gutil_macros.h new file mode 100644 index 0000000..968dddb --- /dev/null +++ b/include/gutil_macros.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014-2015 Jolla Ltd. + * Contact: Slava Monich + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Jolla Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GUTIL_MACROS_H +#define GUTIL_MACROS_H + +#include + +#define G_CAST(address,type,field) \ + ((type *)((guint8*)(address) - G_STRUCT_OFFSET(type,field))) + +#define G_ALIGN2(value) (((value)+1) & ~1) +#define G_ALIGN4(value) (((value)+3) & ~3) +#define G_ALIGN8(value) (((value)+7) & ~7) + +#ifdef __GNUC__ +# define G_PACKED __attribute__((packed)) +#else +# define G_PACKED +#endif + +#endif /* GUTIL_MACROS_H */ + +/* + * Local Variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/gutil_types.h b/include/gutil_types.h new file mode 100644 index 0000000..a3adf7f --- /dev/null +++ b/include/gutil_types.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2014-2015 Jolla Ltd. + * Contact: Slava Monich + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Jolla Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GUTIL_TYPES_H +#define GUTIL_TYPES_H + +#include +#include +#include +#include + +typedef struct glog_module GLogModule; + +#endif /* GUTIL_TYPES_H */ + +/* + * Local Variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/libglibutil.pc.in b/libglibutil.pc.in new file mode 100644 index 0000000..e985e63 --- /dev/null +++ b/libglibutil.pc.in @@ -0,0 +1,10 @@ +name=glibutil +libdir=/usr/lib +includedir=/usr/include + +Name: libglibutil +Description: Library of glib utilities +Version: [version] +Requires: glib-2.0 +Libs: -L${libdir} -l${name} +Cflags: -I${includedir} -I${includedir}/${name} diff --git a/rpm/libglibutil.spec b/rpm/libglibutil.spec new file mode 100644 index 0000000..e244041 --- /dev/null +++ b/rpm/libglibutil.spec @@ -0,0 +1,46 @@ +Name: libglibutil +Version: 1.0 +Release: 0 +Summary: Library of glib utilities +Group: Development/Libraries +License: BSD +URL: https://github.com/nemomobile/libglibutil +Source: %{name}-%{version}.tar.bz2 +BuildRequires: glib2-devel >= 2.0 +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description +Provides glib utility functions and macros + +%package devel +Summary: Development library for %{name} +Requires: %{name} = %{version} +Requires: pkgconfig + +%description devel +This package contains the development library for %{name}. + +%prep +%setup -q + +%build +make KEEP_SYMBOLS=1 release pkgconfig + +%install +rm -rf %{buildroot} +make install-dev DESTDIR=%{buildroot} + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +%{_libdir}/%{name}.so.* + +%files devel +%defattr(-,root,root,-) +%{_libdir}/pkgconfig/*.pc +%{_libdir}/%{name}.so +%{_includedir}/glibutil/*.h diff --git a/src/gutil_log.c b/src/gutil_log.c new file mode 100644 index 0000000..30803be --- /dev/null +++ b/src/gutil_log.c @@ -0,0 +1,527 @@ +/* + * Copyright (C) 2014-2015 Jolla Ltd. + * Contact: Slava Monich + * + * You may use this file under the terms of BSD license as follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Jolla Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "gutil_log.h" + +#if defined(DEBUG) && defined(_WIN32) +# include +#endif + +#ifndef GLOG_SYSLOG +# ifdef unix +# define GLOG_SYSLOG 1 +# else +# define GLOG_SYSLOG 0 +# endif +#endif /* GLOG_SYSLOG */ + +#ifndef GLOG_GLIB +# define GLOG_GLIB 1 +#endif /* GLOG_GLIB */ + +/* Allows timestamps in stdout log */ +gboolean gutil_log_timestamp = TRUE; + +/* Log configuration */ +GLogProc gutil_log_func = gutil_log_stdout; +GLogModule gutil_log_default = { + NULL, /* name */ + NULL, /* parent */ + NULL, /* reserved */ + GLOG_LEVEL_MAX, /* max_level */ + GLOG_LEVEL_DEFAULT, /* level */ + 0 /* flags */ +}; + +/* Log level descriptions */ +static const struct _gutil_log_level { + const char* name; + const char* description; +} gutil_log_levels [] = { + { "none", "Disable log output" }, + { "error", "Errors only"}, + { "warning", "From warning level to errors" }, + { "info", "From information level to errors" }, + { "debug", "From debug messages to errors" }, + { "verbose", "From verbose trace messages to errors" } +}; + +const char GLOG_TYPE_STDOUT[] = "stdout"; +const char GLOG_TYPE_STDERR[] = "stderr"; +const char GLOG_TYPE_CUSTOM[] = "custom"; +#if GLOG_GLIB +const char GLOG_TYPE_GLIB[] = "glib"; +#endif +#if GLOG_SYSLOG +const char GLOG_TYPE_SYSLOG[] = "syslog"; +#endif + +G_STATIC_ASSERT(G_N_ELEMENTS(gutil_log_levels) > GLOG_LEVEL_MAX); +G_STATIC_ASSERT(G_N_ELEMENTS(gutil_log_levels) > GLOG_LEVEL_DEFAULT); + +/** + * Formats the string into the given buffer (most commonly allocated + * on caller's stack). If formatted string fits into the provided buffer, + * returns pointer to the given buffer. If formatted string is too long + * to fit into the provided buffer, allocates a new one and returns pointer + * to it. + */ +static +char* +gutil_log_format( + char* buf, + int bufsize, + const char* format, + va_list va) +{ + int size, nchars = -1; + char* buffer; + if (buf) { + size = bufsize; + buffer = buf; + } else { + size = MAX(100,bufsize); + buffer = g_malloc(size); + } + while (buffer) { + + /* Try to print in the allocated space. */ + va_list va2; + G_VA_COPY(va2, va); + nchars = g_vsnprintf(buffer, size, format, va2); + va_end(va2); + + /* Return the string or try again with more space. */ + if (nchars >= 0) { + if (nchars < size) break; + size = nchars+1; /* Precisely what is needed */ + } else { + size *= 2; /* Twice the old size */ + } + + if (buffer != buf) g_free(buffer); + buffer = g_malloc(size); + } + + return buffer; +} + +/* Forward output to stdout or stderr */ +void +gutil_log_stdio( + FILE* out, + const char* name, + int level, + const char* format, + va_list va) +{ + char t[32]; + char buf[512]; + const char* prefix = ""; + char* msg; + if (gutil_log_timestamp) { + time_t now; + time(&now); + strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S ", localtime(&now)); + } else { + t[0] = 0; + } + switch (level) { + case GLOG_LEVEL_WARN: prefix = "WARNING: "; break; + case GLOG_LEVEL_ERR: prefix = "ERROR: "; break; + default: break; + } + msg = gutil_log_format(buf, sizeof(buf), format, va); +#if defined(DEBUG) && defined(_WIN32) + { + char s[1023]; + if (name) { + g_snprintf(s, sizeof(s), "%s[%s] %s%s\n", t, name, prefix, msg); + } else { + g_snprintf(s, sizeof(s), "%s%s%s\n", t, prefix, msg); + } + OutputDebugStringA(s); + } +#endif + if (name) { + fprintf(out, "%s[%s] %s%s\n", t, name, prefix, msg); + } else { + fprintf(out, "%s%s%s\n", t, prefix, msg); + } + if (msg != buf) g_free(msg); +} + +void +gutil_log_stdout( + const char* name, + int level, + const char* format, + va_list va) +{ + gutil_log_stdio(stdout, name, level, format, va); +} + +void +gutil_log_stderr( + const char* name, + int level, + const char* format, + va_list va) +{ + gutil_log_stdio(stderr, name, level, format, va); +} + +/* Formards output to syslog */ +#if GLOG_SYSLOG +#include +void +gutil_log_syslog( + const char* name, + int level, + const char* format, + va_list va) +{ + int priority; + const char* prefix = NULL; + switch (level) { + default: + case GLOG_LEVEL_INFO: + priority = LOG_NOTICE; + break; + case GLOG_LEVEL_VERBOSE: + priority = LOG_DEBUG; + break; + case GLOG_LEVEL_DEBUG: + priority = LOG_INFO; + break; + case GLOG_LEVEL_WARN: + priority = LOG_WARNING; + prefix = "WARNING! "; + break; + case GLOG_LEVEL_ERR: + priority = LOG_ERR; + prefix = "ERROR! "; + break; + } + if (name || prefix) { + char buf[512]; + g_vsnprintf(buf, sizeof(buf), format, va); + if (!prefix) prefix = ""; + if (name) { + syslog(priority, "[%s] %s%s", name, prefix, buf); + } else { + syslog(priority, "%s%s", prefix, buf); + } + } else { + vsyslog(priority, format, va); + } +} +#endif /* GLOG_SYSLOG */ + +/* Forwards output to g_logv */ +#if GLOG_GLIB +void +gutil_log_glib( + const char* name, + int level, + const char* format, + va_list va) +{ + GLogLevelFlags flags; + switch (level) { + default: + case GLOG_LEVEL_INFO: flags = G_LOG_LEVEL_MESSAGE; break; + case GLOG_LEVEL_VERBOSE: flags = G_LOG_LEVEL_DEBUG; break; + case GLOG_LEVEL_DEBUG: flags = G_LOG_LEVEL_INFO; break; + case GLOG_LEVEL_WARN: flags = G_LOG_LEVEL_WARNING; break; + case GLOG_LEVEL_ERR: flags = G_LOG_LEVEL_CRITICAL; break; + } + g_logv(name, flags, format, va); +} +#endif /* GLOG_GLIB */ + +/* Logging function */ +void +gutil_logv_r( + const GLogModule* module, + int level, + const char* prefix, + const char* format, + va_list va) +{ + if (module->parent && module->level == GLOG_LEVEL_INHERIT) { + gutil_logv_r(module->parent, level, prefix, format, va); + } else { + const int max_level = (module->level == GLOG_LEVEL_INHERIT) ? + gutil_log_default.level : module->level; + if (level > GLOG_LEVEL_NONE && level <= max_level) { + GLogProc log = gutil_log_func; + if (G_LIKELY(log)) { + log(prefix, level, format, va); + } + } + } +} + +void +gutil_logv( + const GLogModule* module, + int level, + const char* format, + va_list va) +{ + if (level != GLOG_LEVEL_NONE && gutil_log_func) { + if (!module) module = &gutil_log_default; + if (G_UNLIKELY(level == GLOG_LEVEL_ALWAYS)) { + GLogProc log = gutil_log_func; + if (G_LIKELY(log)) { + if (level == GLOG_LEVEL_ALWAYS) { + log(module->name, level, format, va); + } + } + } else { + gutil_logv_r(module, level, module->name, format, va); + } + } +} + +void +gutil_log( + const GLogModule* module, + int level, + const char* format, + ...) +{ + va_list va; + va_start(va, format); + gutil_logv(module, level, format, va); + va_end(va); +} + +void +gutil_log_assert( + const GLogModule* module, + int level, + const char* expr, + const char* file, + int line) +{ + gutil_log(module, level, "Assert %s failed at %s:%d\r", expr, file, line); +} + +/** + * Check if logging is enabled for the specified log level + */ +static +gboolean +gutil_log_enabled_r( + const GLogModule* module, + int level) +{ + if (module->parent && module->level == GLOG_LEVEL_INHERIT) { + return gutil_log_enabled_r(module->parent, level); + } else { + const int max_level = (module->level == GLOG_LEVEL_INHERIT) ? + gutil_log_default.level : module->level; + return (level > GLOG_LEVEL_NONE && level <= max_level); + } +} + +gboolean +gutil_log_enabled( + const GLogModule* module, + int level) +{ + if (gutil_log_func) { + if (level == GLOG_LEVEL_ALWAYS) { + return TRUE; + } else if (level > GLOG_LEVEL_NONE) { + if (!module) module = &gutil_log_default; + return gutil_log_enabled_r(module, level); + } + } + return FALSE; +} + +/* gutil_log_parse_option helper */ +static +int +gutil_log_parse_level( + const char* str, + GError** error) +{ + if (str && str[0]) { + guint i; + const size_t len = strlen(str); + if (len == 1) { + const char* valid_numbers = "012345"; + const char* number = strchr(valid_numbers, str[0]); + if (number) { + return number - valid_numbers; + } + } + + for (i=0; i= 0) { + int i; + const size_t namelen = sep - opt; + for (i=0; iname, opt, namelen) && + strlen(modules[i]->name) == namelen) { + modules[i]->level = modlevel; + return TRUE; + } + } + if (error) { + *error = g_error_new(G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Unknown log module '%.*s'", (int)namelen, opt); + } + } + } else { + const int deflevel = gutil_log_parse_level(opt, error); + if (deflevel >= 0) { + gutil_log_default.level = deflevel; + return TRUE; + } + } + return FALSE; +} + +/** + * Generates the string containg description of log levels and list of + * log modules. The caller must deallocate the string with g_free + */ +char* +gutil_log_description( + GLogModule** modules, /* Known modules */ + int count) /* Number of known modules */ +{ + int i; + GString* desc = g_string_sized_new(128); + g_string_append(desc, "Log Levels:\n"); + for (i=0; i<=GLOG_LEVEL_VERBOSE; i++) { + g_string_append_printf(desc, " %d, ", i); + g_string_append_printf(desc, "%-8s ", gutil_log_levels[i].name); + g_string_append(desc, gutil_log_levels[i].description); + if (i == GLOG_LEVEL_DEFAULT) g_string_append(desc, " (default)"); + g_string_append(desc, "\n"); + } + if (modules) { + g_string_append(desc, "\nLog Modules:\n"); + for (i=0; iname); + } + } + return g_string_free(desc, FALSE); +} + +gboolean +gutil_log_set_type( + const char* type, + const char* default_name) +{ +#if GLOG_SYSLOG + if (!g_ascii_strcasecmp(type, GLOG_TYPE_SYSLOG)) { + if (gutil_log_func != gutil_log_syslog) { + openlog(NULL, LOG_PID | LOG_CONS, LOG_USER); + } + gutil_log_default.name = NULL; + gutil_log_func = gutil_log_syslog; + return TRUE; + } + if (gutil_log_func == gutil_log_syslog) { + closelog(); + } +#endif /* GLOG_SYSLOG */ + gutil_log_default.name = default_name; + if (!g_ascii_strcasecmp(type, GLOG_TYPE_STDOUT)) { + gutil_log_func = gutil_log_stdout; + return TRUE; + } if (!g_ascii_strcasecmp(type, GLOG_TYPE_STDERR)) { + gutil_log_func = gutil_log_stderr; + return TRUE; +#if GLOG_GLIB + } else if (!g_ascii_strcasecmp(type, GLOG_TYPE_GLIB)) { + gutil_log_func = gutil_log_glib; + return TRUE; +#endif /* GLOG_GLIB */ + } + return FALSE; +} + +const char* +gutil_log_get_type() +{ + return (gutil_log_func == gutil_log_stdout) ? GLOG_TYPE_STDOUT : + (gutil_log_func == gutil_log_stderr) ? GLOG_TYPE_STDERR : +#if GLOG_SYSLOG + (gutil_log_func == gutil_log_syslog) ? GLOG_TYPE_SYSLOG : +#endif /* GLOG_SYSLOG */ +#if GLOG_GLIB + (gutil_log_func == gutil_log_glib) ? GLOG_TYPE_GLIB : +#endif /* GLOG_GLIB */ + GLOG_TYPE_CUSTOM; +} + +/* + * Local Variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */