/* ** OSSP l2 - Flexible Logging ** 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 ** ** 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; }