added qse_sio_openstd().

added QSE_SED_ZEROA1 and related code
This commit is contained in:
2011-09-20 00:51:02 +00:00
parent ecaed2c2b3
commit 7de8b649ef
11 changed files with 372 additions and 141 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: fio.c 565 2011-09-11 02:48:21Z hyunghwan.chung $
* $Id: fio.c 569 2011-09-19 06:51:02Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -45,8 +45,10 @@
QSE_IMPLEMENT_COMMON_FUNCTIONS (fio)
static qse_ssize_t fio_input (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size);
static qse_ssize_t fio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size);
static qse_ssize_t fio_input (
qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size);
static qse_ssize_t fio_output (
qse_tio_cmd_t cmd, void* arg, void* buf, qse_size_t size);
qse_fio_t* qse_fio_open (
qse_mmgr_t* mmgr, qse_size_t ext,
@ -851,3 +853,34 @@ static qse_ssize_t fio_output (qse_tio_cmd_t cmd, void* arg, void* buf, qse_size
* by fio */
return 0;
}
int qse_getstdfiohandle (qse_fio_std_t std, qse_fio_hnd_t* hnd)
{
qse_fio_hnd_t tab[] =
{
#if defined(_WIN32)
(HANDLE)STD_INPUT_HANDLE,
(HANDLE)STD_OUTPUT_HANDLE,
(HANDLE)STD_ERROR_HANDLE
#elif defined(__OS2__)
(HFILE)0, (HFILE)1, (HFILE)2
#elif defined(__DOS__)
0, 1, 2
#else
0, 1, 2
#endif
};
if (std < 0 || std >= QSE_COUNTOF(tab)) return -1;
#if defined(_WIN32)
{
HANDLE tmp = GetStdHandle (tab[std]);
if (tmp == INVALID_HANDLE_VALUE) return -1;
*hnd = tmp;
}
#else
*hnd = tab[std];
#endif
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: sio.c 568 2011-09-17 15:41:26Z hyunghwan.chung $
* $Id: sio.c 569 2011-09-19 06:51:02Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -194,6 +194,14 @@ qse_sio_t* qse_sio_open (
return sio;
}
qse_sio_t* qse_sio_openstd (
qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_sio_std_t std, int flags)
{
qse_fio_hnd_t hnd;
if (qse_getstdfiohandle (std, &hnd) <= -1) return QSE_NULL;
return qse_sio_open (mmgr, xtnsize, &hnd, flags | QSE_SIO_HANDLE);
}
void qse_sio_close (qse_sio_t* sio)
{
qse_sio_fini (sio);
@ -235,6 +243,14 @@ int qse_sio_init (
return 0;
}
int qse_sio_initstd (
qse_sio_t* sio, qse_mmgr_t* mmgr, qse_sio_std_t std, int flags)
{
qse_fio_hnd_t hnd;
if (qse_getstdfiohandle (std, &hnd) <= -1) return -1;
return qse_sio_init (sio, mmgr, &hnd, flags | QSE_SIO_HANDLE);
}
void qse_sio_fini (qse_sio_t* sio)
{
/*if (qse_sio_flush (sio) == -1) return -1;*/

View File

@ -1,5 +1,5 @@
/*
* $Id: StdSed.cpp 556 2011-08-31 15:43:46Z hyunghwan.chung $
* $Id: StdSed.cpp 569 2011-09-19 06:51:02Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -28,68 +28,69 @@
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
static qse_sio_t* open_sio (StdSed::Stream::Data& io, const qse_char_t* file, int flags)
{
qse_sio_t* sio;
sio = qse_sio_open (((StdSed::sed_t*)io)->mmgr, 0, file, flags);
if (sio == QSE_NULL)
{
qse_cstr_t ea;
ea.ptr = file;
ea.len = qse_strlen (file);
((StdSed::Sed*)io)->setError (QSE_SED_EIOFIL, &ea);
}
return sio;
}
static qse_sio_t* open_sio_std (StdSed::Stream::Data& io, qse_sio_std_t std, int flags)
{
qse_sio_t* sio;
static const qse_char_t* std_names[] =
{
QSE_T("stdin"),
QSE_T("stdout"),
QSE_T("stderr"),
};
sio = qse_sio_openstd (((StdSed::sed_t*)io)->mmgr, 0, std, flags);
if (sio == QSE_NULL)
{
qse_cstr_t ea;
ea.ptr = std_names[std];
ea.len = qse_strlen (std_names[std]);
((StdSed::Sed*)io)->setError (QSE_SED_EIOFIL, &ea);
}
return sio;
}
int StdSed::FileStream::open (Data& io)
{
qse_sio_t* sio;
const char_t* ioname = io.getName();
int oflags;
if (io.getMode() == READ)
oflags = QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR;
else
oflags = QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR;
if (ioname == QSE_NULL)
{
//
// a normal console is indicated by a null name
//
if (io.getMode() == READ)
{
if (infile == QSE_NULL) sio = qse_sio_in;
else
{
sio = qse_sio_open (
((sed_t*)io)->mmgr,
0,
infile,
QSE_SIO_READ
);
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 = infile;
ea.len = qse_strlen (infile);
((Sed*)io)->setError (
QSE_SED_EIOFIL, &ea);
return -1;
}
}
sio = (infile == QSE_NULL)?
open_sio_std (io, QSE_SIO_STDIN, oflags):
open_sio (io, infile, oflags);
}
else
{
if (outfile == QSE_NULL) sio = qse_sio_out;
else
{
sio = qse_sio_open (
((sed_t*)io)->mmgr,
0,
outfile,
QSE_SIO_WRITE |
QSE_SIO_CREATE |
QSE_SIO_TRUNCATE
);
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 = outfile;
ea.len = qse_strlen (outfile);
((Sed*)io)->setError (
QSE_SED_EIOFIL, &ea);
return -1;
}
}
sio = (outfile == QSE_NULL)?
open_sio_std (io, QSE_SIO_STDOUT, oflags):
open_sio (io, outfile, oflags);
}
}
else
@ -97,18 +98,9 @@ int StdSed::FileStream::open (Data& io)
//
// if ioname is not empty, it is a file name
//
sio = qse_sio_open (
((sed_t*)io)->mmgr,
0,
ioname,
(io.getMode() == READ?
QSE_SIO_READ:
(QSE_SIO_WRITE|QSE_SIO_CREATE|QSE_SIO_TRUNCATE))
);
if (sio == QSE_NULL) return -1;
sio = open_sio (io, ioname, oflags);
}
if (sio == QSE_NULL) return -1;
io.setHandle (sio);
return 1;
@ -116,12 +108,7 @@ int StdSed::FileStream::open (Data& io)
int StdSed::FileStream::close (Data& io)
{
qse_sio_t* sio = (qse_sio_t*)io.getHandle();
qse_sio_flush (sio);
if (sio != qse_sio_in && sio != qse_sio_out && sio != qse_sio_err)
qse_sio_close (sio);
qse_sio_close ((qse_sio_t*)io.getHandle());
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: sed.c 568 2011-09-17 15:41:26Z hyunghwan.chung $
* $Id: sed.c 569 2011-09-19 06:51:02Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -1389,6 +1389,14 @@ static int get_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (c != QSE_T('\\'))
{
if ((sed->option & QSE_SED_SAMELINE) &&
c != QSE_CHAR_EOF && c != QSE_T('\n'))
{
/* allow text without a starting backslash
* on the same line as a command */
goto sameline_ok;
}
SETERR0 (sed, QSE_SED_EBSEXP, &sed->src.loc);
return -1;
}
@ -1399,7 +1407,11 @@ static int get_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (c != QSE_CHAR_EOF && c != QSE_T('\n'))
{
if (sed->option & QSE_SED_SAMELINE)
{
/* allow text with a starting backslash
* on the same line as a command */
goto sameline_ok;
}
SETERR0 (sed, QSE_SED_EGBABS, &sed->src.loc);
return -1;
@ -1592,9 +1604,14 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
cmd->a1.type == QSE_SED_ADR_LINE &&
cmd->a1.u.lno <= 0)
{
/* 0 is not allowed as a normal line number */
SETERR0 (sed, QSE_SED_EA1MOI, &sed->src.loc);
goto oops;
if (!(sed->option & QSE_SED_ZEROA1) ||
cmd->a2.type != QSE_SED_ADR_REX)
{
/* 0 is not allowed as a normal line number.
* 0,/regex/ is allowed */
SETERR0 (sed, QSE_SED_EA1MOI, &sed->src.loc);
goto oops;
}
}
/* skip white spaces */
@ -2891,6 +2908,18 @@ static int init_command_block_for_exec (qse_sed_t* sed, qse_sed_cmd_blk_t* b)
/* clear states */
c->state.a1_matched = 0;
if (sed->option & QSE_SED_ZEROA1)
{
if (c->a2.type == QSE_SED_ADR_REX &&
c->a1.type == QSE_SED_ADR_LINE &&
c->a1.u.lno <= 0)
{
/* special handling for 0,/regex/ */
c->state.a1_matched = 1;
}
}
c->state.c_ready = 0;
/* let c point to the next command */

View File

@ -85,18 +85,34 @@ static qse_sio_t* open_sio (qse_sed_t* sed, const qse_char_t* file, int flags)
return sio;
}
static qse_sio_t* open_sio_std (qse_sed_t* sed, qse_sio_std_t std, int flags)
{
qse_sio_t* sio;
static const qse_char_t* std_names[] =
{
QSE_T("stdin"),
QSE_T("stdout"),
QSE_T("stderr"),
};
sio = qse_sio_openstd (sed->mmgr, 0, std, flags);
if (sio == QSE_NULL)
{
qse_cstr_t ea;
ea.ptr = std_names[std];
ea.len = qse_strlen (std_names[std]);
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);
}
if (io->type == QSE_SED_IOSTD_FILE) qse_sio_close (arg->handle);
}
static int open_main_input_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io)
static int open_console_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);
@ -108,18 +124,15 @@ static int open_main_input_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_se
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;
}
{
qse_sio_t* sio;
sio = (io->u.file == QSE_NULL)?
open_sio_std (sed, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR):
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 */
@ -130,7 +143,7 @@ static int open_main_input_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_se
return 0;
}
static int open_main_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io)
static int open_console_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);
@ -142,23 +155,32 @@ static int open_main_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_s
break;
case QSE_SED_IOSTD_FILE:
{
qse_sio_t* sio;
if (io->u.file == QSE_NULL)
{
arg->handle = qse_sio_out;
}
else
{
qse_sio_t* sio;
sio = open_sio (sed, io->u.file,
sio = open_sio_std (
sed, QSE_SIO_STDOUT,
QSE_SIO_WRITE |
QSE_SIO_CREATE |
QSE_SIO_TRUNCATE |
QSE_SIO_IGNOREMBWCERR
);
if (sio == QSE_NULL) return -1;
arg->handle = sio;
}
else
{
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 */
@ -211,7 +233,7 @@ static qse_ssize_t read_main_input_stream (
old = arg->handle;
/* try to open the next input stream */
if (open_main_input_stream (sed, arg, next) <= -1)
if (open_console_input_stream (sed, arg, next) <= -1)
{
/* failed to open the next input stream */
n = -1;
@ -243,11 +265,17 @@ static qse_ssize_t xin (
{
if (arg->path == QSE_NULL)
{
/* main data stream */
if (xtn->e.in == QSE_NULL) arg->handle = qse_sio_in;
/* not file specified. console stream */
if (xtn->e.in == QSE_NULL)
{
sio = open_sio_std (
sed, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
if (sio == QSE_NULL) return -1;
arg->handle = sio;
}
else
{
if (open_main_input_stream (sed, arg, xtn->e.in_cur) <= -1) return -1;
if (open_console_input_stream (sed, arg, xtn->e.in_cur) <= -1) return -1;
}
}
else
@ -265,13 +293,14 @@ static qse_ssize_t xin (
if (arg->path == QSE_NULL)
{
/* main data stream */
if (xtn->e.in) close_main_stream (sed, arg, xtn->e.in_cur);
if (xtn->e.in == QSE_NULL)
qse_sio_close (arg->handle);
else
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);
qse_sio_close (arg->handle);
}
return 0;
@ -311,10 +340,21 @@ static qse_ssize_t xout (
{
if (arg->path == QSE_NULL)
{
if (xtn->e.out == QSE_NULL) arg->handle = qse_sio_out;
if (xtn->e.out == QSE_NULL)
{
sio = open_sio_std (
sed, QSE_SIO_STDOUT,
QSE_SIO_WRITE |
QSE_SIO_CREATE |
QSE_SIO_TRUNCATE |
QSE_SIO_IGNOREMBWCERR
);
if (sio == QSE_NULL) return -1;
arg->handle = sio;
}
else
{
if (open_main_output_stream (sed, arg, xtn->e.out) <= -1) return -1;
if (open_console_output_stream (sed, arg, xtn->e.out) <= -1) return -1;
}
}
else
@ -337,14 +377,14 @@ static qse_ssize_t xout (
{
if (arg->path == QSE_NULL)
{
if (xtn->e.out) close_main_stream (sed, arg, xtn->e.out);
if (xtn->e.out == QSE_NULL)
qse_sio_close (arg->handle);
else
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);
qse_sio_close (arg->handle);
}
return 0;
}
@ -355,7 +395,9 @@ static qse_ssize_t xout (
{
/* main data stream */
if (xtn->e.out == QSE_NULL)
{
return qse_sio_putsn (arg->handle, dat, len);
}
else
{
qse_sed_iostd_t* io = xtn->e.out;
@ -443,14 +485,30 @@ int qse_sed_execstd (
}
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;
}
int qse_sed_execstdfile (
qse_sed_t* sed, const qse_char_t* infile, const qse_char_t* outfile)
{
qse_sed_iostd_t in[2];
qse_sed_iostd_t out;
qse_sed_iostd_t* pin = QSE_NULL, * pout = QSE_NULL;
if (infile)
{
in[0].type = QSE_SED_IOSTD_FILE;
in[0].u.file = infile;
in[1].type = QSE_SED_IOSTD_NULL;
pin = in;
}
if (outfile)
{
out.type = QSE_SED_IOSTD_FILE;
out.u.file = outfile;
pout = &out;
}
return qse_sed_execstd (sed, pin, pout);
}