enhanced qse_sed_t
- changed qse_sed_t to support arbitrary numbers of commands - added qse_set_getmaxdepth() and qse_sed_setmaxdepth() - added relevant wrapper functions to QSE::Sed
This commit is contained in:
parent
7875def835
commit
d851798b3c
@ -48,6 +48,8 @@ public:
|
|||||||
typedef qse_sed_io_arg_t io_arg_t;
|
typedef qse_sed_io_arg_t io_arg_t;
|
||||||
/// The option_t type redefines an option type
|
/// The option_t type redefines an option type
|
||||||
typedef qse_sed_option_t option_t;
|
typedef qse_sed_option_t option_t;
|
||||||
|
/// The depth_t type redefines an depth IDs
|
||||||
|
typedef qse_sed_depth_t depth_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Sed() function creates an uninitialized stream editor.
|
* The Sed() function creates an uninitialized stream editor.
|
||||||
@ -115,6 +117,19 @@ public:
|
|||||||
int opt ///< option code
|
int opt ///< option code
|
||||||
) throw ();
|
) throw ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The getMaxDepth() function gets the maximum processing depth.
|
||||||
|
*/
|
||||||
|
size_t getMaxDepth (depth_t id) const throw ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The setMaxDepth() function gets the maximum processing depth.
|
||||||
|
*/
|
||||||
|
void setMaxDepth (
|
||||||
|
int ids, ///< 0 or a number OR'ed of depth_t values
|
||||||
|
size_t depth ///< 0 maximum depth
|
||||||
|
) throw ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The getErrorMessage() function gets the description of the last
|
* The getErrorMessage() function gets the description of the last
|
||||||
* error occurred. It returns an empty string if the stream editor
|
* error occurred. It returns an empty string if the stream editor
|
||||||
|
@ -35,10 +35,6 @@
|
|||||||
* qse_sed_close (sed);
|
* qse_sed_close (sed);
|
||||||
* @endcode
|
* @endcode
|
||||||
*
|
*
|
||||||
* @todo
|
|
||||||
* - allow flexible numbers of commands
|
|
||||||
* - allow configurable recursion depth for a regular expression
|
|
||||||
*
|
|
||||||
* @example sed01.c
|
* @example sed01.c
|
||||||
* This example shows how to embed a basic stream editor.
|
* This example shows how to embed a basic stream editor.
|
||||||
*/
|
*/
|
||||||
@ -123,6 +119,18 @@ enum qse_sed_option_t
|
|||||||
};
|
};
|
||||||
typedef enum qse_sed_option_t qse_sed_option_t;
|
typedef enum qse_sed_option_t qse_sed_option_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_sed_depth_t type defines IDs for qse_sed_getmaxdepth() and
|
||||||
|
* qse_sed_setmaxdepth().
|
||||||
|
*/
|
||||||
|
enum qse_sed_depth_t
|
||||||
|
{
|
||||||
|
QSE_SED_DEPTH_REX_BUILD = (1 << 0),
|
||||||
|
QSE_SED_DEPTH_REX_MATCH = (1 << 1)
|
||||||
|
};
|
||||||
|
typedef enum qse_sed_depth_t qse_sed_depth_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_sed_io_cmd_t type defines IO command codes. The code indicates
|
* The qse_sed_io_cmd_t type defines IO command codes. The code indicates
|
||||||
* the action to take in an IO handler.
|
* the action to take in an IO handler.
|
||||||
@ -219,6 +227,23 @@ void qse_sed_setoption (
|
|||||||
int opt /**< 0 or a number OR'ed of qse_sed_option_t values */
|
int opt /**< 0 or a number OR'ed of qse_sed_option_t values */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_sed_getmaxdepth() gets the maximum processing depth.
|
||||||
|
*/
|
||||||
|
qse_size_t qse_sed_getmaxdepth (
|
||||||
|
qse_sed_t* sed, /**< a stream editor */
|
||||||
|
qse_sed_depth_t id /**< one of qse_sed_depth_t values */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_sed_setmaxdepth() sets the maximum processing depth.
|
||||||
|
*/
|
||||||
|
void qse_sed_setmaxdepth (
|
||||||
|
qse_sed_t* sed, /**< a stream editor */
|
||||||
|
int ids, /**< 0 or a number OR'ed of qse_sed_depth_t values */
|
||||||
|
qse_size_t depth /**< maximum depth level */
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_sed_geterrstr() gets an error string getter.
|
* The qse_sed_geterrstr() gets an error string getter.
|
||||||
*/
|
*/
|
||||||
|
@ -74,6 +74,18 @@ void Sed::setOption (int opt) throw ()
|
|||||||
qse_sed_setoption (sed, opt);
|
qse_sed_setoption (sed, opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sed::size_t Sed::getMaxDepth (depth_t id) const throw ()
|
||||||
|
{
|
||||||
|
QSE_ASSERT (sed != QSE_NULL);
|
||||||
|
return qse_sed_getmaxdepth (sed, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sed::setMaxDepth (int ids, size_t depth) throw ()
|
||||||
|
{
|
||||||
|
QSE_ASSERT (sed != QSE_NULL);
|
||||||
|
qse_sed_setmaxdepth (sed, ids, depth);
|
||||||
|
}
|
||||||
|
|
||||||
const Sed::char_t* Sed::getErrorMessage () const throw ()
|
const Sed::char_t* Sed::getErrorMessage () const throw ()
|
||||||
{
|
{
|
||||||
return (sed == QSE_NULL)? QSE_T(""): qse_sed_geterrmsg (sed);
|
return (sed == QSE_NULL)? QSE_T(""): qse_sed_geterrmsg (sed);
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
QSE_IMPLEMENT_COMMON_FUNCTIONS (sed)
|
QSE_IMPLEMENT_COMMON_FUNCTIONS (sed)
|
||||||
|
|
||||||
static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd);
|
static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd);
|
||||||
|
static void free_all_command_blocks (qse_sed_t* sed);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@ -137,27 +139,8 @@ static qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
|||||||
qse_map_setcopier (&sed->tmp.labs, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE);
|
qse_map_setcopier (&sed->tmp.labs, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE);
|
||||||
qse_map_setscale (&sed->tmp.labs, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
|
qse_map_setscale (&sed->tmp.labs, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
|
||||||
|
|
||||||
sed->cmd.len = 256; /* TODO: parameterize this value */
|
|
||||||
sed->cmd.buf = QSE_MMGR_ALLOC (
|
|
||||||
sed->mmgr, QSE_SIZEOF(qse_sed_cmd_t) * sed->cmd.len);
|
|
||||||
if (sed->cmd.buf == QSE_NULL)
|
|
||||||
{
|
|
||||||
qse_map_fini (&sed->tmp.labs);
|
|
||||||
qse_str_fini (&sed->tmp.lab);
|
|
||||||
qse_str_fini (&sed->tmp.rex);
|
|
||||||
return QSE_NULL;
|
|
||||||
}
|
|
||||||
sed->cmd.cur = sed->cmd.buf;
|
|
||||||
sed->cmd.end = sed->cmd.buf + sed->cmd.len - 1;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
sed->cmd.lb = &sed->cmd.fb; /* on init, the last points to the first */
|
|
||||||
sed->fb.len = 0; /* the block has no data yet */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (qse_lda_init (&sed->e.txt.appended, mmgr, 32) == QSE_NULL)
|
if (qse_lda_init (&sed->e.txt.appended, mmgr, 32) == QSE_NULL)
|
||||||
{
|
{
|
||||||
QSE_MMGR_FREE (sed->mmgr, sed->cmd.buf);
|
|
||||||
qse_map_fini (&sed->tmp.labs);
|
qse_map_fini (&sed->tmp.labs);
|
||||||
qse_str_fini (&sed->tmp.lab);
|
qse_str_fini (&sed->tmp.lab);
|
||||||
qse_str_fini (&sed->tmp.rex);
|
qse_str_fini (&sed->tmp.rex);
|
||||||
@ -167,7 +150,6 @@ static qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
|||||||
if (qse_str_init (&sed->e.txt.read, mmgr, 256) == QSE_NULL)
|
if (qse_str_init (&sed->e.txt.read, mmgr, 256) == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_lda_fini (&sed->e.txt.appended);
|
qse_lda_fini (&sed->e.txt.appended);
|
||||||
QSE_MMGR_FREE (sed->mmgr, sed->cmd.buf);
|
|
||||||
qse_map_fini (&sed->tmp.labs);
|
qse_map_fini (&sed->tmp.labs);
|
||||||
qse_str_fini (&sed->tmp.lab);
|
qse_str_fini (&sed->tmp.lab);
|
||||||
qse_str_fini (&sed->tmp.rex);
|
qse_str_fini (&sed->tmp.rex);
|
||||||
@ -178,7 +160,6 @@ static qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
|||||||
{
|
{
|
||||||
qse_str_fini (&sed->e.txt.read);
|
qse_str_fini (&sed->e.txt.read);
|
||||||
qse_lda_fini (&sed->e.txt.appended);
|
qse_lda_fini (&sed->e.txt.appended);
|
||||||
QSE_MMGR_FREE (sed->mmgr, sed->cmd.buf);
|
|
||||||
qse_map_fini (&sed->tmp.labs);
|
qse_map_fini (&sed->tmp.labs);
|
||||||
qse_str_fini (&sed->tmp.lab);
|
qse_str_fini (&sed->tmp.lab);
|
||||||
qse_str_fini (&sed->tmp.rex);
|
qse_str_fini (&sed->tmp.rex);
|
||||||
@ -190,29 +171,30 @@ static qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
|||||||
qse_str_fini (&sed->e.txt.held);
|
qse_str_fini (&sed->e.txt.held);
|
||||||
qse_str_fini (&sed->e.txt.read);
|
qse_str_fini (&sed->e.txt.read);
|
||||||
qse_lda_fini (&sed->e.txt.appended);
|
qse_lda_fini (&sed->e.txt.appended);
|
||||||
QSE_MMGR_FREE (sed->mmgr, sed->cmd.buf);
|
|
||||||
qse_map_fini (&sed->tmp.labs);
|
qse_map_fini (&sed->tmp.labs);
|
||||||
qse_str_fini (&sed->tmp.lab);
|
qse_str_fini (&sed->tmp.lab);
|
||||||
qse_str_fini (&sed->tmp.rex);
|
qse_str_fini (&sed->tmp.rex);
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* on init, the last points to the first */
|
||||||
|
sed->cmd.lb = &sed->cmd.fb;
|
||||||
|
/* the block has no data yet */
|
||||||
|
sed->cmd.fb.len = 0;
|
||||||
|
|
||||||
return sed;
|
return sed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void qse_sed_fini (qse_sed_t* sed)
|
static void qse_sed_fini (qse_sed_t* sed)
|
||||||
{
|
{
|
||||||
qse_sed_cmd_t* c;
|
free_all_command_blocks (sed);
|
||||||
|
|
||||||
qse_str_fini (&sed->e.txt.subst);
|
qse_str_fini (&sed->e.txt.subst);
|
||||||
qse_str_fini (&sed->e.txt.held);
|
qse_str_fini (&sed->e.txt.held);
|
||||||
qse_str_fini (&sed->e.txt.read);
|
qse_str_fini (&sed->e.txt.read);
|
||||||
qse_lda_fini (&sed->e.txt.appended);
|
qse_lda_fini (&sed->e.txt.appended);
|
||||||
|
|
||||||
/* TODO: use different data structure -> look at qse_sed_init */
|
|
||||||
for (c = sed->cmd.buf; c != sed->cmd.cur; c++) free_command (sed, c);
|
|
||||||
QSE_MMGR_FREE (sed->mmgr, sed->cmd.buf);
|
|
||||||
|
|
||||||
qse_map_fini (&sed->tmp.labs);
|
qse_map_fini (&sed->tmp.labs);
|
||||||
qse_str_fini (&sed->tmp.lab);
|
qse_str_fini (&sed->tmp.lab);
|
||||||
qse_str_fini (&sed->tmp.rex);
|
qse_str_fini (&sed->tmp.rex);
|
||||||
@ -228,6 +210,18 @@ int qse_sed_getoption (qse_sed_t* sed)
|
|||||||
return sed->option;
|
return sed->option;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qse_size_t qse_sed_getmaxdepth (qse_sed_t* sed, qse_sed_depth_t id)
|
||||||
|
{
|
||||||
|
return (id & QSE_SED_DEPTH_REX_BUILD)? sed->depth.rex.build:
|
||||||
|
(id & QSE_SED_DEPTH_REX_MATCH)? sed->depth.rex.match: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_sed_setmaxdepth (qse_sed_t* sed, int ids, qse_size_t depth)
|
||||||
|
{
|
||||||
|
if (ids & QSE_SED_DEPTH_REX_BUILD) sed->depth.rex.build = depth;
|
||||||
|
if (ids & QSE_SED_DEPTH_REX_MATCH) sed->depth.rex.match = depth;
|
||||||
|
}
|
||||||
|
|
||||||
/* check if c is a space character */
|
/* check if c is a space character */
|
||||||
#define IS_SPACE(c) ((c) == QSE_T(' ') || (c) == QSE_T('\t') || (c) == QSE_T('\r'))
|
#define IS_SPACE(c) ((c) == QSE_T(' ') || (c) == QSE_T('\t') || (c) == QSE_T('\r'))
|
||||||
#define IS_LINTERM(c) ((c) == QSE_T('\n'))
|
#define IS_LINTERM(c) ((c) == QSE_T('\n'))
|
||||||
@ -275,6 +269,47 @@ static void free_address (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int add_command_block (qse_sed_t* sed)
|
||||||
|
{
|
||||||
|
qse_sed_cmd_blk_t* b;
|
||||||
|
|
||||||
|
b = (qse_sed_cmd_blk_t*) QSE_MMGR_ALLOC (sed->mmgr, QSE_SIZEOF(*b));
|
||||||
|
if (b == QSE_NULL)
|
||||||
|
{
|
||||||
|
SETERR0 (sed, QSE_SED_ENOMEM, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSE_MEMSET (b, 0, QSE_SIZEOF(*b));
|
||||||
|
b->next = QSE_NULL;
|
||||||
|
b->len = 0;
|
||||||
|
|
||||||
|
sed->cmd.lb->next = b;
|
||||||
|
sed->cmd.lb = b;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_all_command_blocks (qse_sed_t* sed)
|
||||||
|
{
|
||||||
|
qse_sed_cmd_blk_t* b;
|
||||||
|
|
||||||
|
for (b = &sed->cmd.fb; b != QSE_NULL; )
|
||||||
|
{
|
||||||
|
qse_sed_cmd_blk_t* nxt = b->next;
|
||||||
|
|
||||||
|
while (b->len > 0) free_command (sed, &b->buf[--b->len]);
|
||||||
|
if (b != &sed->cmd.fb) QSE_MMGR_FREE (sed->mmgr, b);
|
||||||
|
|
||||||
|
b = nxt;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSE_MEMSET (&sed->cmd.fb, 0, QSE_SIZEOF(sed->cmd.fb));
|
||||||
|
sed->cmd.lb = &sed->cmd.fb;
|
||||||
|
sed->cmd.lb->len = 0;
|
||||||
|
sed->cmd.lb->next = QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||||
{
|
{
|
||||||
free_address (sed, cmd);
|
free_address (sed, cmd);
|
||||||
@ -371,9 +406,9 @@ static void* compile_rex (qse_sed_t* sed, qse_char_t rxend)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: maximum depth - optionize the second parameter */
|
|
||||||
code = qse_buildrex (
|
code = qse_buildrex (
|
||||||
sed->mmgr, 0,
|
sed->mmgr,
|
||||||
|
sed->depth.rex.build,
|
||||||
QSE_STR_PTR(&sed->tmp.rex),
|
QSE_STR_PTR(&sed->tmp.rex),
|
||||||
QSE_STR_LEN(&sed->tmp.rex),
|
QSE_STR_LEN(&sed->tmp.rex),
|
||||||
QSE_NULL
|
QSE_NULL
|
||||||
@ -582,7 +617,9 @@ static int get_label (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
|
|
||||||
if (IS_CMDTERM(c))
|
if (IS_CMDTERM(c))
|
||||||
{
|
{
|
||||||
if (c != QSE_T('#') && c != QSE_CHAR_EOF) NXTSC (sed);
|
if (c != QSE_T('}') &&
|
||||||
|
c != QSE_T('#') &&
|
||||||
|
c != QSE_CHAR_EOF) NXTSC (sed);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -888,7 +925,8 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
|
|
||||||
QSE_ASSERT (cmd->u.subst.rex == QSE_NULL);
|
QSE_ASSERT (cmd->u.subst.rex == QSE_NULL);
|
||||||
cmd->u.subst.rex = qse_buildrex (
|
cmd->u.subst.rex = qse_buildrex (
|
||||||
sed->mmgr, 0,
|
sed->mmgr,
|
||||||
|
sed->depth.rex.build,
|
||||||
QSE_STR_PTR(t[0]),
|
QSE_STR_PTR(t[0]),
|
||||||
QSE_STR_LEN(t[0]),
|
QSE_STR_LEN(t[0]),
|
||||||
QSE_NULL
|
QSE_NULL
|
||||||
@ -1003,10 +1041,10 @@ oops:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_command (qse_sed_t* sed)
|
/* process a command code and following parts into cmd */
|
||||||
|
static int get_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||||
{
|
{
|
||||||
qse_cint_t c;
|
qse_cint_t c;
|
||||||
qse_sed_cmd_t* cmd = sed->cmd.cur;
|
|
||||||
|
|
||||||
c = CURSC (sed);
|
c = CURSC (sed);
|
||||||
cmd->lnum = sed->src.lnum;
|
cmd->lnum = sed->src.lnum;
|
||||||
@ -1028,7 +1066,7 @@ static int get_command (qse_sed_t* sed)
|
|||||||
|
|
||||||
case QSE_T(':'):
|
case QSE_T(':'):
|
||||||
/* label - this is not a command */
|
/* label - this is not a command */
|
||||||
cmd->type = c;
|
cmd->type = QSE_SED_CMD_NOOP;
|
||||||
if (cmd->a1.type != QSE_SED_ADR_NONE)
|
if (cmd->a1.type != QSE_SED_ADR_NONE)
|
||||||
{
|
{
|
||||||
/* label cannot have an address */
|
/* label cannot have an address */
|
||||||
@ -1044,7 +1082,7 @@ static int get_command (qse_sed_t* sed)
|
|||||||
|
|
||||||
c = CURSC (sed);
|
c = CURSC (sed);
|
||||||
while (IS_SPACE(c)) c = NXTSC(sed);
|
while (IS_SPACE(c)) c = NXTSC(sed);
|
||||||
return 0;
|
break;
|
||||||
|
|
||||||
case QSE_T('{'):
|
case QSE_T('{'):
|
||||||
/* insert a negated branch command at the beginning
|
/* insert a negated branch command at the beginning
|
||||||
@ -1069,6 +1107,8 @@ static int get_command (qse_sed_t* sed)
|
|||||||
{
|
{
|
||||||
qse_sed_cmd_t* tc;
|
qse_sed_cmd_t* tc;
|
||||||
|
|
||||||
|
cmd->type = QSE_SED_CMD_NOOP;
|
||||||
|
|
||||||
if (sed->tmp.grp.level <= 0)
|
if (sed->tmp.grp.level <= 0)
|
||||||
{
|
{
|
||||||
/* group not balanced */
|
/* group not balanced */
|
||||||
@ -1080,7 +1120,7 @@ static int get_command (qse_sed_t* sed)
|
|||||||
tc->u.branch.target = cmd;
|
tc->u.branch.target = cmd;
|
||||||
|
|
||||||
NXTSC (sed);
|
NXTSC (sed);
|
||||||
return 0;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case QSE_T('q'):
|
case QSE_T('q'):
|
||||||
@ -1187,7 +1227,7 @@ static int get_command (qse_sed_t* sed)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
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, const qse_char_t* sptr, qse_size_t slen)
|
||||||
@ -1203,9 +1243,9 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
|
|||||||
sed->src.cc = (slen > 0)? (*sptr): QSE_CHAR_EOF;
|
sed->src.cc = (slen > 0)? (*sptr): QSE_CHAR_EOF;
|
||||||
|
|
||||||
/* free all the commands previously compiled */
|
/* free all the commands previously compiled */
|
||||||
for (cmd = sed->cmd.buf; cmd != sed->cmd.cur; cmd++)
|
free_all_command_blocks (sed);
|
||||||
free_command (sed, cmd);
|
QSE_ASSERT (sed->cmd.lb == &sed->cmd.fb && sed->cmd.lb->len == 0);
|
||||||
cmd = sed->cmd.cur = sed->cmd.buf;
|
cmd = &sed->cmd.lb->buf[sed->cmd.lb->len];
|
||||||
|
|
||||||
/* clear the label table */
|
/* clear the label table */
|
||||||
qse_map_clear (&sed->tmp.labs);
|
qse_map_clear (&sed->tmp.labs);
|
||||||
@ -1308,27 +1348,19 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
|
|||||||
while (IS_SPACE(c)) c = NXTSC (sed);
|
while (IS_SPACE(c)) c = NXTSC (sed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n = get_command (sed, cmd);
|
||||||
n = get_command (sed);
|
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
{
|
{
|
||||||
free_address (sed, cmd);
|
free_address (sed, cmd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (n > 0)
|
|
||||||
|
sed->cmd.lb->len++;
|
||||||
|
if (sed->cmd.lb->len >= QSE_COUNTOF(sed->cmd.lb->buf))
|
||||||
{
|
{
|
||||||
QSE_ASSERT (n == 1);
|
if (add_command_block (sed) <= -1) return -1;
|
||||||
|
|
||||||
if (sed->cmd.cur >= sed->cmd.end)
|
|
||||||
{
|
|
||||||
/* TODO: too many commands. change errnum */
|
|
||||||
free_command (sed, cmd);
|
|
||||||
SETERR0 (sed, QSE_SED_ENOMEM, 0);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd = ++sed->cmd.cur;
|
|
||||||
}
|
}
|
||||||
|
cmd = &sed->cmd.lb->buf[sed->cmd.lb->len];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sed->tmp.grp.level != 0)
|
if (sed->tmp.grp.level != 0)
|
||||||
@ -1814,9 +1846,10 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
{
|
{
|
||||||
if (max_count == 0 || sub_count < max_count)
|
if (max_count == 0 || sub_count < max_count)
|
||||||
{
|
{
|
||||||
/* TODO: maximum match depth... */
|
|
||||||
n = qse_matchrex (
|
n = qse_matchrex (
|
||||||
sed->mmgr, 0, cmd->u.subst.rex, opt,
|
sed->mmgr,
|
||||||
|
sed->depth.rex.match,
|
||||||
|
cmd->u.subst.rex, opt,
|
||||||
str_ptr, str_len,
|
str_ptr, str_len,
|
||||||
cur_ptr, cur_len,
|
cur_ptr, cur_len,
|
||||||
&mat, &errnum
|
&mat, &errnum
|
||||||
@ -1824,7 +1857,7 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
}
|
}
|
||||||
else n = 0;
|
else n = 0;
|
||||||
|
|
||||||
if (n == -1)
|
if (n <= -1)
|
||||||
{
|
{
|
||||||
SETERR0 (sed, QSE_SED_EREXMA, cmd->lnum);
|
SETERR0 (sed, QSE_SED_EREXMA, cmd->lnum);
|
||||||
return -1;
|
return -1;
|
||||||
@ -1972,7 +2005,9 @@ static int match_a (qse_sed_t* sed, qse_sed_cmd_t* cmd, qse_sed_adr_t* a)
|
|||||||
QSE_STR_CHAR(line,llen-1) == QSE_T('\n')) llen--;
|
QSE_STR_CHAR(line,llen-1) == QSE_T('\n')) llen--;
|
||||||
|
|
||||||
n = qse_matchrex (
|
n = qse_matchrex (
|
||||||
sed->mmgr, 0, a->u.rex, 0,
|
sed->mmgr,
|
||||||
|
sed->depth.rex.match,
|
||||||
|
a->u.rex, 0,
|
||||||
QSE_STR_PTR(line), llen,
|
QSE_STR_PTR(line), llen,
|
||||||
QSE_STR_PTR(line), llen,
|
QSE_STR_PTR(line), llen,
|
||||||
&match, &errnum);
|
&match, &errnum);
|
||||||
@ -2114,13 +2149,16 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
|
|
||||||
switch (cmd->type)
|
switch (cmd->type)
|
||||||
{
|
{
|
||||||
|
case QSE_SED_CMD_NOOP:
|
||||||
|
break;
|
||||||
|
|
||||||
case QSE_SED_CMD_QUIT:
|
case QSE_SED_CMD_QUIT:
|
||||||
n = write_str (sed,
|
n = write_str (sed,
|
||||||
QSE_STR_PTR(&sed->e.in.line),
|
QSE_STR_PTR(&sed->e.in.line),
|
||||||
QSE_STR_LEN(&sed->e.in.line));
|
QSE_STR_LEN(&sed->e.in.line));
|
||||||
if (n <= -1) return QSE_NULL;
|
if (n <= -1) return QSE_NULL;
|
||||||
case QSE_SED_CMD_QUIT_QUIET:
|
case QSE_SED_CMD_QUIT_QUIET:
|
||||||
jumpto = sed->cmd.cur + 1;
|
jumpto = &sed->cmd.quit;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QSE_SED_CMD_APPEND:
|
case QSE_SED_CMD_APPEND:
|
||||||
@ -2162,7 +2200,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
|
|
||||||
/* move past the last command so as to start
|
/* move past the last command so as to start
|
||||||
* the next cycle */
|
* the next cycle */
|
||||||
jumpto = sed->cmd.cur;
|
jumpto = &sed->cmd.over;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QSE_SED_CMD_DELETE_FIRSTLN:
|
case QSE_SED_CMD_DELETE_FIRSTLN:
|
||||||
@ -2185,12 +2223,12 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
/* if the pattern space is not empty,
|
/* if the pattern space is not empty,
|
||||||
* arrange to execute from the first
|
* arrange to execute from the first
|
||||||
* command */
|
* command */
|
||||||
jumpto = sed->cmd.cur + 2;
|
jumpto = &sed->cmd.again;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* arrange to start the the next cycle */
|
/* finish the current cycle */
|
||||||
jumpto = sed->cmd.cur;
|
jumpto = &sed->cmd.over;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2200,9 +2238,9 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
case QSE_SED_CMD_DELETE:
|
case QSE_SED_CMD_DELETE:
|
||||||
/* delete the pattern space */
|
/* delete the pattern space */
|
||||||
qse_str_clear (&sed->e.in.line);
|
qse_str_clear (&sed->e.in.line);
|
||||||
/* move past the last command so as to start
|
|
||||||
* the next cycle */
|
/* finish the current cycle */
|
||||||
jumpto = sed->cmd.cur;
|
jumpto = &sed->cmd.over;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QSE_SED_CMD_PRINT_LNNUM:
|
case QSE_SED_CMD_PRINT_LNNUM:
|
||||||
@ -2301,8 +2339,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
/* EOF is reached. */
|
/* EOF is reached. */
|
||||||
/*jumpto = sed->cmd.cur + 1;*/
|
jumpto = &sed->cmd.over;
|
||||||
jumpto = sed->cmd.cur;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2313,8 +2350,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
/* EOF is reached. */
|
/* EOF is reached. */
|
||||||
/*jumpto = sed->cmd.cur + 1;*/
|
jumpto = &sed->cmd.over;
|
||||||
jumpto = sed->cmd.cur;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2407,7 +2443,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jumpto == QSE_NULL) jumpto = cmd + 1;
|
if (jumpto == QSE_NULL) jumpto = cmd->state.next;
|
||||||
return jumpto;
|
return jumpto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2424,9 +2460,112 @@ static void close_outfile (qse_map_t* map, void* dptr, qse_size_t dlen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int init_command_block_for_exec (qse_sed_t* sed, qse_sed_cmd_blk_t* b)
|
||||||
|
{
|
||||||
|
qse_size_t i;
|
||||||
|
|
||||||
|
QSE_ASSERT (b->len <= QSE_COUNTOF(b->buf));
|
||||||
|
|
||||||
|
for (i = 0; i < b->len; i++)
|
||||||
|
{
|
||||||
|
qse_sed_cmd_t* c = &b->buf[i];
|
||||||
|
const qse_xstr_t* file = QSE_NULL;
|
||||||
|
|
||||||
|
/* clear states */
|
||||||
|
c->state.a1_matched = 0;
|
||||||
|
c->state.c_ready = 0;
|
||||||
|
|
||||||
|
/* let c point to the next command */
|
||||||
|
if (i + 1 >= b->len)
|
||||||
|
{
|
||||||
|
if (b->next == QSE_NULL || b->next->len <= 0)
|
||||||
|
c->state.next = &sed->cmd.over;
|
||||||
|
else
|
||||||
|
c->state.next = &b->next->buf[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c->state.next = &b->buf[i+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((c->type == QSE_SED_CMD_BRANCH ||
|
||||||
|
c->type == QSE_SED_CMD_BRANCH_COND) &&
|
||||||
|
c->u.branch.target == QSE_NULL)
|
||||||
|
{
|
||||||
|
/* resolve unresolved branch targets */
|
||||||
|
qse_map_pair_t* pair;
|
||||||
|
qse_xstr_t* lab = &c->u.branch.label;
|
||||||
|
|
||||||
|
if (lab->ptr == QSE_NULL)
|
||||||
|
{
|
||||||
|
/* arrange to branch past the last */
|
||||||
|
c->u.branch.target = &sed->cmd.over;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* resolve the target */
|
||||||
|
pair = qse_map_search (
|
||||||
|
&sed->tmp.labs, lab->ptr, lab->len);
|
||||||
|
if (pair == QSE_NULL)
|
||||||
|
{
|
||||||
|
SETERR1 (
|
||||||
|
sed, QSE_SED_ELABNF,
|
||||||
|
c->lnum, lab->ptr, lab->len
|
||||||
|
);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->u.branch.target = QSE_MAP_VPTR(pair);
|
||||||
|
|
||||||
|
/* free resolved label name */
|
||||||
|
QSE_MMGR_FREE (sed->mmgr, lab->ptr);
|
||||||
|
lab->ptr = QSE_NULL;
|
||||||
|
lab->len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* open output files in advance */
|
||||||
|
if (c->type == QSE_SED_CMD_WRITE_FILE ||
|
||||||
|
c->type == QSE_SED_CMD_WRITE_FILELN)
|
||||||
|
{
|
||||||
|
file = &c->u.file;
|
||||||
|
}
|
||||||
|
else if (c->type == QSE_SED_CMD_SUBSTITUTE &&
|
||||||
|
c->u.subst.file.ptr != QSE_NULL)
|
||||||
|
{
|
||||||
|
file = &c->u.subst.file;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file != QSE_NULL)
|
||||||
|
{
|
||||||
|
/* call this function to an open output file */
|
||||||
|
int n = write_str_to_file (
|
||||||
|
sed, c, QSE_NULL, 0,
|
||||||
|
file->ptr, file->len
|
||||||
|
);
|
||||||
|
if (n <= -1) return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int init_all_commands_for_exec (qse_sed_t* sed)
|
||||||
|
{
|
||||||
|
qse_sed_cmd_blk_t* b;
|
||||||
|
|
||||||
|
for (b = &sed->cmd.fb; b != QSE_NULL; b = b->next)
|
||||||
|
{
|
||||||
|
if (init_command_block_for_exec (sed, b) <= -1) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
|
int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
|
||||||
{
|
{
|
||||||
qse_sed_cmd_t* c, * j;
|
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -2505,74 +2644,10 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
|
|||||||
sed->e.out.eof = 1;
|
sed->e.out.eof = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = sed->cmd.buf; c < sed->cmd.cur; c++)
|
if (init_all_commands_for_exec (sed) <= -1)
|
||||||
{
|
{
|
||||||
const qse_xstr_t* file = QSE_NULL;
|
ret = -1;
|
||||||
|
goto done;
|
||||||
/* clear states */
|
|
||||||
c->state.a1_matched = 0;
|
|
||||||
c->state.c_ready = 0;
|
|
||||||
|
|
||||||
if ((c->type == QSE_SED_CMD_BRANCH ||
|
|
||||||
c->type == QSE_SED_CMD_BRANCH_COND) &&
|
|
||||||
c->u.branch.target == QSE_NULL)
|
|
||||||
{
|
|
||||||
/* resolve unresolved branch targets */
|
|
||||||
qse_map_pair_t* pair;
|
|
||||||
qse_xstr_t* lab = &c->u.branch.label;
|
|
||||||
|
|
||||||
if (lab->ptr == QSE_NULL)
|
|
||||||
{
|
|
||||||
/* arrange to branch past the last */
|
|
||||||
c->u.branch.target = sed->cmd.cur;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* resolve the target */
|
|
||||||
pair = qse_map_search (
|
|
||||||
&sed->tmp.labs, lab->ptr, lab->len);
|
|
||||||
if (pair == QSE_NULL)
|
|
||||||
{
|
|
||||||
SETERR1 (
|
|
||||||
sed, QSE_SED_ELABNF,
|
|
||||||
c->lnum, lab->ptr, lab->len
|
|
||||||
);
|
|
||||||
ret = -1;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->u.branch.target = QSE_MAP_VPTR(pair);
|
|
||||||
|
|
||||||
/* free resolved label name */
|
|
||||||
QSE_MMGR_FREE (sed->mmgr, lab->ptr);
|
|
||||||
lab->ptr = QSE_NULL;
|
|
||||||
lab->len = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* open output files in advance */
|
|
||||||
if (c->type == QSE_SED_CMD_WRITE_FILE ||
|
|
||||||
c->type == QSE_SED_CMD_WRITE_FILELN)
|
|
||||||
{
|
|
||||||
file = &c->u.file;
|
|
||||||
}
|
|
||||||
else if (c->type == QSE_SED_CMD_SUBSTITUTE &&
|
|
||||||
c->u.subst.file.ptr != QSE_NULL)
|
|
||||||
{
|
|
||||||
file = &c->u.subst.file;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file != QSE_NULL)
|
|
||||||
{
|
|
||||||
/* call this function to an open output file */
|
|
||||||
n = write_str_to_file (
|
|
||||||
sed, c, QSE_NULL, 0,
|
|
||||||
file->ptr, file->len
|
|
||||||
);
|
|
||||||
if (n <= -1) { ret = -1; goto done; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -2586,28 +2661,33 @@ int qse_sed_exec (qse_sed_t* sed, qse_sed_io_fun_t inf, qse_sed_io_fun_t outf)
|
|||||||
qse_lda_clear (&sed->e.txt.appended);
|
qse_lda_clear (&sed->e.txt.appended);
|
||||||
qse_str_clear (&sed->e.txt.read);
|
qse_str_clear (&sed->e.txt.read);
|
||||||
|
|
||||||
again:
|
if (sed->cmd.fb.len > 0)
|
||||||
c = sed->cmd.buf;
|
|
||||||
while (c < sed->cmd.cur)
|
|
||||||
{
|
{
|
||||||
n = match_address (sed, c);
|
qse_sed_cmd_t* c, * j;
|
||||||
if (n <= -1) { ret = -1; goto done; }
|
|
||||||
|
|
||||||
if (c->negated) n = !n;
|
again:
|
||||||
if (n == 0)
|
c = &sed->cmd.fb.buf[0];
|
||||||
|
|
||||||
|
while (c != &sed->cmd.over)
|
||||||
{
|
{
|
||||||
c++;
|
n = match_address (sed, c);
|
||||||
continue;
|
if (n <= -1) { ret = -1; goto done; }
|
||||||
|
|
||||||
|
if (c->negated) n = !n;
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = exec_cmd (sed, c);
|
||||||
|
if (j == QSE_NULL) { ret = -1; goto done; }
|
||||||
|
if (j == &sed->cmd.quit) goto done;
|
||||||
|
if (j == &sed->cmd.again) goto again;
|
||||||
|
|
||||||
|
/* go to the next command */
|
||||||
|
c = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
j = exec_cmd (sed, c);
|
|
||||||
if (j == QSE_NULL) { ret = -1; goto done; }
|
|
||||||
if (j == sed->cmd.cur + 1) goto done;
|
|
||||||
if (j == sed->cmd.cur + 2) goto again;
|
|
||||||
|
|
||||||
QSE_ASSERT (j <= sed->cmd.cur);
|
|
||||||
/* go to the next command */
|
|
||||||
c = j;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(sed->option & QSE_SED_QUIET))
|
if (!(sed->option & QSE_SED_QUIET))
|
||||||
|
@ -44,6 +44,7 @@ struct qse_sed_adr_t
|
|||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define QSE_SED_CMD_NOOP QSE_T('\0')
|
||||||
#define QSE_SED_CMD_QUIT QSE_T('q')
|
#define QSE_SED_CMD_QUIT QSE_T('q')
|
||||||
#define QSE_SED_CMD_QUIT_QUIET QSE_T('Q')
|
#define QSE_SED_CMD_QUIT_QUIET QSE_T('Q')
|
||||||
#define QSE_SED_CMD_APPEND QSE_T('a')
|
#define QSE_SED_CMD_APPEND QSE_T('a')
|
||||||
@ -118,13 +119,17 @@ struct qse_sed_cmd_t
|
|||||||
{
|
{
|
||||||
int a1_matched;
|
int a1_matched;
|
||||||
int c_ready;
|
int c_ready;
|
||||||
|
|
||||||
|
/* points to the next command for fast traversal and
|
||||||
|
* fast random jumps */
|
||||||
|
qse_sed_cmd_t* next;
|
||||||
} state;
|
} state;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qse_sed_cmd_blk_t
|
struct qse_sed_cmd_blk_t
|
||||||
{
|
{
|
||||||
qse_size_t len;
|
qse_size_t len;
|
||||||
qse_sed_cmd_t buf[512];
|
qse_sed_cmd_t buf[256];
|
||||||
qse_sed_cmd_blk_t* next;
|
qse_sed_cmd_blk_t* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -142,6 +147,15 @@ struct qse_sed_t
|
|||||||
|
|
||||||
int option; /**< stores options */
|
int option; /**< stores options */
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
qse_size_t build;
|
||||||
|
qse_size_t match;
|
||||||
|
} rex;
|
||||||
|
} depth;
|
||||||
|
|
||||||
/** source text pointers */
|
/** source text pointers */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -172,6 +186,7 @@ struct qse_sed_t
|
|||||||
} tmp;
|
} tmp;
|
||||||
|
|
||||||
/** compiled commands */
|
/** compiled commands */
|
||||||
|
#if 0
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
qse_size_t len; /**< buffer size */
|
qse_size_t len; /**< buffer size */
|
||||||
@ -179,14 +194,17 @@ struct qse_sed_t
|
|||||||
qse_sed_cmd_t* end; /**< end of the buffer */
|
qse_sed_cmd_t* end; /**< end of the buffer */
|
||||||
qse_sed_cmd_t* cur; /**< points next to the last command */
|
qse_sed_cmd_t* cur; /**< points next to the last command */
|
||||||
} cmd;
|
} cmd;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
qse_sed_cmd_blk_t fb; /**< the first block is static */
|
qse_sed_cmd_blk_t fb; /**< the first block is static */
|
||||||
qse_sed_cmd_blk_t* lb; /**< points to the last block */
|
qse_sed_cmd_blk_t* lb; /**< points to the last block */
|
||||||
|
|
||||||
|
qse_sed_cmd_t quit;
|
||||||
|
qse_sed_cmd_t again;
|
||||||
|
qse_sed_cmd_t over;
|
||||||
} cmd;
|
} cmd;
|
||||||
#endif
|
|
||||||
|
|
||||||
/** data for execution */
|
/** data for execution */
|
||||||
struct
|
struct
|
||||||
|
Loading…
Reference in New Issue
Block a user