From 2e818033c91d3643d387e3c624b4150a866226dc Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 11 Mar 2009 07:38:35 +0000 Subject: [PATCH] sed - enhanced a function to get text following 'a', 'i', 'c'. --- qse/include/qse/utl/sed.h | 4 ++- qse/lib/utl/sed.c | 59 ++++++++++++++++++++++----------------- qse/lib/utl/sed.h | 3 +- qse/test/utl/sed01.c | 5 ++-- 4 files changed, 41 insertions(+), 30 deletions(-) diff --git a/qse/include/qse/utl/sed.h b/qse/include/qse/utl/sed.h index 9c969b58..f3711b2f 100644 --- a/qse/include/qse/utl/sed.h +++ b/qse/include/qse/utl/sed.h @@ -41,7 +41,9 @@ enum qse_sed_errnum_t enum qse_sed_option_t { - QSE_SED_STRIPLS = (1 << 0) /* strip leading spaces from text*/ + QSE_SED_STRIPLS = (1 << 0), /* strip leading spaces from text*/ + QSE_SED_KEEPTBS = (1 << 1), /* keep an trailing backslash */ + QSE_SED_ENSURENL = (1 << 2) /* ensure NL at the text end */ }; typedef struct qse_sed_t qse_sed_t; diff --git a/qse/lib/utl/sed.c b/qse/lib/utl/sed.c index 5f34b8ad..afc19573 100644 --- a/qse/lib/utl/sed.c +++ b/qse/lib/utl/sed.c @@ -214,7 +214,7 @@ static qse_sed_a_t* address (qse_sed_t* sed, qse_sed_a_t* a) return a; } -/* get the text following 'a' and 'i' command. +/* get the text for the 'a', 'i', and 'c' commands. * POSIX: * The argument text shall consist of one or more lines. Each embedded * in the text shall be preceded by a backslash. Other backslashes @@ -223,10 +223,19 @@ static qse_sed_a_t* address (qse_sed_t* sed, qse_sed_a_t* a) static qse_str_t* get_text (qse_sed_t* sed, qse_sed_c_t* cmd) { qse_cint_t c; - qse_str_t* text = QSE_NULL; + qse_str_t* t = QSE_NULL; - text = qse_str_open (sed->mmgr, 0, 128); - if (text == QSE_NULL) goto oops; +#define ADD(sed,str,c,errlabel) \ +do { \ + if (qse_str_ccat (str, c) == (qse_size_t)-1) \ + { \ + sed->errnum = QSE_SED_ENOMEM; \ + goto errlabel; \ + } \ +} while (0) + + t = qse_str_open (sed->mmgr, 0, 128); + if (t == QSE_NULL) goto oops; do { @@ -245,22 +254,23 @@ static qse_str_t* get_text (qse_sed_t* sed, qse_sed_c_t* cmd) if (c == QSE_T('\\')) { c = NXTSC (sed); - if (c == QSE_CHAR_EOF) break; - /* TODO: alternate bahavior - add \ to text. */ - + if (c == QSE_CHAR_EOF) + { + if (sed->option & QSE_SED_KEEPTBS) + ADD (sed, t, QSE_T('\\'), oops); + + break; + } } else if (c == QSE_T('\n')) nl = 1; - if (qse_str_ccat (text, c) == (qse_size_t)-1) - { - sed->errnum = QSE_SED_ENOMEM; - goto oops; - } + ADD (sed, t, c, oops); if (c == QSE_T('\n')) { ADVSCP (sed); - if (nl) break; + if (nl) goto done; + break; } c = NXTSC (sed); @@ -268,20 +278,19 @@ static qse_str_t* get_text (qse_sed_t* sed, qse_sed_c_t* cmd) } while (c != QSE_CHAR_EOF); - if (/*(sed->option & QSE_SED_ENSURENL) &&*/ QSE_STR_LEN(text) == 0) +done: + if ((sed->option & QSE_SED_ENSURENL) && c != QSE_T('\n')) { - if (qse_str_ccat (text, QSE_T('\n')) == (qse_size_t)-1) - { - sed->errnum = QSE_SED_ENOMEM; - goto oops; - } + ADD (sed, t, QSE_T('\n'), oops); } - return text; + return t; oops: - if (text != QSE_NULL) qse_str_close (text); + if (t != QSE_NULL) qse_str_close (t); return QSE_NULL; + +#undef ADD } static int command (qse_sed_t* sed) @@ -333,9 +342,10 @@ qse_printf (QSE_T("command not recognized [%c]\n"), c); case QSE_SED_CMD_A: case QSE_SED_CMD_I: + case QSE_SED_CMD_C: { cmd->type = c; - /* + /* TODO: this check for A and I if (cmd->a2.type != QSE_SED_A_NONE) { sed->errnum = QSE_SED_EA2PHB; @@ -371,15 +381,12 @@ qse_printf (QSE_T("command not recognized [%c]\n"), c); { qse_char_t ttt[1000]; -fgets (ttt, QSE_COUNTOF(ttt), stdin); +qse_fgets (ttt, QSE_COUNTOF(ttt), QSE_STDIN); qse_printf (QSE_T("%s%s"), ttt, QSE_STR_PTR(cmd->u.text)); } break; } - case QSE_T('c'): - break; - case QSE_T('g'): break; diff --git a/qse/lib/utl/sed.h b/qse/lib/utl/sed.h index ec70cfcf..85ee2dee 100644 --- a/qse/lib/utl/sed.h +++ b/qse/lib/utl/sed.h @@ -64,7 +64,8 @@ struct qse_sed_c_t QSE_SED_CMD_EQ = QSE_T('='), /* print current line number */ QSE_SED_CMD_A = QSE_T('a'), /* append text */ - QSE_SED_CMD_I = QSE_T('i') /* insert text */ + QSE_SED_CMD_I = QSE_T('i'), /* insert text */ + QSE_SED_CMD_C = QSE_T('c') /* change text */ } type; /* TODO: change the data type to a shorter one to save space */ diff --git a/qse/test/utl/sed01.c b/qse/test/utl/sed01.c index d72bdf3e..0671b8f7 100644 --- a/qse/test/utl/sed01.c +++ b/qse/test/utl/sed01.c @@ -23,13 +23,14 @@ #include #include #include +#include int sed_main (int argc, qse_char_t* argv[]) { qse_sed_t* sed = QSE_NULL; int ret = -1; - if (argc != 2) + if (argc != 2 && argc != 3) { qse_fprintf (QSE_STDERR, QSE_T("usage: %s string\n"), argv[0]); return -1; @@ -42,7 +43,7 @@ int sed_main (int argc, qse_char_t* argv[]) goto oops; } - qse_sed_setoption (sed, QSE_SED_STRIPLS); + if (argc == 3) qse_sed_setoption (sed, qse_strtoi(argv[2])); if (qse_sed_compile (sed, argv[1], qse_strlen(argv[1])) == -1) {