* fixed a bug of not setting the IGNORECASE option properly to TRE.

* added code to treat a regular expressio delimiter as a normal character when present within [] of a regular expression.
* changed code to allow 0 as a starting address of a start~step address form.
* added code to accept 'I' as a option to the 's' command.
This commit is contained in:
hyung-hwan 2011-09-08 09:36:08 +00:00
parent 5be63c4b38
commit 92b4c29551
4 changed files with 161 additions and 126 deletions

View File

@ -217,7 +217,6 @@ static int handle_args (int argc, qse_char_t* argv[])
} }
} }
if (opt.ind < argc && g_script_file == QSE_NULL) if (opt.ind < argc && g_script_file == QSE_NULL)
g_script = argv[opt.ind++]; g_script = argv[opt.ind++];
if (opt.ind < argc) g_infile = argv[opt.ind++]; if (opt.ind < argc) g_infile = argv[opt.ind++];

View File

@ -1,5 +1,5 @@
/* /*
* $Id: sed.h 560 2011-09-06 14:18:36Z hyunghwan.chung $ * $Id: sed.h 562 2011-09-07 15:36:08Z hyunghwan.chung $
* *
Copyright 2006-2011 Chung, Hyung-Hwan. Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -89,6 +89,7 @@ enum qse_sed_errnum_t
QSE_SED_EREXBL, /**< failed to compile regular expression '${0}' */ QSE_SED_EREXBL, /**< failed to compile regular expression '${0}' */
QSE_SED_EREXMA, /**< failed to match regular expression */ QSE_SED_EREXMA, /**< failed to match regular expression */
QSE_SED_EA1PHB, /**< address 1 prohibited for '${0}' */ QSE_SED_EA1PHB, /**< address 1 prohibited for '${0}' */
QSE_SED_EA1MOI, /**< address 1 missing or invalid */
QSE_SED_EA2PHB, /**< address 2 prohibited */ QSE_SED_EA2PHB, /**< address 2 prohibited */
QSE_SED_EA2MOI, /**< address 2 missing or invalid */ QSE_SED_EA2MOI, /**< address 2 missing or invalid */
QSE_SED_ENEWLN, /**< newline expected */ QSE_SED_ENEWLN, /**< newline expected */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: err.c 560 2011-09-06 14:18:36Z hyunghwan.chung $ * $Id: err.c 562 2011-09-07 15:36:08Z hyunghwan.chung $
* *
Copyright 2006-2011 Chung, Hyung-Hwan. Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -34,6 +34,7 @@ const qse_char_t* qse_sed_dflerrstr (qse_sed_t* sed, qse_sed_errnum_t errnum)
QSE_T("failed to compile regular expression '${0}'"), QSE_T("failed to compile regular expression '${0}'"),
QSE_T("failed to match regular expression"), QSE_T("failed to match regular expression"),
QSE_T("address 1 prohibited for '${0}'"), QSE_T("address 1 prohibited for '${0}'"),
QSE_T("address 1 missing or invalid"),
QSE_T("address 2 prohibited for '${0}'"), QSE_T("address 2 prohibited for '${0}'"),
QSE_T("address 2 missing or invalid"), QSE_T("address 2 missing or invalid"),
QSE_T("newline expected"), QSE_T("newline expected"),

View File

