head 1.13;
access;
symbols
L2_0_9_13:1.13
FSL_1_7_0:1.13
L2_0_9_12:1.13
LMTP2NNTP_1_4_1:1.13
LMTP2NNTP_1_4_0:1.13
FSL_1_6_1:1.13
L2_0_9_11:1.13
FSL_1_6_0:1.12
FSL_1_6b2:1.12
L2_0_9_10:1.12
FSL_1_6b1:1.12
L2_0_9_9:1.12
LMTP2NNTP_1_3_0:1.11
LMTP2NNTP_1_3b2:1.11
LMTP2NNTP_1_3b1:1.11
LMTP2NNTP_1_3a3:1.11
FSL_1_5_0:1.11
LMTP2NNTP_1_3a2:1.11
FSL_1_5a3:1.11
LMTP2NNTP_1_3a1:1.11
FSL_1_5a2:1.11
L2_0_9_8:1.11
FSL_1_5a1:1.11
L2_0_9_7:1.11
L2_0_9_6:1.11
FSL_1_4_0:1.11
FSL_1_4b1:1.11
L2_0_9_5:1.11
FSL_1_4a1:1.11
FSL_1_3_0:1.11
FSL_1_3b1:1.11
L2_0_9_4:1.11
FSL_1_2_1:1.11
L2_0_9_3:1.11
FSL_1_2_0:1.11
L2_0_9_2:1.11
FSL_1_1_0:1.11
FSL_1_1b1:1.11
WORKOFF:1.11.0.2
WORKOFF_BP:1.11
FSL_1_0_8:1.11
LMTP2NNTP_1_2_0:1.10
LMTP2NNTP_1_2b4:1.10
LMTP2NNTP_1_2b3:1.10
LMTP2NNTP_1_2b2:1.10
LMTP2NNTP_1_2b1:1.10
LMTP2NNTP_1_2a8:1.10
LMTP2NNTP_1_2a7:1.10
FSL_1_0_7:1.10
FSL_1_0_6:1.9
FSL_1_0_5:1.9
FSL_1_0_4:1.9
L2_0_9_1:1.9
FSL_1_0_3:1.9
LMTP2NNTP_1_2a6:1.9
FSL_1_0_2:1.9
FSL_1_0_1:1.9
FSL_1_0_0:1.9
FSL_0_9_0:1.9
L2_0_9_0:1.9
FSL_0_1_12:1.8
FSL_0_1_11:1.8
FSL_0_1_10:1.7
FSL_0_1_9:1.7
FSL_0_1_8:1.7
FSL_0_1_7:1.7
FSL_0_1_6:1.7
FSL_0_1_5:1.7
FSL_0_1_1:1.7
LMTP2NNTP_1_2a5:1.7
LMTP2NNTP_1_2a4:1.7
LMTP2NNTP_1_2a3:1.7
LMTP2NNTP_1_2a1:1.6
LMTP2NNTP_1_1_1:1.5
LMTP2NNTP_1_1_0:1.5
LMTP2NNTP_1_1b4:1.5
LMTP2NNTP_1_1b3:1.5
L2_CHANNEL_ONLY_REVAMPING_BEFORE:1.5
LMTP2NNTP_1_1b2:1.5
LMTP2NNTP_1_1b1:1.5
L2_0_1_0:1.5;
locks; strict;
comment @ * @;
1.13
date 2005.10.03.08.08.11; author rse; state Exp;
branches;
next 1.12;
1.12
date 2005.01.24.15.03.18; author rse; state Exp;
branches;
next 1.11;
1.11
date 2003.02.13.15.37.28; author rse; state Exp;
branches;
next 1.10;
1.10
date 2003.01.06.11.41.52; author rse; state Exp;
branches;
next 1.9;
1.9
date 2002.07.30.19.08.25; author rse; state Exp;
branches;
next 1.8;
1.8
date 2002.07.29.17.42.25; author rse; state Exp;
branches;
next 1.7;
1.7
date 2002.01.02.17.07.38; author rse; state Exp;
branches;
next 1.6;
1.6
date 2001.11.07.13.05.20; author rse; state Exp;
branches;
next 1.5;
1.5
date 2001.09.08.22.06.09; author rse; state Exp;
branches;
next 1.4;
1.4
date 2001.09.06.14.37.53; author rse; state Exp;
branches;
next 1.3;
1.3
date 2001.09.05.13.34.58; author rse; state Exp;
branches;
next 1.2;
1.2
date 2001.09.05.07.41.18; author rse; state Exp;
branches;
next 1.1;
1.1
date 2001.09.04.13.52.59; author rse; state Exp;
branches;
next ;
desc
@@
1.13
log
@Adjust copyright messages for new year 2005.
@
text
@/*
** OSSP l2 - Flexible Logging
** Copyright (c) 2001-2005 Cable & Wireless
** Copyright (c) 2001-2005 The OSSP Project
** Copyright (c) 2001-2005 Ralf S. Engelschall
**
** 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_param.c: parameter parsing support
*/
#include "l2.h"
#include "l2_p.h"
#include
#include
#include
#include
#include
l2_result_t l2_util_setparams(l2_env_t *env, l2_param_t pa[], const char *fmt, va_list ap)
{
char *cpB, *cpE;
char *spec;
int ok;
int i;
int n;
/* argument sanity check */
if (env == NULL || pa == NULL || fmt == NULL)
return L2_ERR_ARG;
/* on-the-fly create or just take over parameter specification string */
spec = l2_util_vasprintf(fmt, ap);
/* enter the parsing loop */
cpE = spec;
while (*cpE != '\0') {
/* determine begin of parameter name */
cpB = cpE;
if ((n = strspn(cpB, " \t\r\n")) > 0)
cpB += n;
/* determine end of parameter name */
cpE = cpB;
if (!isalpha((int)*cpE)) {
l2_env_errorinfo(env, L2_ERR_ARG,
"expected alpha-numerical parameter "
"start character, got '%c'", *cpE);
return L2_ERR_ARG;
}
cpE++;
while (isalnum((int)*cpE))
cpE++;
if (*cpE != '=') {
l2_env_errorinfo(env, L2_ERR_ARG,
"expected assignment operator ('='), "
"got '%c'", *cpE);
return L2_ERR_ARG;
}
*cpE++ = '\0';
/* try to match with configured parameters */
ok = FALSE;
for (i = 0; pa[i].name != NULL; i++) {
if (strcmp(pa[i].name, cpB) == 0) {
ok = TRUE;
break;
}
}
if (!ok) {
l2_env_errorinfo(env, L2_ERR_ARG, "unknown parameter name '%s'", cpB);
return L2_ERR_ARG;
}
/* determine parameter value */
cpB = cpE;
if ((n = strspn(cpB, " \t\r\n")) > 0)
cpB += n;
if (*cpB == '"') {
cpB++;
while (1) {
cpE = cpB;
if ((cpE = strchr(cpE+1, '"')) == NULL) {
l2_env_errorinfo(env, L2_ERR_ARG, "closing quote ('\"') not found");
return L2_ERR_ARG;
}
if (*(cpE-1) != '\\')
break;
}
}
else {
cpE = cpB;
while (1) {
if ((n = strcspn(cpE, " \t\r\n,")) > 0) {
cpE += n;
if (*(cpE-1) == '\\') {
cpE++;
continue;
}
}
break;
}
}
*cpE++ = '\0';
/* store parameter value */
switch (pa[i].type) {
case L2_TYPE_INT: {
/* integer parameter */
long val;
if (strlen(cpB) > 2 && cpB[0] == '0' && cpB[1] == 'x')
val = strtol(cpB+2, &cpE, 16);
else if (strlen(cpB) > 1 && cpB[0] == '0')
val = strtol(cpB+1, &cpE, 8);
else
val = strtol(cpB, &cpE, 10);
if ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE) {
l2_env_errorinfo(env, L2_ERR_ARG,
"numerical parameter value out of range "
"('%s')", cpB);
return L2_ERR_ARG;
}
if (*cpE != '\0') {
l2_env_errorinfo(env, L2_ERR_ARG,
"expected valid numerical parameter value, "
"got '%c' character", *cpE);
return L2_ERR_ARG;
}
*(int *)(pa[i].store) = (int)val;
break;
}
case L2_TYPE_FLT: {
/* floating point parameter */
double val = strtod(cpB, &cpE);
if (val == HUGE_VAL && errno == ERANGE) {
l2_env_errorinfo(env, L2_ERR_ARG,
"floating point parameter value too huge "
"('%s')", cpB);
return L2_ERR_ARG;
}
if (val == 0 && cpE == cpB) {
l2_env_errorinfo(env, L2_ERR_ARG,
"floating point parameter value conversion failed "
"('%s')", cpB);
}
if (*cpE != '\0') {
l2_env_errorinfo(env, L2_ERR_ARG,
"expected valid floating point parameter value, "
"got '%c' character", *cpE);
return L2_ERR_ARG;
}
*(float *)(pa[i].store) = (float)val;
break;
}
case L2_TYPE_STR: {
/* string parameter */
if (*(char **)(pa[i].store) != NULL)
free(*(char **)(pa[i].store));
*(char **)(pa[i].store) = strdup(cpB);
break;
}
}
/* skip delimiter */
if ((n = strspn(cpE, " \t\r\n,")) > 0)
cpE += n;
}
free(spec);
return L2_OK;
}
@
1.12
log
@Adjust copyright messages for new year 2005.
@
text
@d3 3
a5 3
** Copyright (c) 2001-2004 Cable & Wireless
** Copyright (c) 2001-2004 The OSSP Project
** Copyright (c) 2001-2004 Ralf S. Engelschall
@
1.11
log
@Remove NULL checks for va_list based variables because it is not
portable to assume that va_list behaves like a pointer or other
scalar type. Indeed it is a full structure on some platforms like
FreeBSD/alpha.
@
text
@d3 3
a5 3
** Copyright (c) 2001-2003 Cable & Wireless Deutschland GmbH
** Copyright (c) 2001-2003 The OSSP Project (http://www.ossp.org/)
** Copyright (c) 2001-2003 Ralf S. Engelschall
@
1.10
log
@- remove trailing whitespaces
- adjust copyright messages
- consistently use "OSSP l2"
- consistently talk about "Flexible Logging"
- use standard OSSP ASCII-art
@
text
@d49 1
a49 1
if (env == NULL || pa == NULL || fmt == NULL || ap == NULL)
@
1.9
log
@polish for release
@
text
@d2 4
a5 3
** OSSP l2 - Logging Library
** Copyright (c) 2001-2002 The OSSP Project (http://www.ossp.org/)
** Copyright (c) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/)
d7 1
a7 1
** This file is part of OSSP L2, a flexible logging library which
d45 1
a45 1
int i;
d66 1
a66 1
l2_env_errorinfo(env, L2_ERR_ARG,
d75 1
a75 1
l2_env_errorinfo(env, L2_ERR_ARG,
d138 1
a138 1
l2_env_errorinfo(env, L2_ERR_ARG,
d144 1
a144 1
l2_env_errorinfo(env, L2_ERR_ARG,
d156 1
a156 1
l2_env_errorinfo(env, L2_ERR_ARG,
d162 1
a162 1
l2_env_errorinfo(env, L2_ERR_ARG,
d167 1
a167 1
l2_env_errorinfo(env, L2_ERR_ARG,
d177 1
a177 1
if (*(char **)(pa[i].store) != NULL)
@
1.8
log
@allow hexadecimal and octal integer values, too. (especially for file permissions)
@
text
@d2 1
a2 1
** L2 - OSSP Logging Library
d7 1
a7 1
** can be found at http://www.ossp.org/pkg/l2/.
@
1.7
log
@bump copyright year
@
text
@d129 7
a135 1
long val = strtol(cpB, &cpE, 10);
@
1.6
log
@Hell, I've seldom seen that it is needed to prepare and adjust such a
lot of subtle details of existing code in order to make a new feature
implementable in a straight-forward way. Anyway, here comes one more
preparation change for the forthcoming channel tree specification
parser:
- change l2_util_setparam() to take an l2_env_t parameter
which allows the function to report better error messages.
- completely rewrite l2_util_setparam() to support calls
l2_channel_configure(ch, "n1=v1,n2=v2,n3=v3")
and/or
l2_channel_configure(ch, "n1=%x,n2=%x,n3=%x", v1, v2, v3)
instead of
l2_channel_configure(ch, "n1,n2,n3", v1, v2, v3)
This is both a step forward to make the interface of
l2_channel_configure() more flexible (because one now can directly
inline values instead of having them to be passed explicitly) and
allows the spec parser not having to know the type (integer, floating
point or string) of a parameter (which is important if one wants the
parser to be independent of the implementing channel handlers).
@
text
@d3 2
a4 2
** Copyright (c) 2001 The OSSP Project (http://www.ossp.org/)
** Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/)
@
1.5
log
@fix memory leak for string parameters
@
text
@d33 1
d35 3
d39 1
a39 1
l2_result_t l2_util_setparams(l2_param_t pa[], const char *fmt, va_list ap)
d41 2
a42 2
const char *cpB, *cpE;
const char *cpC, *cpG;
d45 1
d47 2
a48 1
if (pa == NULL || fmt == NULL || ap == NULL)
d50 6
a55 1
cpE = fmt;
d59 2
a60 2
while (*cpB == ',')
cpB++;
d64 8
a71 1
while (*cpE != ',' && *cpE != '\0')
d73 7
d84 23
a106 4
cpC = pa[i].name;
cpG = cpB;
while (*cpC != '\0' && cpG < cpE) {
if (*cpC != *cpG)
a107 2
cpC++;
cpG++;
d109 44
a152 34
if (*cpC == '\0' && cpG == cpE) {
/* parameter matched, so store value */
switch (pa[i].type) {
case L2_TYPE_CHAR:
*(char *)(pa[i].store) = va_get(ap, char);
break;
case L2_TYPE_SHORT:
*(short *)(pa[i].store) = va_get(ap, short);
break;
case L2_TYPE_INT:
*(int *)(pa[i].store) = va_get(ap, int);
break;
case L2_TYPE_LONG:
*(long *)(pa[i].store) = va_get(ap, long);
break;
case L2_TYPE_FLOAT:
*(float *)(pa[i].store) = va_get(ap, float);
break;
case L2_TYPE_DOUBLE:
*(double *)(pa[i].store) = va_get(ap, double);
break;
case L2_TYPE_STRING:
if (*(char **)(pa[i].store) != NULL)
free(*(char **)(pa[i].store));
*(char **)(pa[i].store) = va_get(ap, charptr);
if (*(char **)(pa[i].store) != NULL)
*(char **)(pa[i].store) = strdup(*(char **)(pa[i].store));
break;
case L2_TYPE_CHARPTR:
*(char **)(pa[i].store) = va_get(ap, charptr);
break;
case L2_TYPE_VOIDPTR:
*(void **)(pa[i].store) = va_get(ap, voidptr);
break;
d154 19
a172 1
ok = TRUE;
d176 4
a179 2
if (!ok)
return L2_ERR_USE;
d181 3
@
1.4
log
@Replace generic L2_ERROR with more granular L2_ERR_XXX and
make sure that we always check with "!= L2_OK".
@
text
@d89 2
@
1.3
log
@fix L2_TYPE_STRING: argument can be NULL
@
text
@d43 1
a43 1
return L2_ERROR;
d105 1
a105 1
return L2_ERROR;
@
1.2
log
@Provide an L2_TYPE_STRING for the channel configuration steps. This is
like L2_TYPE_CHARPTR but treats the target as a NUL-terminated string
and performs a strdup() on it. This make the channels simpler, because
they no longer have to post-process the configuration step in order to
make own copies of provided strings.
@
text
@d89 3
a91 1
*(char **)(pa[i].store) = strdup(va_get(ap, charptr));
@
1.1
log
@Wohhooooo! Here comes the underlying message formatting support:
1. renamed l2_channel_setparam() to l2_util_setparam() because it
is just a utility function and is not tied to any channel.
2. moved l2_util_setparam() to its own l2_ut_param.c source file.
3. added l2_ut_format.c which contains a slightly adjusted version
of Str's str_format() stuff under the name l2_util_format().
4. use l2_util_format() in l2_stream.c instead of vsnprintf()
and this way finally support l2_formatter_t callbacks.
5. cleanup adjustments to the l2_stream_formatter() API.
Let's rock...
@
text
@d88 3
@