added more code to xli
This commit is contained in:
@ -151,15 +151,14 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_awk_prm_t* pr
|
||||
if (init_token (mmgr, &awk->tok) == -1) goto oops;
|
||||
if (init_token (mmgr, &awk->ntok) == -1) goto oops;
|
||||
|
||||
awk->sio.names = qse_htb_open (
|
||||
awk->sio_names = qse_htb_open (
|
||||
mmgr, QSE_SIZEOF(awk), 128, 70, QSE_SIZEOF(qse_char_t), 1
|
||||
);
|
||||
if (awk->sio.names == QSE_NULL) goto oops;
|
||||
*(qse_awk_t**)QSE_XTN(awk->sio.names) = awk;
|
||||
qse_htb_setmancbs (awk->sio.names,
|
||||
if (awk->sio_names == QSE_NULL) goto oops;
|
||||
*(qse_awk_t**)QSE_XTN(awk->sio_names) = awk;
|
||||
qse_htb_setmancbs (awk->sio_names,
|
||||
qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER)
|
||||
);
|
||||
awk->sio.inp = &awk->sio.arg;
|
||||
|
||||
/* TODO: initial map size?? */
|
||||
awk->tree.funs = qse_htb_open (
|
||||
@ -257,7 +256,7 @@ oops:
|
||||
if (awk->parse.named) qse_htb_close (awk->parse.named);
|
||||
if (awk->parse.funs) qse_htb_close (awk->parse.funs);
|
||||
if (awk->tree.funs) qse_htb_close (awk->tree.funs);
|
||||
if (awk->sio.names) qse_htb_close (awk->sio.names);
|
||||
if (awk->sio_names) qse_htb_close (awk->sio_names);
|
||||
fini_token (&awk->ntok);
|
||||
fini_token (&awk->tok);
|
||||
fini_token (&awk->ptok);
|
||||
@ -287,7 +286,7 @@ int qse_awk_close (qse_awk_t* awk)
|
||||
qse_htb_close (awk->parse.funs);
|
||||
|
||||
qse_htb_close (awk->tree.funs);
|
||||
qse_htb_close (awk->sio.names);
|
||||
qse_htb_close (awk->sio_names);
|
||||
|
||||
fini_token (&awk->ntok);
|
||||
fini_token (&awk->tok);
|
||||
@ -391,26 +390,11 @@ int qse_awk_clear (qse_awk_t* awk)
|
||||
awk->tree.chain_tail = QSE_NULL;
|
||||
awk->tree.chain_size = 0;
|
||||
|
||||
QSE_ASSERT (awk->sio.inp == &awk->sio.arg);
|
||||
/* this table must not be cleared here as there can be a reference
|
||||
* to an entry of this table from errinf.fil when qse_awk_parse()
|
||||
* failed. this table is cleared in qse_awk_parse().
|
||||
* qse_htb_clear (awk->sio.names);
|
||||
* qse_htb_clear (awk->sio_names);
|
||||
*/
|
||||
|
||||
awk->sio.last.c = QSE_CHAR_EOF;
|
||||
awk->sio.last.line = 0;
|
||||
awk->sio.last.colm = 0;
|
||||
awk->sio.last.file = QSE_NULL;
|
||||
awk->sio.nungots = 0;
|
||||
|
||||
awk->sio.arg.flags = 0;
|
||||
awk->sio.arg.name = QSE_NULL;
|
||||
awk->sio.arg.line = 1;
|
||||
awk->sio.arg.colm = 1;
|
||||
awk->sio.arg.b.pos = 0;
|
||||
awk->sio.arg.b.len = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -201,9 +201,9 @@ struct qse_awk_t
|
||||
qse_awk_sio_lxc_t ungot[5];
|
||||
|
||||
qse_awk_sio_arg_t arg; /* for the top level source */
|
||||
qse_awk_sio_arg_t* inp; /* current input */
|
||||
qse_htb_t* names;
|
||||
qse_awk_sio_arg_t* inp; /* current input argument. */
|
||||
} sio;
|
||||
qse_htb_t* sio_names;
|
||||
|
||||
/* previous token */
|
||||
qse_awk_tok_t ptok;
|
||||
|
@ -101,7 +101,7 @@ const qse_char_t* qse_awk_dflerrstr (const qse_awk_t* awk, qse_awk_errnum_t errn
|
||||
QSE_T("'nextfile' illegal in the END block"),
|
||||
QSE_T("both prefix and postfix increment/decrement operator present"),
|
||||
QSE_T("illegal operand for increment/decrement operator"),
|
||||
QSE_T("'include' not followed by a string"),
|
||||
QSE_T("'@include' not followed by a string"),
|
||||
QSE_T("include level too deep"),
|
||||
QSE_T("@word '${0}' not recognized"),
|
||||
QSE_T("@ not followed by a valid word"),
|
||||
|
@ -601,7 +601,7 @@ oops:
|
||||
if (ret <= -1)
|
||||
{
|
||||
/* an error occurred and control has reached here
|
||||
* probably, some included files might not have beed
|
||||
* probably, some included files might not have been
|
||||
* closed. close them */
|
||||
while (awk->sio.inp != &awk->sio.arg)
|
||||
{
|
||||
@ -667,9 +667,15 @@ int qse_awk_parse (qse_awk_t* awk, qse_awk_sio_t* sio)
|
||||
QSE_ASSERT (awk->parse.depth.expr == 0);
|
||||
|
||||
qse_awk_clear (awk);
|
||||
qse_htb_clear (awk->sio.names);
|
||||
qse_htb_clear (awk->sio_names);
|
||||
|
||||
QSE_MEMSET (&awk->sio, 0, QSE_SIZEOF(awk->sio));
|
||||
awk->sio.inf = sio->in;
|
||||
awk->sio.outf = sio->out;
|
||||
awk->sio.last.c = QSE_CHAR_EOF;
|
||||
awk->sio.arg.line = 1;
|
||||
awk->sio.arg.colm = 1;
|
||||
awk->sio.inp = &awk->sio.arg;
|
||||
|
||||
n = parse (awk);
|
||||
if (n == 0 && awk->sio.outf != QSE_NULL) n = deparse (awk);
|
||||
@ -740,9 +746,9 @@ static int begin_include (qse_awk_t* awk)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* store the file name to awk->sio.names */
|
||||
/* store the file name to awk->sio_names */
|
||||
pair = qse_htb_ensert (
|
||||
awk->sio.names,
|
||||
awk->sio_names,
|
||||
QSE_STR_PTR(awk->tok.name),
|
||||
QSE_STR_LEN(awk->tok.name) + 1, /* to include '\0' */
|
||||
QSE_NULL, 0
|
||||
@ -771,6 +777,8 @@ static int begin_include (qse_awk_t* awk)
|
||||
|
||||
arg->flags = QSE_AWK_SIO_INCLUDED;
|
||||
arg->name = QSE_HTB_KPTR(pair);
|
||||
arg->line = 1;
|
||||
arg->colm = 1;
|
||||
|
||||
CLRERR (awk);
|
||||
op = awk->sio.inf (awk, QSE_AWK_SIO_OPEN, arg, QSE_NULL, 0);
|
||||
@ -785,9 +793,6 @@ static int begin_include (qse_awk_t* awk)
|
||||
awk->sio.inp = arg;
|
||||
awk->parse.depth.incl++;
|
||||
|
||||
awk->sio.inp->line = 1;
|
||||
awk->sio.inp->colm = 1;
|
||||
|
||||
/* read in the first character in the included file.
|
||||
* so the next call to get_token() sees the character read
|
||||
* from this file. */
|
||||
@ -851,8 +856,7 @@ static int parse_progunit (qse_awk_t* awk)
|
||||
|
||||
if (!MATCH(awk,TOK_STR))
|
||||
{
|
||||
SETERR_LOC (
|
||||
awk, QSE_AWK_EINCLSTR, &awk->ptok.loc);
|
||||
SETERR_LOC (awk, QSE_AWK_EINCLSTR, &awk->ptok.loc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -6081,7 +6085,6 @@ retry:
|
||||
|
||||
ADD_TOKEN_CHAR (awk, tok, c);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -6249,10 +6252,7 @@ static int deparse (qse_awk_t* awk)
|
||||
|
||||
QSE_ASSERT (awk->sio.outf != QSE_NULL);
|
||||
|
||||
awk->sio.arg.name = QSE_NULL;
|
||||
awk->sio.arg.handle = QSE_NULL;
|
||||
awk->sio.arg.b.len = 0;
|
||||
awk->sio.arg.b.pos = 0;
|
||||
QSE_MEMSET (&awk->sio.arg, 0, QSE_SIZEOF(awk->sio.arg));
|
||||
|
||||
CLRERR (awk);
|
||||
op = awk->sio.outf (
|
||||
|
@ -749,8 +749,6 @@ static qse_ssize_t sf_in_open (
|
||||
awk->sio.arg.name = xtn->s.in.x[0].u.file.path;
|
||||
else
|
||||
awk->sio.arg.name = QSE_NULL;
|
||||
awk->sio.arg.line = 1;
|
||||
awk->sio.arg.colm = 1;
|
||||
}
|
||||
|
||||
return x;
|
||||
@ -902,8 +900,6 @@ static qse_ssize_t sf_in_read (
|
||||
awk->sio.arg.name = xtn->s.in.x[next].u.file.path;
|
||||
else
|
||||
awk->sio.arg.name = QSE_NULL;
|
||||
awk->sio.arg.line = 1;
|
||||
awk->sio.arg.colm = 1;
|
||||
|
||||
goto again;
|
||||
}
|
||||
|
@ -62,12 +62,14 @@ qse_sed_t* qse_sed_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
|
||||
qse_sed_t* sed;
|
||||
|
||||
sed = (qse_sed_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_sed_t) + xtnsize);
|
||||
if (sed == QSE_NULL) return QSE_NULL;
|
||||
|
||||
if (qse_sed_init (sed, mmgr) <= -1)
|
||||
if (sed)
|
||||
{
|
||||
QSE_MMGR_FREE (sed->mmgr, sed);
|
||||
return QSE_NULL;
|
||||
if (qse_sed_init (sed, mmgr) <= -1)
|
||||
{
|
||||
QSE_MMGR_FREE (sed->mmgr, sed);
|
||||
return QSE_NULL;
|
||||
}
|
||||
else QSE_MEMSET (QSE_XTN(sed), 0, xtnsize);
|
||||
}
|
||||
|
||||
return sed;
|
||||
|
@ -6,7 +6,7 @@ AM_CPPFLAGS = \
|
||||
-I$(includedir)
|
||||
|
||||
lib_LTLIBRARIES = libqsexli.la
|
||||
libqsexli_la_SOURCES = xli.h xli.c read.c
|
||||
libqsexli_la_SOURCES = xli.h xli.c read.c write.c std.c
|
||||
libqsexli_la_LDFLAGS = -L../cmn -L$(libdir) -version-info 1:0:0 -no-undefined
|
||||
libqsexli_la_LIBADD = -lqsecmn
|
||||
|
||||
|
@ -79,7 +79,7 @@ am__uninstall_files_from_dir = { \
|
||||
am__installdirs = "$(DESTDIR)$(libdir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
libqsexli_la_DEPENDENCIES =
|
||||
am_libqsexli_la_OBJECTS = xli.lo read.lo
|
||||
am_libqsexli_la_OBJECTS = xli.lo read.lo write.lo std.lo
|
||||
libqsexli_la_OBJECTS = $(am_libqsexli_la_OBJECTS)
|
||||
libqsexli_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
@ -282,7 +282,7 @@ AM_CPPFLAGS = \
|
||||
-I$(includedir)
|
||||
|
||||
lib_LTLIBRARIES = libqsexli.la
|
||||
libqsexli_la_SOURCES = xli.h xli.c read.c
|
||||
libqsexli_la_SOURCES = xli.h xli.c read.c write.c std.c
|
||||
libqsexli_la_LDFLAGS = -L../cmn -L$(libdir) -version-info 1:0:0 -no-undefined
|
||||
libqsexli_la_LIBADD = -lqsecmn
|
||||
all: all-am
|
||||
@ -359,8 +359,10 @@ mostlyclean-compile:
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xli.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/std.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/write.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xli.Plo@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
|
@ -21,35 +21,16 @@
|
||||
#include "xli.h"
|
||||
#include <qse/cmn/chr.h>
|
||||
|
||||
#if 0
|
||||
static int open_stream (qse_xli_t* xli)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
xli->errnum = QSE_XLI_ENOERR;
|
||||
n = xli->src.fun (xli, QSE_XLI_IO_OPEN, &xli->src.arg, QSE_NULL, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (xli->errnum == QSE_XLI_ENOERR) xli->errnum = QSE_XLI_EIOUSR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
xli->src.cur = xli->src.buf;
|
||||
xli->src.end = xli->src.buf;
|
||||
xli->src.cc = QSE_CHAR_EOF;
|
||||
xli->src.loc.line = 1;
|
||||
xli->src.loc.colm = 0;
|
||||
|
||||
xli->src.eof = 0;
|
||||
return 0;
|
||||
}
|
||||
static int get_char (qse_xli_t* xli);
|
||||
static int get_token (qse_xli_t* xli);
|
||||
static int read_list (qse_xli_t* xli, qse_xli_list_t* list);
|
||||
|
||||
static int close_stream (qse_xli_t* xli)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
xli->errnum = QSE_XLI_ENOERR;
|
||||
n = xli->src.fun (xli, QSE_XLI_IO_CLOSE, &xli->src.arg, QSE_NULL, 0);
|
||||
n = xli->sio.inf (xli, QSE_XLI_IO_CLOSE, xli->sio.inp, QSE_NULL, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (xli->errnum == QSE_XLI_ENOERR) xli->errnum = QSE_XLI_EIOUSR;
|
||||
@ -59,36 +40,6 @@ static int close_stream (qse_xli_t* xli)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_stream (qse_xli_t* xli)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
xli->errnum = QSE_XLI_ENOERR;
|
||||
n = xli->src.fun (
|
||||
xli, QSE_XLI_IO_READ, &xli->src.arg,
|
||||
xli->src.buf, QSE_COUNTOF(xli->src.buf)
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (xli->errnum == QSE_XLI_ENOERR) xli->errnum = QSE_XLI_EIOUSR;
|
||||
return -1; /* error */
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
/* don't change xli->src.cur and xli->src.end.
|
||||
* they remain the same on eof */
|
||||
xli->src.eof = 1;
|
||||
return 0; /* eof */
|
||||
}
|
||||
|
||||
xli->src.cur = xli->src.buf;
|
||||
xli->src.end = xli->src.buf + n;
|
||||
return 1; /* read something */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
enum tok_t
|
||||
{
|
||||
TOK_EOF,
|
||||
@ -253,8 +204,7 @@ static int classify_ident (qse_xli_t* xli, const qse_cstr_t* name)
|
||||
right = mid - 1;
|
||||
}
|
||||
else if (n < 0) left = mid + 1;
|
||||
|
||||
return kwp->type;
|
||||
else return kwp->type;
|
||||
}
|
||||
|
||||
return TOK_IDENT;
|
||||
@ -307,6 +257,114 @@ static int get_symbols (qse_xli_t* xli, qse_cint_t c, qse_xli_tok_t* tok)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int end_include (qse_xli_t* xli)
|
||||
{
|
||||
int x;
|
||||
qse_xli_io_arg_t* cur;
|
||||
|
||||
if (xli->sio.inp == &xli->sio.arg) return 0; /* no include */
|
||||
|
||||
/* if it is an included file, close it and
|
||||
* retry to read a character from an outer file */
|
||||
|
||||
xli->errnum = QSE_XLI_ENOERR;
|
||||
x = xli->sio.inf (
|
||||
xli, QSE_XLI_IO_CLOSE,
|
||||
xli->sio.inp, QSE_NULL, 0);
|
||||
|
||||
/* if closing has failed, still destroy the
|
||||
* sio structure first as normal and return
|
||||
* the failure below. this way, the caller
|
||||
* does not call QSE_XLI_SIO_CLOSE on
|
||||
* xli->sio.inp again. */
|
||||
|
||||
cur = xli->sio.inp;
|
||||
xli->sio.inp = xli->sio.inp->next;
|
||||
|
||||
QSE_ASSERT (cur->name != QSE_NULL);
|
||||
QSE_MMGR_FREE (xli->mmgr, cur);
|
||||
/* xli->parse.depth.incl--; */
|
||||
|
||||
if (x != 0)
|
||||
{
|
||||
/* the failure mentioned above is returned here */
|
||||
if (xli->errnum == QSE_XLI_ENOERR) xli->errnum = QSE_XLI_EIOUSR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
xli->sio.last = xli->sio.inp->last;
|
||||
return 1; /* ended the included file successfully */
|
||||
}
|
||||
|
||||
static int begin_include (qse_xli_t* xli)
|
||||
{
|
||||
qse_ssize_t op;
|
||||
qse_xli_io_arg_t* arg = QSE_NULL;
|
||||
qse_htb_pair_t* pair = QSE_NULL;
|
||||
|
||||
/* store the file name to xli->sio_names */
|
||||
pair = qse_htb_ensert (
|
||||
xli->sio_names,
|
||||
QSE_STR_PTR(xli->tok.name),
|
||||
QSE_STR_LEN(xli->tok.name) + 1, /* to include '\0' */
|
||||
QSE_NULL, 0
|
||||
);
|
||||
if (pair == QSE_NULL)
|
||||
{
|
||||
#if 0
|
||||
SETERR_LOC (xli, QSE_XLI_ENOMEM, &xli->ptok.loc);
|
||||
#endif
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/*QSE_HTB_VPTR(pair) = QSE_HTB_KPTR(pair);
|
||||
QSE_HTB_VLEN(pair) = QSE_HTB_KLEN(pair);*/
|
||||
|
||||
arg = (qse_xli_io_arg_t*) qse_xli_callocmem (xli, QSE_SIZEOF(*arg));
|
||||
if (arg == QSE_NULL)
|
||||
{
|
||||
#if 0
|
||||
ADJERR_LOC (xli, &xli->ptok.loc);
|
||||
#endif
|
||||
goto oops;
|
||||
}
|
||||
|
||||
arg->flags = QSE_XLI_IO_INCLUDED;
|
||||
arg->name = QSE_HTB_KPTR(pair);
|
||||
arg->line = 1;
|
||||
arg->colm = 1;
|
||||
|
||||
xli->errnum = QSE_XLI_ENOERR;
|
||||
op = xli->sio.inf (xli, QSE_XLI_IO_OPEN, arg, QSE_NULL, 0);
|
||||
if (op <= -1)
|
||||
{
|
||||
if (xli->errnum == QSE_XLI_ENOERR) xli->errnum = QSE_XLI_EIOUSR;
|
||||
goto oops;
|
||||
}
|
||||
|
||||
arg->next = xli->sio.inp;
|
||||
xli->sio.inp = arg;
|
||||
/* xli->parse.depth.incl++; */
|
||||
|
||||
/* read in the first character in the included file.
|
||||
* so the next call to get_token() sees the character read
|
||||
* from this file. */
|
||||
if (get_char (xli) <= -1 || get_token (xli) <= -1)
|
||||
{
|
||||
end_include (xli);
|
||||
/* i don't jump to oops since i've called
|
||||
* end_include() where xli->sio.inp/arg is freed. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
if (arg) QSE_MMGR_FREE (xli->mmgr, arg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int get_token_into (qse_xli_t* xli, qse_xli_tok_t* tok)
|
||||
{
|
||||
qse_cint_t c;
|
||||
@ -330,7 +388,6 @@ retry:
|
||||
|
||||
if (c == QSE_CHAR_EOF)
|
||||
{
|
||||
#if 0
|
||||
n = end_include (xli);
|
||||
if (n <= -1) return -1;
|
||||
if (n >= 1)
|
||||
@ -340,7 +397,6 @@ retry:
|
||||
skip_semicolon_after_include = 1;
|
||||
goto retry;
|
||||
}
|
||||
#endif
|
||||
|
||||
ADD_TOKEN_STR (xli, tok, QSE_T("<EOF>"), 5);
|
||||
SET_TOKEN_TYPE (xli, tok, TOK_EOF);
|
||||
@ -399,10 +455,9 @@ retry:
|
||||
else if (c == QSE_T('\'') || c == QSE_T('\"'))
|
||||
{
|
||||
/* single-quoted string - no escaping */
|
||||
qse_cint_t sc = c;
|
||||
qse_cint_t cc = c;
|
||||
|
||||
SET_TOKEN_TYPE (xli, tok,
|
||||
((sc == QSE_T('\''))? TOK_SQSTR: TOK_DQSTR));
|
||||
SET_TOKEN_TYPE (xli, tok, ((cc == QSE_T('\''))? TOK_SQSTR: TOK_DQSTR));
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -417,7 +472,7 @@ retry:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (c == sc)
|
||||
if (c == cc)
|
||||
{
|
||||
/* terminating quote */
|
||||
GET_CHAR (xli);
|
||||
@ -426,7 +481,6 @@ retry:
|
||||
|
||||
ADD_TOKEN_CHAR (xli, tok, c);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -479,38 +533,198 @@ static int get_token (qse_xli_t* xli)
|
||||
return get_token_into (xli, &xli->tok);
|
||||
}
|
||||
|
||||
static int read_pair (qse_xli_t* xli, qse_xli_list_t* list)
|
||||
{
|
||||
qse_char_t* key = QSE_NULL;
|
||||
qse_char_t* name = QSE_NULL;
|
||||
int got_eq = 0;
|
||||
qse_xli_pair_t* pair;
|
||||
|
||||
key = qse_strdup (QSE_STR_PTR(xli->tok.name), xli->mmgr);
|
||||
if (key == QSE_NULL)
|
||||
{
|
||||
xli->errnum = QSE_XLI_ENOMEM;
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
if (MATCH (xli, TOK_SQSTR) || MATCH(xli, TOK_DQSTR))
|
||||
{
|
||||
name = qse_strdup (QSE_STR_PTR(xli->tok.name), xli->mmgr);
|
||||
if (name == QSE_NULL)
|
||||
{
|
||||
xli->errnum = QSE_XLI_ENOMEM;
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
}
|
||||
|
||||
if (MATCH (xli, TOK_EQ))
|
||||
{
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
got_eq = 1;
|
||||
}
|
||||
|
||||
if (MATCH (xli, TOK_LBRACE))
|
||||
{
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
|
||||
/* TODO: make it optional??? check duplicate entries... */
|
||||
|
||||
/* insert a pair with an empty list */
|
||||
pair = qse_xli_insertpairwithemptylist (xli, list, QSE_NULL, key, name);
|
||||
if (pair == QSE_NULL) goto oops;
|
||||
|
||||
if (read_list (xli, (qse_xli_list_t*)pair->val) <= -1) goto oops;
|
||||
|
||||
if (!MATCH (xli, TOK_RBRACE))
|
||||
{
|
||||
/* TODO: syntax error */
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
|
||||
/* semicolon is optional for a list */
|
||||
if (MATCH (xli, TOK_SEMICOLON))
|
||||
{
|
||||
/* skip the semicolon */
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
}
|
||||
}
|
||||
else if (MATCH (xli, TOK_SQSTR) || MATCH (xli, TOK_DQSTR))
|
||||
{
|
||||
if (!got_eq)
|
||||
{
|
||||
/* TODO: syntax error */
|
||||
goto oops;
|
||||
}
|
||||
|
||||
pair = qse_xli_insertpairwithstr (
|
||||
xli, list, QSE_NULL, key, name,
|
||||
QSE_STR_PTR(xli->tok.name), MATCH (xli, TOK_SQSTR));
|
||||
if (pair == QSE_NULL) goto oops;
|
||||
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
|
||||
/* semicolon is mandatory for a string */
|
||||
if (!MATCH (xli, TOK_SEMICOLON))
|
||||
{
|
||||
/* TODO: syntax error */
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (get_token (xli) <= -1) goto oops;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: syntax error */
|
||||
goto oops;
|
||||
}
|
||||
|
||||
QSE_MMGR_FREE (xli->mmgr, name);
|
||||
QSE_MMGR_FREE (xli->mmgr, key);
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
if (name) QSE_MMGR_FREE (xli->mmgr, name);
|
||||
if (key) QSE_MMGR_FREE (xli->mmgr, key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int read_list (qse_xli_t* xli, qse_xli_list_t* list)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (MATCH (xli, TOK_XINCLUDE))
|
||||
{
|
||||
if (get_token(xli) <= -1) goto oops;
|
||||
|
||||
if (!MATCH(xli,TOK_SQSTR) && !MATCH(xli,TOK_DQSTR))
|
||||
{
|
||||
#if 0
|
||||
SETERR_LOC (xli, QSE_XLI_EINCLSTR, &xli->ptok.loc);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (begin_include (xli) <= -1) goto oops;
|
||||
}
|
||||
else if (MATCH (xli, TOK_IDENT))
|
||||
{
|
||||
if (read_pair (xli, list) <= -1) goto oops;
|
||||
}
|
||||
else if (MATCH (xli, TOK_TEXT))
|
||||
{
|
||||
if (get_token(xli) <= -1) goto oops;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
if (io == QSE_NULL)
|
||||
{
|
||||
xli->errnum = QSE_XLI_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
QSE_MEMSET (&xli->sio, 0, QSE_SIZEOF(xli->sio));
|
||||
xli->sio.inf = io;
|
||||
#if 0
|
||||
if (open_stream (xli) <= -1) return -1;
|
||||
xli->sio.arg.line = 1;
|
||||
xli->sio.arg.colm = 1;
|
||||
xli->sio.inp = &xli->sio.arg;
|
||||
qse_htb_clear (xli->sio_names);
|
||||
|
||||
close_stream (xli);
|
||||
#endif
|
||||
|
||||
do
|
||||
xli->errnum = QSE_XLI_ENOERR;
|
||||
n = xli->sio.inf (xli, QSE_XLI_IO_OPEN, xli->sio.inp, QSE_NULL, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (get_token (xli) <= -1) return -1;
|
||||
if (MATCH (xli, TOK_XINCLUDE))
|
||||
{
|
||||
}
|
||||
else if (MATCH (xli, TOK_IDENT))
|
||||
{
|
||||
}
|
||||
else if (MATCH (xli, TOK_TEXT))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
if (xli->errnum == QSE_XLI_ENOERR) xli->errnum = QSE_XLI_EIOUSR;
|
||||
return -1;
|
||||
}
|
||||
while (1);
|
||||
/* the input stream is open now */
|
||||
|
||||
if (get_char (xli) <= -1 || get_token (xli) <= -1) goto oops;
|
||||
if (read_list (xli, &xli->root) <= -1) goto oops;
|
||||
|
||||
if (!MATCH (xli, TOK_EOF))
|
||||
{
|
||||
/* TODO: set erro code */
|
||||
qse_printf (QSE_T("NOT ENDING WITH EOF... %s\n"), QSE_STR_PTR(xli->tok.name));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
QSE_ASSERT (xli->sio.inp == &xli->sio.arg);
|
||||
close_stream (xli);
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
/* an error occurred and control has reached here
|
||||
* probably, some included files might not have been
|
||||
* closed. close them */
|
||||
while (xli->sio.inp != &xli->sio.arg)
|
||||
{
|
||||
qse_xli_io_arg_t* next;
|
||||
|
||||
/* nothing much to do about a close error */
|
||||
close_stream (xli);
|
||||
|
||||
next = xli->sio.inp->next;
|
||||
QSE_ASSERT (xli->sio.inp->name != QSE_NULL);
|
||||
QSE_MMGR_FREE (xli->mmgr, xli->sio.inp);
|
||||
xli->sio.inp = next;
|
||||
}
|
||||
|
||||
close_stream (xli);
|
||||
return -1;
|
||||
}
|
||||
|
35
qse/lib/xli/write.c
Normal file
35
qse/lib/xli/write.c
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright 2006-2012 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
|
||||
QSE is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
QSE is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "xli.h"
|
||||
|
||||
int qse_xli_write (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
{
|
||||
if (io == QSE_NULL)
|
||||
{
|
||||
xli->errnum = QSE_XLI_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: write data to io stream */
|
||||
xli->errnum = QSE_XLI_ENOIMPL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -25,12 +25,14 @@ qse_xli_t* qse_xli_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
|
||||
qse_xli_t* xli;
|
||||
|
||||
xli = (qse_xli_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_xli_t) + xtnsize);
|
||||
if (xli == QSE_NULL) return QSE_NULL;
|
||||
|
||||
if (qse_xli_init (xli, mmgr) <= -1)
|
||||
if (xli)
|
||||
{
|
||||
QSE_MMGR_FREE (xli->mmgr, xli);
|
||||
return QSE_NULL;
|
||||
if (qse_xli_init (xli, mmgr) <= -1)
|
||||
{
|
||||
QSE_MMGR_FREE (xli->mmgr, xli);
|
||||
return QSE_NULL;
|
||||
}
|
||||
else QSE_MEMSET (QSE_XTN(xli), 0, xtnsize);
|
||||
}
|
||||
|
||||
return xli;
|
||||
@ -53,17 +55,30 @@ int qse_xli_init (qse_xli_t* xli, qse_mmgr_t* mmgr)
|
||||
xli->mmgr = mmgr;
|
||||
|
||||
xli->tok.name = qse_str_open (mmgr, 0, 128);
|
||||
if (xli->tok.name == QSE_NULL)
|
||||
{
|
||||
xli->errnum = QSE_XLI_ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
if (xli->tok.name == QSE_NULL) goto oops;
|
||||
|
||||
xli->sio_names = qse_htb_open (
|
||||
mmgr, QSE_SIZEOF(xli), 128, 70, QSE_SIZEOF(qse_char_t), 1
|
||||
);
|
||||
if (xli->sio_names == QSE_NULL) goto oops;
|
||||
*(qse_xli_t**)QSE_XTN(xli->sio_names) = xli;
|
||||
qse_htb_setmancbs (xli->sio_names,
|
||||
qse_gethtbmancbs(QSE_HTB_MANCBS_INLINE_KEY_COPIER)
|
||||
);
|
||||
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
xli->errnum = QSE_XLI_ENOMEM;
|
||||
if (xli->sio_names) qse_htb_close (xli->sio_names);
|
||||
if (xli->tok.name) qse_str_close (xli->tok.name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void qse_xli_fini (qse_xli_t* xli)
|
||||
{
|
||||
qse_xli_clear (xli);
|
||||
qse_htb_close (xli->sio_names);
|
||||
qse_str_close (xli->tok.name);
|
||||
}
|
||||
|
||||
@ -154,6 +169,7 @@ static void insert_atom (
|
||||
{
|
||||
/* insert it to the tail */
|
||||
atom->prev = parent->tail;
|
||||
if (parent->tail) parent->tail->next = atom;
|
||||
parent->tail = atom;
|
||||
if (parent->head == QSE_NULL) parent->head = atom;
|
||||
}
|
||||
@ -175,7 +191,7 @@ static void insert_atom (
|
||||
}
|
||||
}
|
||||
|
||||
qse_xli_atom_t* qse_xli_insertpair (
|
||||
qse_xli_pair_t* qse_xli_insertpair (
|
||||
qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer,
|
||||
const qse_char_t* key, const qse_char_t* name, qse_xli_val_t* value)
|
||||
{
|
||||
@ -196,17 +212,35 @@ qse_xli_atom_t* qse_xli_insertpair (
|
||||
pair->name = pair->key + klen + 1;
|
||||
pair->val = value; /* this assumes it points to a dynamically allocated atom */
|
||||
|
||||
insert_atom (xli, parent, peer, pair);
|
||||
qse_strcpy (pair->key, key);
|
||||
if (name) qse_strcpy (pair->name, name);
|
||||
|
||||
return (qse_xli_atom_t*)pair;
|
||||
insert_atom (xli, parent, peer, (qse_xli_atom_t*)pair);
|
||||
return pair;
|
||||
}
|
||||
|
||||
qse_xli_atom_t* qse_xli_insertpairwithstr (
|
||||
qse_xli_pair_t* qse_xli_insertpairwithemptylist (
|
||||
qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer,
|
||||
const qse_char_t* key, const qse_char_t* name, const qse_char_t* value)
|
||||
const qse_char_t* key, const qse_char_t* name)
|
||||
{
|
||||
qse_xli_list_t* val;
|
||||
qse_xli_pair_t* tmp;
|
||||
|
||||
val = qse_xli_callocmem (xli, QSE_SIZEOF(*val));
|
||||
if (val == QSE_NULL) return QSE_NULL;
|
||||
|
||||
val->type = QSE_XLI_LIST;
|
||||
tmp = qse_xli_insertpair (xli, parent, peer, key, name, (qse_xli_val_t*)val);
|
||||
if (tmp == QSE_NULL) qse_xli_freemem (xli, val);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
qse_xli_pair_t* qse_xli_insertpairwithstr (
|
||||
qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer,
|
||||
const qse_char_t* key, const qse_char_t* name, const qse_char_t* value, int verbatim)
|
||||
{
|
||||
qse_xli_str_t* val;
|
||||
qse_xli_atom_t* tmp;
|
||||
qse_xli_pair_t* tmp;
|
||||
qse_size_t vlen;
|
||||
|
||||
vlen = qse_strlen (value);
|
||||
@ -216,13 +250,14 @@ qse_xli_atom_t* qse_xli_insertpairwithstr (
|
||||
val->type = QSE_XLI_STR;
|
||||
val->ptr = (const qse_char_t*)(val + 1);
|
||||
val->len = vlen;
|
||||
tmp = qse_xli_insertpair (xli, parent, peer, key, name, val);
|
||||
val->verbatim = verbatim;
|
||||
tmp = qse_xli_insertpair (xli, parent, peer, key, name, (qse_xli_val_t*)val);
|
||||
if (tmp == QSE_NULL) qse_xli_freemem (xli, val);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
qse_xli_atom_t* qse_xli_inserttext (
|
||||
qse_xli_t* xli, qse_xli_atom_t* parent, qse_xli_atom_t* peer, const qse_char_t* str)
|
||||
qse_xli_text_t* qse_xli_inserttext (
|
||||
qse_xli_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer, const qse_char_t* str)
|
||||
{
|
||||
qse_xli_text_t* text;
|
||||
qse_size_t slen;
|
||||
@ -236,21 +271,48 @@ qse_xli_atom_t* qse_xli_inserttext (
|
||||
text->ptr = (const qse_char_t*)(text + 1);
|
||||
text->len = slen;
|
||||
|
||||
insert_atom (xli, parent, peer, text);
|
||||
insert_atom (xli, parent, peer, (qse_xli_atom_t*)text);
|
||||
|
||||
return (qse_xli_atom_t*)text;
|
||||
return text;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
|
||||
int qse_xli_write (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
static void free_list (qse_xli_t* xli, qse_xli_list_t* list);
|
||||
|
||||
static void free_atom (qse_xli_t* xli, qse_xli_atom_t* atom)
|
||||
{
|
||||
/* TODO: write data to io stream */
|
||||
xli->errnum = QSE_XLI_ENOIMPL;
|
||||
return -1;
|
||||
if (atom->type == QSE_XLI_PAIR)
|
||||
{
|
||||
qse_xli_pair_t* pair = (qse_xli_pair_t*)atom;
|
||||
|
||||
if (pair->val->type == QSE_XLI_LIST)
|
||||
free_list (xli, (qse_xli_list_t*)pair->val);
|
||||
|
||||
QSE_MMGR_FREE (xli->mmgr, pair->val);
|
||||
}
|
||||
|
||||
QSE_MMGR_FREE (xli->mmgr, atom);
|
||||
}
|
||||
|
||||
static void free_list (qse_xli_t* xli, qse_xli_list_t* list)
|
||||
{
|
||||
qse_xli_atom_t* p, * n;
|
||||
|
||||
p = list->head;
|
||||
while (p)
|
||||
{
|
||||
n = p->next;
|
||||
free_atom (xli, p);
|
||||
p = n;
|
||||
}
|
||||
|
||||
list->head = QSE_NULL;
|
||||
list->tail = QSE_NULL;
|
||||
}
|
||||
|
||||
void qse_xli_clear (qse_xli_t* xli)
|
||||
{
|
||||
/* TODO: free data under xli->root */
|
||||
free_list (xli, &xli->root);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include <qse/xli/xli.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/htb.h>
|
||||
#include "../cmn/mem.h"
|
||||
|
||||
typedef struct qse_xli_tok_t qse_xli_tok_t;
|
||||
@ -52,11 +53,11 @@ struct qse_xli_t
|
||||
struct
|
||||
{
|
||||
qse_xli_io_impl_t inf; /* input handler */
|
||||
qse_xli_io_lxc_t last;
|
||||
qse_xli_io_arg_t arg; /* for top level */
|
||||
qse_xli_io_arg_t* inp; /* current */
|
||||
|
||||
qse_xli_io_lxc_t last;
|
||||
} sio;
|
||||
qse_htb_t* sio_names;
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user