enhanced the Sed class with a few more methods

This commit is contained in:
2009-05-28 23:00:24 +00:00
parent fb9cdaa1c0
commit 9dfcf671a4
8 changed files with 268 additions and 426 deletions

View File

@ -36,15 +36,23 @@ QSE_BEGIN_NAMESPACE(QSE)
class Sed: public Mmgr
{
public:
/// Type sed_t type redefines a stream editor type
typedef qse_sed_t sed_t;
typedef qse_sed_errnum_t errnum_t;
/// The errnum_t type redefines an error number type
typedef qse_sed_errnum_t errnum_t;
/// The errstr_t type redefines an error formattering string getter type
typedef qse_sed_errstr_t errstr_t;
/// The io_cmd_t type redefines an IO command type
typedef qse_sed_io_cmd_t io_cmd_t;
/// The io_arg_t type redefines an IO data type
typedef qse_sed_io_arg_t io_arg_t;
/// The option_t type redefines an option type
typedef qse_sed_option_t option_t;
/**
* The Sed() function creates a uninitialized stream editor.
* The Sed() function creates an uninitialized stream editor.
*/
Sed () throw (): sed (QSE_NULL) {}
Sed () throw (): sed (QSE_NULL), dflerrstr (QSE_NULL) {}
/**
* The open() function initializes a stream editor and makes it
@ -54,7 +62,7 @@ public:
int open () throw ();
/**
* The close() function finalized a stream editor.
* The close() function finalizes a stream editor.
*/
void close () throw ();
@ -84,34 +92,48 @@ public:
*/
int execute () throw ();
/**
* The getOption() function gets the current options.
* @return current option code
*/
int getOption () const throw ();
/**
* The setOption() function sets options for a stream editor.
* The option code @a opt is 0 or OR'ed of #option_t enumerators.
*/
void setOption (
int opt ///< option code
) throw ();
/**
* The getErrorMessage() function gets the description of the last
* error occurred. It returns an empty string if the stream editor
* has not been initialized with the open() function.
*/
const char_t* getErrorMessage() const;
const char_t* getErrorMessage() const throw ();
/**
* The getErrorLine() function gets the number of the line where
* the last error occurred. It returns 0 if the stream editor has
* not been initialized with the open() function.
*/
size_t getErrorLine () const;
size_t getErrorLine () const throw ();
/**
* The getErrorNumber() function gets the number of the last
* error occurred. It returns 0 if the stream editor has not been
* initialized with the open function.
* error occurred. It returns QSE_SED_ENOERR if the stream editor
* has not been initialized with the open() function.
*/
errnum_t getErrorNumber () const;
errnum_t getErrorNumber () const throw ();
protected:
/**
* The IO class is a base class for IO operation. It wraps around the
* qse_sed_io_arg_t type and exposes relevant information to
* The IOBase class is a base class for IO operation. It wraps around
* the primitive Sed::io_arg_t type and exposes relevant information to
* an IO handler
*/
class IO
class IOBase
{
public:
/**
@ -124,7 +146,7 @@ protected:
};
protected:
IO (io_arg_t* arg, Mode mode): arg(arg), mode (mode) {}
IOBase (io_arg_t* arg, Mode mode): arg(arg), mode (mode) {}
public:
/**
@ -168,22 +190,22 @@ protected:
* The Console class inherits the IO class and provides functionality
* for console IO operations.
*/
class Console: public IO
class Console: public IOBase
{
protected:
friend class Sed;
Console (io_arg_t* arg, Mode mode): IO (arg, mode) {}
Console (io_arg_t* arg, Mode mode): IOBase (arg, mode) {}
};
/**
* The File class inherits the IO class and provides functionality
* for file IO operations.
*/
class File: public IO
class File: public IOBase
{
protected:
friend class Sed;
File (io_arg_t* arg, Mode mode): IO (arg, mode) {}
File (io_arg_t* arg, Mode mode): IOBase (arg, mode) {}
public:
/**
@ -199,28 +221,131 @@ protected:
/**
* The openConsole() function should be implemented by a subclass
* to open a console
* to open a console. It can get the mode requested by invoking
* the Console::getMode() function over the console object @a io.
*
* When it comes to the meaning of the return value, 0 may look
* a bit tricky. Easygoers can just return 1 on success and never
* return 0 from openConsole().
* - If 0 is returned for a Console::READ console, the execute()
* function returns success after having calle closeConsole() as it
* has opened a console but has reached EOF.
* - If 0 is returned for a Console::WRITE console and there are any
* following writeConsole() requests, the execute() function
* returns failure after having called closeConsole() as it cannot
* write further on EOF.
*
* @return -1 on failure, 1 on success, 0 on success but reached EOF.
*/
virtual int openConsole (Console& io) = 0;
virtual int closeConsole (Console& io) = 0;
virtual ssize_t readConsole (
Console& io, char_t* buf, size_t len) = 0;
virtual ssize_t writeConsole (
Console& io, const char_t* data, size_t len) = 0;
virtual int openConsole (
Console& io ///< a console object
) = 0;
virtual int openFile (File& io) = 0;
virtual int closeFile (File& io) = 0;
/**
* The closeConsole() function should be implemented by a subclass
* to close a console.
*/
virtual int closeConsole (
Console& io ///< a console object
) = 0;
/**
* The readConsole() function should be implemented by a subclass
* to read from a console. It should fill the memory area pointed to
* by @a buf, but at most \a len characters.
* @return the number of characters read on success,
* 0 on EOF, -1 on failure
*/
virtual ssize_t readConsole (
Console& io, ///< a console object
char_t* buf, ///< a buffer pointer
size_t len ///< the size of a buffer
) = 0;
/**
* The writeConsole() function should be implemented by a subclass
* to write to a console. It should write up to @a len characters
* from the memory are pointed to by @a data.
* @return the number of characters written on success
* 0 on EOF, -1 on failure
* @note The number of characters written may be less than @a len.
* But the return value 0 causes execute() to fail as
* writeConsole() is called when there are data to write and
* it has indicated EOF.
*/
virtual ssize_t writeConsole (
Console& io, ///< a console object
const char_t* data, ///< a pointer to data to write
size_t len ///< the length of data
) = 0;
/**
* The openFile() function should be implemented by a subclass
* to open a file. It can get the mode requested by invoking
* the File::getMode() function over the file object @a io.
* @return -1 on failure, 1 on success, 0 on success but reached EOF.
*/
virtual int openFile (
File& io ///< a file object
) = 0;
/**
* The closeFile() function should be implemented by a subclass
* to close a file.
*/
virtual int closeFile (
File& io ///< a file object
) = 0;
/**
* The readFile() function should be implemented by a subclass
* to read from a file. It should fill the memory area pointed to
* by @a buf, but at most \a len characters.
* @return the number of characters read on success,
* 0 on EOF, -1 on failure
*/
virtual ssize_t readFile (
File& io, char_t* buf, size_t len) = 0;
File& io, ///< a file object
char_t* buf, ///< a buffer pointer
size_t len ///< the size of a buffer
) = 0;
/**
* The writeFile() function should be implemented by a subclass
* to write to a file. It should write up to @a len characters
* from the memory are pointed to by @a data.
* @return the number of characters written on success
* 0 on EOF, -1 on failure
* @note The number of characters written may be less than @a len.
* But the return value 0 causes execute() to fail as
* writeFile() is called when there are data to write and
* it has indicated EOF.
*/
virtual ssize_t writeFile (
File& io, const char_t* data, size_t len) = 0;
File& io, ///< a file object
const char_t* data, ///< a pointer to data to write
size_t len ///< the length of data
) = 0;
/**
* The getErrorString() function returns an error formatting string
* for the error number @a num. A subclass wishing to customize
* an error formatting string may override this function.
*/
virtual const char_t* getErrorString (
errnum_t num ///< an error number
);
protected:
/// handle to a primitive sed object
sed_t* sed;
/// default error formatting string getter
errstr_t dflerrstr;
private:
static ssize_t xin (sed_t* s, io_cmd_t cmd, io_arg_t* arg) throw ();
static ssize_t xout (sed_t* s, io_cmd_t cmd, io_arg_t* arg) throw ();
static const char_t* xerrstr (sed_t* s, errnum_t num) throw ();
};
/////////////////////////////////

