added more code to xli

This commit is contained in:
2013-02-06 14:31:32 +00:00
parent ee2d918538
commit 60255caf39
23 changed files with 1523 additions and 179 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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"),

View File

@ -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 (

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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 $@ $<

View File

@ -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
View 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;
}

View File

@ -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);
}

View File

@ -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;
};