* added QSE_SIO_NOCLOSE.
* enhanced qse_sed_comp() to accept an array of qse_sed_iostd_t
This commit is contained in:
@ -406,15 +406,19 @@ int qse_fio_init (
|
||||
void qse_fio_fini (qse_fio_t* fio)
|
||||
{
|
||||
if (fio->tio != QSE_NULL) qse_tio_close (fio->tio);
|
||||
|
||||
if (!(fio->flags & QSE_FIO_NOCLOSE))
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
CloseHandle (fio->handle);
|
||||
CloseHandle (fio->handle);
|
||||
#elif defined(__OS2__)
|
||||
DosClose (fio->handle);
|
||||
DosClose (fio->handle);
|
||||
#elif defined(__DOS__)
|
||||
close (fio->handle);
|
||||
close (fio->handle);
|
||||
#else
|
||||
QSE_CLOSE (fio->handle);
|
||||
QSE_CLOSE (fio->handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
qse_fio_hnd_t qse_fio_gethandle (qse_fio_t* fio)
|
||||
@ -437,7 +441,10 @@ qse_fio_off_t qse_fio_seek (
|
||||
FILE_CURRENT,
|
||||
FILE_END
|
||||
};
|
||||
LARGE_INTEGER x, y;
|
||||
LARGE_INTEGER x;
|
||||
#if 0
|
||||
LARGE_INTEGER y;
|
||||
#endif
|
||||
|
||||
QSE_ASSERT (QSE_SIZEOF(offset) <= QSE_SIZEOF(x.QuadPart));
|
||||
|
||||
@ -856,13 +863,18 @@ static qse_ssize_t fio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size
|
||||
|
||||
int qse_getstdfiohandle (qse_fio_std_t std, qse_fio_hnd_t* hnd)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
DWORD tab[] =
|
||||
{
|
||||
STD_INPUT_HANDLE,
|
||||
STD_OUTPUT_HANDLE,
|
||||
STD_ERROR_HANDLE
|
||||
};
|
||||
#else
|
||||
|
||||
qse_fio_hnd_t tab[] =
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
(HANDLE)STD_INPUT_HANDLE,
|
||||
(HANDLE)STD_OUTPUT_HANDLE,
|
||||
(HANDLE)STD_ERROR_HANDLE
|
||||
#elif defined(__OS2__)
|
||||
#if defined(__OS2__)
|
||||
(HFILE)0, (HFILE)1, (HFILE)2
|
||||
#elif defined(__DOS__)
|
||||
0, 1, 2
|
||||
@ -871,6 +883,8 @@ int qse_getstdfiohandle (qse_fio_std_t std, qse_fio_hnd_t* hnd)
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
if (std < 0 || std >= QSE_COUNTOF(tab)) return -1;
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
@ -43,8 +43,8 @@
|
||||
/* Returns number of bytes to add to (char *)ptr to make it
|
||||
properly aligned for the type. */
|
||||
#define ALIGN(ptr, type) \
|
||||
((((long)ptr) % sizeof(type))? \
|
||||
(sizeof(type) - (((long)ptr) % QSE_SIZEOF(type))) : 0)
|
||||
((((qse_uintptr_t)ptr) % QSE_SIZEOF(type))? \
|
||||
(QSE_SIZEOF(type) - (((qse_uintptr_t)ptr) % QSE_SIZEOF(type))) : 0)
|
||||
|
||||
|
||||
QSE_IMPLEMENT_COMMON_FUNCTIONS (pma)
|
||||
@ -133,7 +133,7 @@ void* qse_pma_alloc (qse_pma_t* pma, qse_size_t size)
|
||||
}
|
||||
|
||||
/* Make sure the next pointer will be aligned. */
|
||||
size += ALIGN((long)(pma->ptr + size), long);
|
||||
size += ALIGN((qse_uintptr_t)(pma->ptr + size), qse_uintptr_t);
|
||||
|
||||
/* Allocate from current block. */
|
||||
ptr = pma->ptr;
|
||||
|
@ -41,6 +41,8 @@ static qse_sio_t __sio_in =
|
||||
0, /* errnum */
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* this is not a handle. it is adjusted to
|
||||
* an actual handle in __sio_input () */
|
||||
(HANDLE)STD_INPUT_HANDLE, /* handle */
|
||||
#elif defined(__OS2__)
|
||||
(HFILE)0, /* handle */
|
||||
@ -85,6 +87,8 @@ static qse_sio_t __sio_out =
|
||||
0,
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* this is not a handle. it is adjusted to
|
||||
* an actual handle in __sio_output () */
|
||||
(HANDLE)STD_OUTPUT_HANDLE,
|
||||
#elif defined(__OS2__)
|
||||
(HFILE)1,
|
||||
@ -129,6 +133,8 @@ static qse_sio_t __sio_err =
|
||||
0,
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* this is not a handle. it is adjusted to
|
||||
* an actual handle in __sio_output () */
|
||||
(HANDLE)STD_ERROR_HANDLE,
|
||||
#elif defined(__OS2__)
|
||||
(HFILE)2,
|
||||
@ -200,7 +206,7 @@ qse_sio_t* qse_sio_openstd (
|
||||
qse_fio_hnd_t hnd;
|
||||
if (qse_getstdfiohandle (std, &hnd) <= -1) return QSE_NULL;
|
||||
return qse_sio_open (mmgr, xtnsize,
|
||||
(const qse_char_t*)&hnd, flags | QSE_SIO_HANDLE);
|
||||
(const qse_char_t*)&hnd, flags | QSE_SIO_HANDLE /*| QSE_SIO_NOCLOSE*/);
|
||||
}
|
||||
|
||||
void qse_sio_close (qse_sio_t* sio)
|
||||
|
@ -178,16 +178,16 @@ tre_tnfa_run_parallel(qse_mmgr_t* mmgr, const tre_tnfa_t *tnfa, const void *stri
|
||||
/* Get the various pointers within tmp_buf (properly aligned). */
|
||||
tmp_tags = (void *)buf;
|
||||
tmp_buf = buf + tbytes;
|
||||
tmp_buf += ALIGN(tmp_buf, long);
|
||||
tmp_buf += ALIGN(tmp_buf, qse_uintptr_t);
|
||||
reach_next = (void *)tmp_buf;
|
||||
tmp_buf += rbytes;
|
||||
tmp_buf += ALIGN(tmp_buf, long);
|
||||
tmp_buf += ALIGN(tmp_buf, qse_uintptr_t);
|
||||
reach = (void *)tmp_buf;
|
||||
tmp_buf += rbytes;
|
||||
tmp_buf += ALIGN(tmp_buf, long);
|
||||
tmp_buf += ALIGN(tmp_buf, qse_uintptr_t);
|
||||
reach_pos = (void *)tmp_buf;
|
||||
tmp_buf += pbytes;
|
||||
tmp_buf += ALIGN(tmp_buf, long);
|
||||
tmp_buf += ALIGN(tmp_buf, qse_uintptr_t);
|
||||
for (i = 0; i < tnfa->num_states; i++)
|
||||
{
|
||||
reach[i].tags = (void *)tmp_buf;
|
||||
|
@ -281,8 +281,8 @@ typedef enum { STR_WIDE, STR_BYTE, STR_MBS, STR_USER } tre_str_type_t;
|
||||
/* Returns number of bytes to add to (char *)ptr to make it
|
||||
properly aligned for the type. */
|
||||
#define ALIGN(ptr, type) \
|
||||
((((long)ptr) % sizeof(type)) \
|
||||
? (sizeof(type) - (((long)ptr) % sizeof(type))) \
|
||||
((((qse_uintptr_t)ptr) % QSE_SIZEOF(type)) \
|
||||
? (QSE_SIZEOF(type) - (((qse_uintptr_t)ptr) % QSE_SIZEOF(type))) \
|
||||
: 0)
|
||||
|
||||
#undef MAX
|
||||
|
@ -48,16 +48,12 @@ void Sed::close ()
|
||||
}
|
||||
}
|
||||
|
||||
int Sed::compile (const char_t* sptr)
|
||||
int Sed::compile (Stream& sstream)
|
||||
{
|
||||
QSE_ASSERT (sed != QSE_NULL);
|
||||
return qse_sed_comp (sed, sptr, qse_strlen(sptr));
|
||||
}
|
||||
|
||||
int Sed::compile (const char_t* sptr, size_t slen)
|
||||
{
|
||||
QSE_ASSERT (sed != QSE_NULL);
|
||||
return qse_sed_comp (sed, sptr, slen);
|
||||
this->sstream = &sstream;
|
||||
return qse_sed_comp (sed, sin);
|
||||
}
|
||||
|
||||
int Sed::execute (Stream& iostream)
|
||||
@ -145,6 +141,33 @@ void Sed::setConsoleLine (size_t num)
|
||||
qse_sed_setlinnum (sed, num);
|
||||
}
|
||||
|
||||
Sed::ssize_t Sed::sin (
|
||||
sed_t* s, io_cmd_t cmd, io_arg_t* arg, char_t* buf, size_t len)
|
||||
{
|
||||
Sed* sed = *(Sed**)QSE_XTN(s);
|
||||
|
||||
Stream::Data iodata (sed, Stream::READ, arg);
|
||||
|
||||
try
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case QSE_SED_IO_OPEN:
|
||||
return sed->sstream->open (iodata);
|
||||
case QSE_SED_IO_CLOSE:
|
||||
return sed->sstream->close (iodata);
|
||||
case QSE_SED_IO_READ:
|
||||
return sed->sstream->read (iodata, buf, len);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Sed::ssize_t Sed::xin (
|
||||
sed_t* s, io_cmd_t cmd, io_arg_t* arg, char_t* buf, size_t len)
|
||||
{
|
||||
|
@ -347,8 +347,101 @@ static int matchtre (
|
||||
#define NXTSC(sed) getnextsc(sed)
|
||||
#define PEEPNXTSC(sed) ((sed->src.cur < sed->src.end)? *sed->src.cur: QSE_CHAR_EOF)
|
||||
|
||||
static int open_script_stream (qse_sed_t* sed)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
sed->errnum = QSE_SED_ENOERR;
|
||||
n = sed->src.fun (sed, QSE_SED_IO_OPEN, &sed->src.arg, QSE_NULL, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (sed->errnum == QSE_SED_ENOERR)
|
||||
SETERR0 (sed, QSE_SED_EIOUSR, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sed->src.cur = sed->src.buf;
|
||||
sed->src.end = sed->src.buf;
|
||||
sed->src.cc = QSE_CHAR_EOF;
|
||||
sed->src.loc.line = 1;
|
||||
sed->src.loc.colm = 0;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
sed->src.eof = 1;
|
||||
return 0; /* end of file */
|
||||
}
|
||||
else
|
||||
{
|
||||
sed->src.eof = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int close_script_stream (qse_sed_t* sed)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
sed->errnum = QSE_SED_ENOERR;
|
||||
n = sed->src.fun (sed, QSE_SED_IO_CLOSE, &sed->src.arg, QSE_NULL, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (sed->errnum == QSE_SED_ENOERR)
|
||||
SETERR0 (sed, QSE_SED_EIOUSR, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_script_stream (qse_sed_t* sed, qse_size_t rem)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
|
||||
sed->errnum = QSE_SED_ENOERR;
|
||||
n = sed->src.fun (
|
||||
sed, QSE_SED_IO_READ, &sed->src.arg,
|
||||
&sed->src.buf[rem], QSE_COUNTOF(sed->src.buf) - rem
|
||||
);
|
||||
if (n <= -1)
|
||||
{
|
||||
if (sed->errnum == QSE_SED_ENOERR)
|
||||
SETERR0 (sed, QSE_SED_EIOUSR, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
sed->src.eof = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sed->src.end = &sed->src.buf[rem] + n;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static qse_cint_t getnextsc (qse_sed_t* sed)
|
||||
{
|
||||
if (sed->src.cur + 1 >= sed->src.end && !sed->src.eof)
|
||||
{
|
||||
qse_size_t rem = sed->src.end - sed->src.cur;
|
||||
if (sed->src.cur != sed->src.buf && rem > 0)
|
||||
{
|
||||
QSE_MEMCPY (sed->src.buf, sed->src.cur, rem * QSE_SIZEOF(qse_char_t));
|
||||
sed->src.cur = sed->src.buf;
|
||||
sed->src.end = sed->src.buf + rem;
|
||||
}
|
||||
if (read_script_stream (sed, rem) <= -1) return -1;
|
||||
|
||||
if (sed->src.cur + 1 >= sed->src.end && !sed->src.eof)
|
||||
{
|
||||
/* read again if it didn't read enough */
|
||||
qse_size_t rem = sed->src.end - sed->src.cur;
|
||||
QSE_ASSERT (sed->src.buf == sed->src.cur);
|
||||
if (read_script_stream (sed, rem) <= -1) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sed->src.cur < sed->src.end)
|
||||
{
|
||||
if (sed->src.cc == QSE_T('\n'))
|
||||
@ -1598,16 +1691,22 @@ static int get_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
|
||||
int qse_sed_comp (qse_sed_t* sed, qse_sed_io_fun_t inf)
|
||||
{
|
||||
qse_cint_t c;
|
||||
qse_sed_cmd_t* cmd = QSE_NULL;
|
||||
qse_sed_loc_t a1_loc;
|
||||
|
||||
if (inf == QSE_NULL)
|
||||
{
|
||||
qse_sed_seterrnum (sed, QSE_SED_EINVAL, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* store the source code pointers */
|
||||
sed->src.ptr = sptr;
|
||||
sed->src.end = sptr + slen;
|
||||
sed->src.cur = sptr;
|
||||
sed->src.fun = inf;
|
||||
if (open_script_stream (sed) <= -1) return -1;
|
||||
|
||||
sed->src.loc.line = 1;
|
||||
sed->src.loc.colm = 0;
|
||||
sed->src.cc = QSE_CHAR_EOF;
|
||||
@ -1730,17 +1829,19 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
|
||||
if (cmd->a1.type == QSE_SED_ADR_LINE && cmd->a1.u.lno <= 0)
|
||||
{
|
||||
if (cmd->a2.type == QSE_SED_ADR_STEP ||
|
||||
((sed->option & QSE_SED_EXTENDEDADR) && cmd->a2.type == QSE_SED_ADR_REX))
|
||||
((sed->option & QSE_SED_EXTENDEDADR) &&
|
||||
cmd->a2.type == QSE_SED_ADR_REX))
|
||||
{
|
||||
/* 0 as the first address is allowed in this two contexts.
|
||||
* 0~step
|
||||
* 0,/regex/
|
||||
* however, '0~0' is not allowed. but at this point '0~0' is
|
||||
* already transformed to '0'. and disallowing it is achieved
|
||||
* gratuitously.
|
||||
* '0~0' is not allowed. but at this point '0~0'
|
||||
* is already transformed to '0'. and disallowing it is
|
||||
* achieved gratuitously.
|
||||
*/
|
||||
/* nothing to do - adding negation to the condition dropped
|
||||
* code readability so i decided to write this part of code this way.
|
||||
* code readability so i decided to write this part of code
|
||||
* this way.
|
||||
*/
|
||||
}
|
||||
else
|
||||
@ -1785,13 +1886,15 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
|
||||
if (sed->tmp.grp.level != 0)
|
||||
{
|
||||
SETERR0 (sed, QSE_SED_EGRNBA, &sed->src.loc);
|
||||
return -1;
|
||||
goto oops;
|
||||
}
|
||||
|
||||
close_script_stream (sed);
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
if (cmd) free_address (sed, cmd);
|
||||
close_script_stream (sed);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2185,6 +2288,7 @@ static int write_file (
|
||||
qse_char_t buf[512];
|
||||
#endif
|
||||
|
||||
arg.handle = QSE_NULL;
|
||||
arg.path = cmd->u.file.ptr;
|
||||
sed->errnum = QSE_SED_ENOERR;
|
||||
n = sed->e.in.fun (sed, QSE_SED_IO_OPEN, &arg, QSE_NULL, 0);
|
||||
@ -2304,7 +2408,10 @@ static int emit_append (qse_sed_t* sed, qse_sed_app_t* app)
|
||||
return write_file (sed, app->cmd, 1);
|
||||
|
||||
default:
|
||||
QSE_ASSERT (!"should never happen - app->cmd->type must be one of APPEND,READ_FILE,READ_FILELN");
|
||||
QSE_ASSERTX (
|
||||
!"should never happen",
|
||||
"app->cmd->type must be one of APPEND,READ_FILE,READ_FILELN"
|
||||
);
|
||||
SETERR0 (sed, QSE_SED_EINTERN, &app->cmd->loc);
|
||||
return -1;
|
||||
}
|
||||
|
@ -191,8 +191,13 @@ struct qse_sed_t
|
||||
/** source text pointers */
|
||||
struct
|
||||
{
|
||||
qse_sed_loc_t loc; /**< location */
|
||||
qse_cint_t cc; /**< last character read */
|
||||
qse_sed_io_fun_t fun; /**< input stream handler */
|
||||
qse_sed_io_arg_t arg;
|
||||
qse_char_t buf[1024];
|
||||
int eof;
|
||||
|
||||
qse_sed_loc_t loc; /**< location */
|
||||
qse_cint_t cc; /**< last character read */
|
||||
const qse_char_t* ptr; /**< beginning of the source text */
|
||||
const qse_char_t* end; /**< end of the source text */
|
||||
const qse_char_t* cur; /**< current source text pointer */
|
||||
|
@ -24,20 +24,35 @@
|
||||
#include <qse/cmn/sio.h>
|
||||
#include "../cmn/mem.h"
|
||||
|
||||
typedef struct xtn_in_t xtn_in_t;
|
||||
struct xtn_in_t
|
||||
{
|
||||
qse_sed_iostd_t* ptr;
|
||||
qse_sed_iostd_t* cur;
|
||||
qse_size_t mempos;
|
||||
};
|
||||
|
||||
typedef struct xtn_out_t xtn_out_t;
|
||||
struct xtn_out_t
|
||||
{
|
||||
qse_sed_iostd_t* ptr;
|
||||
qse_str_t* memstr;
|
||||
};
|
||||
|
||||
typedef struct xtn_t xtn_t;
|
||||
struct xtn_t
|
||||
{
|
||||
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;
|
||||
xtn_in_t in;
|
||||
} s;
|
||||
struct
|
||||
{
|
||||
xtn_in_t in;
|
||||
xtn_out_t out;
|
||||
} e;
|
||||
};
|
||||
|
||||
typedef struct xtn_t xtn_t;
|
||||
|
||||
qse_sed_t* qse_sed_openstd (qse_size_t xtnsize)
|
||||
{
|
||||
@ -65,9 +80,30 @@ void* qse_sed_getxtnstd (qse_sed_t* sed)
|
||||
return (void*)((xtn_t*)QSE_XTN(sed) + 1);
|
||||
}
|
||||
|
||||
int qse_sed_compstd (qse_sed_t* sed, const qse_char_t* sptr)
|
||||
static int verify_iostd_in (qse_sed_t* sed, qse_sed_iostd_t in[])
|
||||
{
|
||||
return qse_sed_comp (sed, sptr, qse_strlen(sptr));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qse_sio_t* open_sio (qse_sed_t* sed, const qse_char_t* file, int flags)
|
||||
@ -112,7 +148,8 @@ static void close_main_stream (
|
||||
if (io->type == QSE_SED_IOSTD_FILE) qse_sio_close (arg->handle);
|
||||
}
|
||||
|
||||
static int open_console_input_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io)
|
||||
static int open_input_stream (
|
||||
qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io, xtn_in_t* base)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*) QSE_XTN (sed);
|
||||
|
||||
@ -136,14 +173,21 @@ static int open_console_input_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse
|
||||
|
||||
case QSE_SED_IOSTD_MEM:
|
||||
/* don't store anything to arg->handle */
|
||||
xtn->e.in_mempos = 0;
|
||||
base->mempos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (base == &xtn->s.in)
|
||||
{
|
||||
qse_sed_setfilename (sed, ....);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_console_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io)
|
||||
static int open_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);
|
||||
|
||||
@ -184,8 +228,8 @@ static int open_console_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qs
|
||||
|
||||
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)
|
||||
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;
|
||||
@ -196,34 +240,68 @@ static int open_console_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qs
|
||||
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)
|
||||
static qse_ssize_t read_input_stream (
|
||||
qse_sed_t* sed, qse_sed_io_arg_t* arg,
|
||||
qse_char_t* buf, qse_size_t len, xtn_in_t* base)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*) QSE_XTN (sed);
|
||||
qse_sed_iostd_t* io, * next;
|
||||
void* old, * new;
|
||||
qse_ssize_t n = 0;
|
||||
int newline_forced = 0;
|
||||
|
||||
if (len > QSE_TYPE_MAX(qse_ssize_t)) len = QSE_TYPE_MAX(qse_ssize_t);
|
||||
|
||||
do
|
||||
{
|
||||
io = xtn->e.in_cur;
|
||||
io = base->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++];
|
||||
while (base->mempos < io->u.mem.len && n < len)
|
||||
buf[n++] = io->u.mem.ptr[base->mempos++];
|
||||
}
|
||||
else n = qse_sio_getsn (arg->handle, buf, len);
|
||||
|
||||
if (n != 0) break;
|
||||
if (n != 0)
|
||||
{
|
||||
if (n <= -1)
|
||||
{
|
||||
if (io->type == QSE_SED_IOSTD_FILE)
|
||||
{
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = io->u.file;
|
||||
ea.len = qse_strlen (io->u.file);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
|
||||
}
|
||||
}
|
||||
else n += newline_forced; /* success */
|
||||
break;
|
||||
}
|
||||
|
||||
/* end of file on the current input stream */
|
||||
/* ============================================= */
|
||||
/* == end of file on the current input stream == */
|
||||
/* ============================================= */
|
||||
|
||||
next = xtn->e.in_cur + 1;
|
||||
if (base == &xtn->s.in && !newline_forced)
|
||||
{
|
||||
/* == ONLY FOR A SCRIPT STREAM ==
|
||||
* squeeze in a new line in case the previous script
|
||||
* stream doesn't end with a line terminator.*/
|
||||
|
||||
/* TODO: support different line terminator */
|
||||
buf[0] = QSE_T('\n');
|
||||
buf++; len--;
|
||||
newline_forced = 1;
|
||||
|
||||
/* set the line number to 0 for the newline
|
||||
* squeezed in */
|
||||
sed->src.loc.line = 0;
|
||||
sed->src.loc.colm = 0;
|
||||
}
|
||||
|
||||
next = base->cur + 1;
|
||||
if (next->type == QSE_SED_IOSTD_NULL)
|
||||
{
|
||||
/* no next stream available - return 0 */
|
||||
@ -233,9 +311,17 @@ static qse_ssize_t read_main_input_stream (
|
||||
old = arg->handle;
|
||||
|
||||
/* try to open the next input stream */
|
||||
if (open_console_input_stream (sed, arg, next) <= -1)
|
||||
if (open_input_stream (sed, arg, next, base) <= -1)
|
||||
{
|
||||
/* failed to open the next input stream */
|
||||
if (next->type == QSE_SED_IOSTD_FILE)
|
||||
{
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = next->u.file;
|
||||
ea.len = qse_strlen (next->u.file);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
|
||||
}
|
||||
|
||||
n = -1;
|
||||
break;
|
||||
}
|
||||
@ -245,14 +331,51 @@ static qse_ssize_t read_main_input_stream (
|
||||
close_main_stream (sed, arg, io);
|
||||
|
||||
arg->handle = new;
|
||||
xtn->e.in_cur++;
|
||||
base->cur++;
|
||||
}
|
||||
while (1);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static qse_ssize_t xin (
|
||||
static qse_ssize_t s_in (
|
||||
qse_sed_t* sed, qse_sed_io_cmd_t cmd, qse_sed_io_arg_t* arg,
|
||||
qse_char_t* buf, qse_size_t len)
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*) QSE_XTN (sed);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case QSE_SED_IO_OPEN:
|
||||
{
|
||||
if (open_input_stream (sed, arg, xtn->s.in.cur, &xtn->s.in) <= -1) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
case QSE_SED_IO_CLOSE:
|
||||
{
|
||||
close_main_stream (sed, arg, xtn->s.in.cur);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case QSE_SED_IO_READ:
|
||||
{
|
||||
return read_input_stream (sed, arg, buf, len, &xtn->s.in);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
QSE_ASSERTX (
|
||||
!"should never happen",
|
||||
"cmd must be one of OPEN,CLOSE,READ"
|
||||
);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EINTERN, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static qse_ssize_t x_in (
|
||||
qse_sed_t* sed, qse_sed_io_cmd_t cmd, qse_sed_io_arg_t* arg,
|
||||
qse_char_t* buf, qse_size_t len)
|
||||
{
|
||||
@ -265,8 +388,8 @@ static qse_ssize_t xin (
|
||||
{
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
/* not file specified. console stream */
|
||||
if (xtn->e.in == QSE_NULL)
|
||||
/* no file specified. console stream */
|
||||
if (xtn->e.in.ptr == QSE_NULL)
|
||||
{
|
||||
sio = open_sio_std (
|
||||
sed, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
|
||||
@ -275,7 +398,7 @@ static qse_ssize_t xin (
|
||||
}
|
||||
else
|
||||
{
|
||||
if (open_console_input_stream (sed, arg, xtn->e.in_cur) <= -1) return -1;
|
||||
if (open_input_stream (sed, arg, xtn->e.in.cur, &xtn->e.in) <= -1) return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -293,10 +416,10 @@ static qse_ssize_t xin (
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
/* main data stream */
|
||||
if (xtn->e.in == QSE_NULL)
|
||||
if (xtn->e.in.ptr == QSE_NULL)
|
||||
qse_sio_close (arg->handle);
|
||||
else
|
||||
close_main_stream (sed, arg, xtn->e.in_cur);
|
||||
close_main_stream (sed, arg, xtn->e.in.cur);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -311,23 +434,48 @@ static qse_ssize_t xin (
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
/* main data stream */
|
||||
if (xtn->e.in == QSE_NULL)
|
||||
return qse_sio_getsn (arg->handle, buf, len);
|
||||
if (xtn->e.in.ptr == QSE_NULL)
|
||||
{
|
||||
qse_ssize_t n;
|
||||
n = qse_sio_getsn (arg->handle, buf, len);
|
||||
if (n <= -1)
|
||||
{
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = QSE_T("stdin");
|
||||
ea.len = 5;
|
||||
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
else
|
||||
return read_main_input_stream (sed, arg, buf, len);
|
||||
return read_input_stream (sed, arg, buf, len, &xtn->e.in);
|
||||
}
|
||||
else
|
||||
{
|
||||
return qse_sio_getsn (arg->handle, buf, len);
|
||||
qse_ssize_t n;
|
||||
n = qse_sio_getsn (arg->handle, buf, len);
|
||||
if (n <= -1)
|
||||
{
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = arg->path;
|
||||
ea.len = qse_strlen (arg->path);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
QSE_ASSERTX (
|
||||
!"should never happen",
|
||||
"cmd must be one of OPEN,CLOSE,READ"
|
||||
);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EINTERN, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static qse_ssize_t xout (
|
||||
static qse_ssize_t x_out (
|
||||
qse_sed_t* sed, qse_sed_io_cmd_t cmd, qse_sed_io_arg_t* arg,
|
||||
qse_char_t* dat, qse_size_t len)
|
||||
{
|
||||
@ -340,7 +488,7 @@ static qse_ssize_t xout (
|
||||
{
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
if (xtn->e.out == QSE_NULL)
|
||||
if (xtn->e.out.ptr== QSE_NULL)
|
||||
{
|
||||
sio = open_sio_std (
|
||||
sed, QSE_SIO_STDOUT,
|
||||
@ -354,7 +502,7 @@ static qse_ssize_t xout (
|
||||
}
|
||||
else
|
||||
{
|
||||
if (open_console_output_stream (sed, arg, xtn->e.out) <= -1) return -1;
|
||||
if (open_output_stream (sed, arg, xtn->e.out.ptr) <= -1) return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -377,10 +525,10 @@ static qse_ssize_t xout (
|
||||
{
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
if (xtn->e.out == QSE_NULL)
|
||||
if (xtn->e.out.ptr== QSE_NULL)
|
||||
qse_sio_close (arg->handle);
|
||||
else
|
||||
close_main_stream (sed, arg, xtn->e.out);
|
||||
close_main_stream (sed, arg, xtn->e.out.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -394,18 +542,27 @@ static qse_ssize_t xout (
|
||||
if (arg->path == QSE_NULL)
|
||||
{
|
||||
/* main data stream */
|
||||
if (xtn->e.out == QSE_NULL)
|
||||
if (xtn->e.out.ptr== QSE_NULL)
|
||||
{
|
||||
return qse_sio_putsn (arg->handle, dat, len);
|
||||
qse_ssize_t n;
|
||||
n = qse_sio_putsn (arg->handle, dat, len);
|
||||
if (n <= -1)
|
||||
{
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = QSE_T("stdin");
|
||||
ea.len = 5;
|
||||
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_sed_iostd_t* io = xtn->e.out;
|
||||
qse_sed_iostd_t* io = xtn->e.out.ptr;
|
||||
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)
|
||||
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;
|
||||
@ -415,50 +572,70 @@ static qse_ssize_t xout (
|
||||
}
|
||||
else
|
||||
{
|
||||
return qse_sio_putsn (arg->handle, dat, len);
|
||||
qse_ssize_t n;
|
||||
n = qse_sio_putsn (arg->handle, dat, len);
|
||||
if (n <= -1)
|
||||
{
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = io->u.file;
|
||||
ea.len = qse_strlen(io->u.file);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return qse_sio_putsn (arg->handle, dat, len);
|
||||
qse_ssize_t n;
|
||||
n = qse_sio_putsn (arg->handle, dat, len);
|
||||
if (n <= -1)
|
||||
{
|
||||
qse_cstr_t ea;
|
||||
ea.ptr = arg->path;
|
||||
ea.len = qse_strlen(arg->path);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
QSE_ASSERTX (
|
||||
!"should never happen",
|
||||
"cmd must be one of OPEN,CLOSE,WRITE"
|
||||
);
|
||||
qse_sed_seterrnum (sed, QSE_SED_EINTERN, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int qse_sed_compstd (qse_sed_t* sed, qse_sed_iostd_t in[])
|
||||
{
|
||||
xtn_t* xtn = (xtn_t*) QSE_XTN (sed);
|
||||
|
||||
if (in == QSE_NULL)
|
||||
{
|
||||
/* it requires a valid array unlike qse_sed_execstd(). */
|
||||
qse_sed_seterrnum (sed, QSE_SED_EINVAL, QSE_NULL);
|
||||
return -1;
|
||||
}
|
||||
if (verify_iostd_in (sed, in) <= -1) return -1;
|
||||
|
||||
QSE_MEMSET (&xtn->s, 0, QSE_SIZEOF(xtn->s));
|
||||
xtn->s.in.ptr = in;
|
||||
xtn->s.in.cur = in;
|
||||
|
||||
return qse_sed_comp (sed, s_in);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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 (in && verify_iostd_in (sed, in) <= -1) return -1;
|
||||
|
||||
if (out)
|
||||
{
|
||||
@ -472,18 +649,18 @@ int qse_sed_execstd (
|
||||
}
|
||||
|
||||
QSE_MEMSET (&xtn->e, 0, QSE_SIZEOF(xtn->e));
|
||||
xtn->e.in = in;
|
||||
xtn->e.out = out;
|
||||
xtn->e.in_cur = in;
|
||||
xtn->e.in.ptr = in;
|
||||
xtn->e.in.cur = in;
|
||||
xtn->e.out.ptr= out;
|
||||
|
||||
n = qse_sed_exec (sed, xin, xout);
|
||||
n = qse_sed_exec (sed, x_in, x_out);
|
||||
|
||||
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);
|
||||
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 (xtn->e.out.memstr) qse_str_close (xtn->e.out.memstr);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
Reference in New Issue
Block a user