View File

@ -60,48 +60,53 @@ typedef struct qse_sed_t qse_sed_t;
*/
enum qse_sed_errnum_t
{
QSE_SED_ENOERR, /**< no error occurred */
QSE_SED_ENOMEM, /**< insufficient memory is available */
QSE_SED_ECMDNR, /**< a command is not recognized */
QSE_SED_ECMDMS, /**< a command is missing */
QSE_SED_ECMDIC, /**< a command is incomplete */
QSE_SED_EREXIC, /**< regular expression incomplete */
QSE_SED_EREXBL, /**< regular expression build error */
QSE_SED_EREXMA, /**< regular expression match error */
QSE_SED_EA1PHB, /**< address 1 prohibited */
QSE_SED_ENOERR, /**< no error */
QSE_SED_ENOMEM, /**< out of memory */
QSE_SED_ECMDNR, /**< command '${0}' not recognized */
QSE_SED_ECMDMS, /**< command code missing */
QSE_SED_ECMDIC, /**< command '${0}' incomplete */
QSE_SED_EREXIC, /**< regular expression '${0}' incomplete */
QSE_SED_EREXBL, /**< failed to compile regular expression '${0}' */
QSE_SED_EREXMA, /**< failed to match regular expression */
QSE_SED_EA1PHB, /**< address 1 prohibited for '${0}' */
QSE_SED_EA2PHB, /**< address 2 prohibited */
QSE_SED_EA2MOI, /**< address 2 missing or invalid */
QSE_SED_ENEWLN, /**< a new line is expected */
QSE_SED_EBSEXP, /**< \ is expected */
QSE_SED_EBSDEL, /**< \ used a delimiter */
QSE_SED_EGBABS, /**< garbage after \ */
QSE_SED_ESCEXP, /**< ; is expected */
QSE_SED_ELABEM, /**< label name is empty */
QSE_SED_ELABDU, /**< duplicate label name */
QSE_SED_ELABNF, /**< label not found */
QSE_SED_EFILEM, /**< file name is empty */
QSE_SED_ENEWLN, /**< newline expected */
QSE_SED_EBSEXP, /**< backslash expected */
QSE_SED_EBSDEL, /**< backslash used as delimiter */
QSE_SED_EGBABS, /**< garbage after backslash */
QSE_SED_ESCEXP, /**< semicolon expected */
QSE_SED_ELABEM, /**< empty label name */
QSE_SED_ELABDU, /**< duplicate label name '${0}' */
QSE_SED_ELABNF, /**< label '${0}' not found */
QSE_SED_EFILEM, /**< empty file name */
QSE_SED_EFILIL, /**< illegal file name */
QSE_SED_ETSNSL, /**< translation set not the same length*/
QSE_SED_ETSNSL, /**< strings in translation set not the same length*/
QSE_SED_EGRNBA, /**< group brackets not balanced */
QSE_SED_EGRNTD, /**< group nested too deeply */
QSE_SED_EGRNTD, /**< group nesting too deep */
QSE_SED_EOCSDU, /**< multiple occurrence specifiers */
QSE_SED_EOCSZE, /**< occurrence specifier to s is zero */
QSE_SED_EOCSZE, /**< occurrence specifier zero */
QSE_SED_EOCSTL, /**< occurrence specifier too large */
QSE_SED_EIOFIL, /**< file io error */
QSE_SED_EIOUSR /**< user io error */
QSE_SED_EIOFIL, /**< io error with file '${0}'*/
QSE_SED_EIOUSR /**< error returned by user io handler */
};
typedef enum qse_sed_errnum_t qse_sed_errnum_t;
/**
* The qse_sed_errstr_t type defines a prototype for an error string getter.
* The qse_sed_errstr_t type defines a error string getter. It should return
* an error formatting string for an error number requested. A new string
* should contain the same number of positional parameters (${X}) as in the
* default error formatting string. You can set a new getter into a stream
* editor with the qse_sed_seterrstr() function to customize an error string.
*/
typedef const qse_char_t* (*qse_sed_errstr_t) (
qse_sed_t* sed, qse_sed_errnum_t errnum
qse_sed_t* sed, /**< a stream editor */
qse_sed_errnum_t num /**< an error number */
);
/**
* The qse_sed_option_t type defines various option codes for a stream editor.
* Options can be XOR'ed with each other and be passed to a stream editor with
* Options can be OR'ed with each other and be passed to a stream editor with
* the qse_sed_setoption() function.
*/
enum qse_sed_option_t
@ -112,6 +117,7 @@ enum qse_sed_option_t
QSE_SED_QUIET = (1 << 3), /**< do not print pattern space */
QSE_SED_CLASSIC = (1 << 4) /**< disable extended features */
};
typedef enum qse_sed_option_t qse_sed_option_t;
/**
* The qse_sed_io_cmd_t type defines IO command codes. The code indicates
@ -131,21 +137,23 @@ typedef enum qse_sed_io_cmd_t qse_sed_io_cmd_t;
*/
struct qse_sed_io_arg_t
{
void* handle;
const qse_char_t* path;
void* handle; /**< IO handle */
const qse_char_t* path; /**< file path. QSE_NULL for a console */
union
{
/** read buffer */
struct
{
qse_char_t* buf;
qse_size_t len;
qse_char_t* buf; /**< buffer pointer */
qse_size_t len; /**< buffer size */
} r;
/** data to write */
struct
{
const qse_char_t* data;
qse_size_t len;
const qse_char_t* data; /**< data pointer */
qse_size_t len; /**< data length */
} w;
} u;
};
@ -193,7 +201,7 @@ void qse_sed_close (
/**
* The qse_sed_getoption() function retrieves the current options set in
* a stream editor.
* @return 0 or a number XOR'ed of qse_sed_option_t values
* @return 0 or a number OR'ed of qse_sed_option_t values
*/
int qse_sed_getoption (
qse_sed_t* sed /**< a stream editor */
@ -204,7 +212,7 @@ int qse_sed_getoption (
*/
void qse_sed_setoption (
qse_sed_t* sed, /**< a stream editor */
int opt /**< 0 or a number XOR'ed of qse_sed_option_t values */
int opt /**< 0 or a number OR'ed of qse_sed_option_t values */
);
/**
@ -215,7 +223,28 @@ qse_sed_errstr_t qse_sed_geterrstr (
);
/**
* The qse_sed_seterrstr() sets an error string getter.
* The qse_sed_seterrstr() sets an error string getter that is called to
* compose an error message when its retrieval is requested.
*
* Here is an example of changing the formatting string for the #QSE_SED_ECMDNR
* error.
* @code
* qse_sed_errstr_t orgerrstr;
*
* const qse_char_t* myerrstr (qse_sed_t* sed, qse_sed_errnum_t num)
* {
* if (num == QSE_SED_ECMDNR) return QSE_T("unrecognized command ${0}");
* return orgerrstr (sed, num);
* }
* int main ()
* {
* qse_sed_t* sed;
* ...
* orgerrstr = qse_sed_geterrstr (sed);
* qse_sed_seterrstr (sed, myerrstr);
* ...
* }
* @endcode
*/
void qse_sed_seterrstr (
qse_sed_t* sed, /**< a stream editor */