ref: 8a603a071dc58deb4ab66b76572c5a82767fa8db
dir: /venti/config.c/
#include "platform.h"
#include "dat.h"
#include "fns.h"
#include <stdio.h>
static char magic[] = "venti config\n";
static uint8_t magiclen = sizeof(magic);
// Precondition: buf points to an array of >= MaxConfig+1 bytes
void
readconfig(char *path, char *buf)
{
size_t fsize, n = 0, offset = 0;
int fd = open(path, OREAD);
if(fd < 0)
sysfatal("Unable to open '%s' for config file", path);
fsize = fdsize(fd);
if(fsize > PartBlank)
offset = PartBlank - MaxConfig;
else if(fsize > MaxConfig)
sysfatal("Config file '%s' too large (size %lu, max %lu)!", path, fsize, MaxConfig);
n = pread(fd, buf, MaxConfig, offset);
if(n == 0)
sysfatal("Config file '%s' empty!", path);
if(offset != 0){
if(memcmp(buf, magic, magiclen) != 0)
sysfatal("bad venti config magic in '%s'", path);
memmove(buf, buf + magiclen, MaxConfig - magiclen);
n -= magiclen;
}
buf[n] = 0;
}
/* Skips to the next part of the string with meaning - i.e. skips comments and whitespace */
/* *line indicates whether a line was found */
static char*
skip(char *c, int *line)
{
if(c == NULL)
return NULL;
if(line != NULL)
*line = 0;
while(*c == '#' || isspace(*c)){
if(*c == '#'){
while(*c != '\n' && *c != 0)
c += 1;
/* either at a newline or end-of-string */
}
while(isspace(*c)){
if(*c == '\n' && line != NULL)
*line = 1;
c += 1;
}
}
if(*c == 0)
return NULL;
return c;
}
static int
confis(char **c, char *test, char **out)
{
int lined;
if(!strbegins(*c, test))
return 0;
*c += strlen(test) + 1;
*out = untilspace(*c);
*c += strlen(*out);
if(*out == NULL)
sysfatal("Out of memory");
*c = skip(*c, &lined);
if(lined == 0)
sysfatal("config error: garbage found after '%s' line", test);
return 1;
}
static void
indexname(config *conf, char *name)
{
if(conf->index != NULL)
sysfatal("configuration error: multiple names specified for index");
if(!nameok(name))
sysfatal("Invalid name specified for index: '%s'", name);
conf->index = name;
}
static void
parseconfig(config *conf, char *buf)
{
char *c = buf, *tmp;
while((c = skip(c, NULL)) != NULL){
if(confis(&c, "index", &tmp))
indexname(conf, tmp);
else if(confis(&c, "isect", &tmp))
sysfatal("TODO isect '%s'", tmp);
else if(strbegins(c, "arenas "))
sysfatal("TODO arenas");
else
sysfatal("TODO load config from '%s' (offset %d)", c, c - buf);
}
}
config
loadconfig(char *path)
{
char buf[MaxConfig + 1];
config conf;
memset(&conf, 0, sizeof(conf));
readconfig(path, buf);
parseconfig(&conf, buf);
return conf;
}