silcconfig.c
- Author: Johnny Mnemonic <johnny@themnemonic.org>
+ Author: Giovanni Giacobbi <giovanni@giacobbi.net>
- Copyright (C) 1997 - 2002 Pekka Riikonen
+ Copyright (C) 2002 - 2003 Giovanni Giacobbi
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.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
*/
/* $Id$ */
-#include "silcincludes.h"
+#include "silc.h"
/* limit debug logging verbosity */
#if 0
char *p; /* the Parser poitner */
SilcUInt32 len; /* fixed length of the whole file */
SilcUInt32 line; /* current parsing line, strictly linked to p */
- bool included; /* wether this file is main or included */
+ SilcBool included; /* wether this file is main or included */
};
/* We need the entity to base our block-style parsing on */
static void my_trim_spaces(SilcConfigFile *file)
{
register char *r = file->p;
- while (isspace(*r))
+ while ((*r != '\0' && *r != EOF) && isspace(*r))
if (*r++ == '\n') file->line++;
file->p = r;
}
static void my_skip_line(SilcConfigFile *file)
{
register char *r = file->p;
- while (*r && (*r != '\n') && (*r != '\r')) r++;
- file->p = (*r ? r + 1 : r);
+ while ((*r != '\0' && *r != EOF) && (*r != '\n') && (*r != '\r')) r++;
+ file->p = ((*r != '\0' && *r != EOF) ? r + 1 : r);
file->line++;
}
/* Obtains a text token from the current position until first separator.
}
return NULL;
}
-/* ... */
+/* Converts a string in the type specified. returns a dynamically
+ * allocated pointer. */
static void *silc_config_marshall(SilcConfigType type, const char *val)
{
void *pt;
int val_int;
- bool val_bool;
+ SilcBool val_boolean;
char *val_tmp;
SilcUInt32 val_size;
case SILC_CONFIG_ARG_TOGGLE:
if (!strcasecmp(val, "yes") || !strcasecmp(val, "true") ||
!strcasecmp(val, "on") || !strcasecmp(val, "1")) {
- val_bool = TRUE;
+ val_boolean = TRUE;
}
else if (!strcasecmp(val, "no") || !strcasecmp(val, "false") ||
!strcasecmp(val, "off") || !strcasecmp(val, "0")) {
- val_bool = FALSE;
+ val_boolean = FALSE;
}
else
return NULL;
- pt = silc_calloc(1, sizeof(val_bool));
- *(bool *)pt = (bool) val_bool;
+ pt = silc_calloc(1, sizeof(val_boolean));
+ *(SilcBool *)pt = (SilcBool) val_boolean;
return pt;
case SILC_CONFIG_ARG_INT:
val_int = (int) strtol(val, &val_tmp, 0);
/* (Private) destroy a SilcConfigEntity */
-static void silc_config_destroy(SilcConfigEntity ent, bool destroy_opts)
+static void silc_config_destroy(SilcConfigEntity ent, SilcBool destroy_opts)
{
SilcConfigOption *oldopt, *nextopt;
SILC_CONFIG_DEBUG(("Freeing config entity [ent=0x%x] [opts=0x%x]",
/* Registers a new option in the specified entity.
* Returns TRUE on success, FALSE if already registered. */
-bool silc_config_register(SilcConfigEntity ent, const char *name,
+SilcBool silc_config_register(SilcConfigEntity ent, const char *name,
SilcConfigType type, SilcConfigCallback cb,
const SilcConfigTable *subtable, void *context)
{
/* Register a new option table in the specified config entity */
-bool silc_config_register_table(SilcConfigEntity ent,
+SilcBool silc_config_register_table(SilcConfigEntity ent,
const SilcConfigTable table[], void *context)
{
int i;
}
else {
void *pt;
- int ret;
+ int ret = 0; /* very important in case of no cb */
if (*(*p)++ != '=')
return SILC_CONFIG_EEXPECTEDEQUAL;
pt = silc_config_marshall(thisopt->type, buf);
if (!pt)
return SILC_CONFIG_EINVALIDTEXT;
- if (thisopt->cb) {
+ if (thisopt->cb)
ret = thisopt->cb(thisopt->type, thisopt->name, file->line,
pt, thisopt->context);
- if (ret) {
- SILC_CONFIG_DEBUG(("Callback refused the value [ret=%d]", ret));
- return ret;
- }
- }
+
+ /* since we have to free "pt" both on failure and on success, we
+ assume that ret == 0 if we didn't actually call any cb. */
silc_free(pt);
+ if (ret) {
+ SILC_CONFIG_DEBUG(("Callback refused the value [ret=%d]", ret));
+ return ret;
+ }
}
continue;