From 9d258def0e57ded90da89a170f6b4bb1a53e38c0 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 10 May 2009 08:46:26 +0000 Subject: [PATCH] added more code --- qse/lib/utl/sed.c | 223 +++++++++++++++++++++------------------------- qse/lib/utl/sed.h | 22 ++--- 2 files changed, 116 insertions(+), 129 deletions(-) diff --git a/qse/lib/utl/sed.c b/qse/lib/utl/sed.c index b3e54068..5eda9be9 100644 --- a/qse/lib/utl/sed.c +++ b/qse/lib/utl/sed.c @@ -206,9 +206,9 @@ static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd) switch (cmd->type) { - case QSE_SED_CMD_A: - case QSE_SED_CMD_I: - case QSE_SED_CMD_C: + case QSE_SED_CMD_APPEND: + case QSE_SED_CMD_INSERT: + case QSE_SED_CMD_CHANGE: if (cmd->u.text.ptr != QSE_NULL) QSE_MMGR_FREE (sed->mmgr, cmd->u.text.ptr); break; @@ -1449,12 +1449,12 @@ static int write_num (qse_sed_t* sed, qse_size_t x) 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: - 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: { @@ -1463,7 +1463,7 @@ static int match_a1 (qse_sed_t* sed, qse_sed_cmd_t* cmd) qse_str_t* line; qse_size_t llen; - QSE_ASSERT (cmd->a1.u.rex != QSE_NULL); + QSE_ASSERT (a->u.rex != QSE_NULL); line = &sed->eio.in.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 ( sed->mmgr, 0, - cmd->a1.u.rex, + a->u.rex, 0, QSE_STR_PTR(line), llen, @@ -1493,6 +1493,13 @@ static int match_a1 (qse_sed_t* sed, qse_sed_cmd_t* cmd) qse_char_t c; 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); 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 */ } -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. * return -1 on error, 0 on no match, 1 on match. */ 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) { QSE_ASSERT (cmd->a2.type == QSE_SED_A_NONE); return 1; } - - if (cmd->a1_matched == 0) + else if (cmd->a2.type != QSE_SED_A_NONE) { - a1 = match_a1 (sed, cmd); - if (a1 <= -1) return -1; - - if (a1 == 0) return 0; - else + /* two addresses */ + if (cmd->state.a1_matched) { - cmd->a1_matched = 1; + 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; + } + + return 1; + } + + cmd->state.a1_matched = 0; + //lastaddr = 1; + return 1; + } + else + { + 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; } } else { - a2 = match_a2 (sed, cmd); - if (a2 <= -1) return -1; - - if (a2 == 0) return 0; - else - { - if (a2 == 1) cmd->a1_matched = 0; - return 1; - } + /* single address */ + n = match_a (sed, &cmd->a1); + return (n <= -1)? -1: + (n == 0)? 0: 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; + qse_sed_cmd_t* jumpto = QSE_NULL; switch (cmd->type) { - case QSE_SED_CMD_Q: + case QSE_SED_CMD_QUIT: n = write_str (sed, QSE_STR_PTR(&sed->eio.in.line), QSE_STR_LEN(&sed->eio.in.line)); - if (n <= -1) return -1; - case QSE_SED_CMD_QQ: - return 0; - - 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; + if (n <= -1) return QSE_NULL; + case QSE_SED_CMD_QUIT_QUIET: + jumpto = sed->cmd.cur + 1; 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 ( &sed->text_appended, QSE_LDA_SIZE(&sed->text_appended), &cmd->u.text, 0) == (qse_size_t)-1) { sed->errnum = QSE_SED_ENOMEM; - return -1; + return QSE_NULL; } break; - case QSE_SED_CMD_I: + case QSE_SED_CMD_INSERT: n = write_str (sed, QSE_STR_PTR(&cmd->u.text), QSE_STR_LEN(&cmd->u.text)); - if (n <= -1) return -1; + if (n <= -1) return QSE_NULL; break; - case QSE_SED_CMD_C: - // TODO: this behavior is wrong.... - // fix this.... + case QSE_SED_CMD_CHANGE: + /* change the input space */ n = qse_str_ncpy ( &sed->eio.in.line, 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) { 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; } - 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) { + qse_sed_cmd_t* c, * j; qse_ssize_t n; 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; } + /* clear states */ + for (c = sed->cmd.buf; c < sed->cmd.cur; c++) c->state.a1_matched = 0; + while (1) { - qse_sed_cmd_t* c; qse_size_t i; 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; } - n = exec_cmd (sed, c); - if (n <= -1) { ret = -1; goto done; } - if (n == 0) goto done; + j = exec_cmd (sed, c); + if (j == QSE_NULL) { ret = -1; 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.... */ - c++; + /* go to the next command */ + c = j; } if (!(sed->option & QSE_SED_QUIET)) diff --git a/qse/lib/utl/sed.h b/qse/lib/utl/sed.h index c19ad203..7f517dad 100644 --- a/qse/lib/utl/sed.h +++ b/qse/lib/utl/sed.h @@ -48,21 +48,20 @@ struct qse_sed_cmd_t { enum { - /* print current line number */ - QSE_SED_CMD_EQ = QSE_T('='), - QSE_SED_CMD_Q = QSE_T('q'), - QSE_SED_CMD_QQ = QSE_T('Q'), + QSE_SED_CMD_PRINT_LNUM = QSE_T('='), + QSE_SED_CMD_QUIT = QSE_T('q'), + QSE_SED_CMD_QUIT_QUIET = QSE_T('Q'), /* delete pattern space */ - QSE_SED_CMD_D = QSE_T('d'), - QSE_SED_CMD_DD = QSE_T('D'), + QSE_SED_CMD_DELETE = QSE_T('d'), + QSE_SED_CMD_DD = QSE_T('D'), /* a \<\n> text - append text */ - QSE_SED_CMD_A = QSE_T('a'), + QSE_SED_CMD_APPEND = QSE_T('a'), /* i \<\n> text - insert text */ - QSE_SED_CMD_I = QSE_T('i'), + QSE_SED_CMD_INSERT = QSE_T('i'), /* 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_HH = QSE_T('H'), @@ -99,7 +98,6 @@ struct qse_sed_cmd_t } type; int negated; - int a1_matched; qse_sed_a_t a1; /* optional start address */ qse_sed_a_t a2; /* optional end address */ @@ -138,6 +136,10 @@ struct qse_sed_cmd_t void* rex; } u; + struct + { + int a1_matched; + } state; }; #endif