@ -1,5 +1,5 @@
/* /*
* $Id: sed.c 560 2011-09-06 14:18:36Z hyunghwan.chung $ * $Id: sed.c 562 2011-09-07 15:36:08Z hyunghwan.chung $
* *
Copyright 2006-2011 Chung, Hyung-Hwan. Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -162,12 +162,31 @@ 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_BUILD) sed->depth.rex.build = depth;
if (ids & QSE_SED_DEPTH_REX_MATCH) sed->depth.rex.match = depth; if (ids & QSE_SED_DEPTH_REX_MATCH) sed->depth.rex.match = depth;
} }
#else #endif
static qse_tre_t* maketre ( static void* build_rex (
qse_sed_t* sed, const qse_cstr_t* str, const qse_sed_loc_t* loc) qse_sed_t* sed, const qse_cstr_t* str,
int ignorecase, const qse_sed_loc_t* loc)
{ {
#ifdef USE_REX
void* rex;
int opt = 0;
if ((sed->option & QSE_SED_EXTENDEDREX) == 0) opt |= QSE_REX_NOBOUND;
rex = qse_buildrex (
sed->mmgr, sed->depth.rex.build,
opt, str->ptr, str->len, QSE_NULL
);
if (rex == QSE_NULL)
{
SETERR1 (sed, QSE_SED_EREXBL, str->ptr, str->len, loc);
}
return rex;
#else
qse_tre_t* tre; qse_tre_t* tre;
int opt = 0;
tre = qse_tre_open (sed->mmgr, 0); tre = qse_tre_open (sed->mmgr, 0);
if (tre == QSE_NULL) if (tre == QSE_NULL)
@ -176,8 +195,11 @@ static qse_tre_t* maketre (
return QSE_NULL; return QSE_NULL;
} }
if (qse_tre_compx (tre, str->ptr, str->len, QSE_NULL, /* ignorecase is a compile option for TRE */
((sed->option & QSE_SED_EXTENDEDREX)? QSE_TRE_EXTENDED: 0)) <= -1) if (ignorecase) opt |= QSE_TRE_IGNORECASE;
if (sed->option & QSE_SED_EXTENDEDREX) opt |= QSE_TRE_EXTENDED;
if (qse_tre_compx (tre, str->ptr, str->len, QSE_NULL, opt) <= -1)
{ {
qse_sed_errnum_t errnum; qse_sed_errnum_t errnum;
errnum = (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMEM)? errnum = (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMEM)?
@ -189,13 +211,19 @@ static qse_tre_t* maketre (
} }
return tre; return tre;
#endif
} }
static QSE_INLINE void freetre (qse_sed_t* sed, qse_tre_t* tre) static QSE_INLINE void free_rex (qse_sed_t* sed, void* rex)
{ {
qse_tre_close (tre); #ifdef USE_REX
qse_freerex (sed->mmgr, rex);
#else
qse_tre_close (rex);
#endif
} }
#ifndef USE_REX
static int matchtre ( static int matchtre (
qse_sed_t* sed, qse_tre_t* tre, int opt, qse_sed_t* sed, qse_tre_t* tre, int opt,
const qse_cstr_t* str, qse_cstr_t* mat, const qse_cstr_t* str, qse_cstr_t* mat,
@ -285,26 +313,14 @@ static void free_address (qse_sed_t* sed, qse_sed_cmd_t* cmd)
{ {
QSE_ASSERT (cmd->a2.u.rex != QSE_NULL); QSE_ASSERT (cmd->a2.u.rex != QSE_NULL);
if (cmd->a2.u.rex != EMPTY_REX) if (cmd->a2.u.rex != EMPTY_REX)
{ free_rex (sed, cmd->a2.u.rex);
#ifdef USE_REX
qse_freerex (sed->mmgr, cmd->a2.u.rex);
#else
freetre (sed, cmd->a2.u.rex);
#endif
}
cmd->a2.type = QSE_SED_ADR_NONE; cmd->a2.type = QSE_SED_ADR_NONE;
} }
if (cmd->a1.type == QSE_SED_ADR_REX) if (cmd->a1.type == QSE_SED_ADR_REX)
{ {
QSE_ASSERT (cmd->a1.u.rex != QSE_NULL); QSE_ASSERT (cmd->a1.u.rex != QSE_NULL);
if (cmd->a1.u.rex != EMPTY_REX) if (cmd->a1.u.rex != EMPTY_REX)
{ free_rex (sed, cmd->a1.u.rex);
#ifdef USE_REX
qse_freerex (sed->mmgr, cmd->a1.u.rex);
#else
freetre (sed, cmd->a1.u.rex);
#endif
}
cmd->a1.type = QSE_SED_ADR_NONE; cmd->a1.type = QSE_SED_ADR_NONE;
} }
} }
@ -383,13 +399,7 @@ static void free_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (cmd->u.subst.rpl.ptr) if (cmd->u.subst.rpl.ptr)
QSE_MMGR_FREE (sed->mmgr, cmd->u.subst.rpl.ptr); QSE_MMGR_FREE (sed->mmgr, cmd->u.subst.rpl.ptr);
if (cmd->u.subst.rex && cmd->u.subst.rex != EMPTY_REX) if (cmd->u.subst.rex && cmd->u.subst.rex != EMPTY_REX)
{ free_rex (sed, cmd->u.subst.rex);
#ifdef USE_REX
qse_freerex (sed->mmgr, cmd->u.subst.rex);
#else
freetre (sed, cmd->u.subst.rex);
#endif
}
break; break;
case QSE_SED_CMD_TRANSLATE: case QSE_SED_CMD_TRANSLATE:
@ -435,47 +445,76 @@ Omitted for clash with regular expression \b.
return c; return c;
} }
static void* compile_rex (qse_sed_t* sed, qse_char_t rxend) static int pickup_rex (
qse_sed_t* sed, qse_char_t rxend,
int really, const qse_sed_cmd_t* cmd, qse_str_t* buf)
{ {
#ifdef USE_REX
void* code;
#endif
qse_cint_t c; qse_cint_t c;
qse_size_t in_bracket = 0;
qse_size_t chars_from_opening_bracket = 0;
qse_str_clear (&sed->tmp.rex); qse_str_clear (buf);
for (;;) for (;;)
{ {
c = NXTSC (sed); c = NXTSC (sed);
if (c == QSE_CHAR_EOF || c == QSE_T('\n')) if (c == QSE_CHAR_EOF || IS_LINTERM(c))
{ {
SETERR1 ( if (cmd)
sed, QSE_SED_EREXIC, {
QSE_STR_PTR(&sed->tmp.rex), SETERR1 (
QSE_STR_LEN(&sed->tmp.rex), sed, QSE_SED_ECMDIC,
&sed->src.loc &cmd->type, 1,
); &sed->src.loc
return QSE_NULL; );
}
else
{
SETERR1 (
sed, QSE_SED_EREXIC,
QSE_STR_PTR(buf), QSE_STR_LEN(buf),
&sed->src.loc
);
}
return -1;
} }
if (c == rxend) break; if (c == rxend && in_bracket <= 0) break;
if (c == QSE_T('\\')) if (c == QSE_T('\\'))
{ {
qse_cint_t nc; qse_cint_t nc;
nc = NXTSC (sed); nc = NXTSC (sed);
if (nc == QSE_CHAR_EOF /*|| nc == QSE_T('\n')*/) if (nc == QSE_CHAR_EOF /*|| IS_LINTERM(nc)*/)
{ {
SETERR1 ( if (cmd)
sed, QSE_SED_EREXIC, {
QSE_STR_PTR(&sed->tmp.rex), SETERR1 (
QSE_STR_LEN(&sed->tmp.rex), sed, QSE_SED_ECMDIC,
&sed->src.loc &cmd->type, 1,
); &sed->src.loc
return QSE_NULL; );
}
else
{
SETERR1 (
sed, QSE_SED_EREXIC,
QSE_STR_PTR(buf),
QSE_STR_LEN(buf),
&sed->src.loc
);
}
return -1;
} }
if (in_bracket > 0 && nc == QSE_T(']'))
{
/* if really is not set, in_bracket is alyway 0.
* so this block is never reached */
if (chars_from_opening_bracket > 1) in_bracket--;
}
if (nc == QSE_T('\n')) c = nc; if (nc == QSE_T('\n')) c = nc;
else else
{ {
@ -487,50 +526,50 @@ static void* compile_rex (qse_sed_t* sed, qse_char_t rxend)
/* if the character after a backslash is not special at the /* if the character after a backslash is not special at the
* this layer, add the backslash into the regular expression * this layer, add the backslash into the regular expression
* buffer as it is. */ * buffer as it is. */
if (qse_str_ccat (&sed->tmp.rex, QSE_T('\\')) == (qse_size_t)-1) if (qse_str_ccat (buf, QSE_T('\\')) == (qse_size_t)-1)
{ {
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL); SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
return QSE_NULL; return -1;
} }
} }
c = ec; c = ec;
} }
} }
else if (really)
{
/* this block sets a flag to indicate that we are in []
* of a regular expression. */
if (qse_str_ccat (&sed->tmp.rex, c) == (qse_size_t)-1) if (c == QSE_T('['))
{
if (in_bracket <= 0) chars_from_opening_bracket = 0;
in_bracket++;
}
else if (in_bracket > 0 && c == QSE_T(']'))
{
/* if it is the first character after [,
* it is a normal character. */
if (chars_from_opening_bracket > 1) in_bracket--;
}
}
if (qse_str_ccat (buf, c) == (qse_size_t)-1)
{ {
SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL); SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL);
return QSE_NULL; return -1;
} }
chars_from_opening_bracket++;
} }
if (QSE_STR_LEN(&sed->tmp.rex) == 0) return EMPTY_REX; return 0;
}
#ifdef USE_REX static QSE_INLINE void* compile_rex_address (qse_sed_t* sed, qse_char_t rxend)
code = qse_buildrex ( {
sed->mmgr, if (pickup_rex (sed, rxend, 1, QSE_NULL, &sed->tmp.rex) <= -1) return QSE_NULL;
sed->depth.rex.build, /* TODO: support ignore case option for address */
((sed->option&QSE_SED_EXTENDEDREX)? 0:QSE_REX_NOBOUND), return build_rex (sed, QSE_STR_CSTR(&sed->tmp.rex), 0, &sed->src.loc);
QSE_STR_PTR(&sed->tmp.rex),
QSE_STR_LEN(&sed->tmp.rex),
QSE_NULL
);
if (code == QSE_NULL)
{
SETERR1 (
sed, QSE_SED_EREXBL,
QSE_STR_PTR(&sed->tmp.rex),
QSE_STR_LEN(&sed->tmp.rex),
&sed->src.loc
);
return QSE_NULL;
}
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) static qse_sed_adr_t* get_address (qse_sed_t* sed, qse_sed_adr_t* a)
@ -553,8 +592,10 @@ static qse_sed_adr_t* get_address (qse_sed_t* sed, qse_sed_adr_t* a)
} }
while ((c = CURSC(sed)) >= QSE_T('0') && c <= QSE_T('9')); while ((c = CURSC(sed)) >= QSE_T('0') && c <= QSE_T('9'));
#if 0
/* line number 0 is illegal */ /* line number 0 is illegal */
if (lno == 0) return QSE_NULL; if (lno == 0) return QSE_NULL;
#endif
a->type = QSE_SED_ADR_LINE; a->type = QSE_SED_ADR_LINE;
a->u.lno = lno; a->u.lno = lno;
@ -562,7 +603,7 @@ static qse_sed_adr_t* get_address (qse_sed_t* sed, qse_sed_adr_t* a)
else if (c == QSE_T('/')) else if (c == QSE_T('/'))
{ {
/* /REGEX/ */ /* /REGEX/ */
a->u.rex = compile_rex (sed, c); a->u.rex = compile_rex_address (sed, c);
if (a->u.rex == QSE_NULL) return QSE_NULL; if (a->u.rex == QSE_NULL) return QSE_NULL;
a->type = QSE_SED_ADR_REX; a->type = QSE_SED_ADR_REX;
NXTSC (sed); NXTSC (sed);
@ -578,7 +619,7 @@ static qse_sed_adr_t* get_address (qse_sed_t* sed, qse_sed_adr_t* a)
return QSE_NULL; return QSE_NULL;
} }
a->u.rex = compile_rex (sed, c); a->u.rex = compile_rex_address (sed, c);
if (a->u.rex == QSE_NULL) return QSE_NULL; if (a->u.rex == QSE_NULL) return QSE_NULL;
a->type = QSE_SED_ADR_REX; a->type = QSE_SED_ADR_REX;
NXTSC (sed); NXTSC (sed);
@ -668,7 +709,7 @@ done:
return 0; return 0;
oops: oops:
if (t != QSE_NULL) qse_str_close (t); if (t) qse_str_close (t);
return -1; return -1;
#undef ADD #undef ADD
@ -819,7 +860,7 @@ static int get_branch_target (qse_sed_t* sed, qse_sed_cmd_t* cmd)
return 0; return 0;
oops: oops:
if (t != QSE_NULL) qse_str_close (t); if (t) qse_str_close (t);
return -1; return -1;
} }
@ -892,7 +933,7 @@ static int get_file (qse_sed_t* sed, qse_xstr_t* xstr)
return 0; return 0;
oops: oops:
if (t != QSE_NULL) qse_str_close (t); if (t) qse_str_close (t);
return -1; return -1;
} }
@ -920,7 +961,6 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
{ {
qse_cint_t c, delim; qse_cint_t c, delim;
qse_str_t* t[2] = { QSE_NULL, QSE_NULL }; qse_str_t* t[2] = { QSE_NULL, QSE_NULL };
int i;
c = CURSC (sed); c = CURSC (sed);
CHECK_CMDIC (sed, cmd, c, goto oops); CHECK_CMDIC (sed, cmd, c, goto oops);
@ -943,6 +983,10 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
goto oops; goto oops;
} }
if (pickup_rex (sed, delim, 1, cmd, t[0]) <= -1) goto oops;
if (pickup_rex (sed, delim, 0, cmd, t[1]) <= -1) goto oops;
#if 0
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
c = NXTSC (sed); c = NXTSC (sed);
@ -994,6 +1038,7 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
c = NXTSC (sed); c = NXTSC (sed);
} }
} }
#endif
/* skip spaces before options */ /* skip spaces before options */
do { c = NXTSC(sed); } while (IS_SPACE(c)); do { c = NXTSC(sed); } while (IS_SPACE(c));
@ -1006,7 +1051,7 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
cmd->u.subst.p = 1; cmd->u.subst.p = 1;
c = NXTSC (sed); c = NXTSC (sed);
} }
else if (c == QSE_T('i')) else if (c == QSE_T('i') || c == QSE_T('I'))
{ {
cmd->u.subst.i = 1; cmd->u.subst.i = 1;
c = NXTSC (sed); c = NXTSC (sed);
@ -1068,29 +1113,10 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (QSE_STR_LEN(t[0]) <= 0) cmd->u.subst.rex = EMPTY_REX; if (QSE_STR_LEN(t[0]) <= 0) cmd->u.subst.rex = EMPTY_REX;
else else
{ {
#ifdef USE_REX cmd->u.subst.rex = build_rex (
cmd->u.subst.rex = qse_buildrex ( sed, QSE_STR_CSTR(t[0]),
sed->mmgr, cmd->u.subst.i, &sed->src.loc);
sed->depth.rex.build,
((sed->option&QSE_SED_EXTENDEDREX)? 0:QSE_REX_NOBOUND),
QSE_STR_PTR(t[0]),
QSE_STR_LEN(t[0]),
QSE_NULL
);
if (cmd->u.subst.rex == QSE_NULL)
{
SETERR1 (
sed, QSE_SED_EREXBL,
QSE_STR_PTR(t[0]),
QSE_STR_LEN(t[0]),
&sed->src.loc
);
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; if (cmd->u.subst.rex == QSE_NULL) goto oops;
#endif
} }
qse_str_yield (t[1], &cmd->u.subst.rpl, 0); qse_str_yield (t[1], &cmd->u.subst.rpl, 0);
@ -1100,7 +1126,7 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
return 0; return 0;
oops: oops:
if (t[1] != QSE_NULL) qse_str_close (t[1]); if (t[1]) qse_str_close (t[1]);
return -1; return -1;
} }
@ -1190,7 +1216,7 @@ static int get_transet (qse_sed_t* sed, qse_sed_cmd_t* cmd)
return 0; return 0;
oops: oops:
if (t != QSE_NULL) qse_str_close (t); if (t) qse_str_close (t);
return -1; return -1;
} }
@ -1471,6 +1497,7 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
if (get_address (sed, &cmd->a1) == QSE_NULL) if (get_address (sed, &cmd->a1) == QSE_NULL)
{ {
cmd = QSE_NULL; cmd = QSE_NULL;
SETERR0 (sed, QSE_SED_EA1MOI, &sed->src.loc);
goto oops; goto oops;
} }
@ -1490,6 +1517,7 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
if (get_address (sed, &cmd->a2) == QSE_NULL) if (get_address (sed, &cmd->a2) == QSE_NULL)
{ {
QSE_ASSERT (cmd->a2.type == QSE_SED_ADR_NONE); QSE_ASSERT (cmd->a2.type == QSE_SED_ADR_NONE);
SETERR0 (sed, QSE_SED_EA2MOI, &sed->src.loc);
goto oops; goto oops;
} }
@ -1501,7 +1529,7 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
goto oops; goto oops;
} }
} }
else if ((sed->option&QSE_SED_STARTSTEP) && else if ((sed->option & QSE_SED_STARTSTEP) &&
(delim == QSE_T('~'))) (delim == QSE_T('~')))
{ {
if (cmd->a1.type != QSE_SED_ADR_LINE || if (cmd->a1.type != QSE_SED_ADR_LINE ||
@ -1519,6 +1547,15 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
else cmd->a2.type = QSE_SED_ADR_NONE; else cmd->a2.type = QSE_SED_ADR_NONE;
} }
if (cmd->a2.type != QSE_SED_ADR_STEP &&
cmd->a1.type == QSE_SED_ADR_LINE &&
cmd->a1.u.lno <= 0)
{
/* 0 is not allowed as a normal line number */
SETERR0 (sed, QSE_SED_EA1MOI, &sed->src.loc);
goto oops;
}
/* skip white spaces */ /* skip white spaces */
while (IS_SPACE(c)) c = NXTSC (sed); while (IS_SPACE(c)) c = NXTSC (sed);
@ -1560,7 +1597,7 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
return 0; return 0;
oops: oops:
if (cmd != QSE_NULL) free_address (sed, cmd); if (cmd) free_address (sed, cmd);
return -1; return -1;
} }
@ -2037,8 +2074,6 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
qse_str_clear (&sed->e.txt.subst); qse_str_clear (&sed->e.txt.subst);
#ifdef USE_REX #ifdef USE_REX
if (cmd->u.subst.i) opt = QSE_REX_IGNORECASE; if (cmd->u.subst.i) opt = QSE_REX_IGNORECASE;
#else
if (cmd->u.subst.i) opt = QSE_TRE_IGNORECASE;
#endif #endif
str.ptr = QSE_STR_PTR(&sed->e.in.line); str.ptr = QSE_STR_PTR(&sed->e.in.line);
@ -2133,8 +2168,7 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
} }
if (mat.len == 0 && if (mat.len == 0 &&
pmat.ptr != QSE_NULL && pmat.ptr && mat.ptr == pmat.ptr + pmat.len)
mat.ptr == pmat.ptr + pmat.len)
{ {
/* match length is 0 and the match is still at the /* match length is 0 and the match is still at the
* end of the previous match */ * end of the previous match */
@ -2269,7 +2303,7 @@ static int do_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (n <= -1) return -1; if (n <= -1) return -1;
} }
if (cmd->u.subst.file.ptr != QSE_NULL) if (cmd->u.subst.file.ptr)
{ {
n = write_str_to_file ( n = write_str_to_file (
sed, cmd, sed, cmd,
@ -2547,7 +2581,7 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
QSE_STR_PTR(&sed->e.in.line), QSE_STR_PTR(&sed->e.in.line),
QSE_STR_LEN(&sed->e.in.line), QSE_STR_LEN(&sed->e.in.line),
QSE_T('\n')); QSE_T('\n'));
if (nl != QSE_NULL) if (nl)
{ {
/* if a new line is found. delete up to it */ /* if a new line is found. delete up to it */
qse_str_del (&sed->e.in.line, 0, qse_str_del (&sed->e.in.line, 0,
@ -2801,7 +2835,7 @@ static void close_outfile (qse_map_t* map, void* dptr, qse_size_t dlen)
qse_sed_io_arg_t* arg = dptr; qse_sed_io_arg_t* arg = dptr;
QSE_ASSERT (dlen == QSE_SIZEOF(*arg)); QSE_ASSERT (dlen == QSE_SIZEOF(*arg));
if (arg->handle != QSE_NULL) if (arg->handle)
{ {
qse_sed_t* sed = *(qse_sed_t**)QSE_XTN(map); qse_sed_t* sed = *(qse_sed_t**)QSE_XTN(map);
sed->e.out.fun (sed, QSE_SED_IO_CLOSE, arg, QSE_NULL, 0); sed->e.out.fun (sed, QSE_SED_IO_CLOSE, arg, QSE_NULL, 0);
@ -2881,12 +2915,12 @@ static int init_command_block_for_exec (qse_sed_t* sed, qse_sed_cmd_blk_t* b)
file = &c->u.file; file = &c->u.file;
} }
else if (c->type == QSE_SED_CMD_SUBSTITUTE && else if (c->type == QSE_SED_CMD_SUBSTITUTE &&
c->u.subst.file.ptr != QSE_NULL) c->u.subst.file.ptr)
{ {
file = &c->u.subst.file; file = &c->u.subst.file;
} }
if (file != QSE_NULL) if (file)
{ {
/* call this function to an open output file */ /* call this function to an open output file */
int n = write_str_to_file ( int n = write_str_to_file (