added more code

This commit is contained in:
hyung-hwan 2009-05-10 08:46:26 +00:00
parent 5aeac8aa19
commit 9d258def0e
2 changed files with 116 additions and 129 deletions

View File

@ -206,9 +206,9 @@ static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
switch (cmd->type) switch (cmd->type)
{ {
case QSE_SED_CMD_A: case QSE_SED_CMD_APPEND:
case QSE_SED_CMD_I: case QSE_SED_CMD_INSERT:
case QSE_SED_CMD_C: case QSE_SED_CMD_CHANGE:
if (cmd->u.text.ptr != QSE_NULL) if (cmd->u.text.ptr != QSE_NULL)
QSE_MMGR_FREE (sed->mmgr, cmd->u.text.ptr); QSE_MMGR_FREE (sed->mmgr, cmd->u.text.ptr);
break; break;
@ -1449,12 +1449,12 @@ static int write_num (qse_sed_t* sed, qse_size_t x)
return 0; return 0;
} }
static int match_a1 (qse_sed_t* sed, qse_sed_cmd_t* cmd) static int match_a (qse_sed_t* sed, qse_sed_a_t* a)
{ {
switch (cmd->a1.type) switch (a->type)
{ {
case QSE_SED_A_LINE: case QSE_SED_A_LINE:
return (sed->eio.in.num == cmd->a1.u.line)? 1: 0; return (sed->eio.in.num == a->u.line)? 1: 0;
case QSE_SED_A_REX: case QSE_SED_A_REX:
{ {
@ -1463,7 +1463,7 @@ static int match_a1 (qse_sed_t* sed, qse_sed_cmd_t* cmd)
qse_str_t* line; qse_str_t* line;
qse_size_t llen; qse_size_t llen;
QSE_ASSERT (cmd->a1.u.rex != QSE_NULL); QSE_ASSERT (a->u.rex != QSE_NULL);
line = &sed->eio.in.line; line = &sed->eio.in.line;
llen = QSE_STR_LEN(line); llen = QSE_STR_LEN(line);
@ -1475,7 +1475,7 @@ static int match_a1 (qse_sed_t* sed, qse_sed_cmd_t* cmd)
n = qse_matchrex ( n = qse_matchrex (
sed->mmgr, sed->mmgr,
0, 0,
cmd->a1.u.rex, a->u.rex,
0, 0,
QSE_STR_PTR(line), QSE_STR_PTR(line),
llen, llen,
@ -1493,6 +1493,13 @@ static int match_a1 (qse_sed_t* sed, qse_sed_cmd_t* cmd)
qse_char_t c; qse_char_t c;
int n; int n;
if (sed->eio.in.xbuf_len < 0)
{
/* we know that we've reached eof as it has
* been done so previously */
return 1;
}
n = read_char (sed, &c); n = read_char (sed, &c);
if (n <= -1) return -1; if (n <= -1) return -1;
@ -1511,155 +1518,112 @@ static int match_a1 (qse_sed_t* sed, qse_sed_cmd_t* cmd)
} }
} }
QSE_ASSERT (cmd->a1.type == QSE_SED_A_NONE); QSE_ASSERT (a->type == QSE_SED_A_NONE);
return 1; /* match */ return 1; /* match */
} }
static int match_a2 (qse_sed_t* sed, qse_sed_cmd_t* cmd)
{
switch (cmd->a2.type)
{
case QSE_SED_A_LINE:
return (sed->eio.in.num == cmd->a2.u.line)? 1:
(sed->eio.in.num < cmd->a2.u.line)? 2: 0;
case QSE_SED_A_REX:
{
qse_str_t match;
int errnum, n;
qse_str_t* line;
qse_size_t llen;
QSE_ASSERT (cmd->a2.u.rex != QSE_NULL);
line = &sed->eio.in.line;
llen = QSE_STR_LEN(line);
/* TODO: support different line end scheme */
if (llen > 0 &&
QSE_STR_CHAR(line,llen-1) == QSE_T('\n')) llen--;
n = qse_matchrex (
sed->mmgr,
0,
cmd->a2.u.rex,
0,
QSE_STR_PTR(line),
llen,
&match.ptr, &match.len, &errnum);
if (n <= -1)
{
sed->errnum = QSE_SED_EREXMA;
return -1;
}
return (n == 0)? 2: 1;
}
case QSE_SED_A_DOL:
{
qse_char_t c;
int n;
n = read_char (sed, &c);
if (n <= -1) return -1;
QSE_ASSERT (sed->eio.in.xbuf_len == 0);
if (n == 0)
{
/* eof has been reached */
sed->eio.in.xbuf_len--;
return 1;
}
else
{
sed->eio.in.xbuf[sed->eio.in.xbuf_len++] = c;
return 2;
}
}
}
QSE_ASSERT (cmd->a2.type == QSE_SED_A_NONE);
return 0; /* no match unlike a1 */
}
/* match an address against input. /* match an address against input.
* return -1 on error, 0 on no match, 1 on match. */ * return -1 on error, 0 on no match, 1 on match. */
static int match_address (qse_sed_t* sed, qse_sed_cmd_t* cmd) static int match_address (qse_sed_t* sed, qse_sed_cmd_t* cmd)
{ {
int a1, a2; int n;
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);
return 1; return 1;
} }
else if (cmd->a2.type != QSE_SED_A_NONE)
if (cmd->a1_matched == 0)
{ {
a1 = match_a1 (sed, cmd); /* two addresses */
if (a1 <= -1) return -1; if (cmd->state.a1_matched)
{
n = match_a (sed, &cmd->a2);
if (n <= -1) return -1;
if (n == 0)
{
if (cmd->a2.type == QSE_SED_A_LINE &&
sed->eio.in.num > cmd->a2.u.line)
{
cmd->state.a1_matched = 0;
return 0;
}
if (a1 == 0) return 0; return 1;
}
cmd->state.a1_matched = 0;
//lastaddr = 1;
return 1;
}
else else
{ {
cmd->a1_matched = 1; n = match_a (sed, &cmd->a1);
if (n <= -1) return -1;
if (n == 0) return 0;
if (cmd->a2.type == QSE_SED_A_LINE &&
sed->eio.in.num >= cmd->a2.u.line)
{
//lastaddr = 1;
}
else
{
cmd->state.a1_matched = 1;
}
return 1; return 1;
} }
} }
else else
{ {
a2 = match_a2 (sed, cmd); /* single address */
if (a2 <= -1) return -1; n = match_a (sed, &cmd->a1);
return (n <= -1)? -1:
if (a2 == 0) return 0; (n == 0)? 0: 1;
else
{
if (a2 == 1) cmd->a1_matched = 0;
return 1;
}
} }
} }
static int exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd) static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
{ {
int n; int n;
qse_sed_cmd_t* jumpto = QSE_NULL;
switch (cmd->type) switch (cmd->type)
{ {
case QSE_SED_CMD_Q: case QSE_SED_CMD_QUIT:
n = write_str (sed, n = write_str (sed,
QSE_STR_PTR(&sed->eio.in.line), QSE_STR_PTR(&sed->eio.in.line),
QSE_STR_LEN(&sed->eio.in.line)); QSE_STR_LEN(&sed->eio.in.line));
if (n <= -1) return -1; if (n <= -1) return QSE_NULL;
case QSE_SED_CMD_QQ: case QSE_SED_CMD_QUIT_QUIET:
return 0; jumpto = sed->cmd.cur + 1;
case QSE_SED_CMD_EQ:
if (write_num (sed, sed->eio.in.num) <= -1) return -1;
if (write_char (sed, QSE_T('\n')) <= -1) return -1;
break; break;
case QSE_SED_CMD_A: 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 ( if (qse_lda_insert (
&sed->text_appended, &sed->text_appended,
QSE_LDA_SIZE(&sed->text_appended), QSE_LDA_SIZE(&sed->text_appended),
&cmd->u.text, 0) == (qse_size_t)-1) &cmd->u.text, 0) == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; sed->errnum = QSE_SED_ENOMEM;
return -1; return QSE_NULL;
} }
break; break;
case QSE_SED_CMD_I: case QSE_SED_CMD_INSERT:
n = write_str (sed, n = write_str (sed,
QSE_STR_PTR(&cmd->u.text), QSE_STR_PTR(&cmd->u.text),
QSE_STR_LEN(&cmd->u.text)); QSE_STR_LEN(&cmd->u.text));
if (n <= -1) return -1; if (n <= -1) return QSE_NULL;
break; break;
case QSE_SED_CMD_C: case QSE_SED_CMD_CHANGE:
// TODO: this behavior is wrong.... /* change the input space */
// fix this....
n = qse_str_ncpy ( n = qse_str_ncpy (
&sed->eio.in.line, &sed->eio.in.line,
QSE_STR_PTR(&cmd->u.text), QSE_STR_PTR(&cmd->u.text),
@ -1667,16 +1631,30 @@ static int exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (n == (qse_size_t)-1) if (n == (qse_size_t)-1)
{ {
sed->errnum = QSE_SED_ENOMEM; sed->errnum = QSE_SED_ENOMEM;
return -1; return QSE_NULL;
} }
/* move past the last command so as to start
* the next cycle */
jumpto = sed->cmd.cur;
break;
case QSE_SED_CMD_DELETE:
/* delete the input space */
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;
} }
return 1; if (jumpto == NULL) jumpto = cmd + 1;
return jumpto;
} }
int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf) int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
{ {
qse_sed_cmd_t* c, * j;
qse_ssize_t n; qse_ssize_t n;
int ret = 0; int ret = 0;
@ -1723,9 +1701,11 @@ int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
sed->eio.out.eof = 1; sed->eio.out.eof = 1;
} }
/* clear states */
for (c = sed->cmd.buf; c < sed->cmd.cur; c++) c->state.a1_matched = 0;
while (1) while (1)
{ {
qse_sed_cmd_t* c;
qse_size_t i; qse_size_t i;
n = read_line (sed); n = read_line (sed);
@ -1747,12 +1727,17 @@ int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
continue; continue;
} }
n = exec_cmd (sed, c); j = exec_cmd (sed, c);
if (n <= -1) { ret = -1; goto done; } if (j == QSE_NULL) { ret = -1; goto done; }
if (n == 0) goto done; if (j > sed->cmd.cur)
{
/* finish the current cycle */
QSE_ASSERT (j == sed->cmd.cur + 1);
goto done;
}
/* TODO: if exec_cmd jumped change c.... */ /* go to the next command */
c++; c = j;
} }
if (!(sed->option & QSE_SED_QUIET)) if (!(sed->option & QSE_SED_QUIET))

