fixed a bug in run_delete()
This commit is contained in:
parent
8e221ca599
commit
faf9c80f3f
@ -48,6 +48,14 @@ struct qse_sed_t
|
|||||||
QSE_DEFINE_COMMON_FIELDS (sed)
|
QSE_DEFINE_COMMON_FIELDS (sed)
|
||||||
qse_sed_errnum_t errnum;
|
qse_sed_errnum_t errnum;
|
||||||
|
|
||||||
|
/* source code pointers */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
const qse_char_t* ptr;
|
||||||
|
const qse_char_t* end;
|
||||||
|
const qse_char_t* cur;
|
||||||
|
} src;
|
||||||
|
|
||||||
void* lastrex;
|
void* lastrex;
|
||||||
qse_str_t rexbuf; /* temporary regular expression buffer */
|
qse_str_t rexbuf; /* temporary regular expression buffer */
|
||||||
|
|
||||||
@ -56,8 +64,8 @@ struct qse_sed_t
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
qse_sed_c_t* buf;
|
qse_sed_c_t* buf;
|
||||||
qse_sed_c_t* cur;
|
|
||||||
qse_sed_c_t* end;
|
qse_sed_c_t* end;
|
||||||
|
qse_sed_c_t* cur;
|
||||||
} cmd;
|
} cmd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: run.c 91 2009-03-01 14:54:28Z hyunghwan.chung $
|
* $Id: run.c 92 2009-03-02 03:34:43Z hyunghwan.chung $
|
||||||
*
|
*
|
||||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
@ -2574,11 +2574,10 @@ static int run_delete (qse_awk_rtx_t* run, qse_awk_nde_delete_t* nde)
|
|||||||
out.type = QSE_AWK_RTX_VALTOSTR_CPL;
|
out.type = QSE_AWK_RTX_VALTOSTR_CPL;
|
||||||
out.u.cpl.ptr = buf;
|
out.u.cpl.ptr = buf;
|
||||||
out.u.cpl.len = QSE_COUNTOF(buf);
|
out.u.cpl.len = QSE_COUNTOF(buf);
|
||||||
|
|
||||||
key = qse_awk_rtx_valtostr (run, idx, &out);
|
key = qse_awk_rtx_valtostr (run, idx, &out);
|
||||||
if (key == QSE_NULL)
|
if (key == QSE_NULL)
|
||||||
{
|
{
|
||||||
/* if it doesn't work, switch to dynamic mode */
|
/* retry it in dynamic mode */
|
||||||
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
|
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
|
||||||
key = qse_awk_rtx_valtostr (run, idx, &out);
|
key = qse_awk_rtx_valtostr (run, idx, &out);
|
||||||
}
|
}
|
||||||
@ -2592,15 +2591,12 @@ static int run_delete (qse_awk_rtx_t* run, qse_awk_nde_delete_t* nde)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out.type == QSE_AWK_RTX_VALTOSTR_CPL)
|
keylen = (out.type == QSE_AWK_RTX_VALTOSTR_CPL)?
|
||||||
keylen = out.u.cpl.len;
|
out.u.cpl.len: out.u.cpldup.len;
|
||||||
else
|
|
||||||
keylen = out.u.cpldup.len;
|
|
||||||
|
|
||||||
qse_map_delete (map, key, keylen);
|
qse_map_delete (map, key, keylen);
|
||||||
|
|
||||||
if (out.type == QSE_AWK_RTX_VALTOSTR_CPLDUP)
|
if (key != buf) QSE_AWK_FREE (run->awk, key);
|
||||||
QSE_AWK_FREE (run->awk, out.u.cpldup.ptr);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2707,21 +2703,12 @@ static int run_delete (qse_awk_rtx_t* run, qse_awk_nde_delete_t* nde)
|
|||||||
out.type = QSE_AWK_RTX_VALTOSTR_CPL;
|
out.type = QSE_AWK_RTX_VALTOSTR_CPL;
|
||||||
out.u.cpl.ptr = buf;
|
out.u.cpl.ptr = buf;
|
||||||
out.u.cpl.len = QSE_COUNTOF(buf);
|
out.u.cpl.len = QSE_COUNTOF(buf);
|
||||||
if (qse_awk_rtx_valtostr (run, idx, &out) == QSE_NULL)
|
key = qse_awk_rtx_valtostr (run, idx, &out);
|
||||||
|
if (key == QSE_NULL)
|
||||||
{
|
{
|
||||||
/* if it doesn't work, switch to dynamic mode */
|
/* retry it in the dynamic mode */
|
||||||
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
|
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
|
||||||
if (qse_awk_rtx_valtostr (run, idx, &out) != QSE_NULL)
|
key = qse_awk_rtx_valtostr (run, idx, &out);
|
||||||
{
|
|
||||||
key = out.u.cpldup.ptr;
|
|
||||||
keylen = out.u.cpldup.len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
key = out.u.cpl.ptr;
|
|
||||||
keylen = out.u.cpl.len;
|
|
||||||
QSE_ASSERT (key == buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_awk_rtx_refdownval (run, idx);
|
qse_awk_rtx_refdownval (run, idx);
|
||||||
@ -2732,7 +2719,11 @@ static int run_delete (qse_awk_rtx_t* run, qse_awk_nde_delete_t* nde)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keylen = (out.type == QSE_AWK_RTX_VALTOSTR_CPL)?
|
||||||
|
out.u.cpl.len: out.u.cpldup.len;
|
||||||
|
|
||||||
qse_map_delete (map, key, keylen);
|
qse_map_delete (map, key, keylen);
|
||||||
|
|
||||||
if (key != buf) QSE_AWK_FREE (run->awk, key);
|
if (key != buf) QSE_AWK_FREE (run->awk, key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -83,14 +83,13 @@ void qse_sed_fini (qse_sed_t* sed)
|
|||||||
qse_str_fini (&sed->rexbuf);
|
qse_str_fini (&sed->rexbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the current character without advancing the pointer */
|
/* get the current charanter of the source code */
|
||||||
#define CC(ptr,end) ((ptr < end)? *ptr: QSE_CHAR_EOF)
|
#define CURSC(sed) \
|
||||||
/* get the current character advancing the pointer */
|
(((sed)->src.cur < (sed)->src.end)? *(sed)->src.cur: QSE_CHAR_EOF)
|
||||||
#define NC(ptr,end) ((ptr < end)? *ptr++: QSE_CHAR_EOF)
|
/* advance the current pointer of the source code */
|
||||||
|
#define ADVSCP(sed) ((sed)->src.cur++)
|
||||||
|
|
||||||
static const void* compile (
|
static void* compile_regex (qse_sed_t* sed, qse_char_t seof)
|
||||||
qse_sed_t* sed, const qse_char_t* ptr,
|
|
||||||
const qse_char_t* end, qse_char_t seof)
|
|
||||||
{
|
{
|
||||||
void* code;
|
void* code;
|
||||||
qse_cint_t c;
|
qse_cint_t c;
|
||||||
@ -99,7 +98,8 @@ static const void* compile (
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
c = NC (ptr, end);
|
ADVSCP (sed);
|
||||||
|
c = CURSC (sed);
|
||||||
if (c == QSE_CHAR_EOF || c == QSE_T('\n'))
|
if (c == QSE_CHAR_EOF || c == QSE_T('\n'))
|
||||||
{
|
{
|
||||||
sed->errnum = QSE_SED_ETMTXT;
|
sed->errnum = QSE_SED_ETMTXT;
|
||||||
@ -110,7 +110,8 @@ static const void* compile (
|
|||||||
|
|
||||||
if (c == QSE_T('\\'))
|
if (c == QSE_T('\\'))
|
||||||
{
|
{
|
||||||
c = NC (ptr, end);
|
ADVSCP (sed);
|
||||||
|
c = CURSC (sed);
|
||||||
if (c == QSE_CHAR_EOF || c == QSE_T('\n'))
|
if (c == QSE_CHAR_EOF || c == QSE_T('\n'))
|
||||||
{
|
{
|
||||||
sed->errnum = QSE_SED_ETMTXT;
|
sed->errnum = QSE_SED_ETMTXT;
|
||||||
@ -141,25 +142,23 @@ static const void* compile (
|
|||||||
}
|
}
|
||||||
|
|
||||||
sed->lastrex = code;
|
sed->lastrex = code;
|
||||||
return ptr;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const qse_char_t* address (
|
static qse_sed_a_t* address (qse_sed_t* sed, qse_sed_a_t* a)
|
||||||
qse_sed_t* sed, const qse_char_t* ptr,
|
|
||||||
const qse_char_t* end, qse_sed_a_t* a)
|
|
||||||
{
|
{
|
||||||
qse_cint_t c;
|
qse_cint_t c;
|
||||||
|
|
||||||
c = NC (ptr, end);
|
c = CURSC (sed);
|
||||||
if ((c = *ptr) == QSE_T('$'))
|
if (c == QSE_T('$'))
|
||||||
{
|
{
|
||||||
a->type = QSE_SED_A_DOL;
|
a->type = QSE_SED_A_DOL;
|
||||||
ptr++;
|
ADVSCP (sed);
|
||||||
}
|
}
|
||||||
else if (c == QSE_T('/'))
|
else if (c == QSE_T('/'))
|
||||||
{
|
{
|
||||||
ptr++;
|
ADVSCP (sed);
|
||||||
if (compile (sed, ptr, end, c) == QSE_NULL)
|
if (compile_regex (sed, c) == QSE_NULL)
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
|
|
||||||
a->u.rex = sed->lastrex;
|
a->u.rex = sed->lastrex;
|
||||||
@ -171,9 +170,9 @@ static const qse_char_t* address (
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
lno = lno * 10 + c - QSE_T('0');
|
lno = lno * 10 + c - QSE_T('0');
|
||||||
ptr++;
|
ADVSCP (sed);
|
||||||
}
|
}
|
||||||
while ((c = *ptr) >= QSE_T('0') && c <= QSE_T('9'));
|
while ((c = CURSC(sed)) >= QSE_T('0') && c <= QSE_T('9'));
|
||||||
|
|
||||||
/* line number 0 is illegal */
|
/* line number 0 is illegal */
|
||||||
if (lno == 0) return QSE_NULL;
|
if (lno == 0) return QSE_NULL;
|
||||||
@ -190,22 +189,21 @@ static const qse_char_t* address (
|
|||||||
a->type = QSE_SED_A_NONE;
|
a->type = QSE_SED_A_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const qse_char_t* command (
|
static int command (qse_sed_t* sed)
|
||||||
qse_sed_t* sed, const qse_char_t* ptr, const qse_char_t* end)
|
|
||||||
{
|
{
|
||||||
qse_cint_t c;
|
qse_cint_t c;
|
||||||
qse_sed_c_t* cmd = sed->cmd.cur;
|
qse_sed_c_t* cmd = sed->cmd.cur;
|
||||||
|
|
||||||
c = NC (ptr, end);
|
c = CURSC (sed);
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
sed->errnum = QSE_SED_ECMDNR;
|
sed->errnum = QSE_SED_ECMDNR;
|
||||||
return QSE_NULL;
|
return -1;
|
||||||
|
|
||||||
case QSE_T('{'):
|
case QSE_T('{'):
|
||||||
/* insert a negated branch command at the beginning
|
/* insert a negated branch command at the beginning
|
||||||
@ -224,7 +222,7 @@ static const qse_char_t* command (
|
|||||||
{
|
{
|
||||||
/* label cannot have an address */
|
/* label cannot have an address */
|
||||||
sed->errnum = QSE_SED_EA1PHB;
|
sed->errnum = QSE_SED_EA1PHB;
|
||||||
return QSE_NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip white spaces */
|
/* skip white spaces */
|
||||||
@ -237,7 +235,7 @@ static const qse_char_t* command (
|
|||||||
if (cmd->a2.type != QSE_SED_A_NONE)
|
if (cmd->a2.type != QSE_SED_A_NONE)
|
||||||
{
|
{
|
||||||
sed->errnum = QSE_SED_EA2PHB;
|
sed->errnum = QSE_SED_EA2PHB;
|
||||||
return QSE_NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -246,16 +244,24 @@ static const qse_char_t* command (
|
|||||||
if (cmd->a2.type != QSE_SED_A_NONE)
|
if (cmd->a2.type != QSE_SED_A_NONE)
|
||||||
{
|
{
|
||||||
sed->errnum = QSE_SED_EA2PHB;
|
sed->errnum = QSE_SED_EA2PHB;
|
||||||
return QSE_NULL;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = CURSC (sed);
|
||||||
|
if (c == QSE_T('\\'))
|
||||||
|
{
|
||||||
|
ADVSCP (sed);
|
||||||
|
c = CURSC (sed);
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: something wrong??? */
|
||||||
}
|
}
|
||||||
|
|
||||||
c = CC (ptr, end);
|
|
||||||
if (c == QSE_T('\\')) c = NC (ptr, end);
|
|
||||||
if (c != QSE_T('\n')) /* TODO: handle \r\n or others */
|
if (c != QSE_T('\n')) /* TODO: handle \r\n or others */
|
||||||
{
|
{
|
||||||
/* new line is expected */
|
/* new line is expected */
|
||||||
sed->errnum = QSE_SED_ENEWLN;
|
sed->errnum = QSE_SED_ENEWLN;
|
||||||
return QSE_NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: get the next line... */
|
/* TODO: get the next line... */
|
||||||
@ -325,17 +331,20 @@ static const qse_char_t* command (
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const qse_char_t* fcomp (
|
static int compile_source (
|
||||||
qse_sed_t* sed, const qse_char_t* ptr, qse_size_t len)
|
qse_sed_t* sed, const qse_char_t* ptr, qse_size_t len)
|
||||||
{
|
{
|
||||||
qse_cint_t c;
|
qse_cint_t c;
|
||||||
const qse_char_t* end = ptr + len;
|
|
||||||
|
|
||||||
qse_sed_c_t* cmd = sed->cmd.cur;
|
qse_sed_c_t* cmd = sed->cmd.cur;
|
||||||
|
|
||||||
|
/* store the source code pointers */
|
||||||
|
sed->src.ptr = ptr;
|
||||||
|
sed->src.end = ptr + len;
|
||||||
|
sed->src.cur = ptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* # comment
|
* # comment
|
||||||
* :label
|
* :label
|
||||||
@ -345,13 +354,13 @@ static const qse_char_t* fcomp (
|
|||||||
*/
|
*/
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
c = CC (ptr, end);
|
c = CURSC (sed);
|
||||||
|
|
||||||
/* skip white spaces */
|
/* skip white spaces */
|
||||||
while (c == QSE_T(' ') || c == QSE_T('\t'))
|
while (c == QSE_T(' ') || c == QSE_T('\t'))
|
||||||
{
|
{
|
||||||
ptr++;
|
ADVSCP (sed);
|
||||||
c = CC (ptr, end);
|
c = CURSC (sed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if it has reached the end or is commented */
|
/* check if it has reached the end or is commented */
|
||||||
@ -359,8 +368,8 @@ static const qse_char_t* fcomp (
|
|||||||
|
|
||||||
if (c == QSE_T(';'))
|
if (c == QSE_T(';'))
|
||||||
{
|
{
|
||||||
/* semicolon without a meaningful address-command pair */
|
/* semicolon without a address-command pair */
|
||||||
ptr++;
|
ADVSCP (sed);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,10 +377,9 @@ static const qse_char_t* fcomp (
|
|||||||
QSE_MEMSET (cmd, 0, QSE_SIZEOF(*cmd));
|
QSE_MEMSET (cmd, 0, QSE_SIZEOF(*cmd));
|
||||||
|
|
||||||
/* process address */
|
/* process address */
|
||||||
ptr = address (sed, ptr, end, &cmd->a1);
|
if (address (sed, &cmd->a1) == QSE_NULL) return -1;
|
||||||
if (ptr == QSE_NULL) return QSE_NULL;
|
|
||||||
|
|
||||||
c = CC (ptr, end);
|
c = CURSC (sed);
|
||||||
if (cmd->a1.type != QSE_SED_A_NONE)
|
if (cmd->a1.type != QSE_SED_A_NONE)
|
||||||
{
|
{
|
||||||
/* if (cmd->a1.type == QSE_SED_A_LAST)
|
/* if (cmd->a1.type == QSE_SED_A_LAST)
|
||||||
@ -381,12 +389,13 @@ static const qse_char_t* fcomp (
|
|||||||
if (c == QSE_T(',') || c == QSE_T(';'))
|
if (c == QSE_T(',') || c == QSE_T(';'))
|
||||||
{
|
{
|
||||||
/* maybe an address range */
|
/* maybe an address range */
|
||||||
ptr++;
|
ADVSCP (sed);
|
||||||
|
|
||||||
/* TODO: skip white spaces??? */
|
/* TODO: skip white spaces??? */
|
||||||
ptr = address (sed, ptr, end, &cmd->a2);
|
if (address (sed, &cmd->a2) == QSE_NULL)
|
||||||
if (ptr == QSE_NULL) return QSE_NULL;
|
return -1;
|
||||||
c = CC (ptr, end);
|
|
||||||
|
c = CURSC (sed);
|
||||||
}
|
}
|
||||||
else cmd->a2.type = QSE_SED_A_NONE;
|
else cmd->a2.type = QSE_SED_A_NONE;
|
||||||
}
|
}
|
||||||
@ -394,8 +403,8 @@ static const qse_char_t* fcomp (
|
|||||||
/* skip white spaces */
|
/* skip white spaces */
|
||||||
while (c == QSE_T(' ') || c == QSE_T('\t'))
|
while (c == QSE_T(' ') || c == QSE_T('\t'))
|
||||||
{
|
{
|
||||||
ptr++;
|
ADVSCP (sed);
|
||||||
c = CC (ptr, end);
|
c = CURSC (sed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == QSE_T('!'))
|
if (c == QSE_T('!'))
|
||||||
@ -404,8 +413,7 @@ static const qse_char_t* fcomp (
|
|||||||
cmd->negfl = 1;
|
cmd->negfl = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = command (sed, ptr, end);
|
if (command (sed) == -1) return -1;
|
||||||
if (ptr == QSE_NULL) return QSE_NULL;
|
|
||||||
|
|
||||||
if (sed->cmd.cur >= sed->cmd.end)
|
if (sed->cmd.cur >= sed->cmd.end)
|
||||||
{
|
{
|
||||||
@ -415,5 +423,5 @@ static const qse_char_t* fcomp (
|
|||||||
cmd = ++sed->cmd.cur;
|
cmd = ++sed->cmd.cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
SUBDIRS = cmn awk
|
SUBDIRS = cmn utl awk
|
||||||
|
8
qse/test/utl/Makefile.am
Normal file
8
qse/test/utl/Makefile.am
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
bin_PROGRAMS = sed01
|
||||||
|
|
||||||
|
LDFLAGS = -L../../lib/cmn -L../../lib/utl -L../../lib/sed
|
||||||
|
LDADD = -lqseutl -lqsecmn $(LIBM)
|
||||||
|
|
||||||
|
sed01_SOURCES = sed01.c
|
25
qse/test/utl/sed01.c
Normal file
25
qse/test/utl/sed01.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <qse/utl/sed.h>
|
||||||
|
#include <qse/utl/stdio.h>
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user