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_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_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_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("label name too long"),
QSE_T("empty label name"), QSE_T("empty label name"),
QSE_T("duplicate label name"), QSE_T("duplicate label name"),
QSE_T("label not found"),
QSE_T("empty file name"), QSE_T("empty file name"),
QSE_T("illegal file name"), QSE_T("illegal file name"),
QSE_T("command not terminated properly"), 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); QSE_MMGR_FREE (sed->mmgr, cmd->u.text.ptr);
break; break;
case QSE_SED_CMD_B: case QSE_SED_CMD_BRANCH:
case QSE_SED_CMD_T: case QSE_SED_CMD_T:
if (cmd->u.branch.label.ptr != QSE_NULL) if (cmd->u.branch.label.ptr != QSE_NULL)
QSE_MMGR_FREE (sed->mmgr, cmd->u.branch.label.ptr); 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 * of a group. this way, all the commands in a group
* can be skipped. the branch target is set once a * can be skipped. the branch target is set once a
* corresponding } is met. */ * corresponding } is met. */
cmd->type = QSE_SED_CMD_B; cmd->type = QSE_SED_CMD_BRANCH;
cmd->negated = !cmd->negated; cmd->negated = !cmd->negated;
if (sed->grplvl >= QSE_COUNTOF(sed->grpcmd)) if (sed->grplvl >= QSE_COUNTOF(sed->grpcmd))
@ -1005,20 +1006,6 @@ qse_printf (QSE_T("command not recognized [%c]\n"), c);
ADVSCP (sed); ADVSCP (sed);
return 0; 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'):
case QSE_T('Q'): case QSE_T('Q'):
cmd->type = c; cmd->type = c;
@ -1081,7 +1068,15 @@ qse_printf (QSE_T("%s%s"), ttt, cmd->u.text.ptr);
break; 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('D'): case QSE_T('D'):
case QSE_T('h'): 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('l'):
case QSE_T('n'): case QSE_T('n'):
case QSE_T('N'): case QSE_T('N'):
case QSE_T('p'):
case QSE_T('P'):
case QSE_T('x'): case QSE_T('x'):
cmd->type = c; cmd->type = c;
ADVSCP (sed); ADVSCP (sed);
@ -1235,9 +1228,14 @@ static int compile_source (
if (c == QSE_T('!')) if (c == QSE_T('!'))
{ {
/* negate */ /* allow any number of the negation indicators */
cmd->negated = 1; do {
do { ADVSCP (sed); } while (IS_SPACE(c)); 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; int n;
cmd->state.c_ready = 0;
if (cmd->a1.type == QSE_SED_A_NONE) if (cmd->a1.type == QSE_SED_A_NONE)
{ {
QSE_ASSERT (cmd->a2.type == QSE_SED_A_NONE); QSE_ASSERT (cmd->a2.type == QSE_SED_A_NONE);
cmd->state.c_ready = 1;
return 1; return 1;
} }
else if (cmd->a2.type != QSE_SED_A_NONE) 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 && if (cmd->a2.type == QSE_SED_A_LINE &&
sed->eio.in.num > cmd->a2.u.line) sed->eio.in.num > cmd->a2.u.line)
{ {
/* exit the range */
cmd->state.a1_matched = 0; cmd->state.a1_matched = 0;
return 0; return 0;
} }
/* still in the range. return match
* despite the actual mismatch */
return 1; return 1;
} }
/* exit the range */
cmd->state.a1_matched = 0; cmd->state.a1_matched = 0;
//lastaddr = 1; cmd->state.c_ready = 1;
return 1; return 1;
} }
else else
{ {
n = match_a (sed, &cmd->a1); n = match_a (sed, &cmd->a1);
if (n <= -1) return -1; if (n <= -1) return -1;
if (n == 0) return 0; if (n == 0)
{
return 0;
}
if (cmd->a2.type == QSE_SED_A_LINE && if (cmd->a2.type == QSE_SED_A_LINE &&
sed->eio.in.num >= cmd->a2.u.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 else
{ {
/* mark that the first is matched so as to
* move on to the range test */
cmd->state.a1_matched = 1; cmd->state.a1_matched = 1;
} }
return 1; return 1;
} }
} }
else else
{ {
/* single address */ /* single address */
cmd->state.c_ready = 1;
n = match_a (sed, &cmd->a1); n = match_a (sed, &cmd->a1);
return (n <= -1)? -1: return (n <= -1)? -1:
(n == 0)? 0: 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; jumpto = sed->cmd.cur + 1;
break; 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: case QSE_SED_CMD_APPEND:
if (qse_lda_insert ( 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; break;
case QSE_SED_CMD_CHANGE: case QSE_SED_CMD_CHANGE:
/* change the input space */ if (cmd->state.c_ready)
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; /* change the input space */
return QSE_NULL; 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; break;
case QSE_SED_CMD_DELETE: 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 */ * the next cycle */
jumpto = sed->cmd.cur; jumpto = sed->cmd.cur;
break; 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; 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_L = QSE_T('l'),
QSE_SED_CMD_N = QSE_T('n'), QSE_SED_CMD_N = QSE_T('n'),
QSE_SED_CMD_NN = 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'), QSE_SED_CMD_PP = QSE_T('P'),
/* exchange hold space and pattern space */ /* exchange hold space and pattern space */
QSE_SED_CMD_X = QSE_T('x'), QSE_SED_CMD_X = QSE_T('x'),
/* branch */ /* branch */
QSE_SED_CMD_B = QSE_T('b'), QSE_SED_CMD_BRANCH = QSE_T('b'),
QSE_SED_CMD_T = QSE_T('t'), QSE_SED_CMD_T = QSE_T('t'),
/* r filename - append a text from a file */ /* r filename - append a text from a file */
@ -139,6 +139,7 @@ struct qse_sed_cmd_t
struct struct
{ {
int a1_matched; int a1_matched;
int c_ready;
} state; } state;
}; };