- Changed the way Mmgr is used. A subclass inheriting Mmged is instantiated with a pointer to Mmgr which used to be the parent class.

- Separated the I/O stream handler from the Sed class and abstracted it into Sed::IOStream.
- Implemented StdSed::StdStream.
This commit is contained in:
2009-12-19 06:34:42 +00:00
parent 232c0cc1c4
commit de7082d0d0
31 changed files with 944 additions and 630 deletions

View File

@ -11,6 +11,9 @@ awk03_SOURCES = awk03.c
awk04_SOURCES = awk04.c
if ENABLE_CXX
CXXLIB = -lqseawkxx -lqsecmnxx
bin_PROGRAMS += awk05 awk06 awk07 awk08
awk05_SOURCES = awk05.cpp
@ -18,8 +21,8 @@ awk06_SOURCES = awk06.cpp
awk07_SOURCES = awk07.cpp
awk08_SOURCES = awk08.cpp
awk05_LDADD = -lqseawkxx $(LDADD)
awk06_LDADD = -lqseawkxx $(LDADD)
awk07_LDADD = -lqseawkxx $(LDADD)
awk08_LDADD = -lqseawkxx $(LDADD)
awk05_LDADD = $(CXXLIB) $(LDADD)
awk06_LDADD = $(CXXLIB) $(LDADD)
awk07_LDADD = $(CXXLIB) $(LDADD)
awk08_LDADD = $(CXXLIB) $(LDADD)
endif

View File

@ -76,19 +76,23 @@ am__awk05_SOURCES_DIST = awk05.cpp
@ENABLE_CXX_TRUE@am_awk05_OBJECTS = awk05.$(OBJEXT)
awk05_OBJECTS = $(am_awk05_OBJECTS)
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
@ENABLE_CXX_TRUE@awk05_DEPENDENCIES = $(am__DEPENDENCIES_2)
@ENABLE_CXX_TRUE@awk05_DEPENDENCIES = $(am__DEPENDENCIES_1) \
@ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_2)
am__awk06_SOURCES_DIST = awk06.cpp
@ENABLE_CXX_TRUE@am_awk06_OBJECTS = awk06.$(OBJEXT)
awk06_OBJECTS = $(am_awk06_OBJECTS)
@ENABLE_CXX_TRUE@awk06_DEPENDENCIES = $(am__DEPENDENCIES_2)
@ENABLE_CXX_TRUE@awk06_DEPENDENCIES = $(am__DEPENDENCIES_1) \
@ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_2)
am__awk07_SOURCES_DIST = awk07.cpp
@ENABLE_CXX_TRUE@am_awk07_OBJECTS = awk07.$(OBJEXT)
awk07_OBJECTS = $(am_awk07_OBJECTS)
@ENABLE_CXX_TRUE@awk07_DEPENDENCIES = $(am__DEPENDENCIES_2)
@ENABLE_CXX_TRUE@awk07_DEPENDENCIES = $(am__DEPENDENCIES_1) \
@ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_2)
am__awk08_SOURCES_DIST = awk08.cpp
@ENABLE_CXX_TRUE@am_awk08_OBJECTS = awk08.$(OBJEXT)
awk08_OBJECTS = $(am_awk08_OBJECTS)
@ENABLE_CXX_TRUE@awk08_DEPENDENCIES = $(am__DEPENDENCIES_2)
@ENABLE_CXX_TRUE@awk08_DEPENDENCIES = $(am__DEPENDENCIES_1) \
@ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_2)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/qse
depcomp = $(SHELL) $(top_srcdir)/ac/au/depcomp
am__depfiles_maybe = depfiles
@ -266,14 +270,15 @@ awk01_SOURCES = awk01.c
awk02_SOURCES = awk02.c
awk03_SOURCES = awk03.c
awk04_SOURCES = awk04.c
@ENABLE_CXX_TRUE@CXXLIB = -lqseawkxx -lqsecmnxx
@ENABLE_CXX_TRUE@awk05_SOURCES = awk05.cpp
@ENABLE_CXX_TRUE@awk06_SOURCES = awk06.cpp
@ENABLE_CXX_TRUE@awk07_SOURCES = awk07.cpp
@ENABLE_CXX_TRUE@awk08_SOURCES = awk08.cpp
@ENABLE_CXX_TRUE@awk05_LDADD = -lqseawkxx $(LDADD)
@ENABLE_CXX_TRUE@awk06_LDADD = -lqseawkxx $(LDADD)
@ENABLE_CXX_TRUE@awk07_LDADD = -lqseawkxx $(LDADD)
@ENABLE_CXX_TRUE@awk08_LDADD = -lqseawkxx $(LDADD)
@ENABLE_CXX_TRUE@awk05_LDADD = $(CXXLIB) $(LDADD)
@ENABLE_CXX_TRUE@awk06_LDADD = $(CXXLIB) $(LDADD)
@ENABLE_CXX_TRUE@awk07_LDADD = $(CXXLIB) $(LDADD)
@ENABLE_CXX_TRUE@awk08_LDADD = $(CXXLIB) $(LDADD)
all: all-am
.SUFFIXES:

