Add a new library context object.

With the introduction of a context object, library initialization and
shutdown can be performed without requiring any global state. A single
process can use multiple independent contexts without any problems. The
lack of a global state also improves the thread-safety of the library.

At the moment, the new context object is primary used to implement an
improved logging system.
This commit is contained in:
Jef Driesen 2012-05-22 21:22:37 +02:00
parent 3df5cb09d7
commit 0f6d23757f
6 changed files with 189 additions and 0 deletions

View File

@ -2,6 +2,7 @@ libdivecomputerdir = $(includedir)/libdivecomputer
libdivecomputer_HEADERS = \
version.h \
common.h \
context.h \
utils.h \
buffer.h \
descriptor.h \

View File

@ -0,0 +1,54 @@
/*
* libdivecomputer
*
* Copyright (C) 2012 Jef Driesen
*
* 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
*/
#ifndef DC_CONTEXT_H
#define DC_CONTEXT_H
#include "common.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct dc_context_t dc_context_t;
typedef enum dc_loglevel_t {
DC_LOGLEVEL_NONE,
DC_LOGLEVEL_ERROR,
DC_LOGLEVEL_WARNING,
DC_LOGLEVEL_INFO,
DC_LOGLEVEL_DEBUG,
DC_LOGLEVEL_ALL
} dc_loglevel_t;
dc_status_t
dc_context_new (dc_context_t **context);
dc_status_t
dc_context_free (dc_context_t *context);
dc_status_t
dc_context_set_loglevel (dc_context_t *context, dc_loglevel_t loglevel);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DC_CONTEXT_H */

View File

@ -13,6 +13,7 @@ libdivecomputer_la_SOURCES = \
version.c \
descriptor.c \
iterator-private.h iterator.c \
context-private.h context.c \
device-private.h device.c \
parser-private.h parser.c \
datetime.c \

42
src/context-private.h Normal file
View File

@ -0,0 +1,42 @@
/*
* libdivecomputer
*
* Copyright (C) 2012 Jef Driesen
*
* 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
*/
#ifndef DC_CONTEXT_PRIVATE_H
#define DC_CONTEXT_PRIVATE_H
#include <libdivecomputer/context.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define ERROR(context, ...) dc_context_log (context, DC_LOGLEVEL_ERROR, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define WARNING(context, ...) dc_context_log (context, DC_LOGLEVEL_WARNING, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define INFO(context, ...) dc_context_log (context, DC_LOGLEVEL_INFO, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define DEBUG(context, ...) dc_context_log (context, DC_LOGLEVEL_DEBUG, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
dc_status_t
dc_context_log (dc_context_t *context, dc_loglevel_t loglevel, const char *file, unsigned int line, const char *function, const char *format, ...);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DC_CONTEXT_PRIVATE_H */

87
src/context.c Normal file
View File

@ -0,0 +1,87 @@
/*
* libdivecomputer
*
* Copyright (C) 2012 Jef Driesen
*
* 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 <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "context-private.h"
struct dc_context_t {
dc_loglevel_t loglevel;
};
dc_status_t
dc_context_new (dc_context_t **out)
{
dc_context_t *context = NULL;
if (out == NULL)
return DC_STATUS_INVALIDARGS;
context = (dc_context_t *) malloc (sizeof (dc_context_t));
if (context == NULL)
return DC_STATUS_NOMEMORY;
context->loglevel = DC_LOGLEVEL_WARNING;
*out = context;
return DC_STATUS_SUCCESS;
}
dc_status_t
dc_context_free (dc_context_t *context)
{
free (context);
return DC_STATUS_SUCCESS;
}
dc_status_t
dc_context_set_loglevel (dc_context_t *context, dc_loglevel_t loglevel)
{
if (context == NULL)
return DC_STATUS_INVALIDARGS;
context->loglevel = loglevel;
return DC_STATUS_SUCCESS;
}
dc_status_t
dc_context_log (dc_context_t *context, dc_loglevel_t loglevel, const char *file, unsigned int line, const char *function, const char *format, ...)
{
va_list ap;
if (context == NULL)
return DC_STATUS_INVALIDARGS;
if (loglevel > context->loglevel)
return DC_STATUS_SUCCESS;
va_start (ap, format);
vfprintf (stderr, format, ap);
va_end (ap);
return DC_STATUS_SUCCESS;
}

View File

@ -17,6 +17,10 @@ dc_datetime_localtime
dc_datetime_gmtime
dc_datetime_mktime
dc_context_new
dc_context_free
dc_context_set_loglevel
dc_iterator_next
dc_iterator_free