postgresql/contrib/tsearch2/prs_dcfg.c

179 lines
3.6 KiB
C
Raw Normal View History

2003-08-04 08:43:34 +08:00
/*
* Simple config parser
2003-07-21 18:27:44 +08:00
* Teodor Sigaev <teodor@sigaev.ru>
*/
#include "postgres.h"
#include <ctype.h>
2003-07-21 18:27:44 +08:00
#include "dict.h"
#include "common.h"
#include "ts_locale.h"
2003-07-21 18:27:44 +08:00
#define CS_WAITKEY 0
#define CS_INKEY 1
#define CS_WAITEQ 2
#define CS_WAITVALUE 3
#define CS_INVALUE 4
2003-08-04 08:43:34 +08:00
#define CS_IN2VALUE 5
2003-07-21 18:27:44 +08:00
#define CS_WAITDELIM 6
#define CS_INESC 7
#define CS_IN2ESC 8
static char *
2003-08-04 08:43:34 +08:00
nstrdup(char *ptr, int len)
{
char *res = palloc(len + 1),
*cptr;
memcpy(res, ptr, len);
res[len] = '\0';
2003-07-21 18:27:44 +08:00
cptr = ptr = res;
2003-08-04 08:43:34 +08:00
while (*ptr)
{
if (t_iseq(ptr, '\\'))
2003-07-21 18:27:44 +08:00
ptr++;
2006-10-04 08:30:14 +08:00
COPYCHAR(cptr, ptr);
cptr += pg_mblen(ptr);
ptr += pg_mblen(ptr);
2003-07-21 18:27:44 +08:00
}
2003-08-04 08:43:34 +08:00
*cptr = '\0';
2003-07-21 18:27:44 +08:00
return res;
}
void
2003-08-04 08:43:34 +08:00
parse_cfgdict(text *in, Map ** m)
{
Map *mptr;
char *ptr = VARDATA(in),
*begin = NULL;
char num = 0;
int state = CS_WAITKEY;
2003-07-21 18:27:44 +08:00
2003-08-04 08:43:34 +08:00
while (ptr - VARDATA(in) < VARSIZE(in) - VARHDRSZ)
{
2006-10-04 08:30:14 +08:00
if (t_iseq(ptr, ','))
2003-08-04 08:43:34 +08:00
num++;
2006-10-04 08:30:14 +08:00
ptr += pg_mblen(ptr);
2003-07-21 18:27:44 +08:00
}
2003-08-04 08:43:34 +08:00
*m = mptr = (Map *) palloc(sizeof(Map) * (num + 2));
memset(mptr, 0, sizeof(Map) * (num + 2));
ptr = VARDATA(in);
while (ptr - VARDATA(in) < VARSIZE(in) - VARHDRSZ)
{
if (state == CS_WAITKEY)
{
if (t_isalpha(ptr))
2003-08-04 08:43:34 +08:00
{
begin = ptr;
state = CS_INKEY;
}
else if (!t_isspace(ptr))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error"),
errdetail("Syntax error in position %d.",
(int) (ptr - VARDATA(in)))));
2003-08-04 08:43:34 +08:00
}
else if (state == CS_INKEY)
{
if (t_isspace(ptr))
2003-08-04 08:43:34 +08:00
{
mptr->key = nstrdup(begin, ptr - begin);
state = CS_WAITEQ;
}
2006-10-04 08:30:14 +08:00
else if (t_iseq(ptr, '='))
2003-08-04 08:43:34 +08:00
{
mptr->key = nstrdup(begin, ptr - begin);
state = CS_WAITVALUE;
}
else if (!t_isalpha(ptr))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error"),
errdetail("Syntax error in position %d.",
(int) (ptr - VARDATA(in)))));
2003-08-04 08:43:34 +08:00
}
else if (state == CS_WAITEQ)
{
if (t_iseq(ptr, '='))
2003-08-04 08:43:34 +08:00
state = CS_WAITVALUE;
else if (!t_isspace(ptr))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error"),
errdetail("Syntax error in position %d.",
(int) (ptr - VARDATA(in)))));
2003-08-04 08:43:34 +08:00
}
else if (state == CS_WAITVALUE)
{
if (t_iseq(ptr, '"'))
2003-08-04 08:43:34 +08:00
{
begin = ptr + 1;
state = CS_INVALUE;
}
else if (!t_isspace(ptr))
2003-08-04 08:43:34 +08:00
{
begin = ptr;
state = CS_IN2VALUE;
2003-07-21 18:27:44 +08:00
}
2003-08-04 08:43:34 +08:00
}
else if (state == CS_INVALUE)
{
if (t_iseq(ptr, '"'))
2003-08-04 08:43:34 +08:00
{
mptr->value = nstrdup(begin, ptr - begin);
2003-07-21 18:27:44 +08:00
mptr++;
2003-08-04 08:43:34 +08:00
state = CS_WAITDELIM;
}
else if (t_iseq(ptr, '\\'))
2003-08-04 08:43:34 +08:00
state = CS_INESC;
}
else if (state == CS_IN2VALUE)
{
if (t_isspace(ptr) || t_iseq(ptr, ','))
2003-08-04 08:43:34 +08:00
{
mptr->value = nstrdup(begin, ptr - begin);
2003-07-21 18:27:44 +08:00
mptr++;
state = (t_iseq(ptr, ',')) ? CS_WAITKEY : CS_WAITDELIM;
2003-08-04 08:43:34 +08:00
}
else if (t_iseq(ptr, '\\'))
2003-08-04 08:43:34 +08:00
state = CS_INESC;
}
else if (state == CS_WAITDELIM)
{
if (t_iseq(ptr, ','))
2003-08-04 08:43:34 +08:00
state = CS_WAITKEY;
else if (!t_isspace(ptr))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error"),
errdetail("Syntax error in position %d.",
(int) (ptr - VARDATA(in)))));
2003-08-04 08:43:34 +08:00
}
else if (state == CS_INESC)
state = CS_INVALUE;
else if (state == CS_IN2ESC)
state = CS_IN2VALUE;
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad parser state"),
errdetail("%d at position %d.",
state, (int) (ptr - VARDATA(in)))));
2006-10-04 08:30:14 +08:00
ptr += pg_mblen(ptr);
2003-07-21 18:27:44 +08:00
}
2003-08-04 08:43:34 +08:00
if (state == CS_IN2VALUE)
{
mptr->value = nstrdup(begin, ptr - begin);
2003-07-21 18:27:44 +08:00
mptr++;
2003-08-04 08:43:34 +08:00
}
else if (!(state == CS_WAITDELIM || state == CS_WAITKEY))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unexpected end of line")));
2003-07-21 18:27:44 +08:00
}