View File

@ -6,11 +6,14 @@ LDFLAGS = -L../../lib/cmn -L../../lib/sed
LDADD = -lqsesed -lqsecmn $(LIBM)
if ENABLE_CXX
CXXLIB = -lqsesedxx -lqsecmnxx
bin_PROGRAMS += sed02 sed03
sed02_SOURCES = sed02.cpp
sed02_LDADD = -lqsesedxx $(LDADD)
sed02_LDADD = $(CXXLIB) $(LDADD)
sed03_SOURCES = sed03.cpp
sed03_LDADD = -lqsesedxx $(LDADD)
sed03_LDADD = $(CXXLIB) $(LDADD)
endif

View File

@ -58,11 +58,13 @@ am__sed02_SOURCES_DIST = sed02.cpp
sed02_OBJECTS = $(am_sed02_OBJECTS)
am__DEPENDENCIES_1 =
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
@ENABLE_CXX_TRUE@sed02_DEPENDENCIES = $(am__DEPENDENCIES_2)
@ENABLE_CXX_TRUE@sed02_DEPENDENCIES = $(am__DEPENDENCIES_1) \
@ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_2)
am__sed03_SOURCES_DIST = sed03.cpp
@ENABLE_CXX_TRUE@am_sed03_OBJECTS = sed03.$(OBJEXT)
sed03_OBJECTS = $(am_sed03_OBJECTS)
@ENABLE_CXX_TRUE@sed03_DEPENDENCIES = $(am__DEPENDENCIES_2)
@ENABLE_CXX_TRUE@sed03_DEPENDENCIES = $(am__DEPENDENCIES_1) \
@ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_2)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/qse
depcomp = $(SHELL) $(top_srcdir)/ac/au/depcomp
am__depfiles_maybe = depfiles
@ -222,10 +224,11 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_srcdir)/include
LDADD = -lqsesed -lqsecmn $(LIBM)
@ENABLE_CXX_TRUE@CXXLIB = -lqsesedxx -lqsecmnxx
@ENABLE_CXX_TRUE@sed02_SOURCES = sed02.cpp
@ENABLE_CXX_TRUE@sed02_LDADD = -lqsesedxx $(LDADD)
@ENABLE_CXX_TRUE@sed02_LDADD = $(CXXLIB) $(LDADD)
@ENABLE_CXX_TRUE@sed03_SOURCES = sed03.cpp
@ENABLE_CXX_TRUE@sed03_LDADD = -lqsesedxx $(LDADD)
@ENABLE_CXX_TRUE@sed03_LDADD = $(CXXLIB) $(LDADD)
all: all-am
.SUFFIXES:

View File

