/*
* Copyright (C) 2001-2006 Michael H. Schimek
* Copyright (C) 2000-2003 Iñaki García Etxebarria
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: misc.c,v 1.6 2006/05/25 08:09:43 mschimek Exp $ */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <ctype.h>
#include <errno.h>
#include "misc.h"
#include "version.h"
#if 2 == VBI_VERSION_MINOR
const char _zvbi_intl_domainname[] = PACKAGE;
#endif
_vbi_log_hook _vbi_global_log;
/**
* @internal
* strlcpy() is a BSD/GNU extension.
*/
size_t
_vbi_strlcpy (char * dst,
const char * src,
size_t len)
{
char *dst1;
char *end;
char c;
assert (NULL != dst);
assert (NULL != src);
assert (len > 0);
dst1 = dst;
end = dst + len - 1;
while (dst < end && (c = *src++))
*dst++ = c;
*dst = 0;
return dst - dst1;
}
/**
* @internal
* strndup() is a BSD/GNU extension.
*/
char *
_vbi_strndup (const char * s,
size_t len)
{
size_t n;
char *r;
if (NULL == s)
return NULL;
n = strlen (s);
len = MIN (len, n);
r = malloc (len + 1);
if (r) {
memcpy (r, s, len);
r[len] = 0;
}
return r;
}
/**
* @internal
* vasprintf() is a GNU extension.
*/
int
_vbi_vasprintf (char ** dstp,
const char * templ,
va_list ap)
{
char *buf;
unsigned long size;
int temp;
assert (NULL != dstp);
assert (NULL != templ);
temp = errno;
buf = NULL;
size = 64;
for (;;) {
char *buf2;
long len;
if (!(buf2 = realloc (buf, size)))
break;
buf = buf2;
len = vsnprintf (buf, size, templ, ap);
if (len < 0) {
/* Not enough. */
size *= 2;
} else if ((unsigned long) len < size) {
*dstp = buf;
errno = temp;
return len;
} else {
/* Size needed. */
size = len + 1;
}
}
free (buf);
*dstp = NULL;
errno = temp;
return -1;
}
/**
* @internal
* asprintf() is a GNU extension.
*/
int
_vbi_asprintf (char ** dstp,
const char * templ,
...)
{
va_list ap;
int len;
va_start (ap, templ);
len = vasprintf (dstp, templ, ap);
va_end (ap);
return len;
}
/** @internal */
vbi_bool
_vbi_keyword_lookup (int * value,
const char ** inout_s,
const _vbi_key_value_pair *table,
unsigned int n_pairs)
{
const char *s;
unsigned int i;
assert (NULL != value);
assert (NULL != inout_s);
assert (NULL != *inout_s);
assert (NULL != table);
s = *inout_s;
while (isspace (*s))
++s;
if (isdigit (*s)) {
long val;
char *end;
val = strtol (s, &end, 10);
for (i = 0; NULL != table[i].key; ++i) {
if (val == table[i].value) {
*value = val;
*inout_s = end;
return TRUE;
}
}
} else {
for (i = 0; i < n_pairs; ++i) {
size_t len = strlen (table[i].key);
if (0 == strncasecmp (s, table[i].key, len)
&& !isalnum (s[len])) {
*value = table[i].value;
*inout_s = s + len;
return TRUE;
}
}
}
return FALSE;
}
/**
* @ingroup Basic
*
* Log function printing messages on standard output.
*
* @since 0.2.22
*/
void
vbi_log_on_stderr (vbi_log_mask level,
const char * context,
const char * message,
void * user_data)
{
vbi_log_mask max_level;
if (0 == strncmp (context, "vbi_", 4)) {
context += 4;
} else if (0 == strncmp (context, "vbi_", 5)) {
context += 5;
}
if (NULL != user_data) {
max_level = * (vbi_log_mask *) user_data;
if (level > max_level)
return;
}
fprintf (stderr, "libzvbi:%s: %s\n", context, message);
}
/** @internal */
void
_vbi_log_vprintf (vbi_log_fn log_fn,
void * user_data,
vbi_log_mask mask,
const char * context,
const char * templ,
va_list ap)
{
int saved_errno;
char *buffer;
assert (NULL != templ);
if (NULL == log_fn)
return;
saved_errno = errno;
vasprintf (&buffer, templ, ap);
if (NULL != buffer) {
log_fn (mask, context, buffer, user_data);
free (buffer);
buffer = NULL;
}
errno = saved_errno;
}
/** @internal */
void
_vbi_log_printf (vbi_log_fn log_fn,
void * user_data,
vbi_log_mask mask,
const char * context,
const char * templ,
...)
{
va_list ap;
va_start (ap, templ);
_vbi_log_vprintf (log_fn, user_data, mask, context, templ, ap);
va_end (ap);
}
syntax highlighted by Code2HTML, v. 0.9.1