|
Packit |
45fded |
/*
|
|
Packit |
45fded |
* Copyright 2006 Eduard Bloch
|
|
Packit |
45fded |
*
|
|
Packit |
45fded |
* Uses my config parser code and small wrappers to provide the old interface.
|
|
Packit |
45fded |
*
|
|
Packit |
45fded |
*/
|
|
Packit |
45fded |
/*
|
|
Packit |
45fded |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
45fded |
* it under the terms of the GNU General Public License version 2
|
|
Packit |
45fded |
* as published by the Free Software Foundation.
|
|
Packit |
45fded |
*
|
|
Packit |
45fded |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
45fded |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
45fded |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
45fded |
* GNU General Public License for more details.
|
|
Packit |
45fded |
*
|
|
Packit |
45fded |
* You should have received a copy of the GNU General Public License along with
|
|
Packit |
45fded |
* this program; see the file COPYING. If not, write to the Free Software
|
|
Packit |
45fded |
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
Packit |
45fded |
*/
|
|
Packit |
45fded |
|
|
Packit |
45fded |
#include <mconfig.h>
|
|
Packit |
45fded |
#include <stdlib.h>
|
|
Packit |
45fded |
#include <stdio.h>
|
|
Packit |
45fded |
#include <ctype.h>
|
|
Packit |
45fded |
#include <string.h>
|
|
Packit |
45fded |
|
|
Packit |
45fded |
enum parstate {
|
|
Packit |
45fded |
KEYBEGINSEARCH,
|
|
Packit |
45fded |
KEYCOMPARE,
|
|
Packit |
45fded |
EQSIGNSEARCH,
|
|
Packit |
45fded |
VALBEGINSEARCH,
|
|
Packit |
45fded |
LASTCHARSEARCH
|
|
Packit |
45fded |
};
|
|
Packit |
45fded |
|
|
Packit |
45fded |
#define GETVAL_BUF_LEN 512
|
|
Packit |
45fded |
#define isUspace(x) isspace( (int) (unsigned char) x)
|
|
Packit |
45fded |
|
|
Packit |
45fded |
static FILE *glob_cfg_ptr = NULL;
|
|
Packit |
45fded |
|
|
Packit |
45fded |
/*
|
|
Packit |
45fded |
* Warning, uses static line buffer, not reentrant. NULL returned if the key isn't found.
|
|
Packit |
45fded |
*/
|
|
Packit |
45fded |
static char *get_value(FILE *srcfile, const char *key, int dorewind) {
|
|
Packit |
45fded |
static char linebuf[GETVAL_BUF_LEN];
|
|
Packit |
45fded |
|
|
Packit |
45fded |
if(!srcfile)
|
|
Packit |
45fded |
return ((char *) NULL);
|
|
Packit |
45fded |
|
|
Packit |
45fded |
if(dorewind)
|
|
Packit |
45fded |
rewind(srcfile);
|
|
Packit |
45fded |
|
|
Packit |
45fded |
if(!key)
|
|
Packit |
45fded |
return NULL;
|
|
Packit |
45fded |
|
|
Packit |
45fded |
next_line:
|
|
Packit |
45fded |
while(fgets(linebuf, sizeof(linebuf)-1, srcfile)) {
|
|
Packit |
45fded |
int i;
|
|
Packit |
45fded |
int keybeg=0;
|
|
Packit |
45fded |
int s=KEYBEGINSEARCH;
|
|
Packit |
45fded |
char *ret=NULL;
|
|
Packit |
45fded |
int lastchar=0;
|
|
Packit |
45fded |
|
|
Packit |
45fded |
/* simple state machine, char position moved by the states (or not),
|
|
Packit |
45fded |
* state change is done by the state (or not) */
|
|
Packit |
45fded |
for( i=0 ; i
|
|
Packit |
45fded |
/* printf("key: %s, %s, s: %d\n", key, linebuf, s); */
|
|
Packit |
45fded |
switch(s) {
|
|
Packit |
45fded |
case(KEYBEGINSEARCH):
|
|
Packit |
45fded |
{
|
|
Packit |
45fded |
if(isUspace(linebuf[i]))
|
|
Packit |
45fded |
i++;
|
|
Packit |
45fded |
else if(linebuf[i] == '#' || linebuf[i]=='\0')
|
|
Packit |
45fded |
goto next_line;
|
|
Packit |
45fded |
else {
|
|
Packit |
45fded |
s=KEYCOMPARE;
|
|
Packit |
45fded |
keybeg=i;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
break;
|
|
Packit |
45fded |
case(KEYCOMPARE): /* compare the key */
|
|
Packit |
45fded |
{
|
|
Packit |
45fded |
if(key[i-keybeg]=='\0')
|
|
Packit |
45fded |
/* end of key, next state decides what to do on this position */
|
|
Packit |
45fded |
s=EQSIGNSEARCH;
|
|
Packit |
45fded |
else {
|
|
Packit |
45fded |
if(linebuf[i-keybeg]!=key[i-keybeg])
|
|
Packit |
45fded |
goto next_line;
|
|
Packit |
45fded |
else
|
|
Packit |
45fded |
i++;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
break;
|
|
Packit |
45fded |
case(EQSIGNSEARCH): /* skip whitespace, stop on =, break on anything else */
|
|
Packit |
45fded |
{
|
|
Packit |
45fded |
if(isUspace(linebuf[i]))
|
|
Packit |
45fded |
i++;
|
|
Packit |
45fded |
else if(linebuf[i]=='=') {
|
|
Packit |
45fded |
s=VALBEGINSEARCH;
|
|
Packit |
45fded |
i++;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
else
|
|
Packit |
45fded |
goto next_line;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
break;
|
|
Packit |
45fded |
case(VALBEGINSEARCH):
|
|
Packit |
45fded |
{
|
|
Packit |
45fded |
if(isUspace(linebuf[i]))
|
|
Packit |
45fded |
i++;
|
|
Packit |
45fded |
else {
|
|
Packit |
45fded |
/* possible at EOF */
|
|
Packit |
45fded |
if(linebuf[i] == '\0')
|
|
Packit |
45fded |
return NULL;
|
|
Packit |
45fded |
|
|
Packit |
45fded |
lastchar=i-1; /* lastchar can be a space, see below */
|
|
Packit |
45fded |
ret= & linebuf[i];
|
|
Packit |
45fded |
s=LASTCHARSEARCH;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
break;
|
|
Packit |
45fded |
case(LASTCHARSEARCH):
|
|
Packit |
45fded |
{
|
|
Packit |
45fded |
if(linebuf[i]) {
|
|
Packit |
45fded |
if(!isUspace(linebuf[i]))
|
|
Packit |
45fded |
lastchar=i;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
else { /* got string end, terminate after the last seen char */
|
|
Packit |
45fded |
if(linebuf+lastchar < ret) /* no non-space found */
|
|
Packit |
45fded |
return NULL;
|
|
Packit |
45fded |
linebuf[lastchar+1]='\0';
|
|
Packit |
45fded |
return ret;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
i++;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
break;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
return NULL;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
|
|
Packit |
45fded |
int cfg_open(const char *name)
|
|
Packit |
45fded |
{
|
|
Packit |
45fded |
if(glob_cfg_ptr) {
|
|
Packit |
45fded |
fclose(glob_cfg_ptr);
|
|
Packit |
45fded |
glob_cfg_ptr=NULL;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
if(!name) {
|
|
Packit |
45fded |
glob_cfg_ptr=NULL;
|
|
Packit |
45fded |
return 0;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
glob_cfg_ptr = fopen(name, "r");
|
|
Packit |
45fded |
return (glob_cfg_ptr ? 0 : -1);
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
|
|
Packit |
45fded |
int cfg_close()
|
|
Packit |
45fded |
{
|
|
Packit |
45fded |
int r;
|
|
Packit |
45fded |
if(!glob_cfg_ptr)
|
|
Packit |
45fded |
return 0;
|
|
Packit |
45fded |
r=fclose(glob_cfg_ptr);
|
|
Packit |
45fded |
glob_cfg_ptr=NULL;
|
|
Packit |
45fded |
return r;
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
|
|
Packit |
45fded |
void cfg_restart()
|
|
Packit |
45fded |
{
|
|
Packit |
45fded |
get_value(glob_cfg_ptr, NULL, 1);
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
|
|
Packit |
45fded |
char *cfg_get(const char *key)
|
|
Packit |
45fded |
{
|
|
Packit |
45fded |
return get_value(glob_cfg_ptr, key, 1);
|
|
Packit |
45fded |
}
|
|
Packit |
45fded |
|
|
Packit |
45fded |
char *cfg_get_next(const char *key)
|
|
Packit |
45fded |
{
|
|
Packit |
45fded |
return get_value(glob_cfg_ptr, key, 0);
|
|
Packit |
45fded |
}
|