@ -20,14 +20,20 @@
#include <qse/sed/StdSed.hpp>
#include <qse/cmn/main.h>
#include <qse/cmn/stdio.h>
#include <iostream>
#ifdef QSE_CHAR_IS_MCHAR
# define xcout std::cout
#else
# define xcout std::wcout
#endif
int sed_main (int argc, qse_char_t* argv[])
{
if (argc != 2)
if (argc < 2 || argc > 4)
{
qse_fprintf (QSE_STDERR,
QSE_T("usage: %s command-string\n"), argv[0]);
xcout << QSE_T("USAGE: ") << argv[0] <<
QSE_T(" command-string [input-file [output-file]]") << std::endl;
return -1;
}
@ -35,23 +41,24 @@ int sed_main (int argc, qse_char_t* argv[])
if (sed.open () == -1)
{
qse_printf (QSE_T("cannot open a stream editor - %s\n"),
sed.getErrorMessage());
xcout << QSE_T("ERR: cannot open") << std::endl;
return -1;
}
if (sed.compile (argv[1]) == -1)
{
qse_printf (QSE_T("cannot compile - %s\n"),
sed.getErrorMessage());
xcout << QSE_T("ERR: cannot compile - ") << sed.getErrorMessage() << std::endl;
sed.close ();
return -1;
}
if (sed.execute () == -1)
qse_char_t* infile = (argc >= 3)? argv[2]: QSE_NULL;
qse_char_t* outfile = (argc >= 4)? argv[3]: QSE_NULL;
QSE::StdSed::StdStream stream (infile, outfile);
if (sed.execute (stream) == -1)
{
qse_printf (QSE_T("cannot execute - %s\n"),
sed.getErrorMessage());
xcout << QSE_T("ERR: cannot execute - ") << sed.getErrorMessage() << std::endl;
sed.close ();
return -1;
}
@ -60,7 +67,7 @@ int sed_main (int argc, qse_char_t* argv[])
return 0;
}
int qse_main (int argc, char* argv[])
int qse_main (int argc, qse_achar_t* argv[])
{
return qse_runmain (argc, argv, sed_main);
}

View File