View File

@ -48,21 +48,20 @@ struct qse_sed_cmd_t
{ {
enum enum
{ {
/* print current line number */ QSE_SED_CMD_PRINT_LNUM = QSE_T('='),
QSE_SED_CMD_EQ = QSE_T('='), QSE_SED_CMD_QUIT = QSE_T('q'),
QSE_SED_CMD_Q = QSE_T('q'), QSE_SED_CMD_QUIT_QUIET = QSE_T('Q'),
QSE_SED_CMD_QQ = QSE_T('Q'),
/* delete pattern space */ /* delete pattern space */
QSE_SED_CMD_D = QSE_T('d'), QSE_SED_CMD_DELETE = QSE_T('d'),
QSE_SED_CMD_DD = QSE_T('D'), QSE_SED_CMD_DD = QSE_T('D'),
/* a \<\n> text - append text */ /* a \<\n> text - append text */
QSE_SED_CMD_A = QSE_T('a'), QSE_SED_CMD_APPEND = QSE_T('a'),
/* i \<\n> text - insert text */ /* i \<\n> text - insert text */
QSE_SED_CMD_I = QSE_T('i'), QSE_SED_CMD_INSERT = QSE_T('i'),
/* c \<\n> text - change text */ /* c \<\n> text - change text */
QSE_SED_CMD_C = QSE_T('c'), QSE_SED_CMD_CHANGE = QSE_T('c'),
QSE_SED_CMD_H = QSE_T('h'), QSE_SED_CMD_H = QSE_T('h'),
QSE_SED_CMD_HH = QSE_T('H'), QSE_SED_CMD_HH = QSE_T('H'),
@ -99,7 +98,6 @@ struct qse_sed_cmd_t
} type; } type;
int negated; int negated;
int a1_matched;
qse_sed_a_t a1; /* optional start address */ qse_sed_a_t a1; /* optional start address */
qse_sed_a_t a2; /* optional end address */ qse_sed_a_t a2; /* optional end address */
@ -138,6 +136,10 @@ struct qse_sed_cmd_t
void* rex; void* rex;
} u; } u;
struct
{
int a1_matched;
} state;
}; };
#endif #endif