added more code

This commit is contained in:
hyung-hwan 2009-05-11 07:27:35 +00:00
parent 9d258def0e
commit 6d68da1669
3 changed files with 98 additions and 42 deletions

View File

@ -45,6 +45,7 @@ enum qse_sed_errnum_t
QSE_SED_ELABTL, /* label too long */
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_EFILIL, /* illegal file name */
QSE_SED_ENOTRM, /* not terminated properly */

View File

@ -140,6 +140,7 @@ const qse_char_t* qse_sed_geterrmsg (qse_sed_t* sed)
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"),
@ -213,7 +214,7 @@ static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
QSE_MMGR_FREE (sed->mmgr, cmd->u.text.ptr);
break;
case QSE_SED_CMD_B:
case QSE_SED_CMD_BRANCH:
case QSE_SED_CMD_T:
if (cmd->u.branch.label.ptr != QSE_NULL)
QSE_MMGR_FREE (sed->mmgr, cmd->u.branch.label.ptr);
@ -979,7 +980,7 @@ qse_printf (QSE_T("command not recognized [%c]\n"), c);
* of a group. this way, all the commands in a group
* can be skipped. the branch target is set once a
* corresponding } is met. */
cmd->type = QSE_SED_CMD_B;
cmd->type = QSE_SED_CMD_BRANCH;
cmd->negated = !cmd->negated;
if (sed->grplvl >= QSE_COUNTOF(sed->grpcmd))
@ -1005,20 +1006,6 @@ qse_printf (QSE_T("command not recognized [%c]\n"), c);
ADVSCP (sed);
return 0;
case QSE_T('='):
cmd->type = c;
if (sed->option & QSE_SED_CLASSIC &&
cmd->a2.type != QSE_SED_A_NONE)
{
sed->errnum = QSE_SED_EA2PHB;
return -1;
}
ADVSCP (sed);
if (terminate_command (sed) <= -1) return -1;
qse_printf (QSE_T("command %c\n"), cmd->type);
break;
case QSE_T('q'):
case QSE_T('Q'):
cmd->type = c;
@ -1081,7 +1068,15 @@ qse_printf (QSE_T("%s%s"), ttt, cmd->u.text.ptr);
break;
}
case QSE_T('='):
if (sed->option & QSE_SED_CLASSIC &&
cmd->a2.type != QSE_SED_A_NONE)
{
sed->errnum = QSE_SED_EA2PHB;
return -1;
}
case QSE_T('p'):
case QSE_T('P'):
case QSE_T('d'):
case QSE_T('D'):
case QSE_T('h'):
@ -1091,8 +1086,6 @@ qse_printf (QSE_T("%s%s"), ttt, cmd->u.text.ptr);
case QSE_T('l'):
case QSE_T('n'):
case QSE_T('N'):
case QSE_T('p'):
case QSE_T('P'):
case QSE_T('x'):
cmd->type = c;
ADVSCP (sed);
@ -1235,9 +1228,14 @@ static int compile_source (
if (c == QSE_T('!'))
{
/* negate */
cmd->negated = 1;
do { ADVSCP (sed); } while (IS_SPACE(c));
/* allow any number of the negation indicators */
do {
cmd->negated = !cmd->negated;
c = NXTSC(sed);
}
while (c== QSE_T('!'));
while (IS_SPACE(c)) c = NXTSC (sed);
}
@ -1528,9 +1526,11 @@ static int match_address (qse_sed_t* sed, qse_sed_cmd_t* cmd)
{
int n;
cmd->state.c_ready = 0;
if (cmd->a1.type == QSE_SED_A_NONE)
{
QSE_ASSERT (cmd->a2.type == QSE_SED_A_NONE);
cmd->state.c_ready = 1;
return 1;
}
else if (cmd->a2.type != QSE_SED_A_NONE)
@ -1545,38 +1545,53 @@ static int match_address (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (cmd->a2.type == QSE_SED_A_LINE &&
sed->eio.in.num > cmd->a2.u.line)
{
/* exit the range */
cmd->state.a1_matched = 0;
return 0;
}
/* still in the range. return match
* despite the actual mismatch */
return 1;
}
/* exit the range */
cmd->state.a1_matched = 0;
//lastaddr = 1;
cmd->state.c_ready = 1;
return 1;
}
else
{
n = match_a (sed, &cmd->a1);
if (n <= -1) return -1;
if (n == 0) return 0;
if (n == 0)
{
return 0;
}
if (cmd->a2.type == QSE_SED_A_LINE &&
sed->eio.in.num >= cmd->a2.u.line)
{
//lastaddr = 1;
/* the line number specified in the second
* address is equal to or less than the current
* line number. */
cmd->state.c_ready = 1;
}
else
{
/* mark that the first is matched so as to
* move on to the range test */
cmd->state.a1_matched = 1;
}
return 1;
}
}
else
{
/* single address */
cmd->state.c_ready = 1;
n = match_a (sed, &cmd->a1);
return (n <= -1)? -1:
(n == 0)? 0: 1;
@ -1599,10 +1614,6 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
jumpto = sed->cmd.cur + 1;
break;
case QSE_SED_CMD_PRINT_LNUM:
if (write_num (sed, sed->eio.in.num) <= -1) return QSE_NULL;
if (write_char (sed, QSE_T('\n')) <= -1) return QSE_NULL;
break;
case QSE_SED_CMD_APPEND:
if (qse_lda_insert (
@ -1623,20 +1634,30 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
break;
case QSE_SED_CMD_CHANGE:
/* change the input space */
n = qse_str_ncpy (
&sed->eio.in.line,
QSE_STR_PTR(&cmd->u.text),
QSE_STR_LEN(&cmd->u.text));
if (n == (qse_size_t)-1)
if (cmd->state.c_ready)
{
sed->errnum = QSE_SED_ENOMEM;
return QSE_NULL;
/* change the input space */
n = qse_str_ncpy (
&sed->eio.in.line,
QSE_STR_PTR(&cmd->u.text),
QSE_STR_LEN(&cmd->u.text));
if (n == (qse_size_t)-1)
{
sed->errnum = QSE_SED_ENOMEM;
return QSE_NULL;
}
/* move past the last command so as to start
* the next cycle */
jumpto = sed->cmd.cur;
}
else
{
/* TODO: prearrange for CHANGE to be executed on the lastline wihtout
matchng the second address */
qse_str_clear (&sed->eio.in.line);
}
/* move past the last command so as to start
* the next cycle */
jumpto = sed->cmd.cur;
break;
case QSE_SED_CMD_DELETE:
@ -1646,6 +1667,39 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
* the next cycle */
jumpto = sed->cmd.cur;
break;
case QSE_SED_CMD_PRINT_LNUM:
if (write_num (sed, sed->eio.in.num) <= -1) return QSE_NULL;
if (write_char (sed, QSE_T('\n')) <= -1) return QSE_NULL;
break;
case QSE_SED_CMD_PRINT:
n = write_str (sed,
QSE_STR_PTR(&sed->eio.in.line),
QSE_STR_LEN(&sed->eio.in.line));
if (n <= -1) return QSE_NULL;
break;
case QSE_SED_CMD_BRANCH:
if (cmd->u.branch.target == QSE_NULL)
{
qse_map_pair_t* pair;
qse_xstr_t* lab = &cmd->u.branch.label;
QSE_ASSERT (lab->ptr != QSE_NULL && lab->len > 0);
pair = qse_map_search (
&sed->labs, lab->ptr, lab->len);
if (pair == QSE_NULL)
{
sed->errnum = QSE_SED_ELABNF;
return QSE_NULL;
}
cmd->u.branch.target = QSE_MAP_VPTR(pair);
}
jumpto = cmd->u.branch.target;
break;
}
if (jumpto == NULL) jumpto = cmd + 1;

View File

@ -71,13 +71,13 @@ struct qse_sed_cmd_t
QSE_SED_CMD_L = QSE_T('l'),
QSE_SED_CMD_N = QSE_T('n'),
QSE_SED_CMD_NN = QSE_T('N'),
QSE_SED_CMD_P = QSE_T('p'),
QSE_SED_CMD_PRINT = QSE_T('p'),
QSE_SED_CMD_PP = QSE_T('P'),
/* exchange hold space and pattern space */
QSE_SED_CMD_X = QSE_T('x'),
/* branch */
QSE_SED_CMD_B = QSE_T('b'),
QSE_SED_CMD_BRANCH = QSE_T('b'),
QSE_SED_CMD_T = QSE_T('t'),
/* r filename - append a text from a file */
@ -139,6 +139,7 @@ struct qse_sed_cmd_t
struct
{
int a1_matched;
int c_ready;
} state;
};