@ -20,6 +20,7 @@
#include <qse/sed/StdSed.hpp>
#include <qse/cmn/main.h>
#include <qse/cmn/sio.h>
#include <string>
#include <iostream>
@ -30,13 +31,111 @@
# define xcout std::wcout
#endif
typedef std::basic_string<QSE::StdSed::char_t> xstring;
typedef QSE::StdSed StdSed; // added for doxygen cross-reference
//
// The StringStream class implements a data I/O stream over strings.
//
class StringStream: public QSE::StdSed::IOStream
{
public:
StringStream (const char_t* in) { this->in.ptr = in; }
int open (Data& io)
{
const char_t* ioname = io.getName ();
if (ioname == QSE_NULL)
{
// open a main data stream
if (io.getMode() == READ)
{
in.cur = in.ptr;
io.setHandle ((void*)in.ptr);
}
else
{
out.erase ();
io.setHandle (&out);
}
}
else
{
// open files for a r or w command
qse_sio_t* sio;
int mode = (io.getMode() == READ)?
QSE_SIO_READ:
(QSE_SIO_WRITE|QSE_SIO_CREATE|QSE_SIO_TRUNCATE);
sio = qse_sio_open (((QSE::Sed*)io)->getMmgr(), 0, ioname, mode);
if (sio == QSE_NULL) return -1;
io.setHandle (sio);
}
return 1;
}
int close (Data& io)
{
const void* handle = io.getHandle();
if (handle != in.ptr && handle != &out)
qse_sio_close ((qse_sio_t*)handle);
return 0;
}
ssize_t read (Data& io, char_t* buf, size_t len)
{
const void* handle = io.getHandle();
if (handle == in.ptr)
{
ssize_t n = qse_strxcpy (buf, len, in.cur);
in.cur += n; return n;
}
else
{
QSE_ASSERT (handle != &out);
return qse_sio_getsn ((qse_sio_t*)handle, buf, len);
}
}
ssize_t write (Data& io, const char_t* buf, size_t len)
{
const void* handle = io.getHandle();
if (handle == &out)
{
try
{
out.append (buf, len);
return len;
}
catch (...)
{
((QSE::Sed*)io)->setError (QSE_SED_ENOMEM);
throw;
}
}
else
{
QSE_ASSERT (handle != in.ptr);
return qse_sio_putsn ((qse_sio_t*)handle, buf, len);
}
}
const char_t* getInput () const { return in.ptr; }
const char_t* getOutput () const { return out.c_str (); }
protected:
struct
{
const char_t* ptr;
const char_t* cur;
} in;
std::basic_string<char_t> out;
};
//
// The MySed class provides a handier interface to QSE::StdSed by
// reimplementing console I/O functions, combining compile() and execute(),
// and utilizing exception handling.
// The MySed class simplifies QSE::StdSed by utilizing exception handling.
//
class MySed: protected QSE::StdSed
{
@ -45,65 +144,26 @@ public:
class Error
{
public:
Error (const char_t* msg) throw (): msg (msg) { }
Error (const char_t* msg) throw (): msg (msg) {}
const char_t* getMessage() const throw() { return msg; }
protected:
const char_t* msg;
};
MySed ()
{
if (QSE::StdSed::open() == -1)
throw Error (QSE_T("cannot open"));
}
MySed () { if (open() <= -1) throw Error (QSE_T("cannot open")); }
~MySed () { close (); }
~MySed ()
{
QSE::StdSed::close ();
}
void run (const char_t* cmds, const char_t* in, xstring& out)
void compile (const char_t* sptr)
{
// remember an input string and an output string
this->in = in; this->out = &out;
// compile source commands and execute compiled commands.
if (QSE::StdSed::compile (cmds) <= -1 ||
QSE::StdSed::execute () <= -1)
{
throw Error (QSE::StdSed::getErrorMessage());
}
if (QSE::StdSed::compile (sptr) <= -1)
throw Error (getErrorMessage());
}
protected:
// override console I/O functions to perform I/O over strings.
int openConsole (Console& io)
{
if (io.getMode() == Console::WRITE) out->clear();
return 1;
}
int closeConsole (Console& io)
void execute (IOStream& stream)
{
return 0;
if (QSE::StdSed::execute (stream) <= -1)
throw Error (getErrorMessage());
}
ssize_t readConsole (Console& io, char_t* buf, size_t len)
{
ssize_t n = qse_strxcpy (buf, len, in);
in += n; return n;
}
ssize_t writeConsole (Console& io, const char_t* buf, size_t len)
{
try { out->append (buf, len); return len; }
catch (...) { QSE::Sed::setError (QSE_SED_ENOMEM); throw; }
}
protected:
const char_t* in;
xstring* out;
};
int sed_main (int argc, qse_char_t* argv[])
@ -111,12 +171,14 @@ int sed_main (int argc, qse_char_t* argv[])
try
{
MySed sed;
xstring out;
sed.run (
QSE_T("y/ABC/abc/;s/abc/def/g"),
QSE_T("ABCDEFabcdef"), out);
xcout << QSE_T("OUTPUT: ") << out << std::endl;
sed.compile (QSE_T("y/ABC/abc/;s/abc/def/g"));
StringStream stream (QSE_T("ABCDEFabcdef"));
sed.execute (stream);
xcout << QSE_T("INPUT: ") << stream.getInput() << std::endl;
xcout << QSE_T("OUTPUT: ") << stream.getOutput() << std::endl;
}
catch (MySed::Error& err)
{
@ -127,7 +189,7 @@ int sed_main (int argc, qse_char_t* argv[])
return 0;
}
int qse_main (int argc, char* argv[])
int qse_main (int argc, qse_achar_t* argv[])
{
return qse_runmain (argc, argv, sed_main);
}