From e8fb5c194814807b296f44f0a50303788574c8d9 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sat, 29 Aug 2015 13:04:46 +0000 Subject: [PATCH] started writing the ini-style file reader in xli --- qse/cmd/xli/xli.c | 96 +--------------- qse/include/qse/xli/xli.h | 8 ++ qse/lib/xli/Makefile.am | 2 +- qse/lib/xli/Makefile.in | 6 +- qse/lib/xli/read-ini.c | 233 ++++++++++++++++++++++++++++++++++++++ qse/lib/xli/read.c | 73 ++++++------ qse/lib/xli/xli.h | 8 ++ 7 files changed, 292 insertions(+), 134 deletions(-) create mode 100644 qse/lib/xli/read-ini.c diff --git a/qse/cmd/xli/xli.c b/qse/cmd/xli/xli.c index 3a2e053c..4647d8ff 100644 --- a/qse/cmd/xli/xli.c +++ b/qse/cmd/xli/xli.c @@ -409,100 +409,6 @@ static int xli_main (int argc, qse_char_t* argv[]) qse_xli_setopt (xli, QSE_XLI_TRAIT, &g_trait); } -#if 0 -{ - - int i; - static struct - { - const qse_char_t* name; - qse_xli_scm_t scm; - } defs[] = - { - { QSE_T("name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("max-nofile"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("max-nproc"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server-default"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, - { QSE_T("server-default.ssl-cert-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server-default.ssl-key-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server-default.root"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server-default.realm"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, - { QSE_T("server-default.auth"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, - { QSE_T("server-default.index"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 0xFFFF } }, - { QSE_T("server-default.auth-rule"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, - { QSE_T("server-default.auth-rule.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.auth-rule.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.auth-rule.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.auth-rule.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server-default.cgi"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, - { QSE_T("server-default.cgi.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, - { QSE_T("server-default.cgi.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, - { QSE_T("server-default.cgi.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, - { QSE_T("server-default.mime"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, - { QSE_T("server-default.mime.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.mime.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.mime.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.mime.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server-default.dir-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, - { QSE_T("server-default.dir-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.dir-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.dir-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.dir-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server-default.file-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, - { QSE_T("server-default.file-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.file-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.file-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server-default.file-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server-default.dir-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server-default.dir-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server-default.error-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server-default.error-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - - { QSE_T("server"), { QSE_XLI_SCM_VALLIST, 0, 0 } }, - { QSE_T("server.bind"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.ssl"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.ssl-cert-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.ssl-key-file"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.host"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYALIAS, 0, 0 } }, - { QSE_T("server.host.location"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYALIAS, 0, 0 } }, - { QSE_T("server.host.location.root"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.host.location.realm"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, - { QSE_T("server.host.location.auth"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 0, 1 } }, - { QSE_T("server.host.location.index"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 0xFFFF } }, - { QSE_T("server.host.location.auth-rule"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, - { QSE_T("server.host.location.auth-rule.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.auth-rule.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.auth-rule.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.auth-rule.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.host.location.cgi"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, - { QSE_T("server.host.location.cgi.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, - { QSE_T("server.host.location.cgi.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, - { QSE_T("server.host.location.cgi.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 0, 2 } }, - { QSE_T("server.host.location.mime"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, - { QSE_T("server.host.location.mime.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.mime.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.mime.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.mime.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.host.location.dir-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, - { QSE_T("server.host.location.dir-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.dir-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.dir-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.dir-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.host.location.file-access"), { QSE_XLI_SCM_VALLIST | QSE_XLI_SCM_KEYNODUP, 0, 0 } }, - { QSE_T("server.host.location.file-access.prefix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.file-access.suffix"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.file-access.name"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYALIAS, 1, 1 } }, - { QSE_T("server.host.location.file-access.other"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.host.location.dir-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.host.location.dir-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.host.location.error-head"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } }, - { QSE_T("server.host.location.error-foot"), { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 } } - }; - -for (i = 0; i < QSE_COUNTOF(defs); i++) qse_xli_definepair (xli, defs[i].name, &defs[i].scm); - -} -#endif in.type = QSE_XLI_IOSTD_FILE; in.u.file.path = g_input_file; in.u.file.cmgr = g_infile_cmgr; @@ -628,7 +534,7 @@ int qse_main (int argc, qse_achar_t* argv[]) #if defined(_WIN32) char locale[100]; - UINT codepage = GetConsoleOutputCP(); + UINT codepage = GetConsoleOutputCP(); if (codepage == CP_UTF8) { /*SetConsoleOUtputCP (CP_UTF8);*/ diff --git a/qse/include/qse/xli/xli.h b/qse/include/qse/xli/xli.h index febce0f1..7b8b36f7 100644 --- a/qse/include/qse/xli/xli.h +++ b/qse/include/qse/xli/xli.h @@ -721,6 +721,14 @@ QSE_EXPORT int qse_xli_read ( qse_xli_io_impl_t io ); +/* + * The qse_xli_readini() function reads the ini-styled text file. + */ +QSE_EXPORT int qse_xli_readini ( + qse_xli_t* xli, + qse_xli_io_impl_t io +); + QSE_EXPORT int qse_xli_write ( qse_xli_t* xli, qse_xli_io_impl_t io diff --git a/qse/lib/xli/Makefile.am b/qse/lib/xli/Makefile.am index 48a7b465..8a121eaa 100644 --- a/qse/lib/xli/Makefile.am +++ b/qse/lib/xli/Makefile.am @@ -5,7 +5,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include lib_LTLIBRARIES = libqsexli.la -libqsexli_la_SOURCES = xli.h xli.c err.c read.c write.c std.c +libqsexli_la_SOURCES = xli.h xli.c err.c read.c read-ini.c write.c std.c libqsexli_la_LDFLAGS = -L../cmn -version-info 1:0:0 -no-undefined libqsexli_la_LIBADD = -lqsecmn diff --git a/qse/lib/xli/Makefile.in b/qse/lib/xli/Makefile.in index 3909e64f..eae44e22 100644 --- a/qse/lib/xli/Makefile.in +++ b/qse/lib/xli/Makefile.in @@ -126,7 +126,8 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libqsexli_la_DEPENDENCIES = -am_libqsexli_la_OBJECTS = xli.lo err.lo read.lo write.lo std.lo +am_libqsexli_la_OBJECTS = xli.lo err.lo read.lo read-ini.lo write.lo \ + std.lo libqsexli_la_OBJECTS = $(am_libqsexli_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -377,7 +378,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include lib_LTLIBRARIES = libqsexli.la -libqsexli_la_SOURCES = xli.h xli.c err.c read.c write.c std.c +libqsexli_la_SOURCES = xli.h xli.c err.c read.c read-ini.c write.c std.c libqsexli_la_LDFLAGS = -L../cmn -version-info 1:0:0 -no-undefined libqsexli_la_LIBADD = -lqsecmn all: all-am @@ -460,6 +461,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/err.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read-ini.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@ diff --git a/qse/lib/xli/read-ini.c b/qse/lib/xli/read-ini.c new file mode 100644 index 00000000..f29da070 --- /dev/null +++ b/qse/lib/xli/read-ini.c @@ -0,0 +1,233 @@ +/* + * $Id$ + * + Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "xli.h" +#include + +/* + * [SECTION1] + * key1 = value1 + * key2 = value2 + * [SECTION2] + * key1 = value1 + * -------------------------------- + * + * SECTION1 = { + * key1 = value1; + * key2 = value2; + * } + * SECTION2 = { + * key1 = value1; + * } + */ + +#define GET_CHAR(xli) \ + do { if (qse_xli_getchar(xli) <= -1) return -1; } while(0) + +#define GET_CHAR_TO(xli,c) \ + do { \ + if (qse_xli_getchar(xli) <= -1) return -1; \ + c = (xli)->rio.last.c; \ + } while(0) + +#define ADD_TOKEN_CHAR(xli,tok,c) \ + do { \ + if (qse_str_ccat((tok)->name,(c)) == (qse_size_t)-1) \ + { \ + qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); \ + return -1; \ + } \ + } while (0) + +#define ADD_TOKEN_STR(xli,tok,s,l) \ + do { \ + if (qse_str_ncat((tok)->name,(s),(l)) == (qse_size_t)-1) \ + { \ + qse_xli_seterrnum (xli, QSE_XLI_ENOMEM, QSE_NULL); \ + return -1; \ + } \ + } while (0) + + +static int skip_spaces (qse_xli_t* xli) +{ + qse_cint_t c = xli->rio.last.c; + while (QSE_ISSPACE(c)) GET_CHAR_TO (xli, c); + return 0; +} + +static int skip_comment (qse_xli_t* xli, qse_xli_tok_t* tok) +{ + qse_cint_t c = xli->rio.last.c; + + if (c == QSE_T(';')) + { + /* skip up to \n */ + /* TODO: support a different line terminator */ + qse_str_clear (tok->name); + + do + { + GET_CHAR_TO (xli, c); + if (c == QSE_T('\n') || c == QSE_CHAR_EOF) break; + + if (xli->opt.trait & QSE_XLI_KEEPTEXT) ADD_TOKEN_CHAR (xli, tok, c); + } + while (1); + + if ((xli->opt.trait & QSE_XLI_KEEPTEXT) && + qse_xli_inserttext (xli, xli->parlink->list, QSE_NULL, QSE_STR_PTR(tok->name)) == QSE_NULL) return -1; + + GET_CHAR (xli); /* eat the new line letter */ + return 1; /* comment by # */ + } + + return 0; +} + +static int get_token_into (qse_xli_t* xli, qse_xli_tok_t* tok) +{ + qse_cint_t c; + int n; + +/*retry:*/ + do + { + if (skip_spaces (xli) <= -1) return -1; + if ((n = skip_comment (xli, tok)) <= -1) return -1; + } + while (n >= 1); + + qse_str_clear (tok->name); + tok->loc.file = xli->rio.last.file; + tok->loc.line = xli->rio.last.line; + tok->loc.colm = xli->rio.last.colm; + + c = xli->rio.last.c; + + if (c == QSE_CHAR_EOF) + { +#if 0 + n = end_include (xli, 0); + if (n <= -1) return -1; + if (n >= 1) + { + /*xli->rio.last = xli->rio.inp->last;*/ + /* mark that i'm retrying after end of an included file */ + skip_semicolon_after_include = 1; + goto retry; + } + + ADD_TOKEN_STR (xli, tok, QSE_T(""), 5); + SET_TOKEN_TYPE (xli, tok, TOK_EOF); +#endif + } +} + +static int __read_list (qse_xli_t* xli, const qse_xli_scm_t* override) +{ + return 0; +} + +static int read_root_list (qse_xli_t* xli) +{ + qse_xli_list_link_t* link; + + link = qse_xli_makelistlink (xli, &xli->root->list); + if (!link) return -1; + + if (qse_xli_getchar (xli) <= -1 || __read_list (xli, QSE_NULL) <= -1) + { + qse_xli_freelistlink (xli, link); + return -1; + } + + QSE_ASSERT (link == xli->parlink); + qse_xli_freelistlink (xli, link); + + return 0; +} + +int qse_xli_readini (qse_xli_t* xli, qse_xli_io_impl_t io) +{ + if (!io) + { + qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL); + return -1; + } + + QSE_MEMSET (&xli->rio, 0, QSE_SIZEOF(xli->rio)); + xli->rio.impl = io; + xli->rio.top.line = 1; + xli->rio.top.colm = 1; + xli->rio.inp = &xli->rio.top; + + qse_xli_seterrnum (xli, QSE_XLI_ENOERR, QSE_NULL); + qse_xli_clearrionames (xli); + + QSE_ASSERT (QSE_STR_LEN(xli->dotted_curkey) == 0); + + if (qse_xli_openstream (xli, xli->rio.inp) <= -1) return -1; + /* the input stream is open now */ + + if (read_root_list (xli) <= -1) goto oops; + + QSE_ASSERT (xli->parlink == QSE_NULL); + +/* + if (!MATCH (xli, TOK_EOF)) + { + qse_xli_seterror (xli, QSE_XLI_ESYNTAX, QSE_NULL, &xli->tok.loc); + goto oops; + } +*/ + + QSE_ASSERT (xli->rio.inp == &xli->rio.top); + qse_xli_closecurrentstream (xli); + qse_str_clear (xli->tok.name); + return 0; + +oops: + /* an error occurred and control has reached here + * probably, some included files might not have been + * closed. close them */ + while (xli->rio.inp != &xli->rio.top) + { + qse_xli_io_arg_t* prev; + + /* nothing much to do about a close error */ + qse_xli_closecurrentstream (xli); + + prev = xli->rio.inp->prev; + QSE_ASSERT (xli->rio.inp->name != QSE_NULL); + QSE_MMGR_FREE (xli->mmgr, xli->rio.inp); + xli->rio.inp = prev; + } + + qse_xli_closecurrentstream (xli); + qse_str_clear (xli->tok.name); + return -1; +} diff --git a/qse/lib/xli/read.c b/qse/lib/xli/read.c index 561488b4..e8b36af5 100644 --- a/qse/lib/xli/read.c +++ b/qse/lib/xli/read.c @@ -27,7 +27,6 @@ #include "xli.h" #include -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, const qse_xli_scm_t* override); @@ -38,7 +37,22 @@ enum static qse_xli_scm_t scm_val_iffy = { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 }; -static int close_current_stream (qse_xli_t* xli) +int qse_xli_openstream (qse_xli_t* xli, qse_xli_io_arg_t* arg) +{ + qse_ssize_t n; + + n = xli->rio.impl (xli, QSE_XLI_IO_OPEN, arg, QSE_NULL, 0); + if (n <= -1) + { + if (xli->errnum == QSE_XLI_ENOERR) + qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL); + return -1; + } + + return 0; +} + +int qse_xli_closecurrentstream (qse_xli_t* xli) { qse_ssize_t n; @@ -73,11 +87,11 @@ enum tok_t }; #define GET_CHAR(xli) \ - do { if (get_char(xli) <= -1) return -1; } while(0) + do { if (qse_xli_getchar(xli) <= -1) return -1; } while(0) #define GET_CHAR_TO(xli,c) \ do { \ - if (get_char(xli) <= -1) return -1; \ + if (qse_xli_getchar(xli) <= -1) return -1; \ c = (xli)->rio.last.c; \ } while(0) @@ -119,7 +133,7 @@ static kwent_t kwtab[] = { { QSE_T("@include"), 8 }, TOK_XINCLUDE } }; -static int get_char (qse_xli_t* xli) +int qse_xli_getchar (qse_xli_t* xli) { qse_ssize_t n; @@ -351,12 +365,7 @@ static int begin_include (qse_xli_t* xli) /* let the argument's prev point field to the current */ arg->prev = xli->rio.inp; - if (xli->rio.impl (xli, QSE_XLI_IO_OPEN, arg, QSE_NULL, 0) <= -1) - { - if (xli->errnum == QSE_XLI_ENOERR) - qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL); - goto oops; - } + if (qse_xli_openstream(xli, arg) <= -1) goto oops; /* i update the current pointer after opening is successful */ xli->rio.inp = arg; @@ -365,7 +374,7 @@ static int begin_include (qse_xli_t* xli) /* 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) + if (qse_xli_getchar (xli) <= -1 || get_token (xli) <= -1) { end_include (xli, 1); /* i don't jump to oops since i've called @@ -426,7 +435,7 @@ retry: ADD_TOKEN_STR (xli, tok, QSE_T(""), 5); SET_TOKEN_TYPE (xli, tok, TOK_EOF); - } + } else if (c == QSE_T('@')) { /* keyword/directive - start with @ */ @@ -985,7 +994,7 @@ oops: return -1; } -static qse_xli_list_link_t* make_list_link (qse_xli_t* xli, qse_xli_list_t* parlist) +qse_xli_list_link_t* qse_xli_makelistlink (qse_xli_t* xli, qse_xli_list_t* parlist) { qse_xli_list_link_t* link; @@ -999,7 +1008,7 @@ static qse_xli_list_link_t* make_list_link (qse_xli_t* xli, qse_xli_list_t* parl return link; } -static void free_list_link (qse_xli_t* xli, qse_xli_list_link_t* link) +void qse_xli_freelistlink (qse_xli_t* xli, qse_xli_list_link_t* link) { xli->parlink = link->next; qse_xli_freemem (xli, link); @@ -1071,7 +1080,7 @@ static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist, const qse_xli_scm { qse_xli_list_link_t* link; - link = make_list_link (xli, parlist); + link = qse_xli_makelistlink (xli, parlist); if (link == QSE_NULL) return -1; /* get_token() here is to read the token after the left brace. @@ -1079,12 +1088,12 @@ static int read_list (qse_xli_t* xli, qse_xli_list_t* parlist, const qse_xli_scm * in case there are comments at the beginning of the list */ if (get_token (xli) <= -1 || __read_list (xli, override) <= -1) { - free_list_link (xli, link); + qse_xli_freelistlink (xli, link); return -1; } QSE_ASSERT (link == xli->parlink); - free_list_link (xli, link); + qse_xli_freelistlink (xli, link); return 0; } @@ -1093,17 +1102,17 @@ static int read_root_list (qse_xli_t* xli) { qse_xli_list_link_t* link; - link = make_list_link (xli, &xli->root->list); - if (link == QSE_NULL) return -1; + link = qse_xli_makelistlink (xli, &xli->root->list); + if (!link) return -1; - if (get_char (xli) <= -1 || get_token (xli) <= -1 || __read_list (xli, QSE_NULL) <= -1) + if (qse_xli_getchar (xli) <= -1 || get_token (xli) <= -1 || __read_list (xli, QSE_NULL) <= -1) { - free_list_link (xli, link); + qse_xli_freelistlink (xli, link); return -1; } QSE_ASSERT (link == xli->parlink); - free_list_link (xli, link); + qse_xli_freelistlink (xli, link); return 0; } @@ -1121,9 +1130,7 @@ void qse_xli_clearrionames (qse_xli_t* xli) int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io) { - qse_ssize_t n; - - if (io == QSE_NULL) + if (!io) { qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL); return -1; @@ -1140,13 +1147,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io) QSE_ASSERT (QSE_STR_LEN(xli->dotted_curkey) == 0); - n = xli->rio.impl (xli, QSE_XLI_IO_OPEN, xli->rio.inp, QSE_NULL, 0); - if (n <= -1) - { - if (xli->errnum == QSE_XLI_ENOERR) - qse_xli_seterrnum (xli, QSE_XLI_EIOUSR, QSE_NULL); - return -1; - } + if (qse_xli_openstream (xli, xli->rio.inp) <= -1) return -1; /* the input stream is open now */ if (read_root_list (xli) <= -1) goto oops; @@ -1160,7 +1161,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io) } QSE_ASSERT (xli->rio.inp == &xli->rio.top); - close_current_stream (xli); + qse_xli_closecurrentstream (xli); qse_str_clear (xli->tok.name); return 0; @@ -1173,7 +1174,7 @@ oops: qse_xli_io_arg_t* prev; /* nothing much to do about a close error */ - close_current_stream (xli); + qse_xli_closecurrentstream (xli); prev = xli->rio.inp->prev; QSE_ASSERT (xli->rio.inp->name != QSE_NULL); @@ -1181,7 +1182,7 @@ oops: xli->rio.inp = prev; } - close_current_stream (xli); + qse_xli_closecurrentstream (xli); qse_str_clear (xli->tok.name); return -1; } diff --git a/qse/lib/xli/xli.h b/qse/lib/xli/xli.h index 5da00d3b..1cd03983 100644 --- a/qse/lib/xli/xli.h +++ b/qse/lib/xli/xli.h @@ -118,6 +118,14 @@ const qse_char_t* qse_xli_dflerrstr ( void qse_xli_clearrionames (qse_xli_t* xli); void qse_xli_clearwionames (qse_xli_t* xli); + +int qse_xli_getchar (qse_xli_t* xli); +int qse_xli_openstream (qse_xli_t* xli, qse_xli_io_arg_t* arg); +int qse_xli_closecurrentstream (qse_xli_t* xli); + +qse_xli_list_link_t* qse_xli_makelistlink (qse_xli_t* xli, qse_xli_list_t* parlist); +void qse_xli_freelistlink (qse_xli_t* xli, qse_xli_list_link_t* link); + #if defined(__cplusplus) } #endif