still working on sed

This commit is contained in:
hyung-hwan 2009-03-27 08:02:50 +00:00
parent ba8bd06016
commit d8a920e263
2 changed files with 104 additions and 59 deletions

View File

@ -118,6 +118,15 @@ for (c = sed->cmd.buf; c != sed->cmd.cur; c++)
QSE_MMGR_FREE (sed->mmgr, c->u.branch.label.ptr);
break;
case QSE_SED_CMD_S:
if (c->u.subst.file.ptr != QSE_NULL)
QSE_MMGR_FREE (sed->mmgr, c->u.subst.file.ptr);
if (c->u.subst.rpl.ptr != QSE_NULL)
QSE_MMGR_FREE (sed->mmgr, c->u.subst.rpl.ptr);
if (c->u.subst.rex.ptr != QSE_NULL)
QSE_MMGR_FREE (sed->mmgr, c->u.subst.rex.ptr);
break;
case QSE_SED_CMD_Y:
if (c->u.transet.ptr != QSE_NULL)
QSE_MMGR_FREE (sed->mmgr, c->u.transet.ptr);
@ -127,8 +136,8 @@ for (c = sed->cmd.buf; c != sed->cmd.cur; c++)
case QSE_SED_CMD_RR:
case QSE_SED_CMD_W:
case QSE_SED_CMD_WW:
if (c->u.filename.ptr != QSE_NULL)
QSE_MMGR_FREE (sed->mmgr, c->u.filename.ptr);
if (c->u.file.ptr != QSE_NULL)
QSE_MMGR_FREE (sed->mmgr, c->u.file.ptr);
break;
}
}
@ -595,7 +604,7 @@ static int get_file_name (qse_sed_t* sed, qse_sed_cmd_t* cmd)
qse_str_setlen (t, QSE_STR_LEN(t) - trailing_spaces);
}
qse_str_yield (t, &cmd->u.filename, 0);
qse_str_yield (t, &cmd->u.file, 0);
qse_str_close (t);
return 0;
@ -607,7 +616,8 @@ oops:
static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
{
qse_cint_t c, delim;
qse_str_t* t = QSE_NULL;
qse_str_t* t[2] = { QSE_NULL, QSE_NULL };
int i;
c = CURSC (sed);
if (c == QSE_CHAR_EOF || IS_LINTERM(c))
@ -625,45 +635,68 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd)
goto oops;
}
t = qse_str_open (sed->mmgr, 0, 32);
if (t == QSE_NULL)
{
sed->errnum = QSE_SED_ENOMEM;
goto oops;
}
c = NXTSC (sed);
while (c != delim)
{
if (c == QSE_CHAR_EOF || IS_LINTERM(c))
for (i = 0; i < 2; i++)
{
t[i] = qse_str_open (sed->mmgr, 0, 32);
if (t[i] == QSE_NULL)
{
sed->errnum = QSE_SED_ENOTRM;
sed->errnum = QSE_SED_ENOMEM;
goto oops;
}
}
if (c == QSE_T('\\'))
for (i = 0; i < 2; i++)
{
c = NXTSC (sed);
while (c != delim)
{
c = NXTSC (sed);
if (c == QSE_CHAR_EOF || IS_LINTERM(c))
{
sed->errnum = QSE_SED_ENOTRM;
goto oops;
}
if (c == QSE_T('n')) c = QSE_T('\n');
}
if (c == QSE_T('\\'))
{
c = NXTSC (sed);
if (c == QSE_CHAR_EOF || IS_LINTERM(c))
{
sed->errnum = QSE_SED_ENOTRM;
goto oops;
}
if (c == QSE_T('n')) c = QSE_T('\n');
}
if (qse_str_ccat (t, c) == (qse_size_t)-1)
{
sed->errnum = QSE_SED_ENOMEM;
goto oops;
}
if (qse_str_ccat (t[i], c) == (qse_size_t)-1)
{
sed->errnum = QSE_SED_ENOMEM;
goto oops;
}
c = NXTSC (sed);
}
c = NXTSC (sed);
}
}
c = NXTSC (sed);
ADVSCP (sed);
if (terminate_command (sed) == -1) goto oops;
qse_str_yield (t[1], &cmd->u.subst.rex, 0);
qse_str_yield (t[0], &cmd->u.subst.rpl, 0);
qse_str_close (t[1]);
qse_str_close (t[0]);
return 0;
oops:
if (t != QSE_NULL) qse_str_close (t);
if (t[1] != QSE_NULL) qse_str_close (t[1]);
if (t[0] != QSE_NULL) qse_str_close (t[0]);
return -1;
}
@ -814,7 +847,7 @@ qse_printf (QSE_T("command not recognized [%c]\n"), c);
* can be skipped. the branch target is set once a
* corresponding } is met. */
cmd->type = QSE_SED_CMD_B;
cmd->negfl = !cmd->negfl;
cmd->negated = !cmd->negated;
if (sed->grplvl >= QSE_COUNTOF(sed->grpcmd))
{
@ -943,7 +976,7 @@ qse_printf (QSE_T("cmd->u.branch.target = [%p]\n"), cmd->u.branch.target);
ADVSCP (sed);
if (get_file_name (sed, cmd) == -1) return -1;
qse_printf (QSE_T("cmd->u.filename= [%.*s]\n"), (int)cmd->u.filename.len, cmd->u.filename.ptr);
qse_printf (QSE_T("cmd->u.file= [%.*s]\n"), (int)cmd->u.file.len, cmd->u.file.ptr);
break;
@ -951,6 +984,8 @@ qse_printf (QSE_T("cmd->u.filename= [%.*s]\n"), (int)cmd->u.filename.len, cmd->u
cmd->type = c;
ADVSCP (sed);
if (get_subst (sed, cmd) == -1) return -1;
qse_printf (QSE_T("rex= [%.*s]\n"), (int)cmd->u.subst.rex.len, cmd->u.subst.rex.ptr);
qse_printf (QSE_T("rpl= [%.*s]\n"), (int)cmd->u.subst.rpl.len, cmd->u.subst.rpl.ptr);
break;
case QSE_T('y'):
@ -1039,7 +1074,7 @@ static int compile_source (
if (c == QSE_T('!'))
{
/* negate */
cmd->negfl = 1;
cmd->negated = 1;
}
n = command (sed);

View File

@ -46,34 +46,8 @@ struct qse_sed_a_t
struct qse_sed_cmd_t
{
qse_sed_a_t a1; /* optional start address */
qse_sed_a_t a2; /* optional end address */
union
{
/* text for the a, i, c commands */
qse_xstr_t text;
/* file name for r, w, R, W */
qse_xstr_t filename;
/* translation set for the y command */
qse_xstr_t transet;
struct
{
qse_xstr_t label;
qse_sed_cmd_t* target;
} branch;
void* rex;
} u;
qse_char_t* rhs; /* right-hand side of sustitution */
enum
{
/* print current line number */
QSE_SED_CMD_EQ = QSE_T('='),
QSE_SED_CMD_Q = QSE_T('q'),
@ -124,8 +98,44 @@ struct qse_sed_cmd_t
} type;
/* TODO: change the data type to a shorter one to save space */
int negfl;
int negated;
qse_sed_a_t a1; /* optional start address */
qse_sed_a_t a2; /* optional end address */
union
{
/* text for the a, i, c commands */
qse_xstr_t text;
/* file name for r, w, R, W */
qse_xstr_t file;
/* data for the s command */
struct
{
qse_xstr_t rex; /* regular expression */
qse_xstr_t rpl; /* replacement */
/* flags */
qse_xstr_t file; /* file name for w */
int pos: 16;
int p: 1; /* print */
int i: 1; /* case insensitive */
} subst;
/* translation set for the y command */
qse_xstr_t transet;
struct
{
qse_xstr_t label;
qse_sed_cmd_t* target;
} branch;
void* rex;
} u;
};
#endif