diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2013-01-04 11:01:15 +0100 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2013-01-04 11:01:15 +0100 |
commit | 76f4ad0d529623ecd36ce8b0a4f3e73c0240e60c (patch) | |
tree | 5ce3c3c9b746c420e96236343677800179813fda /hugin.c | |
parent | 4117304567ceb9454599a4e2889f09443382f74a (diff) |
Rename project from 'Debug Module' to 'Hugin'
Diffstat (limited to 'hugin.c')
-rw-r--r-- | hugin.c | 332 |
1 files changed, 332 insertions, 0 deletions
@@ -0,0 +1,332 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * debug.c + * + * Thu Nov 1 13:38:47 CET 2012 + * Copyright 2012 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Debug Module. + * + * Debug Module is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Debug Module 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Debug Module; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "debug.h" + +#include <stdio.h> +#include <stdarg.h> +#include <time.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#ifdef WITH_DBG_MUTEX +#include <pthread.h> +#endif + +#ifdef WITH_DBG_FILTER +#include "debug_filter.h" +#endif + +#ifdef WITH_DBG_SYSLOG +#include "debug_syslog.h" +#endif + +struct dbg_config_t { + unsigned int flags; + int fd; + int file_fd; + int stdout_no_date; +#ifdef WITH_DBG_MUTEX + pthread_mutex_t mutex; +#endif +#ifdef WITH_DBG_SYSLOG + const char* syslog_host; + int syslog_port; +#endif +} dbg_config = { + DBG_FLAG_DEFAULT, // flags + -1, // fd + -1, // file_fd + 0, //stdout_no_date +#ifdef WITH_DBG_MUTEX + {}, // mutex; +#endif +#ifdef WITH_DBG_SYSLOG + "", // syslog_host; + -1, // syslog_port; +#endif + /* // This doesn't work in C++ + .flags = DBG_FLAG_DEFAULT, + .fd = -1, + .file_fd = -1, + .stdout_no_date = 0 + */ +}; + +#ifdef WITH_DBG_MUTEX + pthread_mutex_t localtime_mutex; +#endif + +struct tm *dbg_localtime(const time_t *timep, struct tm *result) +{ + struct tm *res = NULL; +#ifdef WITH_DBG_MUTEX + pthread_mutex_lock(&localtime_mutex); +#endif + + if(timep && result) { + memcpy(result,localtime(timep),sizeof(*result)); + res = result; + } + +#ifdef WITH_DBG_MUTEX + pthread_mutex_unlock(&localtime_mutex); +#endif + + return res; +} + + +static void dbg_mutex_init() +{ +#ifdef WITH_DBG_MUTEX + if(dbg_config.flags & DBG_FLAG_USE_MUTEX) { + pthread_mutex_init(&dbg_config.mutex, NULL); + } + + pthread_mutex_init(&localtime_mutex, NULL); +#endif +} + +static void dbg_mutex_lock() +{ +#ifdef WITH_DBG_MUTEX + if(dbg_config.flags & DBG_FLAG_USE_MUTEX) { + pthread_mutex_lock(&dbg_config.mutex); + } +#endif +} + +static void dbg_mutex_unlock() +{ +#ifdef WITH_DBG_MUTEX + if(dbg_config.flags & DBG_FLAG_USE_MUTEX) { + pthread_mutex_unlock(&dbg_config.mutex); + } +#endif +} + +static void dbg_mutex_close() +{ +#ifdef WITH_DBG_MUTEX + if(dbg_config.flags & DBG_FLAG_USE_MUTEX) { + // Make sure we don't destroy the mutex while another thread is using it. + dbg_mutex_lock(); + dbg_mutex_unlock(); + pthread_mutex_destroy(&dbg_config.mutex); + } + + pthread_mutex_destroy(&localtime_mutex); +#endif +} + +dbg_status_t dbg_init(unsigned int flags, ...) +{ + dbg_status_t status = DBG_STATUS_OK; + + dbg_config.flags = flags; + + int end = 0; + + va_list vl; + va_start(vl, flags); + while(!end) { + int option = va_arg(vl, int); + switch(option) { + case DBG_OPTION_END: + end = 1; + break; + case DBG_OPTION_FD: + dbg_config.fd = va_arg(vl, int); + break; + case DBG_OPTION_STDOUT_NO_DATE: + dbg_config.stdout_no_date = va_arg(vl, int); + break; + case DBG_OPTION_FILENAME: + if(dbg_config.flags & DBG_FLAG_OUTPUT_TO_FILE) { + const char *filename = (const char*)va_arg(vl, char*); + dbg_config.file_fd = open(filename, O_CREAT | O_RDWR, 0777); + } + break; +#ifdef WITH_DBG_SYSLOG + case DBG_OPTION_SYSLOG_PORT: + dbg_config.syslog_port = va_arg(vl, int); + break; + case DBG_OPTION_SYSLOG_HOST: + dbg_config.syslog_host = (const char*)va_arg(vl, char*); + break; +#endif +#ifdef WITH_DBG_FILTER + case DBG_OPTION_FILTER: + dbg_filter_parse((const char*)va_arg(vl, char*)); + break; +#endif + default: + status = DBG_STATUS_UNKNOWN_OPTION; + printf("option: %x\n", option); + goto err; + } + } + + dbg_mutex_init(); + +#ifdef WITH_DBG_SYSLOG + if(dbg_config.flags & DBG_FLAG_OUTPUT_TO_SYSLOG) { + dbg_syslog_init(dbg_config.syslog_host, dbg_config.syslog_port); + } +#endif + + err: + va_end(vl); + + return status; +} + +void dbg_close() +{ + if(dbg_config.flags & DBG_FLAG_OUTPUT_TO_FILE) { + if(dbg_config.file_fd != -1) close(dbg_config.file_fd); + } + +#ifdef WITH_DBG_SYSLOG + dbg_syslog_close(); +#endif + + dbg_mutex_close(); +} + +/* +static unsigned int gettid() +{ + return (unsigned int)pthread_self(); +} +*/ + +static int dbg_create_header(char *hdr, size_t size) +{ + time_t rawtime = time(NULL); + struct tm t; + dbg_localtime(&rawtime, &t); + + return snprintf(hdr, size, + "%d-%02d-%02d %02d:%02d:%02d", + t.tm_year + 1900, + t.tm_mon + 1, + t.tm_mday, + t.tm_hour, + t.tm_min, + t.tm_sec); +} + +static int dbg_output_fd(int fd, const char *msg, int withdate) +{ + int s; + + if(fd == -1) return 1; + + if(withdate) { + char hdr[32]; + dbg_create_header(hdr, sizeof(hdr)); + + s = write(fd, hdr, strlen(hdr)); + s = write(fd, " ", 1); + } + + s = write(fd, msg, strlen(msg)); + if(msg[strlen(msg) - 1] != '\n') { + s = write(fd, "\n", 1); + } + return 0; +} + +int __debug(const char *func, const int line, + const enum __debug_class cl, + const char *ch, const char *fmt, ...) +{ + int result = 0; + int sz; + + // NOTE: This must be identical to the debug_class_str in debug_filter.c + const char * const debug_class_str[] = + { "fixme", "err", "warn", "info", "debug" }; + + dbg_mutex_lock(); + +#ifdef WITH_DBG_FILTER + if(!dbg_filter_enabled(cl, ch)) goto done; +#endif + + // + // Generate message + // + + char buf[1024]; + sz = snprintf(buf, sizeof(buf), + "%s:%s:%s:%d ", + debug_class_str[(unsigned)cl], ch, func, line); + va_list va; + va_start(va, fmt); + sz += vsnprintf(buf + sz, sizeof(buf) - sz, fmt, va); + va_end(va); + + // + // Send message to output + // + + if(dbg_config.flags & DBG_FLAG_OUTPUT_TO_STDOUT) { + dbg_output_fd(STDOUT_FILENO, buf, dbg_config.stdout_no_date == 0); + } + + if(dbg_config.flags & DBG_FLAG_OUTPUT_TO_STDERR) { + dbg_output_fd(STDERR_FILENO, buf, 1); + } + + if(dbg_config.flags & DBG_FLAG_OUTPUT_TO_FD) { + dbg_output_fd(dbg_config.fd, buf, 1); + } + + if(dbg_config.flags & DBG_FLAG_OUTPUT_TO_FILE) { + dbg_output_fd(dbg_config.file_fd, buf, 1); + } + +#ifdef WITH_DBG_SYSLOG + if(dbg_config.flags & DBG_FLAG_OUTPUT_TO_SYSLOG) { + dbg_syslog_output(buf); + } +#endif + +#ifdef WITH_DBG_FILTER +done: +#endif + dbg_mutex_unlock(); + + return result; +} |