added qse_sed_io_std_t and related code
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: err.c 441 2011-04-22 14:28:43Z hyunghwan.chung $
|
||||
* $Id: err.c 568 2011-09-17 15:41:26Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -25,10 +25,9 @@ const qse_char_t* qse_awk_dflerrstr (qse_awk_t* awk, qse_awk_errnum_t errnum)
|
||||
static const qse_char_t* errstr[] =
|
||||
{
|
||||
QSE_T("no error"),
|
||||
QSE_T("unknown error"),
|
||||
|
||||
QSE_T("invalid parameter or data"),
|
||||
QSE_T("insufficient memory"),
|
||||
QSE_T("invalid parameter or data"),
|
||||
QSE_T("not supported"),
|
||||
QSE_T("operation not allowed"),
|
||||
QSE_T("'${0}' not found"),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sio.c 566 2011-09-11 12:44:56Z hyunghwan.chung $
|
||||
* $Id: sio.c 568 2011-09-17 15:41:26Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -39,6 +39,7 @@ static qse_sio_t __sio_in =
|
||||
{
|
||||
QSE_NULL, /* mmgr */
|
||||
0, /* errnum */
|
||||
|
||||
#if defined(_WIN32)
|
||||
(HANDLE)STD_INPUT_HANDLE, /* handle */
|
||||
#elif defined(__OS2__)
|
||||
@ -48,6 +49,7 @@ static qse_sio_t __sio_in =
|
||||
#else
|
||||
0, /* handle */
|
||||
#endif
|
||||
|
||||
0, /* flags */
|
||||
QSE_NULL /* tio */
|
||||
},
|
||||
@ -81,6 +83,7 @@ static qse_sio_t __sio_out =
|
||||
{
|
||||
QSE_NULL,
|
||||
0,
|
||||
|
||||
#if defined(_WIN32)
|
||||
(HANDLE)STD_OUTPUT_HANDLE,
|
||||
#elif defined(__OS2__)
|
||||
@ -90,6 +93,7 @@ static qse_sio_t __sio_out =
|
||||
#else
|
||||
1,
|
||||
#endif
|
||||
|
||||
0,
|
||||
QSE_NULL
|
||||
},
|
||||
@ -123,6 +127,7 @@ static qse_sio_t __sio_err =
|
||||
{
|
||||
QSE_NULL,
|
||||
0,
|
||||
|
||||
#if defined(_WIN32)
|
||||
(HANDLE)STD_ERROR_HANDLE,
|
||||
#elif defined(__OS2__)
|
||||
@ -132,6 +137,7 @@ static qse_sio_t __sio_err =
|
||||
#else
|
||||
2,
|
||||
#endif
|
||||
|
||||
0,
|
||||
QSE_NULL
|
||||
},
|
||||
|
@ -27,6 +27,7 @@ const qse_char_t* qse_cut_dflerrstr (qse_cut_t* cut, qse_cut_errnum_t errnum)
|
||||
{
|
||||
QSE_T("no error"),
|
||||
QSE_T("insufficient memory"),
|
||||
QSE_T("invalid parameter or data"),
|
||||
QSE_T("selector not valid"),
|
||||
QSE_T("io error with file '${0}'"),
|
||||
QSE_T("error returned by user io handler")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: err.c 562 2011-09-07 15:36:08Z hyunghwan.chung $
|
||||
* $Id: err.c 568 2011-09-17 15:41:26Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -27,6 +27,7 @@ const qse_char_t* qse_sed_dflerrstr (qse_sed_t* sed, qse_sed_errnum_t errnum)
|
||||
{
|
||||
QSE_T("no error"),
|
||||
QSE_T("insufficient memory"),
|
||||
QSE_T("invalid parameter or data"),
|
||||
QSE_T("command '${0}' not recognized"),
|
||||
QSE_T("command code missing"),
|
||||
QSE_T("command '${0}' incomplete"),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sed.c 567 2011-09-14 15:48:08Z hyunghwan.chung $
|
||||
* $Id: sed.c 568 2011-09-17 15:41:26Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -103,7 +103,7 @@ int qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
||||
);
|
||||
|
||||
if (qse_str_init (&sed->e.txt.appended, mmgr, 256) <= -1) goto oops_5;
|
||||
if (qse_str_init (&sed->e.txt.held, mmgr, 256) <= -1) goto oops_6;
|
||||
if (qse_str_init (&sed->e.txt.hold, mmgr, 256) <= -1) goto oops_6;
|
||||
if (qse_str_init (&sed->e.txt.subst, mmgr, 256) <= -1) goto oops_7;
|
||||
|
||||
/* on init, the last points to the first */
|
||||
@ -114,7 +114,7 @@ int qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
||||
return 0;
|
||||
|
||||
oops_7:
|
||||
qse_str_fini (&sed->e.txt.held);
|
||||
qse_str_fini (&sed->e.txt.hold);
|
||||
oops_6:
|
||||
qse_str_fini (&sed->e.txt.appended);
|
||||
oops_5:
|
||||
@ -133,7 +133,7 @@ void qse_sed_fini (qse_sed_t* sed)
|
||||
free_all_command_blocks (sed);
|
||||
|
||||
qse_str_fini (&sed->e.txt.subst);
|
||||
qse_str_fini (&sed->e.txt.held);
|
||||
qse_str_fini (&sed->e.txt.hold);
|
||||
qse_str_fini (&sed->e.txt.appended);
|
||||
|
||||
qse_map_fini (&sed->tmp.labs);
|
||||
@ -1817,6 +1817,7 @@ static int flush (qse_sed_t* sed)
|
||||
while (sed->e.out.len > 0)
|
||||
{
|
||||
sed->errnum = QSE_SED_ENOERR;
|
||||
|
||||
n = sed->e.out.fun (
|
||||
sed, QSE_SED_IO_WRITE, &sed->e.out.arg,
|
||||
&sed->e.out.buf[pos], sed->e.out.len);
|
||||
@ -2694,7 +2695,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
|
||||
case QSE_SED_CMD_HOLD:
|
||||
/* copy the pattern space to the hold space */
|
||||
if (qse_str_ncpy (&sed->e.txt.held,
|
||||
if (qse_str_ncpy (&sed->e.txt.hold,
|
||||
QSE_STR_PTR(&sed->e.in.line),
|
||||
QSE_STR_LEN(&sed->e.in.line)) == (qse_size_t)-1)
|
||||
{
|
||||
@ -2705,7 +2706,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
|
||||
case QSE_SED_CMD_HOLD_APPEND:
|
||||
/* append the pattern space to the hold space */
|
||||
if (qse_str_ncat (&sed->e.txt.held,
|
||||
if (qse_str_ncat (&sed->e.txt.hold,
|
||||
QSE_STR_PTR(&sed->e.in.line),
|
||||
QSE_STR_LEN(&sed->e.in.line)) == (qse_size_t)-1)
|
||||
{
|
||||
@ -2717,8 +2718,8 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
case QSE_SED_CMD_RELEASE:
|
||||
/* copy the hold space to the pattern space */
|
||||
if (qse_str_ncpy (&sed->e.in.line,
|
||||
QSE_STR_PTR(&sed->e.txt.held),
|
||||
QSE_STR_LEN(&sed->e.txt.held)) == (qse_size_t)-1)
|
||||
QSE_STR_PTR(&sed->e.txt.hold),
|
||||
QSE_STR_LEN(&sed->e.txt.hold)) == (qse_size_t)-1)
|
||||
{
|
||||
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
|
||||
return QSE_NULL;
|
||||
@ -2728,8 +2729,8 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
case QSE_SED_CMD_RELEASE_APPEND:
|
||||
/* append the hold space to the pattern space */
|
||||
if (qse_str_ncat (&sed->e.in.line,
|
||||
QSE_STR_PTR(&sed->e.txt.held),
|
||||
QSE_STR_LEN(&sed->e.txt.held)) == (qse_size_t)-1)
|
||||
QSE_STR_PTR(&sed->e.txt.hold),
|
||||
QSE_STR_LEN(&sed->e.txt.hold)) == (qse_size_t)-1)
|
||||
{
|
||||
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
|
||||
return QSE_NULL;
|
||||
@ -2738,7 +2739,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
|
||||
case QSE_SED_CMD_EXCHANGE:
|
||||
/* exchange the pattern space and the hold space */
|
||||
qse_str_swap (&sed->e.in.line, &sed->e.txt.held);
|
||||
qse_str_swap (&sed->e.in.line, &sed->e.txt.hold);
|
||||
break;
|
||||
|
||||
case QSE_SED_CMD_NEXT:
|
||||
@ -3042,8 +3043,8 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
|
||||
sed->e.subst_done = 0;
|
||||
qse_str_clear (&sed->e.txt.appended);
|
||||
qse_str_clear (&sed->e.txt.subst);
|
||||
qse_str_clear (&sed->e.txt.held);
|
||||
if (qse_str_ccat (&sed->e.txt.held, QSE_T('\n')) == (qse_size_t)-1)
|
||||
qse_str_clear (&sed->e.txt.hold);
|
||||
if (qse_str_ccat (&sed->e.txt.hold, QSE_T('\n')) == (qse_size_t)-1)
|
||||
{
|
||||
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
|
||||
return -1;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sed.h 564 2011-09-10 16:14:38Z hyunghwan.chung $
|
||||
* $Id: sed.h 568 2011-09-17 15:41:26Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -262,7 +262,7 @@ struct qse_sed_t
|
||||
struct
|
||||
{
|
||||
qse_str_t appended;
|
||||
qse_str_t held;
|
||||
qse_str_t hold; /* hold space */
|
||||
qse_str_t subst;
|
||||
} txt;
|
||||
|
||||
|
@ -26,8 +26,15 @@
|
||||
|
||||
struct xtn_t
|
||||
{
|
||||
const qse_char_t* infile;
|
||||
const qse_char_t* outfile;
|
||||
struct
|
||||
{
|
||||
qse_sed_iostd_t* in;
|
||||
qse_sed_iostd_t* out;
|
||||
|
||||
qse_sed_iostd_t* in_cur;
|
||||
qse_size_t in_mempos;
|
||||
qse_str_t* out_memstr;
|
||||
} e;
|
||||
};
|
||||
|
||||
typedef struct xtn_t xtn_t;
|
||||
@ -63,6 +70,166 @@ int qse_sed_compstd (qse_sed_t* sed, const qse_char_t* sptr)
|
||||
return qse_sed_comp (sed, sptr, qse_strlen(sptr));
|
||||
}
|
||||
|
||||
static qse_sio_t* open_sio (qse_sed_t* sed, const qse_char_t* file, int flags)
|
||||
{
|
||||
qse_sio_t* sio;
|
||||
|
||||
sio = qse_sio_open (sed->mmgr, 0, file, flags);
|
||||
if (sio == QSE_NULL)
|
||||
{
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = file;
|
||||
ea.len = qse_strlen (file);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
|
||||
}
|
||||
return sio;
|
||||
}
|
||||
|
||||
static void close_main_stream (
|
||||
qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io)
|
||||
{
|
||||
if (io->type == QSE_SED_IOSTD_FILE)
|
||||
{
|
||||
qse_sio_t* sio = (qse_sio_t*)arg->handle;
|
||||
if (sio != qse_sio_in && sio != qse_sio_out && sio != qse_sio_err)
|
||||
qse_sio_close (sio);
|
||||
}
|
||||
}
|
||||
|
||||
static int open_main_input_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*) QSE_XTN (sed);
|
||||
|
||||
QSE_ASSERT (io != QSE_NULL);
|
||||
switch (io->type)
|
||||
{
|
||||
case QSE_SED_IOSTD_SIO:
|
||||
arg->handle = io->u.sio;
|
||||
break;
|
||||
|
||||
case QSE_SED_IOSTD_FILE:
|
||||
if (io->u.file == QSE_NULL)
|
||||
{
|
||||
arg->handle = qse_sio_in;
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_sio_t* sio;
|
||||
sio = open_sio (sed, io->u.file, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
|
||||
if (sio == QSE_NULL) return -1;
|
||||
arg->handle = sio;
|
||||
}
|
||||
break;
|
||||
|
||||
case QSE_SED_IOSTD_MEM:
|
||||
/* don't store anything to arg->handle */
|
||||
xtn->e.in_mempos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_main_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*) QSE_XTN (sed);
|
||||
|
||||
QSE_ASSERT (io != QSE_NULL);
|
||||
switch (io->type)
|
||||
{
|
||||
case QSE_SED_IOSTD_SIO:
|
||||
arg->handle = io->u.sio;
|
||||
break;
|
||||
|
||||
case QSE_SED_IOSTD_FILE:
|
||||
if (io->u.file == QSE_NULL)
|
||||
{
|
||||
arg->handle = qse_sio_out;
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_sio_t* sio;
|
||||
sio = open_sio (sed, io->u.file,
|
||||
QSE_SIO_WRITE |
|
||||
QSE_SIO_CREATE |
|
||||
QSE_SIO_TRUNCATE |
|
||||
QSE_SIO_IGNOREMBWCERR
|
||||
);
|
||||
if (sio == QSE_NULL) return -1;
|
||||
arg->handle = sio;
|
||||
}
|
||||
break;
|
||||
|
||||
case QSE_SED_IOSTD_MEM:
|
||||
/* don't store anything to arg->handle */
|
||||
xtn->e.out_memstr = qse_str_open (sed->mmgr, 0, 512);
|
||||
if (xtn->e.out_memstr == QSE_NULL)
|
||||
{
|
||||
qse_sed_seterrnum (sed, QSE_SED_ENOMEM, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qse_ssize_t read_main_input_stream (
|
||||
qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_char_t* buf, qse_size_t len)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*) QSE_XTN (sed);
|
||||
qse_sed_iostd_t* io, * next;
|
||||
void* old, * new;
|
||||
qse_ssize_t n = 0;
|
||||
|
||||
if (len > QSE_TYPE_MAX(qse_ssize_t)) len = QSE_TYPE_MAX(qse_ssize_t);
|
||||
|
||||
do
|
||||
{
|
||||
io = xtn->e.in_cur;
|
||||
|
||||
QSE_ASSERT (io != QSE_NULL);
|
||||
if (io->type == QSE_SED_IOSTD_MEM)
|
||||
{
|
||||
n = 0;
|
||||
while (xtn->e.in_mempos < io->u.mem.len && n < len)
|
||||
buf[n++] = io->u.mem.ptr[xtn->e.in_mempos++];
|
||||
}
|
||||
else n = qse_sio_getsn (arg->handle, buf, len);
|
||||
|
||||
if (n != 0) break;
|
||||
|
||||
/* end of file on the current input stream */
|
||||
|
||||
next = xtn->e.in_cur + 1;
|
||||
if (next->type == QSE_SED_IOSTD_NULL)
|
||||
{
|
||||
/* no next stream available - return 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
old = arg->handle;
|
||||
|
||||
/* try to open the next input stream */
|
||||
if (open_main_input_stream (sed, arg, next) <= -1)
|
||||
{
|
||||
/* failed to open the next input stream */
|
||||
n = -1;
|
||||
break;
|
||||
}
|
||||
new = arg->handle;
|
||||
|
||||
arg->handle = old;
|
||||
close_main_stream (sed, arg, io);
|
||||
|
||||
arg->handle = new;
|
||||
xtn->e.in_cur++;
|
||||
}
|
||||
while (1);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static qse_ssize_t xin (
|
||||
qse_sed_t* sed, qse_sed_io_cmd_t cmd, qse_sed_io_arg_t* arg,
|
||||
qse_char_t* buf, qse_size_t len)
|
||||
@ -77,67 +244,53 @@ static qse_ssize_t xin (
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
/* main data stream */
|
||||
if (xtn->infile == QSE_NULL) sio = qse_sio_in;
|
||||
if (xtn->e.in == QSE_NULL) arg->handle = qse_sio_in;
|
||||
else
|
||||
{
|
||||
sio = qse_sio_open (
|
||||
sed->mmgr,
|
||||
0,
|
||||
xtn->infile,
|
||||
QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR
|
||||
);
|
||||
if (sio == QSE_NULL)
|
||||
{
|
||||
/* set the error message explicitly
|
||||
* as the file name is different from
|
||||
* the standard console name (NULL) */
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = xtn->infile;
|
||||
ea.len = qse_strlen (xtn->infile);
|
||||
qse_sed_seterrnum (sed,QSE_SED_EIOFIL, &ea);
|
||||
return -1;
|
||||
}
|
||||
if (open_main_input_stream (sed, arg, xtn->e.in_cur) <= -1) return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sio = qse_sio_open (
|
||||
sed->mmgr,
|
||||
0,
|
||||
arg->path,
|
||||
QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR
|
||||
);
|
||||
sio = open_sio (sed, arg->path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
|
||||
if (sio == QSE_NULL) return -1;
|
||||
arg->handle = sio;
|
||||
}
|
||||
|
||||
if (sio == QSE_NULL) return -1;
|
||||
arg->handle = sio;
|
||||
return 1;
|
||||
}
|
||||
|
||||
case QSE_SED_IO_CLOSE:
|
||||
{
|
||||
sio = (qse_sio_t*)arg->handle;
|
||||
if (sio != qse_sio_in && sio != qse_sio_out && sio != qse_sio_err)
|
||||
qse_sio_close (sio);
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
/* main data stream */
|
||||
if (xtn->e.in) close_main_stream (sed, arg, xtn->e.in_cur);
|
||||
}
|
||||
else
|
||||
{
|
||||
sio = (qse_sio_t*)arg->handle;
|
||||
if (sio != qse_sio_in && sio != qse_sio_out && sio != qse_sio_err)
|
||||
qse_sio_close (sio);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case QSE_SED_IO_READ:
|
||||
{
|
||||
qse_ssize_t n = qse_sio_getsn (arg->handle, buf, len);
|
||||
|
||||
if (n == -1)
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
if (arg->path == QSE_NULL && xtn->infile != QSE_NULL)
|
||||
{
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = xtn->infile;
|
||||
ea.len = qse_strlen (xtn->infile);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
|
||||
}
|
||||
/* main data stream */
|
||||
if (xtn->e.in == QSE_NULL)
|
||||
return qse_sio_getsn (arg->handle, buf, len);
|
||||
else
|
||||
return read_main_input_stream (sed, arg, buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
return qse_sio_getsn (arg->handle, buf, len);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
default:
|
||||
@ -149,8 +302,8 @@ static qse_ssize_t xout (
|
||||
qse_sed_t* sed, qse_sed_io_cmd_t cmd, qse_sed_io_arg_t* arg,
|
||||
qse_char_t* dat, qse_size_t len)
|
||||
{
|
||||
qse_sio_t* sio;
|
||||
xtn_t* xtn = (xtn_t*) QSE_XTN (sed);
|
||||
qse_sio_t* sio;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
@ -158,74 +311,76 @@ static qse_ssize_t xout (
|
||||
{
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
if (xtn->outfile == QSE_NULL) sio = qse_sio_out;
|
||||
if (xtn->e.out == QSE_NULL) arg->handle = qse_sio_out;
|
||||
else
|
||||
{
|
||||
sio = qse_sio_open (
|
||||
sed->mmgr,
|
||||
0,
|
||||
xtn->outfile,
|
||||
QSE_SIO_WRITE |
|
||||
QSE_SIO_CREATE |
|
||||
QSE_SIO_TRUNCATE |
|
||||
QSE_SIO_IGNOREMBWCERR
|
||||
);
|
||||
if (sio == QSE_NULL)
|
||||
{
|
||||
/* set the error message explicitly
|
||||
* as the file name is different from
|
||||
* the standard console name (NULL) */
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = xtn->outfile;
|
||||
ea.len = qse_strlen (xtn->outfile);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
|
||||
return -1;
|
||||
}
|
||||
if (open_main_output_stream (sed, arg, xtn->e.out) <= -1) return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sio = qse_sio_open (
|
||||
sed->mmgr,
|
||||
0,
|
||||
arg->path,
|
||||
sio = open_sio (
|
||||
sed, arg->path,
|
||||
QSE_SIO_WRITE |
|
||||
QSE_SIO_CREATE |
|
||||
QSE_SIO_TRUNCATE |
|
||||
QSE_SIO_IGNOREMBWCERR
|
||||
);
|
||||
if (sio == QSE_NULL) return -1;
|
||||
arg->handle = sio;
|
||||
}
|
||||
|
||||
if (sio == QSE_NULL) return -1;
|
||||
arg->handle = sio;
|
||||
return 1;
|
||||
}
|
||||
|
||||
case QSE_SED_IO_CLOSE:
|
||||
{
|
||||
sio = (qse_sio_t*)arg->handle;
|
||||
qse_sio_flush (sio);
|
||||
if (sio != qse_sio_in && sio != qse_sio_out && sio != qse_sio_err)
|
||||
qse_sio_close (sio);
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
if (xtn->e.out) close_main_stream (sed, arg, xtn->e.out);
|
||||
}
|
||||
else
|
||||
{
|
||||
sio = (qse_sio_t*)arg->handle;
|
||||
qse_sio_flush (sio);
|
||||
if (sio != qse_sio_in && sio != qse_sio_out && sio != qse_sio_err)
|
||||
qse_sio_close (sio);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case QSE_SED_IO_WRITE:
|
||||
{
|
||||
qse_ssize_t n = qse_sio_putsn (arg->handle, dat, len);
|
||||
|
||||
if (n == -1)
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
if (arg->path == QSE_NULL && xtn->infile != QSE_NULL)
|
||||
/* main data stream */
|
||||
if (xtn->e.out == QSE_NULL)
|
||||
return qse_sio_putsn (arg->handle, dat, len);
|
||||
else
|
||||
{
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = xtn->infile;
|
||||
ea.len = qse_strlen (xtn->infile);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
|
||||
qse_sed_iostd_t* io = xtn->e.out;
|
||||
if (io->type == QSE_SED_IOSTD_MEM)
|
||||
{
|
||||
if (len > QSE_TYPE_MAX(qse_ssize_t)) len = QSE_TYPE_MAX(qse_ssize_t);
|
||||
|
||||
if (qse_str_ncat (xtn->e.out_memstr, dat, len) == (qse_size_t)-1)
|
||||
{
|
||||
qse_sed_seterrnum (sed, QSE_SED_ENOMEM, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
else
|
||||
{
|
||||
return qse_sio_putsn (arg->handle, dat, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
else
|
||||
{
|
||||
return qse_sio_putsn (arg->handle, dat, len);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
@ -233,10 +388,69 @@ static qse_ssize_t xout (
|
||||
}
|
||||
}
|
||||
|
||||
int qse_sed_execstd (qse_sed_t* sed, const qse_char_t* infile, const qse_char_t* outfile)
|
||||
int qse_sed_execstd (
|
||||
qse_sed_t* sed, qse_sed_iostd_t in[], qse_sed_iostd_t* out)
|
||||
{
|
||||
int n;
|
||||
xtn_t* xtn = (xtn_t*) QSE_XTN (sed);
|
||||
xtn->infile = infile;
|
||||
xtn->outfile = outfile;
|
||||
return qse_sed_exec (sed, xin, xout);
|
||||
|
||||
if (in)
|
||||
{
|
||||
qse_size_t i;
|
||||
|
||||
if (in[0].type == QSE_SED_IOSTD_NULL)
|
||||
{
|
||||
/* if 'in' is specified, it must contains at least one
|
||||
* valid entry */
|
||||
qse_sed_seterrnum (sed, QSE_SED_EINVAL, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; in[i].type != QSE_SED_IOSTD_NULL; i++)
|
||||
{
|
||||
if (in[i].type != QSE_SED_IOSTD_SIO &&
|
||||
in[i].type != QSE_SED_IOSTD_FILE &&
|
||||
in[i].type != QSE_SED_IOSTD_MEM)
|
||||
{
|
||||
qse_sed_seterrnum (sed, QSE_SED_EINVAL, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (out)
|
||||
{
|
||||
if (out->type != QSE_SED_IOSTD_SIO &&
|
||||
out->type != QSE_SED_IOSTD_FILE &&
|
||||
out->type != QSE_SED_IOSTD_MEM)
|
||||
{
|
||||
qse_sed_seterrnum (sed, QSE_SED_EINVAL, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
QSE_MEMSET (&xtn->e, 0, QSE_SIZEOF(xtn->e));
|
||||
xtn->e.in = in;
|
||||
xtn->e.out = out;
|
||||
xtn->e.in_cur = in;
|
||||
|
||||
n = qse_sed_exec (sed, xin, xout);
|
||||
|
||||
if (n >= 0 && out && out->type == QSE_SED_IOSTD_MEM)
|
||||
{
|
||||
QSE_ASSERT (xtn->e.out_memstr != QSE_NULL);
|
||||
qse_str_yield (xtn->e.out_memstr, &out->u.mem, 0);
|
||||
}
|
||||
if (xtn->e.out_memstr) qse_str_close (xtn->e.out_memstr);
|
||||
|
||||
/* if some output without a newline is emitted before
|
||||
* last flush, they can be lost because qse_sio_out
|
||||
* is not explicitly closed() with qse_sio_close()
|
||||
* which in turn calls qse_sio_flush(). let's call it
|
||||
* here directly. I don't care whether some other
|
||||
* threads could have written to this. */
|
||||
qse_sio_flush (qse_sio_out);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user