diff --git a/qse/cmd/sed/sed.c b/qse/cmd/sed/sed.c index 715c7997..28249951 100644 --- a/qse/cmd/sed/sed.c +++ b/qse/cmd/sed/sed.c @@ -137,7 +137,7 @@ static void print_usage (QSE_FILE* out, int argc, qse_char_t* argv[]) qse_fprintf (out, QSE_T(" -h show this message\n")); qse_fprintf (out, QSE_T(" -n disable auto-print\n")); qse_fprintf (out, QSE_T(" -a perform strict address check\n")); - qse_fprintf (out, QSE_T(" -r allow {n,m} in a regular expression\n")); + qse_fprintf (out, QSE_T(" -r use the extended regular expression\n")); qse_fprintf (out, QSE_T(" -s allow text on the same line as c, a, i\n")); qse_fprintf (out, QSE_T(" -l ensure a newline at text end\n")); qse_fprintf (out, QSE_T(" -f file specify a script file\n")); @@ -190,7 +190,7 @@ static int handle_args (int argc, qse_char_t* argv[]) break; case QSE_T('r'): - g_option |= QSE_SED_REXBOUND; + g_option |= QSE_SED_EXTENDEDREX; break; case QSE_T('s'): @@ -237,26 +237,25 @@ qse_char_t* load_script_file (const qse_char_t* file) fp = qse_fopen (file, QSE_T("r")); if (fp == QSE_NULL) return QSE_NULL; - if (qse_str_init (&script, QSE_MMGR_GETDFL(), 1024) == QSE_NULL) + if (qse_str_init (&script, QSE_MMGR_GETDFL(), 1024) <= -1) { qse_fclose (fp); return QSE_NULL; } - while ((c = qse_fgetc (fp)) != QSE_CHAR_EOF) { if (qse_str_ccat (&script, c) == (qse_size_t)-1) { - qse_fclose (fp); qse_str_fini (&script); + qse_fclose (fp); return QSE_NULL; } } - qse_fclose (fp); qse_str_yield (&script, &xstr, 0); qse_str_fini (&script); + qse_fclose (fp); return xstr.ptr; } @@ -293,7 +292,7 @@ int sed_main (int argc, qse_char_t* argv[]) qse_sed_setoption (sed, g_option); - if (g_script_file != QSE_NULL) + if (g_script_file) { QSE_ASSERT (g_script == QSE_NULL); diff --git a/qse/include/qse/cmn/tre.h b/qse/include/qse/cmn/tre.h index ca196193..b03101ea 100644 --- a/qse/include/qse/cmn/tre.h +++ b/qse/include/qse/cmn/tre.h @@ -143,7 +143,7 @@ int qse_tre_execx ( const qse_char_t* str, qse_size_t len, qse_tre_match_t* pmatch, - qse_size_t nmatch, + qse_size_t nmatch, int eflags ); @@ -151,7 +151,7 @@ int qse_tre_exec ( qse_tre_t* tre, const qse_char_t* str, qse_tre_match_t* pmatch, - qse_size_t nmatch, + qse_size_t nmatch, int eflags ); diff --git a/qse/include/qse/sed/Sed.hpp b/qse/include/qse/sed/Sed.hpp index 75122983..34098537 100644 --- a/qse/include/qse/sed/Sed.hpp +++ b/qse/include/qse/sed/Sed.hpp @@ -1,5 +1,5 @@ /* - * $Id: Sed.hpp 507 2011-07-15 15:53:49Z hyunghwan.chung $ + * $Id: Sed.hpp 558 2011-09-02 15:27:44Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -54,8 +54,10 @@ public: typedef qse_sed_io_arg_t io_arg_t; /// The option_t type redefines an option type typedef qse_sed_option_t option_t; +#if 0 /// The depth_t type redefines an depth IDs typedef qse_sed_depth_t depth_t; +#endif /// /// The Stream class is a base class for I/O operation during @@ -214,6 +216,7 @@ public: int opt ///< option code ); +#if 0 /// /// The getMaxDepth() function gets the maximum processing depth for /// an operation type identified by @a id. @@ -229,6 +232,7 @@ public: int ids, ///< 0 or a number OR'ed of depth_t values size_t depth ///< 0 maximum depth ); +#endif /// /// The getErrorMessage() function gets the description of the last diff --git a/qse/include/qse/sed/sed.h b/qse/include/qse/sed/sed.h index 93e1c66f..535a0f41 100644 --- a/qse/include/qse/sed/sed.h +++ b/qse/include/qse/sed/sed.h @@ -1,5 +1,5 @@ /* - * $Id: sed.h 507 2011-07-15 15:53:49Z hyunghwan.chung $ + * $Id: sed.h 558 2011-09-02 15:27:44Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -131,29 +131,17 @@ typedef const qse_char_t* (*qse_sed_errstr_t) ( */ enum qse_sed_option_t { - 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 */ - QSE_SED_QUIET = (1 << 3), /**< do not print pattern space */ - QSE_SED_STRICT = (1 << 4), /**< do strict address check */ - QSE_SED_STARTSTEP = (1 << 5), /**< allow start~step */ - QSE_SED_REXBOUND = (1 << 6), /**< allow {n,m} in regular expression */ - QSE_SED_SAMELINE = (1 << 7), /**< allow text on the same line as c, a, i */ + 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 */ + QSE_SED_QUIET = (1 << 3), /**< do not print pattern space */ + QSE_SED_STRICT = (1 << 4), /**< do strict address check */ + QSE_SED_STARTSTEP = (1 << 5), /**< allow start~step */ + QSE_SED_EXTENDEDREX = (1 << 6), /**< allow {n,m} in regular expression */ + QSE_SED_SAMELINE = (1 << 7), /**< allow text on the same line as c, a, i */ }; typedef enum qse_sed_option_t qse_sed_option_t; - -/** - * The qse_sed_depth_t type defines IDs for qse_sed_getmaxdepth() and - * qse_sed_setmaxdepth(). - */ -enum qse_sed_depth_t -{ - QSE_SED_DEPTH_REX_BUILD = (1 << 0), - QSE_SED_DEPTH_REX_MATCH = (1 << 1) -}; -typedef enum qse_sed_depth_t qse_sed_depth_t; - /** * The qse_sed_io_cmd_t type defines I/O command codes. The code indicates * the action to take in an I/O handler. @@ -246,23 +234,6 @@ void qse_sed_setoption ( int opt /**< 0 or a number OR'ed of #qse_sed_option_t values */ ); -/** - * The qse_sed_getmaxdepth() gets the maximum processing depth. - */ -qse_size_t qse_sed_getmaxdepth ( - qse_sed_t* sed, /**< stream editor */ - qse_sed_depth_t id /**< one of qse_sed_depth_t values */ -); - -/** - * The qse_sed_setmaxdepth() sets the maximum processing depth. - */ -void qse_sed_setmaxdepth ( - qse_sed_t* sed, /**< stream editor */ - int ids, /**< 0 or a number OR'ed of #qse_sed_depth_t values */ - qse_size_t depth /**< maximum depth level */ -); - /** * The qse_sed_geterrstr() gets an error string getter. */ diff --git a/qse/lib/cmn/tre.c b/qse/lib/cmn/tre.c index 30781226..7ce696ae 100644 --- a/qse/lib/cmn/tre.c +++ b/qse/lib/cmn/tre.c @@ -47,7 +47,7 @@ qse_tre_t* qse_tre_open (qse_mmgr_t* mmgr, qse_size_t xtnsize) return QSE_NULL; } - return QSE_NULL; + return tre; } void qse_tre_close (qse_tre_t* tre) diff --git a/qse/lib/cmn/xma.c b/qse/lib/cmn/xma.c index 13e2e7d7..d52ef385 100644 --- a/qse/lib/cmn/xma.c +++ b/qse/lib/cmn/xma.c @@ -49,8 +49,8 @@ struct qse_xma_blk_t struct { - qse_xma_blk_t* prev; /**< link to the previous block */ - qse_xma_blk_t* next; /**< link to the next block */ + qse_xma_blk_t* prev; /**< link to the previous adjacent block */ + qse_xma_blk_t* next; /**< link to the next adjacent block */ } b; }; @@ -379,7 +379,7 @@ void* qse_xma_alloc (qse_xma_t* xma, qse_size_t size) for (++xfi; xfi < XFIMAX(xma) - 1; xfi++) { free = alloc_from_freelist (xma, xfi, size); - if (free != QSE_NULL) break; + if (free) break; } if (free == QSE_NULL) return QSE_NULL; } @@ -392,16 +392,20 @@ static void* _realloc_merge (qse_xma_t* xma, void* b, qse_size_t size) { qse_xma_blk_t* blk = USR_TO_SYS(b); + /* rounds up 'size' to be multiples of ALIGN */ + size = ((size + ALIGN - 1) / ALIGN) * ALIGN; + if (size > blk->size) { /* * grow the current block */ - - qse_size_t req = size - blk->size; + qse_size_t req; qse_xma_blk_t* n; qse_size_t rem; + req = size - blk->size; + n = blk->b.next; /* check if the next adjacent block is available */ diff --git a/qse/lib/sed/Sed.cpp b/qse/lib/sed/Sed.cpp index da0330d7..d6270bef 100644 --- a/qse/lib/sed/Sed.cpp +++ b/qse/lib/sed/Sed.cpp @@ -1,5 +1,5 @@ /* - * $Id: Sed.cpp 441 2011-04-22 14:28:43Z hyunghwan.chung $ + * $Id: Sed.cpp 558 2011-09-02 15:27:44Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -80,6 +80,7 @@ void Sed::setOption (int opt) qse_sed_setoption (sed, opt); } +#if 0 Sed::size_t Sed::getMaxDepth (depth_t id) const { QSE_ASSERT (sed != QSE_NULL); @@ -91,6 +92,7 @@ void Sed::setMaxDepth (int ids, size_t depth) QSE_ASSERT (sed != QSE_NULL); qse_sed_setmaxdepth (sed, ids, depth); } +#endif const Sed::char_t* Sed::getErrorMessage () const { diff --git a/qse/lib/sed/sed.c b/qse/lib/sed/sed.c index 6b53e6f7..c55368d6 100644 --- a/qse/lib/sed/sed.c +++ b/qse/lib/sed/sed.c @@ -1,5 +1,5 @@ /* - * $Id: sed.c 557 2011-09-01 14:45:06Z hyunghwan.chung $ + * $Id: sed.c 558 2011-09-02 15:27:44Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -20,17 +20,19 @@ #include "sed.h" #include "../cmn/mem.h" -#include #include +#ifdef USE_REX +# include +#else +# include +#endif + QSE_IMPLEMENT_COMMON_FUNCTIONS (sed) static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd); static void free_all_command_blocks (qse_sed_t* sed); -static int qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr); -static void qse_sed_fini (qse_sed_t* sed); - #define SETERR0(sed,num,loc) \ do { qse_sed_seterror (sed, num, QSE_NULL, loc); } while (0) @@ -73,7 +75,7 @@ void qse_sed_close (qse_sed_t* sed) QSE_MMGR_FREE (sed->mmgr, sed); } -static int qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr) +int qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr) { if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL(); @@ -121,7 +123,7 @@ oops_1: return -1; } -static void qse_sed_fini (qse_sed_t* sed) +void qse_sed_fini (qse_sed_t* sed) { free_all_command_blocks (sed); @@ -145,6 +147,8 @@ int qse_sed_getoption (qse_sed_t* sed) return sed->option; } + +#ifdef USE_REX qse_size_t qse_sed_getmaxdepth (qse_sed_t* sed, qse_sed_depth_t id) { return (id & QSE_SED_DEPTH_REX_BUILD)? sed->depth.rex.build: @@ -156,6 +160,75 @@ void qse_sed_setmaxdepth (qse_sed_t* sed, int ids, qse_size_t depth) if (ids & QSE_SED_DEPTH_REX_BUILD) sed->depth.rex.build = depth; if (ids & QSE_SED_DEPTH_REX_MATCH) sed->depth.rex.match = depth; } +#endif + +static qse_tre_t* maketre ( + qse_sed_t* sed, const qse_cstr_t* str, const qse_sed_loc_t* loc) +{ + qse_tre_t* tre; + + tre = qse_tre_open (sed->mmgr, 0); + if (tre == QSE_NULL) + { + SETERR0 (sed, QSE_SED_ENOMEM, loc); + return QSE_NULL; + } + + if (qse_tre_compx (tre, str->ptr, str->len, QSE_NULL, + ((sed->option & QSE_SED_EXTENDEDREX)? QSE_TRE_EXTENDED: 0)) <= -1) + { + SETERR1 (sed, QSE_SED_EREXBL, str->ptr, str->len, loc); + qse_tre_close (tre); + return QSE_NULL; + } + + return tre; +} + +static QSE_INLINE void freetre (qse_sed_t* sed, qse_tre_t* tre) +{ + qse_tre_close (tre); +} + +static int matchtre ( + qse_sed_t* sed, qse_tre_t* tre, int opt, + const qse_cstr_t* str, qse_cstr_t* mat, + qse_cstr_t submat[9], const qse_sed_loc_t* loc) +{ + int n; + qse_tre_match_t match[10]; + + n = qse_tre_execx (tre, str->ptr, str->len, match, 10, opt); + if (n <= -1) + { + if (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMATCH) return 0; + SETERR0 (sed, QSE_SED_EREXMA, loc); + return -1; + } + + QSE_ASSERT (match[0].rm_so != -1); + if (mat) + { + mat->ptr = &str->ptr[match[0].rm_so]; + mat->len = match[0].rm_eo - match[0].rm_so; + } + + if (submat) + { + int i; + + /* you must intialize submat before you pass into this + * function because it can abort filling */ + for (i = 1; i <= 10; i++) + { + if (match[i].rm_so == -1) break; + submat[i-1].ptr = &str->ptr[match[i].rm_so]; + submat[i-1].len = match[i].rm_eo - match[i].rm_so; + } + } + return 1; +} + /* check if c is a space character */ #define IS_SPACE(c) ((c) == QSE_T(' ') || (c) == QSE_T('\t') || (c) == QSE_T('\r')) @@ -200,13 +273,15 @@ static void free_address (qse_sed_t* sed, qse_sed_cmd_t* cmd) if (cmd->a2.type == QSE_SED_ADR_REX) { QSE_ASSERT (cmd->a2.u.rex != QSE_NULL); - qse_freerex (sed->mmgr, cmd->a2.u.rex); + /*qse_freerex (sed->mmgr, cmd->a2.u.rex);*/ + freetre (sed, cmd->a2.u.rex); cmd->a2.type = QSE_SED_ADR_NONE; } if (cmd->a1.type == QSE_SED_ADR_REX) { QSE_ASSERT (cmd->a1.u.rex != QSE_NULL); - qse_freerex (sed->mmgr, cmd->a1.u.rex); + /*qse_freerex (sed->mmgr, cmd->a1.u.rex);*/ + freetre (sed, cmd->a1.u.rex); cmd->a1.type = QSE_SED_ADR_NONE; } } @@ -285,7 +360,8 @@ static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd) if (cmd->u.subst.rpl.ptr) QSE_MMGR_FREE (sed->mmgr, cmd->u.subst.rpl.ptr); if (cmd->u.subst.rex) - qse_freerex (sed->mmgr, cmd->u.subst.rex); + /*qse_freerex (sed->mmgr, cmd->u.subst.rex);*/ + freetre (sed, cmd->u.subst.rex); break; case QSE_SED_CMD_TRANSLATE: @@ -300,7 +376,9 @@ static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd) static void* compile_rex (qse_sed_t* sed, qse_char_t rxend) { +#ifdef USE_REX void* code; +#endif qse_cint_t c; qse_str_clear (&sed->tmp.rex); @@ -346,43 +424,11 @@ static void* compile_rex (qse_sed_t* sed, qse_char_t rxend) } } - -#if 0 -{ - qse_tre_t* tre; - - tre = qse_tre_open (sed->mmgr, 0); - if (tre) - { - if (qse_tre_comp (tre, - QSE_STR_PTR(&sed->tmp.rex), - QSE_STR_LEN(&sed->tmp.rex), - QSE_NULL, - QSE_TRE_EXTENDED) <= -1) - { - qse_tre_close (tre); - goto fail: - } - return tre; - } - else - { - SETERR1 ( - sed, QSE_SED_EREXBL, - QSE_STR_PTR(&sed->tmp.rex), - QSE_STR_LEN(&sed->tmp.rex), - &sed->src.loc - ); - return QSE_NULL; - } - -} -#endif - +#ifdef USE_REX code = qse_buildrex ( sed->mmgr, sed->depth.rex.build, - ((sed->option&QSE_SED_REXBOUND)? 0:QSE_REX_NOBOUND), + ((sed->option&QSE_SED_EXTENDEDREX)? 0:QSE_REX_NOBOUND), QSE_STR_PTR(&sed->tmp.rex), QSE_STR_LEN(&sed->tmp.rex), QSE_NULL @@ -399,6 +445,10 @@ static void* compile_rex (qse_sed_t* sed, qse_char_t rxend) } return code; + +#else + return maketre (sed, QSE_STR_CSTR(&sed->tmp.rex), &sed->src.loc); +#endif } static qse_sed_adr_t* get_address (qse_sed_t* sed, qse_sed_adr_t* a) @@ -809,12 +859,14 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd) { CHECK_CMDIC (sed, cmd, c, goto oops); +#if 0 if (c == QSE_T('\\')) { c = NXTSC (sed); CHECK_CMDIC (sed, cmd, c, goto oops); if (c == QSE_T('n')) c = QSE_T('\n'); } +#endif if (qse_str_ccat (t[i], c) == (qse_size_t)-1) { @@ -895,10 +947,12 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd) terminate_command (sed) <= -1) goto oops; QSE_ASSERT (cmd->u.subst.rex == QSE_NULL); + +#ifdef USE_REX cmd->u.subst.rex = qse_buildrex ( sed->mmgr, sed->depth.rex.build, - ((sed->option&QSE_SED_REXBOUND)? 0:QSE_REX_NOBOUND), + ((sed->option&QSE_SED_EXTENDEDREX)? 0:QSE_REX_NOBOUND), QSE_STR_PTR(t[0]), QSE_STR_LEN(t[0]), QSE_NULL @@ -913,6 +967,10 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd) ); goto oops; } +#else + cmd->u.subst.rex = maketre (sed, QSE_STR_CSTR(t[0]), &sed->src.loc); + if (cmd->u.subst.rex == QSE_NULL) goto oops; +#endif qse_str_yield (t[1], &cmd->u.subst.rpl, 0); if (cmd->u.subst.g == 0 && cmd->u.subst.occ == 0) cmd->u.subst.occ = 1; @@ -1833,7 +1891,9 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd) { qse_cstr_t mat, pmat; int opt = 0, repl = 0, n; +#ifdef USE_REX qse_rex_errnum_t errnum; +#endif qse_cstr_t str, cur; const qse_char_t* str_end; @@ -1842,7 +1902,11 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd) QSE_ASSERT (cmd->type == QSE_SED_CMD_SUBSTITUTE); qse_str_clear (&sed->e.txt.subst); +#ifdef USE_REX if (cmd->u.subst.i) opt = QSE_REX_IGNORECASE; +#else + if (cmd->u.subst.i) opt = QSE_TRE_IGNORECASE; +#endif str.ptr = QSE_STR_PTR(&sed->e.in.line); str.len = QSE_STR_LEN(&sed->e.in.line); @@ -1863,6 +1927,7 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd) * end of string($) needs to be tested */ while (cur.ptr <= str_end) { +#ifdef USE_REX if (max_count == 0 || sub_count < max_count) { n = qse_matchrex ( @@ -1871,14 +1936,29 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd) cmd->u.subst.rex, opt, &str, &cur, &mat, &errnum ); + if (n <= -1) + { + SETERR0 (sed, QSE_SED_EREXMA, &cmd->loc); + return -1; + } } else n = 0; +#else + qse_cstr_t submat[9]; - if (n <= -1) + QSE_MEMSET (submat, 0, QSE_SIZEOF(submat)); + if (max_count == 0 || sub_count < max_count) { - SETERR0 (sed, QSE_SED_EREXMA, &cmd->loc); - return -1; + n = matchtre ( + sed, + cmd->u.subst.rex, + ((str.ptr == cur.ptr)? opt: (opt | QSE_TRE_NOTBOL)), + &cur, &mat, submat, &cmd->loc + ); + if (n <= -1) return -1; } + else n = 0; +#endif if (n == 0) { @@ -1930,11 +2010,49 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd) for (i = 0; i < cmd->u.subst.rpl.len; i++) { if ((i+1) < cmd->u.subst.rpl.len && - cmd->u.subst.rpl.ptr[i] == QSE_T('\\') && - cmd->u.subst.rpl.ptr[i+1] == QSE_T('&')) + cmd->u.subst.rpl.ptr[i] == QSE_T('\\')) { - m = qse_str_ccat ( - &sed->e.txt.subst, QSE_T('&')); + qse_char_t nc = cmd->u.subst.rpl.ptr[i+1]; + +#ifndef USE_REX + if (nc >= QSE_T('1') && nc <= QSE_T('9')) + { + int smi = nc - QSE_T('1'); + m = qse_str_ncat (&sed->e.txt.subst, submat[smi].ptr, submat[smi].len); + } + else + { +#endif + switch (nc) + { + case QSE_T('n'): + nc = QSE_T('\n'); + break; + case QSE_T('r'): + nc = QSE_T('\r'); + break; + case QSE_T('t'): + nc = QSE_T('\t'); + break; + case QSE_T('f'): + nc = QSE_T('\f'); + break; + case QSE_T('b'): + nc = QSE_T('\b'); + break; + case QSE_T('v'): + nc = QSE_T('\v'); + break; + case QSE_T('a'): + nc = QSE_T('\a'); + break; +#ifndef USE_REX + } +#endif + + m = qse_str_ccat (&sed->e.txt.subst, nc); + } + i++; } else if (cmd->u.subst.rpl.ptr[i] == QSE_T('&')) @@ -2032,10 +2150,12 @@ static int match_a (qse_sed_t* sed, qse_sed_cmd_t* cmd, qse_sed_adr_t* a) case QSE_SED_ADR_REX: { +#ifdef USE_REX int n; - qse_cstr_t match; - qse_cstr_t line; qse_rex_errnum_t errnum; + qse_cstr_t match; +#endif + qse_cstr_t line; QSE_ASSERT (a->u.rex != QSE_NULL); @@ -2045,6 +2165,7 @@ static int match_a (qse_sed_t* sed, qse_sed_cmd_t* cmd, qse_sed_adr_t* a) if (line.len > 0 && line.ptr[line.len-1] == QSE_T('\n')) line.len--; +#ifdef USE_REX n = qse_matchrex ( sed->mmgr, sed->depth.rex.match, @@ -2058,6 +2179,10 @@ static int match_a (qse_sed_t* sed, qse_sed_cmd_t* cmd, qse_sed_adr_t* a) } return n; +#else + return matchtre (sed, a->u.rex, 0, &line, QSE_NULL, QSE_NULL, &cmd->loc); +#endif + } case QSE_SED_ADR_DOL: { diff --git a/qse/lib/sed/sed.h b/qse/lib/sed/sed.h index c686d31b..d97712b0 100644 --- a/qse/lib/sed/sed.h +++ b/qse/lib/sed/sed.h @@ -1,5 +1,5 @@ /* - * $Id: sed.h 441 2011-04-22 14:28:43Z hyunghwan.chung $ + * $Id: sed.h 558 2011-09-02 15:27:44Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -28,6 +28,23 @@ #define QSE_MAP_AS_RBT #include + +/* + * Define USE_REX to use rex.h on behalf of tre.h + * rex.h currently does not support backreference. + */ +#ifdef USE_REX +enum qse_sed_depth_t +{ + QSE_SED_DEPTH_REX_BUILD = (1 << 0), + QSE_SED_DEPTH_REX_MATCH = (1 << 1) +}; +typedef enum qse_sed_depth_t qse_sed_depth_t +#endif + +#define QSE_SED_CMD_NOOP QSE_T('\0') +#define QSE_SED_CMD_QUIT QSE_T('q') + typedef struct qse_sed_adr_t qse_sed_adr_t; typedef struct qse_sed_cmd_t qse_sed_cmd_t; typedef struct qse_sed_cmd_blk_t qse_sed_cmd_blk_t; @@ -50,8 +67,6 @@ struct qse_sed_adr_t } u; }; -#define QSE_SED_CMD_NOOP QSE_T('\0') -#define QSE_SED_CMD_QUIT QSE_T('q') #define QSE_SED_CMD_QUIT_QUIET QSE_T('Q') #define QSE_SED_CMD_APPEND QSE_T('a') #define QSE_SED_CMD_INSERT QSE_T('i') @@ -262,7 +277,39 @@ struct qse_sed_t extern "C" { #endif -const qse_char_t* qse_sed_dflerrstr (qse_sed_t* sed, qse_sed_errnum_t errnum); +int qse_sed_init ( + qse_sed_t* sed, + qse_mmgr_t* mmgr +); + +void qse_sed_fini ( + qse_sed_t* sed +); + +const qse_char_t* qse_sed_dflerrstr ( + qse_sed_t* sed, + qse_sed_errnum_t errnum +); + + +#ifdef USE_REX +/** + * The qse_sed_getmaxdepth() gets the maximum processing depth. + */ +qse_size_t qse_sed_getmaxdepth ( + qse_sed_t* sed, /**< stream editor */ + qse_sed_depth_t id /**< one of qse_sed_depth_t values */ +); + +/** + * The qse_sed_setmaxdepth() sets the maximum processing depth. + */ +void qse_sed_setmaxdepth ( + qse_sed_t* sed, /**< stream editor */ + int ids, /**< 0 or a number OR'ed of #qse_sed_depth_t values */ + qse_size_t depth /**< maximum depth level */ +); +#endif #ifdef __cplusplus }