improved error handling functions in sed

This commit is contained in:
hyung-hwan 2009-05-22 00:17:17 +00:00
parent a4638abf6d
commit 1893905652
10 changed files with 382 additions and 146 deletions

View File

@ -581,7 +581,7 @@ INPUT_ENCODING = UTF-8
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
FILE_PATTERNS = *.h *.c FILE_PATTERNS = *.h *.c *.hpp *.cpp
# The RECURSIVE tag can be used to turn specify whether or not subdirectories # The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO. # should be searched for input files as well. Possible values are YES and NO.

View File

@ -26,6 +26,13 @@
QSE_BEGIN_NAMESPACE(QSE) QSE_BEGIN_NAMESPACE(QSE)
///////////////////////////////// /////////////////////////////////
/**
* The Mmgr class defines a memory manager interface that can be inherited
* by a class in need of a memory manager as defined in the primitive
* qse_mmgr_t type. Using the class over the primitive type enables you to
* write code in more object-oriented fashion. An inheriting class should
* implement three pure virtual functions.
*/
class Mmgr: public qse_mmgr_t class Mmgr: public qse_mmgr_t
{ {
public: public:
@ -40,20 +47,54 @@ public:
virtual ~Mmgr () {} virtual ~Mmgr () {}
protected: protected:
virtual void* allocMem (qse_size_t n) throw () = 0; /**
virtual void* reallocMem (void* ptr, qse_size_t n) throw () = 0; * The allocMem() function allocates a chunk of memory of the
virtual void freeMem (void* ptr) throw () = 0; * size \a n and return the pointer to the beginning of the chunk.
* If it fails to allocate memory, it should return QSE_NULL.
*/
virtual void* allocMem (
qse_size_t n /**< the size of allocate in bytes */
) throw () = 0;
/**
* The reallocMem() function resizes a chunk of memory previously
* allocated with the allocMem() function. When resized, the contents
* of a surviving memory chunk is left untouched. If it fails to
* resize memory, it should return QSE_NULL.
*/
virtual void* reallocMem (
void* ptr, /**< a pointer to a memory chunk to resize */
qse_size_t n /**< new size in bytes */
) throw () = 0;
/**
* The freeMem() function frees a chunk of memory allocated with
* the allocMem() function or resized with the reallocMem() function.
*/
virtual void freeMem (
void* ptr /**< a pointer to a memory chunk to free */
) throw () = 0;
protected:
/**
* a bridge function from the qse_mmgr_t type the allocMem() function.
*/
static void* alloc_mem (void* data, qse_size_t n) throw () static void* alloc_mem (void* data, qse_size_t n) throw ()
{ {
return ((Mmgr*)data)->allocMem (n); return ((Mmgr*)data)->allocMem (n);
} }
/**
* a bridge function from the qse_mmgr_t type the reallocMem() function.
*/
static void* realloc_mem (void* data, void* ptr, qse_size_t n) throw () static void* realloc_mem (void* data, void* ptr, qse_size_t n) throw ()
{ {
return ((Mmgr*)data)->reallocMem (ptr, n); return ((Mmgr*)data)->reallocMem (ptr, n);
} }
/**
* a bridge function from the qse_mmgr_t type the freeMem() function.
*/
static void free_mem (void* data, void* ptr) throw () static void free_mem (void* data, void* ptr) throw ()
{ {
return ((Mmgr*)data)->freeMem (ptr); return ((Mmgr*)data)->freeMem (ptr);

View File

@ -1,5 +1,5 @@
/* /*
* $Id: macros.h 140 2009-05-18 12:55:01Z hyunghwan.chung $ * $Id: macros.h 150 2009-05-21 06:17:17Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -202,13 +202,23 @@
qse_mmgr_t* mmgr; qse_mmgr_t* mmgr;
/** /**
* The QSE_DEFINE_COMMON_FUNcTIONS() macro defines common object functions. * The QSE_DEFINE_COMMON_FUNCTIONS() macro defines common object functions.
* - @code void qse_xxx_setmmgr (qse_xxx_t* xxx, qse_mmgr_t* mmgr); @endcode
* The qse_xxx_setmmgr() function change the memory manager of a relevant
* object. Take extreme care if you want to use this function.
* - @code qse_mmgr_t* qse_xxx_getmmgr (qse_xxx_t* xxx); @endcode
* The qse_xxx_getmmgr() function returns the memory manager of a relevant
* object.
* - @code void qse_xxx_getxtn (qse_xxx_t* xxx); @endcode
* The qse_xxx_getxtn() function returns the pointer to an extension area
* of a relevant object created with an extension size greater than 0.
*/ */
#define QSE_DEFINE_COMMON_FUNCTIONS(name) \ #define QSE_DEFINE_COMMON_FUNCTIONS(name) \
void qse_##name##_setmmgr (qse_##name##_t* name, qse_mmgr_t* mmgr); \ void qse_##name##_setmmgr (qse_##name##_t* name, qse_mmgr_t* mmgr); \
qse_mmgr_t* qse_##name##_getmmgr (qse_##name##_t* name); \ qse_mmgr_t* qse_##name##_getmmgr (qse_##name##_t* name); \
void* qse_##name##_getxtn (qse_##name##_t* name); void* qse_##name##_getxtn (qse_##name##_t* name);
/** /**
* The QSE_MMGR() macro gets the memory manager field from an object. * The QSE_MMGR() macro gets the memory manager field from an object.
*/ */

View File

@ -65,7 +65,7 @@ enum qse_sed_errnum_t
QSE_SED_ETMTXT, /**< too much text */ QSE_SED_ETMTXT, /**< too much text */
QSE_SED_ECMDNR, /**< a command is not recognized */ QSE_SED_ECMDNR, /**< a command is not recognized */
QSE_SED_ECMDMS, /**< a command is missing */ QSE_SED_ECMDMS, /**< a command is missing */
QSE_SED_ECMDGB, /**< command garbled */ QSE_SED_ECMDIC, /**< a command is incomplete */
QSE_SED_EREXBL, /**< regular expression build error */ QSE_SED_EREXBL, /**< regular expression build error */
QSE_SED_EREXMA, /**< regular expression match error */ QSE_SED_EREXMA, /**< regular expression match error */
QSE_SED_EA1PHB, /**< address 1 prohibited */ QSE_SED_EA1PHB, /**< address 1 prohibited */
@ -76,13 +76,11 @@ enum qse_sed_errnum_t
QSE_SED_EBSDEL, /**< \ used a delimiter */ QSE_SED_EBSDEL, /**< \ used a delimiter */
QSE_SED_EGBABS, /**< garbage after \ */ QSE_SED_EGBABS, /**< garbage after \ */
QSE_SED_ESCEXP, /**< ; is expected */ QSE_SED_ESCEXP, /**< ; is expected */
QSE_SED_ELABTL, /**< label too long */
QSE_SED_ELABEM, /**< label name is empty */ QSE_SED_ELABEM, /**< label name is empty */
QSE_SED_ELABDU, /**< duplicate label name */ QSE_SED_ELABDU, /**< duplicate label name */
QSE_SED_ELABNF, /**< label not found */ QSE_SED_ELABNF, /**< label not found */
QSE_SED_EFILEM, /**< file name is empty */ QSE_SED_EFILEM, /**< file name is empty */
QSE_SED_EFILIL, /**< illegal file name */ QSE_SED_EFILIL, /**< illegal file name */
QSE_SED_ENOTRM, /**< not terminated properly */
QSE_SED_ETSNSL, /**< translation set not the same length*/ QSE_SED_ETSNSL, /**< translation set not the same length*/
QSE_SED_EGRNBA, /**< group brackets not balanced */ QSE_SED_EGRNBA, /**< group brackets not balanced */
QSE_SED_EGRNTD, /**< group nested too deeply */ QSE_SED_EGRNTD, /**< group nested too deeply */
@ -169,8 +167,15 @@ extern "C" {
QSE_DEFINE_COMMON_FUNCTIONS (sed) QSE_DEFINE_COMMON_FUNCTIONS (sed)
/** /**
* The qse_sed_open() function creates a stream editor. * The qse_sed_open() function creates a stream editor object. A memory
* @return A pointer to a stream editor on success, QSE_NULL on a failure * manager provided is used to allocate and destory the object and any dynamic
* data through out its lifetime. An extension area is allocated if an
* extension size greater than 0 is specified. You can access it with the
* qse_sed_getxtn() function and use it to store arbitrary data associated
* with the object. See #QSE_DEFINE_COMMON_FUNCTIONS() for qse_sed_getxtn().
* When done, you should destroy the object with the qse_sed_close() function
* to avoid any resource leaks including memory.
* @return A pointer to a stream editor on success, QSE_NULL on failure
*/ */
qse_sed_t* qse_sed_open ( qse_sed_t* qse_sed_open (
qse_mmgr_t* mmgr, /**< a memory manager */ qse_mmgr_t* mmgr, /**< a memory manager */
@ -202,13 +207,54 @@ void qse_sed_setoption (
); );
/** /**
* The qse_sed_geterrmsg() function retrieves an error message * The qse_sed_geterrnum() function gets the number of the last error.
* @return a pointer to a string describing an error occurred * @return the number of the last error
*/
int qse_sed_geterrnum (
qse_sed_t* sed /**< a stream editor */
);
/**
* The qse_sed_geterrlin() function gets the number of the line where
* the last error has occurred.
* @return the line number of the last error
*/
qse_size_t qse_sed_geterrlin (
qse_sed_t* sed /**< a stream editor */
);
/**
* The qse_sed_geterrmsg() function gets a string describing the last error.
* @return a pointer to an error message
*/ */
const qse_char_t* qse_sed_geterrmsg ( const qse_char_t* qse_sed_geterrmsg (
qse_sed_t* sed /**< a stream editor */ qse_sed_t* sed /**< a stream editor */
); );
/**
* The qse_sed_geterror() function gets an error number, an error line, and
* an error message. The information is set to the memory area pointed to by
* each parameter.
*/
void qse_sed_geterror (
qse_sed_t* sed, /**< a stream editor */
int* errnum, /**< a pointer to an error number holder */
qse_size_t* errlin, /**< a pointer to an error line holder */
const qse_char_t** errmsg /**< a pointer to an error message */
);
/**
* The qse_sed_seterror() function sets an error number, an error line, and
* an error message. An error string is composed of a formatting string
* and an array of formatting parameters.
*/
void qse_sed_seterror (
qse_sed_t* sed, /**< a stream editor */
int errnum, /**< an error number */
qse_size_t errlin, /**< an error line */
const qse_cstr_t* errarg /**< a string array for formatting an error message */
);
/** /**
* The qse_sed_comp() function compiles editing commands into an internal form. * The qse_sed_comp() function compiles editing commands into an internal form.
* @return 0 on success, -1 on error * @return 0 on success, -1 on error

View File

@ -1,5 +1,5 @@
/* /*
* $Id: types.h 127 2009-05-07 13:15:04Z hyunghwan.chung $ * $Id: types.h 150 2009-05-21 06:17:17Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -404,16 +404,37 @@ struct qse_cstr_t
typedef struct qse_cstr_t qse_cstr_t; typedef struct qse_cstr_t qse_cstr_t;
/******/ /******/
/****t* Base/qse_mmgr_t /**
* NAME * The qse_mmgr_t type defines a set type of functions for memory management.
* qse_mmgr_t - define a memory manager * As the type is merely a structure, it is just used as a single container
* SYNOPSIS * for memory management functions with a pointer to user-defined data.
* The user-defined \a data is passed to each memory management function
* whenever it is called. You can allocate, reallocate, and free a memory
* chunk.
*
* For example, a qse_xxx_open() function accepts a pointer of the qse_mmgr_t *
* type and the xxx object uses it to manage dynamic data within the object.
*/ */
struct qse_mmgr_t struct qse_mmgr_t
{ {
/**
* allocate a memory chunk of the size \a n.
* @return a pointer to a memory chunk on success, QSE_NULL on failure.
*/
void* (*alloc) (void* data, qse_size_t n); void* (*alloc) (void* data, qse_size_t n);
/**
* resize a memory chunk pointed to by \a ptr to the size \a n.
* @return a pointer to a memory chunk on success, QSE_NULL on failure.
*/
void* (*realloc) (void* data, void* ptr, qse_size_t n); void* (*realloc) (void* data, void* ptr, qse_size_t n);
/**
* frees a memory chunk pointed to by \a ptr.
*/
void (*free) (void* data, void* ptr); void (*free) (void* data, void* ptr);
/**
* a pointer to user-defined data passed as the first parameter to
* alloc(), realloc(), and free().
*/
void* data; void* data;
}; };
typedef struct qse_mmgr_t qse_mmgr_t; typedef struct qse_mmgr_t qse_mmgr_t;

View File

@ -2,7 +2,7 @@
AM_CPPFLAGS = -I$(top_builddir)/include AM_CPPFLAGS = -I$(top_builddir)/include
lib_LTLIBRARIES = libqsesed.la lib_LTLIBRARIES = libqsesed.la
libqsesed_la_SOURCES = sed.c sed.h libqsesed_la_SOURCES = sed.c err.c sed.h
libqsesed_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L../utl libqsesed_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L../utl
libqsesed_la_LIBADD = -lqsecmn -lqseutl libqsesed_la_LIBADD = -lqsecmn -lqseutl

View File

@ -60,7 +60,7 @@ libqsesed___la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(CXXFLAGS) $(libqsesed___la_LDFLAGS) $(LDFLAGS) -o $@ $(CXXFLAGS) $(libqsesed___la_LDFLAGS) $(LDFLAGS) -o $@
@ENABLE_CXX_TRUE@am_libqsesed___la_rpath = -rpath $(libdir) @ENABLE_CXX_TRUE@am_libqsesed___la_rpath = -rpath $(libdir)
libqsesed_la_DEPENDENCIES = libqsesed_la_DEPENDENCIES =
am_libqsesed_la_OBJECTS = sed.lo am_libqsesed_la_OBJECTS = sed.lo err.lo
libqsesed_la_OBJECTS = $(am_libqsesed_la_OBJECTS) libqsesed_la_OBJECTS = $(am_libqsesed_la_OBJECTS)
libqsesed_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ libqsesed_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@ -219,7 +219,7 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_builddir)/include AM_CPPFLAGS = -I$(top_builddir)/include
lib_LTLIBRARIES = libqsesed.la $(am__append_1) lib_LTLIBRARIES = libqsesed.la $(am__append_1)
libqsesed_la_SOURCES = sed.c sed.h libqsesed_la_SOURCES = sed.c err.c sed.h
libqsesed_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L../utl libqsesed_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L../utl
libqsesed_la_LIBADD = -lqsecmn -lqseutl libqsesed_la_LIBADD = -lqsecmn -lqseutl
@ENABLE_CXX_TRUE@libqsesed___la_SOURCES = Sed.cpp StdSed.cpp @ENABLE_CXX_TRUE@libqsesed___la_SOURCES = Sed.cpp StdSed.cpp
@ -298,6 +298,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Sed.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Sed.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StdSed.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StdSed.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/err.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sed.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sed.Plo@am__quote@
.c.o: .c.o:

147
qse/lib/sed/err.c Normal file
View File

@ -0,0 +1,147 @@
/*
* $Id: err.c 113 2009-03-25 14:53:10Z baconevi $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "sed.h"
static const qse_char_t* geterrstr (int errnum)
{
static const qse_char_t* errstr[] =
{
QSE_T("no error"),
QSE_T("out of memory"),
QSE_T("too much text"),
QSE_T("command ${0} not recognized"),
QSE_T("command code missing"),
QSE_T("command ${0} not terminated properly"),
QSE_T("regular expression build error"),
QSE_T("regular expression match error"),
QSE_T("address 1 prohibited"),
QSE_T("address 2 prohibited"),
QSE_T("invalid step address"),
QSE_T("a new line expected"),
QSE_T("a backslash expected"),
QSE_T("a backslash used as a delimiter"),
QSE_T("garbage after a backslash"),
QSE_T("a semicolon expected"),
QSE_T("empty label name"),
QSE_T("duplicate label name ${0}"),
QSE_T("label ${0} not found"),
QSE_T("empty file name"),
QSE_T("illegal file name"),
QSE_T("strings in translation set not the same length"),
QSE_T("group brackets not balanced"),
QSE_T("group nesting too deep"),
QSE_T("multiple occurrence specifier"),
QSE_T("occurrence specifier is zero"),
QSE_T("occurrence specifier too large"),
QSE_T("error returned by user io handler")
};
return (errnum >= 0 && errnum < QSE_COUNTOF(errstr))?
errstr[errnum]: QSE_T("unknown error");
}
#if 0
const qse_char_t* qse_sed_geterrstr (qse_sed_t* sed, qse_sed_errnum_t num)
{
if (sed != QSE_NULL &&
sed->errstr[num] != QSE_NULL) return sed->errstr[num];
return geterrstr (num);
}
int qse_sed_seterrstr (
qse_sed_t* sed, qse_sed_errnum_t num, const qse_char_t* str)
{
qse_char_t* dup;
if (str == QSE_NULL) dup = QSE_NULL;
else
{
dup = QSE_AWK_STRDUP (sed, str);
if (dup == QSE_NULL) return -1;
}
if (sed->errstr[num] != QSE_NULL)
QSE_AWK_FREE (sed, sed->errstr[num]);
else sed->errstr[num] = dup;
return 0;
}
#endif
int qse_sed_geterrnum (qse_sed_t* sed)
{
return sed->errnum;
}
qse_size_t qse_sed_geterrlin (qse_sed_t* sed)
{
return sed->errlin;
}
const qse_char_t* qse_sed_geterrmsg (qse_sed_t* sed)
{
if (sed->errmsg[0] == QSE_T('\0'))
/*return qse_sed_geterrstr (sed, sed->errnum);*/
return geterrstr (sed->errnum);
return sed->errmsg;
}
void qse_sed_geterror (
qse_sed_t* sed, int* errnum,
qse_size_t* errlin, const qse_char_t** errmsg)
{
if (errnum != QSE_NULL) *errnum = sed->errnum;
if (errlin != QSE_NULL) *errlin = sed->errlin;
if (errmsg != QSE_NULL)
{
*errmsg = (sed->errmsg[0] == QSE_T('\0'))?
/*qse_sed_geterrstr (sed, sed->errnum):*/
geterrstr (sed->errnum):
sed->errmsg;
}
}
void qse_sed_seterrnum (qse_sed_t* sed, int errnum)
{
sed->errnum = errnum;
sed->errlin = 0;
sed->errmsg[0] = QSE_T('\0');
}
void qse_sed_seterrmsg (qse_sed_t* sed,
int errnum, qse_size_t errlin, const qse_char_t* errmsg)
{
sed->errnum = errnum;
sed->errlin = errlin;
qse_strxcpy (sed->errmsg, QSE_COUNTOF(sed->errmsg), errmsg);
}
void qse_sed_seterror (
qse_sed_t* sed, int errnum,
qse_size_t errlin, const qse_cstr_t* errarg)
{
const qse_char_t* errfmt;
sed->errnum = errnum;
sed->errlin = errlin;
errfmt = /*qse_sed_geterrstr (sed, errnum);*/ geterrstr (sed->errnum);
QSE_ASSERT (errfmt != QSE_NULL);
qse_strxfncpy (sed->errmsg, QSE_COUNTOF(sed->errmsg), errfmt, errarg);
}

View File

@ -27,6 +27,16 @@ static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd);
static qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr); static qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr);
static void qse_sed_fini (qse_sed_t* sed); static void qse_sed_fini (qse_sed_t* sed);
#define SETERR0(sed,num,line) \
do { qse_sed_seterror (sed, num, line, QSE_NULL); } while (0)
#define SETERR1(sed,num,line,argp,argl) \
do { \
qse_cstr_t __qse__err__arg__; \
__qse__err__arg__.ptr = argp; __qse__err__arg__.len = argl; \
qse_sed_seterror (sed, num, line, &__qse__err__arg__); \
} while (0)
qse_sed_t* qse_sed_open (qse_mmgr_t* mmgr, qse_size_t xtn) qse_sed_t* qse_sed_open (qse_mmgr_t* mmgr, qse_size_t xtn)
{ {
qse_sed_t* sed; qse_sed_t* sed;
@ -66,14 +76,14 @@ static qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
if (qse_str_init (&sed->rexbuf, mmgr, 0) == QSE_NULL) if (qse_str_init (&sed->rexbuf, mmgr, 0) == QSE_NULL)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return QSE_NULL; return QSE_NULL;
} }
if (qse_map_init (&sed->labs, mmgr, 128, 70) == QSE_NULL) if (qse_map_init (&sed->labs, mmgr, 128, 70) == QSE_NULL)
{ {
qse_str_fini (&sed->rexbuf); qse_str_fini (&sed->rexbuf);
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return QSE_NULL; return QSE_NULL;
} }
qse_map_setcopier (&sed->labs, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE); qse_map_setcopier (&sed->labs, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE);
@ -150,46 +160,6 @@ static void qse_sed_fini (qse_sed_t* sed)
qse_str_fini (&sed->rexbuf); qse_str_fini (&sed->rexbuf);
} }
const qse_char_t* qse_sed_geterrmsg (qse_sed_t* sed)
{
static const qse_char_t* errmsg[] =
{
QSE_T("no error"),
QSE_T("out of memory"),
QSE_T("too much text"),
QSE_T("command not recognized"),
QSE_T("command missing"),
QSE_T("command garbled"),
QSE_T("regular expression build error"),
QSE_T("regular expression match error"),
QSE_T("address 1 prohibited"),
QSE_T("address 2 prohibited"),
QSE_T("invalid step address"),
QSE_T("a new line expected"),
QSE_T("a backslash expected"),
QSE_T("a backslash used as a delimiter"),
QSE_T("garbage after a backslash"),
QSE_T("a semicolon expected"),
QSE_T("label name too long"),
QSE_T("empty label name"),
QSE_T("duplicate label name"),
QSE_T("label not found"),
QSE_T("empty file name"),
QSE_T("illegal file name"),
QSE_T("command not terminated properly"),
QSE_T("strings in translation set not the same length"),
QSE_T("group brackets not balanced"),
QSE_T("group nesting too deep"),
QSE_T("multiple occurrence specifier"),
QSE_T("occurrence specifier is zero"),
QSE_T("occurrence specifier too large"),
QSE_T("error returned by user io handler")
};
return (sed->errnum > 0 && sed->errnum < QSE_COUNTOF(errmsg))?
errmsg[sed->errnum]: QSE_T("unknown error");
}
void qse_sed_setoption (qse_sed_t* sed, int option) void qse_sed_setoption (qse_sed_t* sed, int option)
{ {
sed->option = option; sed->option = option;
@ -314,7 +284,7 @@ static void* compile_rex (qse_sed_t* sed, qse_char_t rxend)
if (qse_str_ccat (&sed->rexbuf, c) == (qse_size_t)-1) if (qse_str_ccat (&sed->rexbuf, c) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return QSE_NULL; return QSE_NULL;
} }
} }
@ -405,7 +375,7 @@ static int get_text (qse_sed_t* sed, qse_sed_cmd_t* cmd)
do { \ do { \
if (qse_str_ccat (str, c) == (qse_size_t)-1) \ if (qse_str_ccat (str, c) == (qse_size_t)-1) \
{ \ { \
sed->errnum = QSE_SED_ENOMEM; \ SETERR0 (sed, QSE_SED_ENOMEM, 0); \
goto errlabel; \ goto errlabel; \
} \ } \
} while (0) } while (0)
@ -497,7 +467,7 @@ static int get_label (qse_sed_t* sed, qse_sed_cmd_t* cmd)
t = qse_str_open (sed->mmgr, 0, 32); t = qse_str_open (sed->mmgr, 0, 32);
if (t == QSE_NULL) if (t == QSE_NULL)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
goto oops; goto oops;
} }
@ -505,7 +475,7 @@ static int get_label (qse_sed_t* sed, qse_sed_cmd_t* cmd)
{ {
if (qse_str_ccat (t, c) == (qse_size_t)-1) if (qse_str_ccat (t, c) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
goto oops; goto oops;
} }
c = NXTSC (sed); c = NXTSC (sed);
@ -515,15 +485,16 @@ static int get_label (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (qse_map_search ( if (qse_map_search (
&sed->labs, QSE_STR_PTR(t), QSE_STR_LEN(t)) != QSE_NULL) &sed->labs, QSE_STR_PTR(t), QSE_STR_LEN(t)) != QSE_NULL)
{ {
sed->errnum = QSE_SED_ELABDU; SETERR1 (sed, QSE_SED_ELABDU, 0,
QSE_STR_PTR(t), QSE_STR_LEN(t));
goto oops; goto oops;
} }
if (qse_map_insert ( if (qse_map_insert (
&sed->labs, QSE_STR_PTR(t), QSE_STR_LEN(t), cmd, 0) == QSE_NULL) &sed->labs, QSE_STR_PTR(t), QSE_STR_LEN(t), cmd, 0) == QSE_NULL)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
goto oops;; goto oops;
} }
/* the label can be followed by a command on the same line without /* the label can be followed by a command on the same line without
@ -581,7 +552,7 @@ static int get_branch_target (qse_sed_t* sed, qse_sed_cmd_t* cmd)
t = qse_str_open (sed->mmgr, 0, 32); t = qse_str_open (sed->mmgr, 0, 32);
if (t == QSE_NULL) if (t == QSE_NULL)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
goto oops; goto oops;
} }
@ -589,7 +560,7 @@ static int get_branch_target (qse_sed_t* sed, qse_sed_cmd_t* cmd)
{ {
if (qse_str_ccat (t, c) == (qse_size_t)-1) if (qse_str_ccat (t, c) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
goto oops; goto oops;
} }
@ -640,7 +611,7 @@ static int get_file (qse_sed_t* sed, qse_xstr_t* xstr)
t = qse_str_open (sed->mmgr, 0, 32); t = qse_str_open (sed->mmgr, 0, 32);
if (t == QSE_NULL) if (t == QSE_NULL)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
goto oops; goto oops;
} }
@ -672,7 +643,7 @@ static int get_file (qse_sed_t* sed, qse_xstr_t* xstr)
if (qse_str_ccat (t, c) == (qse_size_t)-1) if (qse_str_ccat (t, c) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
goto oops; goto oops;
} }
@ -706,7 +677,7 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (c == QSE_CHAR_EOF || IS_LINTERM(c)) if (c == QSE_CHAR_EOF || IS_LINTERM(c))
{ {
/* not terminated properly */ /* not terminated properly */
sed->errnum = QSE_SED_ENOTRM; SETERR1 (sed, QSE_SED_ECMDIC, 0, &cmd->type, 1);
goto oops; goto oops;
} }
@ -723,7 +694,7 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
t[i] = qse_str_open (sed->mmgr, 0, 32); t[i] = qse_str_open (sed->mmgr, 0, 32);
if (t[i] == QSE_NULL) if (t[i] == QSE_NULL)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
goto oops; goto oops;
} }
} }
@ -737,7 +708,7 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
{ {
if (c == QSE_CHAR_EOF || IS_LINTERM(c)) if (c == QSE_CHAR_EOF || IS_LINTERM(c))
{ {
sed->errnum = QSE_SED_ENOTRM; SETERR1 (sed, QSE_SED_ECMDIC, 0, &cmd->type, 1);
goto oops; goto oops;
} }
@ -746,7 +717,7 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
c = NXTSC (sed); c = NXTSC (sed);
if (c == QSE_CHAR_EOF || IS_LINTERM(c)) if (c == QSE_CHAR_EOF || IS_LINTERM(c))
{ {
sed->errnum = QSE_SED_ENOTRM; SETERR1 (sed, QSE_SED_ECMDIC, 0, &cmd->type, 1);
goto oops; goto oops;
} }
@ -755,7 +726,7 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (qse_str_ccat (t[i], c) == (qse_size_t)-1) if (qse_str_ccat (t[i], c) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
goto oops; goto oops;
} }
@ -868,7 +839,7 @@ static int get_transet (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (c == QSE_CHAR_EOF || IS_LINTERM(c)) if (c == QSE_CHAR_EOF || IS_LINTERM(c))
{ {
/* translation set terminated prematurely*/ /* translation set terminated prematurely*/
sed->errnum = QSE_SED_ENOTRM; SETERR1 (sed, QSE_SED_ECMDIC, 0, &cmd->type, 1);
goto oops; goto oops;
} }
@ -883,7 +854,7 @@ static int get_transet (qse_sed_t* sed, qse_sed_cmd_t* cmd)
t = qse_str_open (sed->mmgr, 0, 32); t = qse_str_open (sed->mmgr, 0, 32);
if (t == QSE_NULL) if (t == QSE_NULL)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
goto oops; goto oops;
} }
@ -894,7 +865,7 @@ static int get_transet (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (c == QSE_CHAR_EOF || IS_LINTERM(c)) if (c == QSE_CHAR_EOF || IS_LINTERM(c))
{ {
sed->errnum = QSE_SED_ENOTRM; SETERR1 (sed, QSE_SED_ECMDIC, 0, &cmd->type, 1);
goto oops; goto oops;
} }
@ -903,7 +874,7 @@ static int get_transet (qse_sed_t* sed, qse_sed_cmd_t* cmd)
c = NXTSC (sed); c = NXTSC (sed);
if (c == QSE_CHAR_EOF || IS_LINTERM(c)) if (c == QSE_CHAR_EOF || IS_LINTERM(c))
{ {
sed->errnum = QSE_SED_ENOTRM; SETERR1 (sed, QSE_SED_ECMDIC, 0, &cmd->type, 1);
goto oops; goto oops;
} }
@ -913,7 +884,7 @@ static int get_transet (qse_sed_t* sed, qse_sed_cmd_t* cmd)
b[0] = c; b[0] = c;
if (qse_str_ncat (t, b, 2) == (qse_size_t)-1) if (qse_str_ncat (t, b, 2) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
goto oops; goto oops;
} }
@ -925,7 +896,7 @@ static int get_transet (qse_sed_t* sed, qse_sed_cmd_t* cmd)
{ {
if (c == QSE_CHAR_EOF || IS_LINTERM(c)) if (c == QSE_CHAR_EOF || IS_LINTERM(c))
{ {
sed->errnum = QSE_SED_ENOTRM; SETERR1 (sed, QSE_SED_ECMDIC, 0, &cmd->type, 1);
goto oops; goto oops;
} }
@ -934,7 +905,7 @@ static int get_transet (qse_sed_t* sed, qse_sed_cmd_t* cmd)
c = NXTSC (sed); c = NXTSC (sed);
if (c == QSE_CHAR_EOF || IS_LINTERM(c)) if (c == QSE_CHAR_EOF || IS_LINTERM(c))
{ {
sed->errnum = QSE_SED_ENOTRM; SETERR1 (sed, QSE_SED_ECMDIC, 0, &cmd->type, 1);
goto oops; goto oops;
} }
@ -981,11 +952,14 @@ restart:
switch (c) switch (c)
{ {
default: default:
sed->errnum = QSE_SED_ECMDNR; {
qse_char_t cc = c;
SETERR1 (sed, QSE_SED_ECMDNR, 0, &cc, 1);
return -1; return -1;
}
case QSE_CHAR_EOF: case QSE_CHAR_EOF:
sed->errnum = QSE_SED_ECMDMS; SETERR0 (sed, QSE_SED_ECMDMS, 0);
return -1; return -1;
case QSE_T(':'): case QSE_T(':'):
@ -1264,7 +1238,7 @@ static int compile_source (
{ {
/* TODO: too many commands. change errnum */ /* TODO: too many commands. change errnum */
free_command (sed, cmd); free_command (sed, cmd);
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
@ -1372,7 +1346,7 @@ static int read_file (qse_sed_t* sed, const qse_char_t* path, int line)
if (qse_str_ccat (&sed->e.txt.read, buf[i]) == (qse_size_t)-1) if (qse_str_ccat (&sed->e.txt.read, buf[i]) == (qse_size_t)-1)
{ {
sed->e.in.fun (sed, QSE_SED_IO_CLOSE, &arg); sed->e.in.fun (sed, QSE_SED_IO_CLOSE, &arg);
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
@ -1385,7 +1359,7 @@ static int read_file (qse_sed_t* sed, const qse_char_t* path, int line)
if (qse_str_ncat (&sed->e.txt.read, buf, n) == (qse_size_t)-1) if (qse_str_ncat (&sed->e.txt.read, buf, n) == (qse_size_t)-1)
{ {
sed->e.in.fun (sed, QSE_SED_IO_CLOSE, &arg); sed->e.in.fun (sed, QSE_SED_IO_CLOSE, &arg);
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
} }
@ -1429,7 +1403,7 @@ static int read_line (qse_sed_t* sed, int append)
if (qse_str_ccat (&sed->e.in.line, c) == (qse_size_t)-1) if (qse_str_ccat (&sed->e.in.line, c) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
len++; len++;
@ -1653,7 +1627,7 @@ static int write_str_to_file (
path, plen, &arg, QSE_SIZEOF(arg)); path, plen, &arg, QSE_SIZEOF(arg));
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
} }
@ -1761,7 +1735,7 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
&sed->e.txt.subst, &sed->e.txt.subst,
cur_ptr, cur_len) == (qse_size_t)-1) cur_ptr, cur_len) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
break; break;
@ -1776,7 +1750,7 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (m == (qse_size_t)-1) if (m == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
} }
@ -1788,7 +1762,7 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
&sed->e.txt.subst, cur_ptr, mat.ptr-cur_ptr); &sed->e.txt.subst, cur_ptr, mat.ptr-cur_ptr);
if (m == (qse_size_t)-1) if (m == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
@ -1817,7 +1791,7 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (m == (qse_size_t)-1) if (m == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
} }
@ -1834,7 +1808,7 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
m = qse_str_ccat (&sed->e.txt.subst, QSE_T('\n')); m = qse_str_ccat (&sed->e.txt.subst, QSE_T('\n'));
if (m == (qse_size_t)-1) if (m == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
} }
@ -2053,7 +2027,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
QSE_LDA_SIZE(&sed->e.txt.appended), QSE_LDA_SIZE(&sed->e.txt.appended),
&cmd->u.text, 0) == (qse_size_t)-1) &cmd->u.text, 0) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return QSE_NULL; return QSE_NULL;
} }
break; break;
@ -2075,7 +2049,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
QSE_STR_LEN(&cmd->u.text)); QSE_STR_LEN(&cmd->u.text));
if (n == (qse_size_t)-1) if (n == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return QSE_NULL; return QSE_NULL;
} }
} }
@ -2167,7 +2141,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
QSE_STR_PTR(&sed->e.in.line), QSE_STR_PTR(&sed->e.in.line),
QSE_STR_LEN(&sed->e.in.line)) == (qse_size_t)-1) QSE_STR_LEN(&sed->e.in.line)) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return QSE_NULL; return QSE_NULL;
} }
break; break;
@ -2178,7 +2152,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
QSE_STR_PTR(&sed->e.in.line), QSE_STR_PTR(&sed->e.in.line),
QSE_STR_LEN(&sed->e.in.line)) == (qse_size_t)-1) QSE_STR_LEN(&sed->e.in.line)) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return QSE_NULL; return QSE_NULL;
} }
break; break;
@ -2189,7 +2163,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
QSE_STR_PTR(&sed->e.txt.held), QSE_STR_PTR(&sed->e.txt.held),
QSE_STR_LEN(&sed->e.txt.held)) == (qse_size_t)-1) QSE_STR_LEN(&sed->e.txt.held)) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return QSE_NULL; return QSE_NULL;
} }
break; break;
@ -2200,7 +2174,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
QSE_STR_PTR(&sed->e.txt.held), QSE_STR_PTR(&sed->e.txt.held),
QSE_STR_LEN(&sed->e.txt.held)) == (qse_size_t)-1) QSE_STR_LEN(&sed->e.txt.held)) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return QSE_NULL; return QSE_NULL;
} }
break; break;
@ -2308,7 +2282,10 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
&sed->labs, lab->ptr, lab->len); &sed->labs, lab->ptr, lab->len);
if (pair == QSE_NULL) if (pair == QSE_NULL)
{ {
sed->errnum = QSE_SED_ELABNF; SETERR1 (
sed, QSE_SED_ELABNF, 0,
lab->ptr, lab->len
);
return QSE_NULL; return QSE_NULL;
} }
@ -2384,7 +2361,7 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
qse_str_clear (&sed->e.txt.held); qse_str_clear (&sed->e.txt.held);
if (qse_str_ccat (&sed->e.txt.held, QSE_T('\n')) == (qse_size_t)-1) if (qse_str_ccat (&sed->e.txt.held, QSE_T('\n')) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
@ -2393,7 +2370,7 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
sed->e.out.len = 0; sed->e.out.len = 0;
if (qse_map_init (&sed->e.out.files, sed->mmgr, 128, 70) == QSE_NULL) if (qse_map_init (&sed->e.out.files, sed->mmgr, 128, 70) == QSE_NULL)
{ {
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }
*(qse_sed_t**)QSE_XTN(&sed->e.out.files) = sed; *(qse_sed_t**)QSE_XTN(&sed->e.out.files) = sed;
@ -2414,7 +2391,7 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
if (qse_str_init (&sed->e.in.line, QSE_MMGR(sed), 256) == QSE_NULL) if (qse_str_init (&sed->e.in.line, QSE_MMGR(sed), 256) == QSE_NULL)
{ {
qse_map_fini (&sed->e.out.files); qse_map_fini (&sed->e.out.files);
sed->errnum = QSE_SED_ENOMEM; SETERR0 (sed, QSE_SED_ENOMEM, 0);
return -1; return -1;
} }

View File

@ -34,6 +34,9 @@ struct qse_sed_t
QSE_DEFINE_COMMON_FIELDS (sed) QSE_DEFINE_COMMON_FIELDS (sed)
qse_sed_errnum_t errnum; /**< stores an error number */ qse_sed_errnum_t errnum; /**< stores an error number */
qse_char_t errmsg[128]; /**< error message holder */
qse_size_t errlin; /**< no of the line where an error occurred */
int option; /**< stores options */ int option; /**< stores options */
/** source text pointers */ /** source text pointers */
@ -139,46 +142,36 @@ struct qse_sed_adr_t
} u; } u;
}; };
#define QSE_SED_CMD_QUIT QSE_T('q')
#define QSE_SED_CMD_QUIT_QUIET QSE_T('Q')
#define QSE_SED_CMD_APPEND QSE_T('a')
#define QSE_SED_CMD_INSERT QSE_T('i')
#define QSE_SED_CMD_CHANGE QSE_T('c')
#define QSE_SED_CMD_DELETE QSE_T('d')
#define QSE_SED_CMD_DELETE_FIRSTLN QSE_T('D')
#define QSE_SED_CMD_PRINT_LNNUM QSE_T('=')
#define QSE_SED_CMD_PRINT QSE_T('p')
#define QSE_SED_CMD_PRINT_FIRSTLN QSE_T('P')
#define QSE_SED_CMD_PRINT_CLEARLY QSE_T('l')
#define QSE_SED_CMD_HOLD QSE_T('h')
#define QSE_SED_CMD_HOLD_APPEND QSE_T('H')
#define QSE_SED_CMD_RELEASE QSE_T('g')
#define QSE_SED_CMD_RELEASE_APPEND QSE_T('G')
#define QSE_SED_CMD_EXCHANGE QSE_T('x')
#define QSE_SED_CMD_NEXT QSE_T('n')
#define QSE_SED_CMD_NEXT_APPEND QSE_T('N')
#define QSE_SED_CMD_READ_FILE QSE_T('r')
#define QSE_SED_CMD_READ_FILELN QSE_T('R')
#define QSE_SED_CMD_WRITE_FILE QSE_T('w')
#define QSE_SED_CMD_WRITE_FILELN QSE_T('W')
#define QSE_SED_CMD_BRANCH QSE_T('b')
#define QSE_SED_CMD_BRANCH_COND QSE_T('t')
#define QSE_SED_CMD_SUBSTITUTE QSE_T('s')
#define QSE_SED_CMD_TRANSLATE QSE_T('y')
struct qse_sed_cmd_t struct qse_sed_cmd_t
{ {
enum qse_char_t type;
{
QSE_SED_CMD_QUIT = QSE_T('q'),
QSE_SED_CMD_QUIT_QUIET = QSE_T('Q'),
QSE_SED_CMD_APPEND = QSE_T('a'),
QSE_SED_CMD_INSERT = QSE_T('i'),
QSE_SED_CMD_CHANGE = QSE_T('c'),
QSE_SED_CMD_DELETE = QSE_T('d'),
QSE_SED_CMD_DELETE_FIRSTLN = QSE_T('D'),
QSE_SED_CMD_PRINT_LNNUM = QSE_T('='),
QSE_SED_CMD_PRINT = QSE_T('p'),
QSE_SED_CMD_PRINT_FIRSTLN = QSE_T('P'),
QSE_SED_CMD_PRINT_CLEARLY = QSE_T('l'),
QSE_SED_CMD_HOLD = QSE_T('h'),
QSE_SED_CMD_HOLD_APPEND = QSE_T('H'),
QSE_SED_CMD_RELEASE = QSE_T('g'),
QSE_SED_CMD_RELEASE_APPEND = QSE_T('G'),
QSE_SED_CMD_EXCHANGE = QSE_T('x'),
QSE_SED_CMD_NEXT = QSE_T('n'),
QSE_SED_CMD_NEXT_APPEND = QSE_T('N'),
QSE_SED_CMD_READ_FILE = QSE_T('r'),
QSE_SED_CMD_READ_FILELN = QSE_T('R'),
QSE_SED_CMD_WRITE_FILE = QSE_T('w'),
QSE_SED_CMD_WRITE_FILELN = QSE_T('W'),
QSE_SED_CMD_BRANCH = QSE_T('b'),
QSE_SED_CMD_BRANCH_COND = QSE_T('t'),
QSE_SED_CMD_SUBSTITUTE = QSE_T('s'),
QSE_SED_CMD_TRANSLATE = QSE_T('y')
} type;
int negated; int negated;