libsigrok
log.c
Go to the documentation of this file.
00001 /*
00002  * This file is part of the sigrok project.
00003  *
00004  * Copyright (C) 2011-2012 Uwe Hermann <uwe@hermann-uwe.de>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00019  */
00020 
00021 #include <stdarg.h>
00022 #include <stdio.h>
00023 #include "sigrok.h"
00024 #include "sigrok-internal.h"
00025 
00026 /* Currently selected libsigrok loglevel. Default: SR_LOG_WARN. */
00027 static int sr_loglevel = SR_LOG_WARN; /* Show errors+warnings per default. */
00028 
00029 /* Function prototype. */
00030 static int sr_logv(void *cb_data, int loglevel, const char *format,
00031                    va_list args);
00032 
00033 /* Pointer to the currently selected log callback. Default: sr_logv(). */
00034 static sr_log_callback_t sr_log_callback = sr_logv;
00035 
00036 /*
00037  * Pointer to private data that can be passed to the log callback.
00038  * This can be used (for example) by C++ GUIs to pass a "this" pointer.
00039  */
00040 static void *sr_log_callback_data = NULL;
00041 
00042 /* Log domain (a short string that is used as prefix for all messages). */
00043 #define LOGDOMAIN_MAXLEN 30
00044 #define LOGDOMAIN_DEFAULT "sr: "
00045 static char sr_log_domain[LOGDOMAIN_MAXLEN + 1] = LOGDOMAIN_DEFAULT;
00046 
00047 /**
00048  * Set the libsigrok loglevel.
00049  *
00050  * This influences the amount of log messages (debug messages, error messages,
00051  * and so on) libsigrok will output. Using SR_LOG_NONE disables all messages.
00052  *
00053  * Note that this function itself will also output log messages. After the
00054  * loglevel has changed, it will output a debug message with SR_LOG_DBG for
00055  * example. Whether this message is shown depends on the (new) loglevel.
00056  *
00057  * @param loglevel The loglevel to set (SR_LOG_NONE, SR_LOG_ERR, SR_LOG_WARN,
00058  *                 SR_LOG_INFO, SR_LOG_DBG, or SR_LOG_SPEW).
00059  *
00060  * @return SR_OK upon success, SR_ERR_ARG upon invalid loglevel.
00061  */
00062 SR_API int sr_log_loglevel_set(int loglevel)
00063 {
00064         if (loglevel < SR_LOG_NONE || loglevel > SR_LOG_SPEW) {
00065                 sr_err("Invalid loglevel %d.", loglevel);
00066                 return SR_ERR_ARG;
00067         }
00068 
00069         sr_loglevel = loglevel;
00070 
00071         sr_dbg("libsigrok loglevel set to %d.", loglevel);
00072 
00073         return SR_OK;
00074 }
00075 
00076 /**
00077  * Get the libsigrok loglevel.
00078  *
00079  * @return The currently configured libsigrok loglevel.
00080  */
00081 SR_API int sr_log_loglevel_get(void)
00082 {
00083         return sr_loglevel;
00084 }
00085 
00086 /**
00087  * Set the libsigrok logdomain string.
00088  *
00089  * @param logdomain The string to use as logdomain for libsigrok log
00090  *                  messages from now on. Must not be NULL. The maximum
00091  *                  length of the string is 30 characters (this does not
00092  *                  include the trailing NUL-byte). Longer strings are
00093  *                  silently truncated.
00094  *                  In order to not use a logdomain, pass an empty string.
00095  *                  The function makes its own copy of the input string, i.e.
00096  *                  the caller does not need to keep it around.
00097  *
00098  * @return SR_OK upon success, SR_ERR_ARG upon invalid logdomain.
00099  */
00100 SR_API int sr_log_logdomain_set(const char *logdomain)
00101 {
00102         if (!logdomain) {
00103                 sr_err("log: %s: logdomain was NULL", __func__);
00104                 return SR_ERR_ARG;
00105         }
00106 
00107         /* TODO: Error handling. */
00108         snprintf((char *)&sr_log_domain, LOGDOMAIN_MAXLEN, "%s", logdomain);
00109 
00110         sr_dbg("Log domain set to '%s'.", (const char *)&sr_log_domain);
00111 
00112         return SR_OK;
00113 }
00114 
00115 /**
00116  * Get the currently configured libsigrok logdomain.
00117  *
00118  * @return A copy of the currently configured libsigrok logdomain
00119  *         string. The caller is responsible for g_free()ing the string when
00120  *         it is no longer needed.
00121  */
00122 SR_API char *sr_log_logdomain_get(void)
00123 {
00124         return g_strdup((const char *)&sr_log_domain);
00125 }
00126 
00127 /**
00128  * Set the libsigrok log callback to the specified function.
00129  *
00130  * @param cb Function pointer to the log callback function to use.
00131  *           Must not be NULL.
00132  * @param cb_data Pointer to private data to be passed on. This can be used by
00133  *                the caller to pass arbitrary data to the log functions. This
00134  *                pointer is only stored or passed on by libsigrok, and is
00135  *                never used or interpreted in any way. The pointer is allowed
00136  *                to be NULL if the caller doesn't need/want to pass any data.
00137  *
00138  * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments.
00139  */
00140 SR_API int sr_log_callback_set(sr_log_callback_t cb, void *cb_data)
00141 {
00142         if (!cb) {
00143                 sr_err("log: %s: cb was NULL", __func__);
00144                 return SR_ERR_ARG;
00145         }
00146 
00147         /* Note: 'cb_data' is allowed to be NULL. */
00148 
00149         sr_log_callback = cb;
00150         sr_log_callback_data = cb_data;
00151 
00152         return SR_OK;
00153 }
00154 
00155 /**
00156  * Set the libsigrok log callback to the default built-in one.
00157  *
00158  * Additionally, the internal 'sr_log_callback_data' pointer is set to NULL.
00159  *
00160  * @return SR_OK upon success, a negative error code otherwise.
00161  */
00162 SR_API int sr_log_callback_set_default(void)
00163 {
00164         /*
00165          * Note: No log output in this function, as it should safely work
00166          * even if the currently set log callback is buggy/broken.
00167          */
00168         sr_log_callback = sr_logv;
00169         sr_log_callback_data = NULL;
00170 
00171         return SR_OK;
00172 }
00173 
00174 static int sr_logv(void *cb_data, int loglevel, const char *format, va_list args)
00175 {
00176         int ret;
00177 
00178         /* This specific log callback doesn't need the void pointer data. */
00179         (void)cb_data;
00180 
00181         /* Only output messages of at least the selected loglevel(s). */
00182         if (loglevel > sr_loglevel)
00183                 return SR_OK; /* TODO? */
00184 
00185         if (sr_log_domain[0] != '\0')
00186                 fprintf(stderr, "%s", sr_log_domain);
00187         ret = vfprintf(stderr, format, args);
00188         fprintf(stderr, "\n");
00189 
00190         return ret;
00191 }
00192 
00193 SR_PRIV int sr_log(int loglevel, const char *format, ...)
00194 {
00195         int ret;
00196         va_list args;
00197 
00198         va_start(args, format);
00199         ret = sr_log_callback(sr_log_callback_data, loglevel, format, args);
00200         va_end(args);
00201 
00202         return ret;
00203 }
00204 
00205 SR_PRIV int sr_spew(const char *format, ...)
00206 {
00207         int ret;
00208         va_list args;
00209 
00210         va_start(args, format);
00211         ret = sr_log_callback(sr_log_callback_data, SR_LOG_SPEW, format, args);
00212         va_end(args);
00213 
00214         return ret;
00215 }
00216 
00217 SR_PRIV int sr_dbg(const char *format, ...)
00218 {
00219         int ret;
00220         va_list args;
00221 
00222         va_start(args, format);
00223         ret = sr_log_callback(sr_log_callback_data, SR_LOG_DBG, format, args);
00224         va_end(args);
00225 
00226         return ret;
00227 }
00228 
00229 SR_PRIV int sr_info(const char *format, ...)
00230 {
00231         int ret;
00232         va_list args;
00233 
00234         va_start(args, format);
00235         ret = sr_log_callback(sr_log_callback_data, SR_LOG_INFO, format, args);
00236         va_end(args);
00237 
00238         return ret;
00239 }
00240 
00241 SR_PRIV int sr_warn(const char *format, ...)
00242 {
00243         int ret;
00244         va_list args;
00245 
00246         va_start(args, format);
00247         ret = sr_log_callback(sr_log_callback_data, SR_LOG_WARN, format, args);
00248         va_end(args);
00249 
00250         return ret;
00251 }
00252 
00253 SR_PRIV int sr_err(const char *format, ...)
00254 {
00255         int ret;
00256         va_list args;
00257 
00258         va_start(args, format);
00259         ret = sr_log_callback(sr_log_callback_data, SR_LOG_ERR, format, args);
00260         va_end(args);
00261 
00262         return ret;
00263 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines