changed the structure of qse_xli_str_t. this breaks cmd/httpd/httpd.c

finished the xli output functions mostly
This commit is contained in:
hyung-hwan 2013-06-29 17:01:32 +00:00
parent 8b305fb6a7
commit aeb9b79220
7 changed files with 433 additions and 102 deletions

View File

@ -413,10 +413,10 @@ static int xli_main (int argc, qse_char_t* argv[])
} }
/* TODO: qse_xli_writestd??? */ out.type = QSE_XLI_IOSTD_FILE;
qse_xli_write (xli, QSE_NULL); out.u.file.path = g_output_file? g_output_file: QSE_T("-");
out.u.file.cmgr = g_outfile_cmgr;
ret = 0; ret = qse_xli_writestd (xli, &out);
oops: oops:
if (xli) qse_xli_close (xli); if (xli) qse_xli_close (xli);

View File

@ -133,7 +133,8 @@ struct qse_xli_str_t
{ {
QSE_XLI_VAL_HDR; QSE_XLI_VAL_HDR;
const qse_char_t* ptr; const qse_char_t* ptr;
qse_size_t len; /* take note that qse_strlen(ptr) != len */ qse_size_t len;
qse_xli_str_t* next;
}; };
#define QSE_XLI_ATOM_HDR \ #define QSE_XLI_ATOM_HDR \
@ -533,6 +534,13 @@ QSE_EXPORT qse_size_t qse_xli_getnumpairsbyname (
const qse_char_t* name const qse_char_t* name
); );
QSE_EXPORT qse_xli_str_t* qse_xli_addnextsegtostr (
qse_xli_t* xli,
qse_xli_str_t* str,
const qse_cstr_t* value
);
QSE_EXPORT void qse_xli_clear ( QSE_EXPORT void qse_xli_clear (
qse_xli_t* xli qse_xli_t* xli
); );

View File

@ -29,7 +29,7 @@ static int close_current_stream (qse_xli_t* xli)
{ {
qse_ssize_t n; qse_ssize_t n;
n = xli->sio.impl (xli, QSE_XLI_IO_CLOSE, xli->sio.inp, QSE_NULL, 0); n = xli->rio.impl (xli, QSE_XLI_IO_CLOSE, xli->rio.inp, QSE_NULL, 0);
if (n <= -1) if (n <= -1)
{ {
if (xli->errnum == QSE_XLI_ENOERR) if (xli->errnum == QSE_XLI_ENOERR)
@ -63,7 +63,7 @@ enum tok_t
#define GET_CHAR_TO(xli,c) \ #define GET_CHAR_TO(xli,c) \
do { \ do { \
if (get_char(xli) <= -1) return -1; \ if (get_char(xli) <= -1) return -1; \
c = (xli)->sio.last.c; \ c = (xli)->rio.last.c; \
} while(0) } while(0)
#define ADD_TOKEN_CHAR(xli,tok,c) \ #define ADD_TOKEN_CHAR(xli,tok,c) \
@ -107,11 +107,11 @@ static int get_char (qse_xli_t* xli)
{ {
qse_ssize_t n; qse_ssize_t n;
if (xli->sio.inp->b.pos >= xli->sio.inp->b.len) if (xli->rio.inp->b.pos >= xli->rio.inp->b.len)
{ {
n = xli->sio.impl ( n = xli->rio.impl (
xli, QSE_XLI_IO_READ, xli->sio.inp, xli, QSE_XLI_IO_READ, xli->rio.inp,
xli->sio.inp->b.buf, QSE_COUNTOF(xli->sio.inp->b.buf) xli->rio.inp->b.buf, QSE_COUNTOF(xli->rio.inp->b.buf)
); );
if (n <= -1) if (n <= -1)
{ {
@ -122,47 +122,47 @@ static int get_char (qse_xli_t* xli)
if (n == 0) if (n == 0)
{ {
xli->sio.inp->last.c = QSE_CHAR_EOF; xli->rio.inp->last.c = QSE_CHAR_EOF;
xli->sio.inp->last.line = xli->sio.inp->line; xli->rio.inp->last.line = xli->rio.inp->line;
xli->sio.inp->last.colm = xli->sio.inp->colm; xli->rio.inp->last.colm = xli->rio.inp->colm;
xli->sio.inp->last.file = xli->sio.inp->name; xli->rio.inp->last.file = xli->rio.inp->name;
xli->sio.last = xli->sio.inp->last; xli->rio.last = xli->rio.inp->last;
return 0; return 0;
} }
xli->sio.inp->b.pos = 0; xli->rio.inp->b.pos = 0;
xli->sio.inp->b.len = n; xli->rio.inp->b.len = n;
} }
if (xli->sio.inp->last.c == QSE_T('\n')) if (xli->rio.inp->last.c == QSE_T('\n'))
{ {
/* if the previous charater was a newline, /* if the previous charater was a newline,
* increment the line counter and reset column to 1. * increment the line counter and reset column to 1.
* incrementing it line number here instead of * incrementing it line number here instead of
* updating inp->last causes the line number for * updating inp->last causes the line number for
* TOK_EOF to be the same line as the last newline. */ * TOK_EOF to be the same line as the last newline. */
xli->sio.inp->line++; xli->rio.inp->line++;
xli->sio.inp->colm = 1; xli->rio.inp->colm = 1;
} }
xli->sio.inp->last.c = xli->sio.inp->b.buf[xli->sio.inp->b.pos++]; xli->rio.inp->last.c = xli->rio.inp->b.buf[xli->rio.inp->b.pos++];
xli->sio.inp->last.line = xli->sio.inp->line; xli->rio.inp->last.line = xli->rio.inp->line;
xli->sio.inp->last.colm = xli->sio.inp->colm++; xli->rio.inp->last.colm = xli->rio.inp->colm++;
xli->sio.inp->last.file = xli->sio.inp->name; xli->rio.inp->last.file = xli->rio.inp->name;
xli->sio.last = xli->sio.inp->last; xli->rio.last = xli->rio.inp->last;
return 0; return 0;
} }
static int skip_spaces (qse_xli_t* xli) static int skip_spaces (qse_xli_t* xli)
{ {
qse_cint_t c = xli->sio.last.c; qse_cint_t c = xli->rio.last.c;
while (QSE_ISSPACE(c)) GET_CHAR_TO (xli, c); while (QSE_ISSPACE(c)) GET_CHAR_TO (xli, c);
return 0; return 0;
} }
static int skip_comment (qse_xli_t* xli, qse_xli_tok_t* tok) static int skip_comment (qse_xli_t* xli, qse_xli_tok_t* tok)
{ {
qse_cint_t c = xli->sio.last.c; qse_cint_t c = xli->rio.last.c;
if (c == QSE_T('#')) if (c == QSE_T('#'))
{ {
@ -274,24 +274,24 @@ static int end_include (qse_xli_t* xli, int noeof)
int x; int x;
qse_xli_io_arg_t* cur; qse_xli_io_arg_t* cur;
if (xli->sio.inp == &xli->sio.arg) return 0; /* no include */ if (xli->rio.inp == &xli->rio.top) return 0; /* no include */
/* if it is an included file, close it and /* if it is an included file, close it and
* retry to read a character from an outer file */ * retry to read a character from an outer file */
x = xli->sio.impl ( x = xli->rio.impl (
xli, QSE_XLI_IO_CLOSE, xli, QSE_XLI_IO_CLOSE,
xli->sio.inp, QSE_NULL, 0); xli->rio.inp, QSE_NULL, 0);
/* if closing has failed, still destroy the /* if closing has failed, still destroy the
* sio structure first as normal and return * sio structure first as normal and return
* the failure below. this way, the caller * the failure below. this way, the caller
* does not call QSE_XLI_SIO_CLOSE on * does not call QSE_XLI_SIO_CLOSE on
* xli->sio.inp again. */ * xli->rio.inp again. */
cur = xli->sio.inp; cur = xli->rio.inp;
xli->sio.inp = xli->sio.inp->prev; xli->rio.inp = xli->rio.inp->prev;
QSE_ASSERT (cur->name != QSE_NULL); QSE_ASSERT (cur->name != QSE_NULL);
QSE_MMGR_FREE (xli->mmgr, cur); QSE_MMGR_FREE (xli->mmgr, cur);
@ -308,7 +308,7 @@ static int end_include (qse_xli_t* xli, int noeof)
return -1; return -1;
} }
xli->sio.last = xli->sio.inp->last; xli->rio.last = xli->rio.inp->last;
return 1; /* ended the included file successfully */ return 1; /* ended the included file successfully */
} }
@ -322,8 +322,8 @@ static int begin_include (qse_xli_t* xli)
if (link == QSE_NULL) goto oops; if (link == QSE_NULL) goto oops;
qse_strncpy ((qse_char_t*)(link + 1), QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name)); qse_strncpy ((qse_char_t*)(link + 1), QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name));
link->link = xli->sio_names; link->link = xli->rio_names;
xli->sio_names = link; xli->rio_names = link;
arg = (qse_xli_io_arg_t*) qse_xli_callocmem (xli, QSE_SIZEOF(*arg)); arg = (qse_xli_io_arg_t*) qse_xli_callocmem (xli, QSE_SIZEOF(*arg));
if (arg == QSE_NULL) goto oops; if (arg == QSE_NULL) goto oops;
@ -333,9 +333,9 @@ static int begin_include (qse_xli_t* xli)
arg->colm = 1; arg->colm = 1;
/* let the argument's prev point field to the current */ /* let the argument's prev point field to the current */
arg->prev = xli->sio.inp; arg->prev = xli->rio.inp;
if (xli->sio.impl (xli, QSE_XLI_IO_OPEN, arg, QSE_NULL, 0) <= -1) if (xli->rio.impl (xli, QSE_XLI_IO_OPEN, arg, QSE_NULL, 0) <= -1)
{ {
if (xli->errnum == QSE_XLI_ENOERR) if (xli->errnum == QSE_XLI_ENOERR)
qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL); qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL);
@ -343,7 +343,7 @@ static int begin_include (qse_xli_t* xli)
} }
/* i update the current pointer after opening is successful */ /* i update the current pointer after opening is successful */
xli->sio.inp = arg; xli->rio.inp = arg;
/* xli->parse.depth.incl++; */ /* xli->parse.depth.incl++; */
/* read in the first character in the included file. /* read in the first character in the included file.
@ -353,7 +353,7 @@ static int begin_include (qse_xli_t* xli)
{ {
end_include (xli, 1); end_include (xli, 1);
/* i don't jump to oops since i've called /* i don't jump to oops since i've called
* end_include() where xli->sio.inp/arg is freed. */ * end_include() where xli->rio.inp/arg is freed. */
return -1; return -1;
} }
@ -368,7 +368,7 @@ static int begin_include (qse_xli_t* xli)
oops: oops:
/* i don't need to free 'link' since it's linked to /* i don't need to free 'link' since it's linked to
* xli->sio_names that's freed at the beginning of qse_xli_read() * xli->rio_names that's freed at the beginning of qse_xli_read()
* or by qse_xli_fini() */ * or by qse_xli_fini() */
if (arg) QSE_MMGR_FREE (xli->mmgr, arg); if (arg) QSE_MMGR_FREE (xli->mmgr, arg);
return -1; return -1;
@ -390,11 +390,11 @@ retry:
while (n >= 1); while (n >= 1);
qse_str_clear (tok->name); qse_str_clear (tok->name);
tok->loc.file = xli->sio.last.file; tok->loc.file = xli->rio.last.file;
tok->loc.line = xli->sio.last.line; tok->loc.line = xli->rio.last.line;
tok->loc.colm = xli->sio.last.colm; tok->loc.colm = xli->rio.last.colm;
c = xli->sio.last.c; c = xli->rio.last.c;
if (c == QSE_CHAR_EOF) if (c == QSE_CHAR_EOF)
{ {
@ -402,7 +402,7 @@ retry:
if (n <= -1) return -1; if (n <= -1) return -1;
if (n >= 1) if (n >= 1)
{ {
/*xli->sio.last = xli->sio.inp->last;*/ /*xli->rio.last = xli->rio.inp->last;*/
/* mark that i'm retrying after end of an included file */ /* mark that i'm retrying after end of an included file */
skip_semicolon_after_include = 1; skip_semicolon_after_include = 1;
goto retry; goto retry;
@ -610,11 +610,21 @@ static int read_pair (qse_xli_t* xli)
if (MATCH (xli, TOK_SQSTR) || MATCH (xli, TOK_DQSTR) || MATCH (xli, TOK_IDENT)) if (MATCH (xli, TOK_SQSTR) || MATCH (xli, TOK_DQSTR) || MATCH (xli, TOK_IDENT))
{ {
qse_xli_str_t* curstrseg;
pair = qse_xli_insertpairwithstr (xli, parlist, QSE_NULL, key, name, QSE_STR_CSTR(xli->tok.name));
if (pair == QSE_NULL) goto oops;
curstrseg = (qse_xli_str_t*)pair->val;
#if 0
if (qse_str_ncpy (xli->tmp[0], QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name) + 1) == (qse_size_t)-1) if (qse_str_ncpy (xli->tmp[0], QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name) + 1) == (qse_size_t)-1)
{ {
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
goto oops; goto oops;
} }
#endif
if (get_token (xli) <= -1) goto oops; if (get_token (xli) <= -1) goto oops;
if (MATCH(xli, TOK_COMMA)) if (MATCH(xli, TOK_COMMA))
@ -630,20 +640,28 @@ static int read_pair (qse_xli_t* xli)
goto oops; goto oops;
} }
#if 0
if (qse_str_ncat (xli->tmp[0], QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name) + 1) == (qse_size_t)-1) if (qse_str_ncat (xli->tmp[0], QSE_STR_PTR(xli->tok.name), QSE_STR_LEN(xli->tok.name) + 1) == (qse_size_t)-1)
{ {
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
goto oops; goto oops;
} }
#endif
curstrseg = qse_xli_addnextsegtostr (xli, curstrseg, QSE_STR_CSTR(xli->tok.name));
if (curstrseg == QSE_NULL) goto oops;
if (get_token (xli) <= -1) goto oops; /* skip the value */ if (get_token (xli) <= -1) goto oops; /* skip the value */
} }
while (MATCH (xli, TOK_COMMA)); while (MATCH (xli, TOK_COMMA));
} }
#if 0
pair = qse_xli_insertpairwithstr ( pair = qse_xli_insertpairwithstr (
xli, parlist, QSE_NULL, key, name, QSE_STR_CSTR(xli->tmp[0])); xli, parlist, QSE_NULL, key, name, QSE_STR_CSTR(xli->tmp[0]));
if (pair == QSE_NULL) goto oops; if (pair == QSE_NULL) goto oops;
#endif
/* semicolon is mandatory for a string */ /* semicolon is mandatory for a string */
if (!MATCH (xli, TOK_SEMICOLON)) if (!MATCH (xli, TOK_SEMICOLON))
@ -710,22 +728,33 @@ oops:
return -1; return -1;
} }
static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist) static qse_xli_list_link_t* make_list_link (qse_xli_t* xli, qse_xli_list_t* parlist)
{ {
qse_xli_list_link_t* link = QSE_NULL; qse_xli_list_link_t* link;
link = (qse_xli_list_link_t*) qse_xli_callocmem (xli, QSE_SIZEOF(*link)); link = (qse_xli_list_link_t*) qse_xli_callocmem (xli, QSE_SIZEOF(*link));
if (link == QSE_NULL) goto oops; if (link == QSE_NULL) return QSE_NULL;
link->list = parlist; link->list = parlist;
link->next = xli->parlink; link->next = xli->parlink;
xli->parlink = link; xli->parlink = link;
return link;
}
static void free_list_link (qse_xli_t* xli, qse_xli_list_link_t* link)
{
xli->parlink = link->next;
qse_xli_freemem (xli, link);
}
static int __read_list (qse_xli_t* xli)
{
while (1) while (1)
{ {
if (MATCH (xli, TOK_XINCLUDE)) if (MATCH (xli, TOK_XINCLUDE))
{ {
if (get_token(xli) <= -1) goto oops; if (get_token(xli) <= -1) return -1;
if (!MATCH(xli,TOK_SQSTR) && !MATCH(xli,TOK_DQSTR)) if (!MATCH(xli,TOK_SQSTR) && !MATCH(xli,TOK_DQSTR))
{ {
@ -733,15 +762,15 @@ static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist)
return -1; return -1;
} }
if (begin_include (xli) <= -1) goto oops; if (begin_include (xli) <= -1) return -1;
} }
else if (MATCH (xli, TOK_IDENT)) else if (MATCH (xli, TOK_IDENT))
{ {
if (read_pair (xli) <= -1) goto oops; if (read_pair (xli) <= -1) return -1;
} }
else if (MATCH (xli, TOK_TEXT)) else if (MATCH (xli, TOK_TEXT))
{ {
if (get_token(xli) <= -1) goto oops; if (get_token(xli) <= -1) return -1;
} }
else else
{ {
@ -749,29 +778,54 @@ static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist)
} }
} }
QSE_ASSERT (link == xli->parlink);
xli->parlink = link->next;
qse_xli_freemem (xli, link);
return 0; return 0;
oops:
if (link)
{
QSE_ASSERT (link == xli->parlink);
xli->parlink = link->next;
qse_xli_freemem (xli, link);
}
return -1;
} }
void qse_xli_clearsionames (qse_xli_t* xli) static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist)
{
qse_xli_list_link_t* link;
link = make_list_link (xli, parlist);
if (link == QSE_NULL) return -1;
if (__read_list (xli) <= -1)
{
free_list_link (xli, link);
return -1;
}
QSE_ASSERT (link == xli->parlink);
free_list_link (xli, link);
return 0;
}
static int read_root_list (qse_xli_t* xli)
{
qse_xli_list_link_t* link;
link = make_list_link (xli, &xli->root);
if (link == QSE_NULL) return -1;
if (get_char (xli) <= -1 || get_token (xli) <= -1 || __read_list (xli) <= -1)
{
free_list_link (xli, link);
return -1;
}
QSE_ASSERT (link == xli->parlink);
free_list_link (xli, link);
return 0;
}
void qse_xli_clearrionames (qse_xli_t* xli)
{ {
qse_link_t* cur; qse_link_t* cur;
while (xli->sio_names) while (xli->rio_names)
{ {
cur = xli->sio_names; cur = xli->rio_names;
xli->sio_names = cur->link; xli->rio_names = cur->link;
QSE_MMGR_FREE (xli->mmgr, cur); QSE_MMGR_FREE (xli->mmgr, cur);
} }
} }
@ -786,14 +840,14 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
return -1; return -1;
} }
QSE_MEMSET (&xli->sio, 0, QSE_SIZEOF(xli->sio)); QSE_MEMSET (&xli->rio, 0, QSE_SIZEOF(xli->rio));
xli->sio.impl = io; xli->rio.impl = io;
xli->sio.arg.line = 1; xli->rio.top.line = 1;
xli->sio.arg.colm = 1; xli->rio.top.colm = 1;
xli->sio.inp = &xli->sio.arg; xli->rio.inp = &xli->rio.top;
qse_xli_clearsionames (xli); qse_xli_clearrionames (xli);
n = xli->sio.impl (xli, QSE_XLI_IO_OPEN, xli->sio.inp, QSE_NULL, 0); n = xli->rio.impl (xli, QSE_XLI_IO_OPEN, xli->rio.inp, QSE_NULL, 0);
if (n <= -1) if (n <= -1)
{ {
if (xli->errnum == QSE_XLI_ENOERR) if (xli->errnum == QSE_XLI_ENOERR)
@ -802,8 +856,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
} }
/* the input stream is open now */ /* the input stream is open now */
if (get_char (xli) <= -1 || get_token (xli) <= -1) goto oops; if (read_root_list (xli) <= -1) goto oops;
if (read_list (xli, &xli->root) <= -1) goto oops;
QSE_ASSERT (xli->parlink == QSE_NULL); QSE_ASSERT (xli->parlink == QSE_NULL);
@ -813,7 +866,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
goto oops; goto oops;
} }
QSE_ASSERT (xli->sio.inp == &xli->sio.arg); QSE_ASSERT (xli->rio.inp == &xli->rio.top);
close_current_stream (xli); close_current_stream (xli);
return 0; return 0;
@ -821,17 +874,17 @@ oops:
/* an error occurred and control has reached here /* an error occurred and control has reached here
* probably, some included files might not have been * probably, some included files might not have been
* closed. close them */ * closed. close them */
while (xli->sio.inp != &xli->sio.arg) while (xli->rio.inp != &xli->rio.top)
{ {
qse_xli_io_arg_t* prev; qse_xli_io_arg_t* prev;
/* nothing much to do about a close error */ /* nothing much to do about a close error */
close_current_stream (xli); close_current_stream (xli);
prev = xli->sio.inp->prev; prev = xli->rio.inp->prev;
QSE_ASSERT (xli->sio.inp->name != QSE_NULL); QSE_ASSERT (xli->rio.inp->name != QSE_NULL);
QSE_MMGR_FREE (xli->mmgr, xli->sio.inp); QSE_MMGR_FREE (xli->mmgr, xli->rio.inp);
xli->sio.inp = prev; xli->rio.inp = prev;
} }
close_current_stream (xli); close_current_stream (xli);

