ossp-pkg/l2/l2_ut_level.c
/*
** OSSP l2 - Flexible Logging
** Copyright (c) 2001-2005 Cable & Wireless <http://www.cw.com/>
** Copyright (c) 2001-2005 The OSSP Project <http://www.ossp.org/>
** Copyright (c) 2001-2005 Ralf S. Engelschall <rse@engelschall.com>
**
** This file is part of OSSP l2, a flexible logging library which
** can be found at http://www.ossp.org/pkg/lib/l2/.
**
** Permission to use, copy, modify, and distribute this software for
** any purpose with or without fee is hereby granted, provided that
** the above copyright notice and this permission notice appear in all
** copies.
**
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
** 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.
**
** l2_ut_level.c: level mask transformations
*/
#include "l2.h"
#include "l2_p.h"
#include <string.h>
#include <ctype.h>
static struct {
l2_level_t level;
char *string;
} l2s_table[] = {
{ L2_LEVEL_PANIC, "panic" },
{ L2_LEVEL_CRITICAL, "critical" },
{ L2_LEVEL_ERROR, "error" },
{ L2_LEVEL_WARNING, "warning" },
{ L2_LEVEL_NOTICE, "notice" },
{ L2_LEVEL_INFO, "info" },
{ L2_LEVEL_TRACE, "trace" },
{ L2_LEVEL_DEBUG, "debug" },
{ 0, NULL }
};
l2_result_t l2_util_l2s(char *string, size_t maxlen, int sep, unsigned int levelmask)
{
char hexbuf[2+(sizeof(unsigned int)*2)+1];
int len;
int i;
int l;
len = maxlen;
string[0] = '\0';
for (i = 0; l2s_table[i].level != 0; i++) {
if (levelmask & l2s_table[i].level) {
levelmask &= ~(l2s_table[i].level);
l = strlen(l2s_table[i].string) + 1;
if (len < l)
return L2_ERR_MEM;
sprintf(string+(maxlen-len), "%s%c", l2s_table[i].string, sep);
len -= l;
}
}
if (levelmask != 0) {
sprintf(hexbuf, "0x%x", levelmask);
l = strlen(hexbuf) + 1;
if (len < l)
return L2_ERR_MEM;
sprintf(string+(maxlen-len), "%s%c", hexbuf, sep);
len -= l;
}
/* remove trailing comma */
if ((maxlen-len) > 0)
string[(maxlen-len)-1] = '\0';
return L2_OK;
}
static unsigned int hexval(const char *cpB, const char *cpE)
{
unsigned int hv;
unsigned int nibble;
hv = 0;
while (cpB < cpE) {
nibble = tolower((unsigned int)(*cpB++));
if (isdigit(nibble))
nibble = nibble - '0';
else
nibble = nibble - 'a';
hv = ((hv << 4) | nibble);
}
return hv;
}
static int myishexnumber(int c)
{
if (isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
return 1;
return 0;
}
l2_result_t l2_util_s2l(const char *string, size_t maxlen, int sep, unsigned int *levelmask)
{
const char *cpB;
const char *cpE;
int bFound;
int i;
*levelmask = 0;
cpE = string;
while (1) {
cpB = cpE;
if (cpB >= (string+maxlen))
break;
if ((int)(*cpB) == sep)
cpB++;
for (cpE = cpB; cpE < (string+maxlen) && (int)(*cpE) != sep; cpE++)
;
if (cpE > (string+maxlen))
break;
bFound = 0;
for (i = 0; l2s_table[i].level != 0; i++) {
if (strncasecmp(cpB, l2s_table[i].string, cpE-cpB) == 0) {
*levelmask |= l2s_table[i].level;
bFound = 1;
break;
}
}
if (!bFound) {
if ((cpE > cpB+2) && strncasecmp(cpB, "0x", 2) == 0 && myishexnumber((int)(*(cpB+2)))) {
*levelmask |= hexval(cpB+2, cpE);
}
else
return L2_ERR_ARG;
}
}
return L2_OK;
}