Author: Giovanni Giacobbi <giovanni@giacobbi.net>
- Copyright (C) 2002 - 2003 Giovanni Giacobbi
+ Copyright (C) 2002 - 2006 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
*/
/* $Id$ */
-#include "silcincludes.h"
+#include "silc.h"
/* limit debug logging verbosity */
#if 0
#define SILC_CONFIG_DEBUG(fmt)
#endif
+#define BUF_SIZE 255
+
/* this is the option struct and currently it is only used internally to
* the module and other structs. */
typedef struct SilcConfigOptionStruct {
char *filename; /* the original filename opened */
int level; /* parsing level, how many nested
silc_config_main we have */
- char *base; /* this is a fixed pointer to the base location */
- char *p; /* the Parser poitner */
+ unsigned char *base; /* this is a fixed pointer to the base location */
+ unsigned 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 */
/* Points the first non-space character */
static void my_trim_spaces(SilcConfigFile *file)
{
- register char *r = file->p;
- while ((*r != '\0' && *r != EOF) && isspace(*r))
+ unsigned char *r = file->p;
+ while ((*r != '\0' && *r != (unsigned char)EOF) && isspace((int)*r))
if (*r++ == '\n') file->line++;
file->p = r;
}
+
/* Skips the current line until newline (lf or cr) */
static void my_skip_line(SilcConfigFile *file)
{
- register char *r = file->p;
- while ((*r != '\0' && *r != EOF) && (*r != '\n') && (*r != '\r')) r++;
- file->p = ((*r != '\0' && *r != EOF) ? r + 1 : r);
+ unsigned char *r = file->p;
+ while ((*r != '\0' && *r != (unsigned char)EOF) &&
+ (*r != '\n') && (*r != '\r')) r++;
+ file->p = ((*r != '\0' && *r != (unsigned char)EOF) ? r + 1 : r);
file->line++;
}
+
/* Obtains a text token from the current position until first separator.
* a separator is any non alphanumeric character nor "_" or "-" */
-static char *my_next_token(SilcConfigFile *file, char *to)
+static unsigned char *my_next_token(SilcConfigFile *file, char *to)
{
- register char *o;
+ unsigned int count = 0;
+ unsigned char *o;
+
my_trim_spaces(file);
o = file->p;
- while (isalnum(*o) || (*o == '_') || (*o == '-'))
+ while ((isalnum((int)*o) || (*o == '_') || (*o == '-')) &&
+ count < BUF_SIZE) {
+ count++;
*to++ = *o++;
+ }
*to = '\0';
file->p = o;
return to;
}
+
/* Obtains a string from the current position. The only difference from
* next_token() is that quoted-strings are also accepted */
static char *my_get_string(SilcConfigFile *file, char *to)
{
- char *o;
+ unsigned char *o;
+
my_trim_spaces(file);
o = file->p;
if (*o == '"') {
- char *quot = strchr(++o, '"');
- int len = quot - o;
- if (!quot) { /* XXX FIXME: gotta do something here */
- printf("Bullshit, missing matching \"");
- exit(1);
+ unsigned int count = 0;
+ unsigned char *d = to;
+ while (count < BUF_SIZE) {
+ o++;
+ if (*o == '"') {
+ break;
+ }
+ if (*o == '\\') {
+ o++;
+ }
+ count++;
+ *d++ = *o;
}
- if (len <= 0)
- *to = '\0';
- else {
- strncpy(to, o, len);
- to[len] = '\0';
+ if (count >= BUF_SIZE) { /* XXX FIXME: gotta do something here */
+ fprintf(stderr, "Bullshit, missing matching \"");
+ exit(1);
}
+ *d = '\0';
/* update stream pointer */
- file->p = quot + 1;
- return to;
+ file->p = o + 1;
+ } else {
+ /* we don't need quote parsing, fall-back to token extractor */
+ my_next_token(file, to);
}
- /* we don't need quote parsing, fall-back to token extractor */
- my_next_token(file, to);
return to;
-};
+}
+
/* Skips all comment lines and spaces lines until first useful character */
static void my_skip_comments(SilcConfigFile *file)
{
}
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);
if (val == val_tmp)
return NULL; /* really wrong, there must be at least one digit */
/* Search for a designator */
- switch (tolower(val_tmp[0])) {
+ switch (tolower((int)val_tmp[0])) {
case '\0': /* None */
break;
case 'k': /* Kilobytes */
ret = silc_calloc(1, sizeof(*ret));
ret->filename = strdup(configfile);
- ret->base = ret->p = buffer;
+ ret->base = ret->p = (unsigned char *)buffer;
ret->len = filelen;
ret->line = 1; /* line count, start from first line */
return ret;
ret = silc_calloc(1, sizeof(*ret));
ret->file = file;
return ret;
-};
+}
/* Returns the original filename of the object file */
char *silc_config_read_line(SilcConfigFile *file, SilcUInt32 line)
{
- register char *p;
+ unsigned char *p, *ret = NULL, *endbuf;
int len;
- char *ret = NULL, *endbuf;
if (!file || (line <= 0))
return NULL;
- for (p = file->base; *p && (*p != EOF); p++) {
+ for (p = file->base; *p && (*p != (unsigned char)EOF); p++) {
if (line <= 1)
goto found;
if (*p == '\n')
} else {
ret = silc_memdup(p, strlen(p));
}
- return ret;
+ return (char *)ret;
}
/* Convenience function to read the current parsed line */
/* (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,
- SilcConfigType type, SilcConfigCallback cb,
- const SilcConfigTable *subtable, void *context)
+SilcBool silc_config_register(SilcConfigEntity ent, const char *name,
+ SilcConfigType type, SilcConfigCallback cb,
+ const SilcConfigTable *subtable, void *context)
{
SilcConfigOption *newopt;
SILC_CONFIG_DEBUG(("Register new option=\"%s\" "
/* 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;
static int silc_config_main_internal(SilcConfigEntity ent)
{
SilcConfigFile *file = ent->file;
- char **p = &file->p;
+ unsigned char **p = &file->p;
/* loop throught statements */
while (1) {
- char buf[255];
+ char buf[BUF_SIZE];
SilcConfigOption *thisopt;
/* makes it pointing to the next interesting char */
my_skip_comments(file);
/* got eof? */
- if (**p == '\0' || **p == EOF) {
+ if (**p == '\0' || **p == (unsigned char)EOF) {
if (file->level > 1) /* cannot get eof in a sub-level! */
return SILC_CONFIG_EEXPECTED;
goto finish;