View File

@ -143,7 +143,7 @@ static qse_ssize_t sf_in_open (qse_xli_t* xli, qse_xli_io_arg_t* arg, xtn_t* xtn
{ {
qse_xli_iostd_t* psin = xtn->s.in.x; qse_xli_iostd_t* psin = xtn->s.in.x;
QSE_ASSERT (arg == &xli->sio.arg); QSE_ASSERT (arg == &xli->rio.top);
switch (psin->type) switch (psin->type)
{ {
@ -360,6 +360,7 @@ static qse_ssize_t sf_in (
} }
} }
#if 0
static qse_ssize_t sf_out ( static qse_ssize_t sf_out (
qse_xli_t* xli, qse_xli_io_cmd_t cmd, qse_xli_t* xli, qse_xli_io_cmd_t cmd,
qse_xli_io_arg_t* arg, qse_char_t* data, qse_size_t size) qse_xli_io_arg_t* arg, qse_char_t* data, qse_size_t size)
@ -475,6 +476,243 @@ static qse_ssize_t sf_out (
return -1; return -1;
} }
#endif
static qse_ssize_t sf_out_open (qse_xli_t* xli, qse_xli_io_arg_t* arg, xtn_t* xtn)
{
if (arg->prev == QSE_NULL)
{
qse_xli_iostd_t* psout = xtn->s.out.x;
QSE_ASSERT (arg == &xli->wio.top);
switch (psout->type)
{
/* normal source files */
case QSE_XLI_IOSTD_FILE:
if (psout->u.file.path == QSE_NULL ||
(psout->u.file.path[0] == QSE_T('-') &&
psout->u.file.path[1] == QSE_T('\0')))
{
/* no path name or - -> stdout */
arg->handle = open_sio_std (xli, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR);
}
else
{
arg->handle = open_sio (xli, psout->u.file.path, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH);
}
if (arg->handle == QSE_NULL) return -1;
if (psout->u.file.cmgr) qse_sio_setcmgr (arg->handle, psout->u.file.cmgr);
/* update the object name to something more specific */
arg->name = psout->u.file.path;
if (arg->name == QSE_NULL) arg->name = sio_std_names[QSE_SIO_STDOUT].ptr;
return 0;
case QSE_XLI_IOSTD_STR:
xtn->s.out.u.str.buf = qse_str_open (xli->mmgr, 0, 512);
if (xtn->s.out.u.str.buf == QSE_NULL)
{
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
return -1;
}
return 0;
default:
qse_xli_seterrnum (xli, QSE_XLI_EINTERN, QSE_NULL);
return -1;
}
}
else
{
/* handle the included file - @include */
const qse_char_t* path;
qse_char_t fbuf[64];
qse_char_t* dbuf = QSE_NULL;
QSE_ASSERT (arg->name != QSE_NULL);
path = arg->name;
if (arg->prev->handle)
{
const qse_char_t* outer;
outer = qse_sio_getpath (arg->prev->handle);
if (outer)
{
const qse_char_t* base;
/* i'm being included from another file */
base = qse_basename (outer);
if (base != outer && arg->name[0] != QSE_T('/'))
{
qse_size_t tmplen, totlen, dirlen;
dirlen = base - outer;
totlen = qse_strlen(arg->name) + dirlen;
if (totlen >= QSE_COUNTOF(fbuf))
{
dbuf = qse_xli_allocmem (
xli, QSE_SIZEOF(qse_char_t) * (totlen + 1)
);
if (dbuf == QSE_NULL) return -1;
path = dbuf;
}
else path = fbuf;
tmplen = qse_strncpy ((qse_char_t*)path, outer, dirlen);
qse_strcpy ((qse_char_t*)path + tmplen, arg->name);
}
}
}
arg->handle = qse_sio_open (
xli->mmgr, 0, path, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR | QSE_SIO_KEEPPATH
);
if (dbuf) QSE_MMGR_FREE (xli->mmgr, dbuf);
if (arg->handle == QSE_NULL)
{
qse_cstr_t ea;
ea.ptr = arg->name;
ea.len = qse_strlen(ea.ptr);
qse_xli_seterrnum (xli, QSE_XLI_EIOFIL, &ea);
return -1;
}
return 0;
}
}
static qse_ssize_t sf_out_close (
qse_xli_t* xli, qse_xli_io_arg_t* arg, xtn_t* xtn)
{
if (arg->prev == QSE_NULL)
{
switch (xtn->s.out.x->type)
{
case QSE_XLI_IOSTD_FILE:
QSE_ASSERT (arg->handle != QSE_NULL);
qse_sio_close (arg->handle);
break;
case QSE_XLI_IOSTD_STR:
/* nothing to close */
break;
default:
/* nothing to close */
break;
}
}
else
{
/* handle the included source file - @include */
QSE_ASSERT (arg->handle != QSE_NULL);
qse_sio_close (arg->handle);
}
return 0;
}
static qse_ssize_t sf_out_write (
qse_xli_t* xli, qse_xli_io_arg_t* arg,
qse_char_t* data, qse_size_t size, xtn_t* xtn)
{
if (arg->prev == QSE_NULL)
{
qse_ssize_t n;
switch (xtn->s.out.x->type)
{
case QSE_XLI_IOSTD_FILE:
QSE_ASSERT (arg->handle != QSE_NULL);
n = qse_sio_putstrn (arg->handle, data, size);
if (n <= -1)
{
qse_cstr_t ea;
ea.ptr = xtn->s.out.x->u.file.path;
if (ea.ptr == QSE_NULL) ea.ptr = sio_std_names[QSE_SIO_STDOUT].ptr;
ea.len = qse_strlen(ea.ptr);
qse_xli_seterrnum (xli, QSE_XLI_EIOFIL, &ea);
}
break;
case QSE_XLI_IOSTD_STR:
if (size > QSE_TYPE_MAX(qse_ssize_t)) size = QSE_TYPE_MAX(qse_ssize_t);
if (qse_str_ncat (xtn->s.out.u.str.buf, data, size) == (qse_size_t)-1)
{
qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL);
return -1;
}
n = size;
break;
default:
/* this should never happen */
qse_xli_seterrnum (xli, QSE_XLI_EINTERN, QSE_NULL);
n = -1;
break;
}
return n;
}
else
{
/* handle the included source file - @include */
qse_ssize_t n;
QSE_ASSERT (arg->name != QSE_NULL);
QSE_ASSERT (arg->handle != QSE_NULL);
n = qse_sio_putstrn (arg->handle, data, size);
if (n <= -1)
{
qse_cstr_t ea;
ea.ptr = arg->name;
ea.len = qse_strlen(ea.ptr);
qse_xli_seterrnum (xli, QSE_XLI_EIOFIL, &ea);
}
return n;
}
}
static qse_ssize_t sf_out (
qse_xli_t* xli, qse_xli_io_cmd_t cmd,
qse_xli_io_arg_t* arg, qse_char_t* data, qse_size_t size)
{
xtn_t* xtn = QSE_XTN (xli);
QSE_ASSERT (arg != QSE_NULL);
switch (cmd)
{
case QSE_XLI_IO_OPEN:
return sf_out_open (xli, arg, xtn);
case QSE_XLI_IO_CLOSE:
return sf_out_close (xli, arg, xtn);
case QSE_XLI_IO_WRITE:
return sf_out_write (xli, arg, data, size, xtn);
default:
qse_xli_seterrnum (xli, QSE_XLI_EINTERN, QSE_NULL);
return -1;
}
}
int qse_xli_readstd (qse_xli_t* xli, qse_xli_iostd_t* in) int qse_xli_readstd (qse_xli_t* xli, qse_xli_iostd_t* in)
{ {
xtn_t* xtn = (xtn_t*) QSE_XTN (xli); xtn_t* xtn = (xtn_t*) QSE_XTN (xli);

View File

@ -108,12 +108,16 @@ static int close_current_stream (qse_xli_t* xli, int* org_depth)
} }
xli->wio.inp = arg->prev; xli->wio.inp = arg->prev;
if (org_depth) if (arg == &xli->wio.top)
{ {
*org_depth = (arg == &xli->wio.top)? 0: (((arg_data_t*)(arg + 1))->org_depth); if (org_depth) *org_depth = 0;
}
else
{
if (org_depth) *org_depth = ((arg_data_t*)(arg + 1))->org_depth;
qse_xli_freemem (xli, arg);
} }
qse_xli_freemem (xli, arg);
return 0; return 0;
} }
@ -180,7 +184,7 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
qse_xli_str_t* str = (qse_xli_str_t*)pair->val; qse_xli_str_t* str = (qse_xli_str_t*)pair->val;
if (write_to_current_stream (xli, QSE_T(" = \""), 4, 0) <= -1 || if (write_to_current_stream (xli, QSE_T(" = \""), 4, 0) <= -1 ||
write_to_current_stream (xli, str->ptr, str->len, 1) <= -1 || write_to_current_stream (xli, str->ptr, str->len, 1) <= -1 ||
write_to_current_stream (xli, QSE_T("\";"), 2, 0) <= -1) return -1; write_to_current_stream (xli, QSE_T("\";\n"), 3, 0) <= -1) return -1;
break; break;
} }
@ -197,7 +201,14 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
case QSE_XLI_TEXT: case QSE_XLI_TEXT:
{ {
int i;
const qse_char_t* str = ((qse_xli_text_t*)curatom)->ptr; const qse_char_t* str = ((qse_xli_text_t*)curatom)->ptr;
for (i = 0; i < depth; i++)
{
if (write_to_current_stream (xli, QSE_T("\t"), 1, 0) <= -1) return -1;
}
if (write_to_current_stream (xli, QSE_T("#"), 1, 0) <= -1 || if (write_to_current_stream (xli, QSE_T("#"), 1, 0) <= -1 ||
write_to_current_stream (xli, str, qse_strlen(str), 0) <= -1 || write_to_current_stream (xli, str, qse_strlen(str), 0) <= -1 ||
write_to_current_stream (xli, QSE_T("\n"), 1, 0) <= -1) return -1; write_to_current_stream (xli, QSE_T("\n"), 1, 0) <= -1) return -1;
@ -206,11 +217,17 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
case QSE_XLI_FILE: case QSE_XLI_FILE:
{ {
int i;
const qse_char_t* path = ((qse_xli_file_t*)curatom)->path; const qse_char_t* path = ((qse_xli_file_t*)curatom)->path;
for (i = 0; i < depth; i++)
{
if (write_to_current_stream (xli, QSE_T("\t"), 1, 0) <= -1) return -1;
}
if (write_to_current_stream (xli, QSE_T("@include \""), 10, 0) <= -1 || if (write_to_current_stream (xli, QSE_T("@include \""), 10, 0) <= -1 ||
write_to_current_stream (xli, path, qse_strlen(path), 1) <= -1 || write_to_current_stream (xli, path, qse_strlen(path), 1) <= -1 ||
write_to_current_stream (xli, QSE_T("\""), 1, 0) <= -1) return -1; write_to_current_stream (xli, QSE_T("\";\n"), 3, 0) <= -1) return -1;
if (open_new_stream (xli, ((qse_xli_file_t*)curatom)->path, depth) <= -1) return -1; if (open_new_stream (xli, ((qse_xli_file_t*)curatom)->path, depth) <= -1) return -1;
depth = 0; depth = 0;
@ -230,13 +247,11 @@ int qse_xli_write (qse_xli_t* xli, qse_xli_io_impl_t io)
{ {
int n; int n;
#if 0
if (io == QSE_NULL) if (io == QSE_NULL)
{ {
qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL); qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL);
return -1; return -1;
} }
#endif
QSE_MEMSET (&xli->wio, 0, QSE_SIZEOF(xli->wio)); QSE_MEMSET (&xli->wio, 0, QSE_SIZEOF(xli->wio));
xli->wio.impl = io; xli->wio.impl = io;

View File

@ -94,7 +94,7 @@ void qse_xli_fini (qse_xli_t* xli)
if (xli->tmp[--i]) qse_str_close (xli->tmp[i]); if (xli->tmp[--i]) qse_str_close (xli->tmp[i]);
} }
qse_xli_clearsionames (xli); qse_xli_clearrionames (xli);
} }
qse_mmgr_t* qse_xli_getmmgr (qse_xli_t* xli) qse_mmgr_t* qse_xli_getmmgr (qse_xli_t* xli)
@ -286,6 +286,23 @@ qse_xli_pair_t* qse_xli_insertpairwithstr (
return tmp; return tmp;
} }
qse_xli_str_t* qse_xli_addnextsegtostr (
qse_xli_t* xli, qse_xli_str_t* str, const qse_cstr_t* value)
{
qse_xli_str_t* val;
val = qse_xli_callocmem (xli, QSE_SIZEOF(*val) + ((value->len + 1) * QSE_SIZEOF(*value->ptr)));
if (val == QSE_NULL) return QSE_NULL;
val->type = QSE_XLI_STR;
qse_strncpy ((qse_char_t*)(val + 1), value->ptr, value->len);
val->ptr = (const qse_char_t*)(val + 1);
val->len = value->len;
str->next = val;
return str->next;
}
qse_xli_text_t* qse_xli_inserttext ( 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_t* xli, qse_xli_list_t* parent, qse_xli_atom_t* peer, const qse_char_t* str)
{ {

View File

@ -68,10 +68,10 @@ struct qse_xli_t
{ {
qse_xli_io_impl_t impl; /* input handler */ qse_xli_io_impl_t impl; /* input handler */
qse_xli_io_lxc_t last; qse_xli_io_lxc_t last;
qse_xli_io_arg_t arg; /* for top level */ qse_xli_io_arg_t top; /* for top level */
qse_xli_io_arg_t* inp; /* current */ qse_xli_io_arg_t* inp; /* current */
} sio; } rio;
qse_link_t* sio_names; qse_link_t* rio_names;
struct struct
{ {
@ -93,7 +93,7 @@ void qse_xli_fini (qse_xli_t* xli);
const qse_char_t* qse_xli_dflerrstr ( const qse_char_t* qse_xli_dflerrstr (
const qse_xli_t* xli, qse_xli_errnum_t errnum); const qse_xli_t* xli, qse_xli_errnum_t errnum);
void qse_xli_clearsionames (qse_xli_t* xli); void qse_xli_clearrionames (qse_xli_t* xli);
#if defined(__cplusplus) #if defined(__cplusplus)
} }