wrote qse_xli_writeini()
This commit is contained in:
parent
3e1f52baa9
commit
b4a08c4fee
@ -56,6 +56,10 @@
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#define IO_FLAG_INI_INPUT (1 << 0)
|
||||
#define IO_FLAG_INI_OUTPUT (1 << 1)
|
||||
|
||||
static int g_io_flags = 0;
|
||||
static qse_char_t* g_input_file = QSE_NULL;
|
||||
static qse_char_t* g_output_file = QSE_NULL;
|
||||
static qse_char_t* g_lookup_key = QSE_NULL;
|
||||
@ -151,6 +155,8 @@ static void print_usage (qse_sio_t* out, int argc, qse_char_t* argv[])
|
||||
qse_fprintf (out, QSE_T(" --version show version\n"));
|
||||
qse_fprintf (out, QSE_T(" -i file specify an input file\n"));
|
||||
qse_fprintf (out, QSE_T(" -o file specify an output file\n"));
|
||||
qse_fprintf (out, QSE_T(" -I file specify an ini input file\n"));
|
||||
qse_fprintf (out, QSE_T(" -O file specify an ini output file\n"));
|
||||
qse_fprintf (out, QSE_T(" -u disallow duplicate keys\n"));
|
||||
qse_fprintf (out, QSE_T(" -a allow a key alias\n"));
|
||||
qse_fprintf (out, QSE_T(" -f keep file inclusion info\n"));
|
||||
@ -188,9 +194,9 @@ static int handle_args (int argc, qse_char_t* argv[])
|
||||
static qse_opt_t opt =
|
||||
{
|
||||
#if defined(QSE_BUILD_DEBUG)
|
||||
QSE_T("hi:o:uaftsdnlKSvm:X:"),
|
||||
QSE_T("hi:o:I:O:uaftsdnlKSvm:X:"),
|
||||
#else
|
||||
QSE_T("hi:o:uaftsdnlKSvm:"),
|
||||
QSE_T("hi:o:I:O:uaftsdnlKSvm:"),
|
||||
#endif
|
||||
lng
|
||||
};
|
||||
@ -226,10 +232,22 @@ static int handle_args (int argc, qse_char_t* argv[])
|
||||
|
||||
case QSE_T('i'):
|
||||
g_input_file = opt.arg;
|
||||
g_io_flags &= ~IO_FLAG_INI_INPUT;
|
||||
break;
|
||||
|
||||
case QSE_T('I'):
|
||||
g_input_file = opt.arg;
|
||||
g_io_flags |= IO_FLAG_INI_INPUT;
|
||||
break;
|
||||
|
||||
case QSE_T('o'):
|
||||
g_output_file = opt.arg;
|
||||
g_io_flags &= ~IO_FLAG_INI_OUTPUT;
|
||||
break;
|
||||
|
||||
case QSE_T('O'):
|
||||
g_output_file = opt.arg;
|
||||
g_io_flags |= IO_FLAG_INI_OUTPUT;
|
||||
break;
|
||||
|
||||
case QSE_T('u'):
|
||||
@ -368,7 +386,7 @@ static int xli_main (int argc, qse_char_t* argv[])
|
||||
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
|
||||
qse_xli_t* xli = QSE_NULL;
|
||||
qse_xli_iostd_t in, out;
|
||||
int ret = -1;
|
||||
int ret = -1, n;
|
||||
|
||||
ret = handle_args (argc, argv);
|
||||
if (ret <= -1) return -1;
|
||||
@ -413,7 +431,8 @@ static int xli_main (int argc, qse_char_t* argv[])
|
||||
in.u.file.path = g_input_file;
|
||||
in.u.file.cmgr = g_infile_cmgr;
|
||||
|
||||
if (qse_xli_readinistd (xli, &in) <= -1)
|
||||
n = (g_io_flags & IO_FLAG_INI_INPUT)? qse_xli_readinistd(xli, &in): qse_xli_readstd(xli, &in);
|
||||
if (n <= -1)
|
||||
{
|
||||
const qse_xli_loc_t* errloc;
|
||||
|
||||
@ -506,7 +525,8 @@ static int xli_main (int argc, qse_char_t* argv[])
|
||||
out.type = QSE_XLI_IOSTD_FILE;
|
||||
out.u.file.path = g_output_file? g_output_file: QSE_T("-");
|
||||
out.u.file.cmgr = g_outfile_cmgr;
|
||||
ret = qse_xli_writestd (xli, &out);
|
||||
|
||||
ret = (g_io_flags & IO_FLAG_INI_OUTPUT)? qse_xli_writeinistd(xli, &out): qse_xli_writestd(xli, &out);
|
||||
|
||||
oops:
|
||||
if (xli) qse_xli_close (xli);
|
||||
|
@ -471,7 +471,7 @@ int qse_xli_readini (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
|
||||
QSE_ASSERT (QSE_STR_LEN(xli->dotted_curkey) == 0);
|
||||
|
||||
if (qse_xli_openstream (xli, xli->rio.inp) <= -1) return -1;
|
||||
if (qse_xli_openrstream (xli, xli->rio.inp) <= -1) return -1;
|
||||
/* the input stream is open now */
|
||||
|
||||
if (read_root_list (xli) <= -1) goto oops;
|
||||
@ -483,7 +483,7 @@ int qse_xli_readini (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
}
|
||||
|
||||
QSE_ASSERT (xli->rio.inp == &xli->rio.top);
|
||||
qse_xli_closecurrentstream (xli);
|
||||
qse_xli_closeactiverstream (xli);
|
||||
qse_str_clear (xli->tok.name);
|
||||
return 0;
|
||||
|
||||
@ -496,7 +496,7 @@ oops:
|
||||
qse_xli_io_arg_t* prev;
|
||||
|
||||
/* nothing much to do about a close error */
|
||||
qse_xli_closecurrentstream (xli);
|
||||
qse_xli_closeactiverstream (xli);
|
||||
|
||||
prev = xli->rio.inp->prev;
|
||||
QSE_ASSERT (xli->rio.inp->name != QSE_NULL);
|
||||
@ -504,7 +504,7 @@ oops:
|
||||
xli->rio.inp = prev;
|
||||
}
|
||||
|
||||
qse_xli_closecurrentstream (xli);
|
||||
qse_xli_closeactiverstream (xli);
|
||||
qse_str_clear (xli->tok.name);
|
||||
return -1;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ enum
|
||||
|
||||
static qse_xli_scm_t scm_val_iffy = { QSE_XLI_SCM_VALSTR | QSE_XLI_SCM_KEYNODUP, 1, 1 };
|
||||
|
||||
int qse_xli_openstream (qse_xli_t* xli, qse_xli_io_arg_t* arg)
|
||||
int qse_xli_openrstream (qse_xli_t* xli, qse_xli_io_arg_t* arg)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
@ -52,7 +52,7 @@ int qse_xli_openstream (qse_xli_t* xli, qse_xli_io_arg_t* arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_xli_closecurrentstream (qse_xli_t* xli)
|
||||
int qse_xli_closeactiverstream (qse_xli_t* xli)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
@ -67,8 +67,6 @@ int qse_xli_closecurrentstream (qse_xli_t* xli)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define GET_CHAR(xli) \
|
||||
do { if (qse_xli_getchar(xli) <= -1) return -1; } while(0)
|
||||
|
||||
@ -402,7 +400,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 (qse_xli_openstream(xli, arg) <= -1) goto oops;
|
||||
if (qse_xli_openrstream(xli, arg) <= -1) goto oops;
|
||||
|
||||
/* i update the current pointer after opening is successful */
|
||||
xli->rio.inp = arg;
|
||||
@ -1186,7 +1184,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
|
||||
QSE_ASSERT (QSE_STR_LEN(xli->dotted_curkey) == 0);
|
||||
|
||||
if (qse_xli_openstream (xli, xli->rio.inp) <= -1) return -1;
|
||||
if (qse_xli_openrstream (xli, xli->rio.inp) <= -1) return -1;
|
||||
/* the input stream is open now */
|
||||
|
||||
if (read_root_list (xli) <= -1) goto oops;
|
||||
@ -1200,7 +1198,7 @@ int qse_xli_read (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
}
|
||||
|
||||
QSE_ASSERT (xli->rio.inp == &xli->rio.top);
|
||||
qse_xli_closecurrentstream (xli);
|
||||
qse_xli_closeactiverstream (xli);
|
||||
qse_str_clear (xli->tok.name);
|
||||
return 0;
|
||||
|
||||
@ -1213,7 +1211,7 @@ oops:
|
||||
qse_xli_io_arg_t* prev;
|
||||
|
||||
/* nothing much to do about a close error */
|
||||
qse_xli_closecurrentstream (xli);
|
||||
qse_xli_closeactiverstream (xli);
|
||||
|
||||
prev = xli->rio.inp->prev;
|
||||
QSE_ASSERT (xli->rio.inp->name != QSE_NULL);
|
||||
@ -1221,7 +1219,7 @@ oops:
|
||||
xli->rio.inp = prev;
|
||||
}
|
||||
|
||||
qse_xli_closecurrentstream (xli);
|
||||
qse_xli_closeactiverstream (xli);
|
||||
qse_str_clear (xli->tok.name);
|
||||
return -1;
|
||||
}
|
||||
|
@ -26,7 +26,154 @@
|
||||
|
||||
#include "xli.h"
|
||||
|
||||
static int write_to_current_stream (qse_xli_t* xli, const qse_char_t* ptr, qse_size_t len)
|
||||
{
|
||||
qse_xli_io_arg_t* arg;
|
||||
qse_size_t i;
|
||||
|
||||
arg = xli->wio.inp;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (arg->b.len + 1 > QSE_COUNTOF(arg->b.buf) && qse_xli_flushwstream (xli, arg) <= -1) return -1;
|
||||
arg->b.buf[arg->b.len++] = ptr[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
|
||||
{
|
||||
qse_xli_atom_t* curatom;
|
||||
|
||||
for (curatom = list->head; curatom; curatom = curatom->next)
|
||||
{
|
||||
switch (curatom->type)
|
||||
{
|
||||
case QSE_XLI_PAIR:
|
||||
{
|
||||
qse_xli_pair_t* pair = (qse_xli_pair_t*)curatom;
|
||||
|
||||
if (pair->tag)
|
||||
{
|
||||
/* the tag can't be written. so ignore it */
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
if (depth <= 0)
|
||||
{
|
||||
if (write_to_current_stream (xli, QSE_T("["), 1) <= -1 ||
|
||||
write_to_current_stream (xli, pair->key, qse_strlen(pair->key)) <= -1 ||
|
||||
write_to_current_stream (xli, QSE_T("]\n"), 2) <= -1) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (write_to_current_stream (xli, pair->key, qse_strlen(pair->key)) <= -1) return -1;
|
||||
}
|
||||
|
||||
if (pair->alias)
|
||||
{
|
||||
/* no alias is supported. so ignore it */
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
switch (pair->val->type)
|
||||
{
|
||||
case QSE_XLI_NIL:
|
||||
if (write_to_current_stream (xli, QSE_T("\n"), 1) <= -1) return -1;
|
||||
break;
|
||||
|
||||
case QSE_XLI_STR:
|
||||
{
|
||||
qse_xli_str_t* str = (qse_xli_str_t*)pair->val;
|
||||
|
||||
if (depth > 0)
|
||||
{
|
||||
/* key = value is not supported at the top level */
|
||||
|
||||
if (write_to_current_stream (xli, QSE_T(" = "), 3) <= -1) return -1;
|
||||
while (1)
|
||||
{
|
||||
if (str->tag)
|
||||
{
|
||||
/* no string tag is supported. ignore it */
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
if (write_to_current_stream (xli, str->ptr, str->len) <= -1) return -1;
|
||||
|
||||
#if 0
|
||||
if (!str->next) break;
|
||||
|
||||
if (write_to_current_stream (xli, QSE_T(", "), 2) <= -1) return -1;
|
||||
str = str->next;
|
||||
#else
|
||||
/* no multi-segment string is supported. ignore it */
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (write_to_current_stream (xli, QSE_T("\n"), 1) <= -1) return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_XLI_LIST:
|
||||
if (write_list (xli, (qse_xli_list_t*)pair->val, depth + 1) <= -1) return -1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_XLI_TEXT:
|
||||
{
|
||||
const qse_char_t* str = ((qse_xli_text_t*)curatom)->ptr;
|
||||
|
||||
if (write_to_current_stream (xli, QSE_T(";"), 1) <= -1 ||
|
||||
write_to_current_stream (xli, str, qse_strlen(str)) <= -1 ||
|
||||
write_to_current_stream (xli, QSE_T("\n"), 1) <= -1) return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_XLI_FILE:
|
||||
/* no file inclusion is supported by the ini-format. ignore it */
|
||||
break;
|
||||
|
||||
case QSE_XLI_EOF:
|
||||
/* no file inclusion is supported by the ini-format. so no EOF. ignore it */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_xli_writeini (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
{
|
||||
return -1;
|
||||
int n;
|
||||
|
||||
if (io == QSE_NULL)
|
||||
{
|
||||
qse_xli_seterrnum (xli, QSE_XLI_EINVAL, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
QSE_MEMSET (&xli->wio, 0, QSE_SIZEOF(xli->wio));
|
||||
xli->wio.impl = io;
|
||||
xli->wio.inp = &xli->wio.top;
|
||||
|
||||
qse_xli_seterrnum (xli, QSE_XLI_ENOERR, QSE_NULL);
|
||||
qse_xli_clearwionames (xli);
|
||||
|
||||
/* open the top level stream */
|
||||
if (qse_xli_openwstream (xli, QSE_NULL, 0) <= -1) return -1;
|
||||
|
||||
/* begin writing the root list */
|
||||
n = write_list (xli, &xli->root->list, 0);
|
||||
|
||||
/* close all open streams. there should be only the
|
||||
* top-level stream here if there occurred no errors */
|
||||
while (xli->wio.inp) qse_xli_closeactivewstream (xli, QSE_NULL);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ struct arg_data_t
|
||||
int org_depth;
|
||||
};
|
||||
|
||||
static int flush (qse_xli_t* xli, qse_xli_io_arg_t* arg)
|
||||
int qse_xli_flushwstream (qse_xli_t* xli, qse_xli_io_arg_t* arg)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
@ -54,7 +54,7 @@ static int flush (qse_xli_t* xli, qse_xli_io_arg_t* arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_new_stream (qse_xli_t* xli, const qse_char_t* path, int old_depth)
|
||||
int qse_xli_openwstream (qse_xli_t* xli, const qse_char_t* path, int old_depth)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
qse_xli_io_arg_t* arg;
|
||||
@ -107,14 +107,14 @@ static int open_new_stream (qse_xli_t* xli, const qse_char_t* path, int old_dept
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int close_current_stream (qse_xli_t* xli, int* org_depth)
|
||||
int qse_xli_closeactivewstream (qse_xli_t* xli, int* org_depth)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
qse_xli_io_arg_t* arg;
|
||||
|
||||
arg = xli->wio.inp;
|
||||
|
||||
flush (xli, arg); /* TODO: do i have to care about the result? */
|
||||
qse_xli_flushwstream (xli, arg); /* TODO: do i have to care about the result? */
|
||||
|
||||
n = xli->wio.impl (xli, QSE_XLI_IO_CLOSE, arg, QSE_NULL, 0);
|
||||
if (n <= -1)
|
||||
@ -149,12 +149,12 @@ static int write_to_current_stream (qse_xli_t* xli, const qse_char_t* ptr, qse_s
|
||||
{
|
||||
if (escape && (ptr[i] == QSE_T('\\') || ptr[i] == QSE_T('\"')))
|
||||
{
|
||||
if (arg->b.len + 2 > QSE_COUNTOF(arg->b.buf) && flush (xli, arg) <= -1) return -1;
|
||||
if (arg->b.len + 2 > QSE_COUNTOF(arg->b.buf) && qse_xli_flushwstream (xli, arg) <= -1) return -1;
|
||||
arg->b.buf[arg->b.len++] = QSE_T('\\');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (arg->b.len + 1 > QSE_COUNTOF(arg->b.buf) && flush (xli, arg) <= -1) return -1;
|
||||
if (arg->b.len + 1 > QSE_COUNTOF(arg->b.buf) && qse_xli_flushwstream (xli, arg) <= -1) return -1;
|
||||
}
|
||||
arg->b.buf[arg->b.len++] = ptr[i];
|
||||
}
|
||||
@ -292,13 +292,13 @@ static int write_list (qse_xli_t* xli, qse_xli_list_t* list, int depth)
|
||||
write_to_current_stream (xli, path, qse_strlen(path), 1) <= -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 (qse_xli_openwstream (xli, ((qse_xli_file_t*)curatom)->path, depth) <= -1) return -1;
|
||||
depth = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case QSE_XLI_EOF:
|
||||
if (close_current_stream (xli, &depth) <= -1) return -1;
|
||||
if (qse_xli_closeactivewstream (xli, &depth) <= -1) return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -335,14 +335,14 @@ int qse_xli_write (qse_xli_t* xli, qse_xli_io_impl_t io)
|
||||
qse_xli_clearwionames (xli);
|
||||
|
||||
/* open the top level stream */
|
||||
if (open_new_stream (xli, QSE_NULL, 0) <= -1) return -1;
|
||||
if (qse_xli_openwstream (xli, QSE_NULL, 0) <= -1) return -1;
|
||||
|
||||
/* begin writing the root list */
|
||||
n = write_list (xli, &xli->root->list, 0);
|
||||
|
||||
/* close all open streams. there should be only the
|
||||
* top-level stream here if there occurred no errors */
|
||||
while (xli->wio.inp) close_current_stream (xli, QSE_NULL);
|
||||
while (xli->wio.inp) qse_xli_closeactivewstream (xli, QSE_NULL);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -140,8 +140,12 @@ 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);
|
||||
int qse_xli_openrstream (qse_xli_t* xli, qse_xli_io_arg_t* arg);
|
||||
int qse_xli_closeactiverstream (qse_xli_t* xli);
|
||||
|
||||
int qse_xli_openwstream (qse_xli_t* xli, const qse_char_t* path, int old_depth);
|
||||
int qse_xli_closeactivewstream (qse_xli_t* xli, int* org_depth);
|
||||
int qse_xli_flushwstream (qse_xli_t* xli, qse_xli_io_arg_t* arg);
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user