added more commands for sed
This commit is contained in:
parent
6d68da1669
commit
392d88ab7a
@ -151,7 +151,11 @@ struct qse_sed_t
|
||||
} in;
|
||||
} eio;
|
||||
|
||||
qse_lda_t text_appended;
|
||||
struct
|
||||
{
|
||||
qse_lda_t appended;
|
||||
qse_str_t held;
|
||||
} text;
|
||||
};
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "sed.h"
|
||||
#include "../cmn/mem.h"
|
||||
#include <qse/cmn/rex.h>
|
||||
#include <qse/cmn/chr.h>
|
||||
|
||||
/* TODO: delete stdio.h */
|
||||
#include <qse/utl/stdio.h>
|
||||
@ -91,7 +92,7 @@ qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
||||
sed->cmd.cur = sed->cmd.buf;
|
||||
sed->cmd.end = sed->cmd.buf + 1000 - 1;
|
||||
|
||||
if (qse_lda_init (&sed->text_appended, mmgr, 32) == QSE_NULL)
|
||||
if (qse_lda_init (&sed->text.appended, mmgr, 32) == QSE_NULL)
|
||||
{
|
||||
QSE_MMGR_FREE (sed->mmgr, sed->cmd.buf);
|
||||
qse_map_fini (&sed->labs);
|
||||
@ -99,12 +100,23 @@ qse_sed_t* qse_sed_init (qse_sed_t* sed, qse_mmgr_t* mmgr)
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
if (qse_str_init (&sed->text.held, mmgr, 256) == QSE_NULL)
|
||||
{
|
||||
qse_lda_fini (&sed->text.appended);
|
||||
QSE_MMGR_FREE (sed->mmgr, sed->cmd.buf);
|
||||
qse_map_fini (&sed->labs);
|
||||
qse_str_fini (&sed->rexbuf);
|
||||
return QSE_NULL;
|
||||
|
||||
}
|
||||
|
||||
return sed;
|
||||
}
|
||||
|
||||
void qse_sed_fini (qse_sed_t* sed)
|
||||
{
|
||||
qse_lda_fini (&sed->text_appended);
|
||||
qse_str_fini (&sed->text.held);
|
||||
qse_lda_fini (&sed->text.appended);
|
||||
|
||||
/* TODO: use different data sturect -> look at qse_sed_init */
|
||||
qse_sed_cmd_t* c;
|
||||
@ -1058,13 +1070,6 @@ qse_printf (QSE_T("command %c\n"), cmd->type);
|
||||
/* get_text() starts from the next line */
|
||||
if (get_text (sed, cmd) <= -1) return -1;
|
||||
|
||||
/*
|
||||
{
|
||||
qse_char_t ttt[1000];
|
||||
qse_fgets (ttt, QSE_COUNTOF(ttt), QSE_STDIN);
|
||||
qse_printf (QSE_T("%s%s"), ttt, cmd->u.text.ptr);
|
||||
}
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1077,20 +1082,22 @@ qse_printf (QSE_T("%s%s"), ttt, cmd->u.text.ptr);
|
||||
}
|
||||
case QSE_T('p'):
|
||||
case QSE_T('P'):
|
||||
case QSE_T('l'):
|
||||
|
||||
case QSE_T('d'):
|
||||
case QSE_T('D'):
|
||||
|
||||
case QSE_T('h'):
|
||||
case QSE_T('H'):
|
||||
case QSE_T('g'):
|
||||
case QSE_T('G'):
|
||||
case QSE_T('l'):
|
||||
case QSE_T('x'):
|
||||
|
||||
case QSE_T('n'):
|
||||
case QSE_T('N'):
|
||||
case QSE_T('x'):
|
||||
cmd->type = c;
|
||||
ADVSCP (sed);
|
||||
if (terminate_command (sed) <= -1) return -1;
|
||||
qse_printf (QSE_T("command %c\n"), cmd->type);
|
||||
break;
|
||||
|
||||
case QSE_T('b'):
|
||||
@ -1098,15 +1105,6 @@ qse_printf (QSE_T("command %c\n"), cmd->type);
|
||||
cmd->type = c;
|
||||
ADVSCP (sed);
|
||||
if (get_branch_target (sed, cmd) <= -1) return -1;
|
||||
if (cmd->u.branch.label.ptr != NULL)
|
||||
{
|
||||
qse_printf (QSE_T("cmd->u.branch.label = [%.*s]\n"),
|
||||
cmd->u.branch.label.len, cmd->u.branch.label.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_printf (QSE_T("cmd->u.branch.target = [%p]\n"), cmd->u.branch.target);
|
||||
}
|
||||
break;
|
||||
|
||||
case QSE_T('r'):
|
||||
@ -1116,8 +1114,6 @@ qse_printf (QSE_T("cmd->u.branch.target = [%p]\n"), cmd->u.branch.target);
|
||||
cmd->type = c;
|
||||
ADVSCP (sed);
|
||||
if (get_file (sed, &cmd->u.file) <= -1) return -1;
|
||||
|
||||
qse_printf (QSE_T("cmd->u.file= [%.*s]\n"), (int)cmd->u.file.len, cmd->u.file.ptr);
|
||||
break;
|
||||
|
||||
|
||||
@ -1409,30 +1405,40 @@ static int write_str (qse_sed_t* sed, const qse_char_t* str, qse_size_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_num (qse_sed_t* sed, qse_size_t x)
|
||||
static int write_num (qse_sed_t* sed, qse_size_t x, int base, int width)
|
||||
{
|
||||
qse_size_t last = x % 10;
|
||||
qse_size_t last = x % base;
|
||||
qse_size_t y = 0, dig = 0;
|
||||
|
||||
QSE_ASSERT (base >= 2 && base <= 10);
|
||||
|
||||
if (x < 0)
|
||||
{
|
||||
if (write_char (sed, QSE_T('-')) <= -1) return -1;
|
||||
}
|
||||
|
||||
x = x / 10;
|
||||
x = x / base;
|
||||
if (x < 0) x = -x;
|
||||
|
||||
while (x > 0)
|
||||
{
|
||||
y = y * 10 + (x % 10);
|
||||
x = x / 10;
|
||||
y = y * base + (x % base);
|
||||
x = x / base;
|
||||
dig++;
|
||||
}
|
||||
|
||||
if (width > 0)
|
||||
{
|
||||
while (--width > dig)
|
||||
{
|
||||
if (write_char (sed, QSE_T('0')) <= -1) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
while (y > 0)
|
||||
{
|
||||
if (write_char (sed, (y % 10) + QSE_T('0')) <= -1) return -1;
|
||||
y = y / 10;
|
||||
if (write_char (sed, (y % base) + QSE_T('0')) <= -1) return -1;
|
||||
y = y / base;
|
||||
dig--;
|
||||
}
|
||||
|
||||
@ -1447,6 +1453,76 @@ static int write_num (qse_sed_t* sed, qse_size_t x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define WRITE_CHAR(sed,c) \
|
||||
do { if (write_char(sed,c) <= -1) return -1; } while (0)
|
||||
#define WRITE_STR(sed,str,len) \
|
||||
do { if (write_str(sed,str,len) <= -1) return -1; } while (0)
|
||||
#define WRITE_NUM(sed,num,base,width) \
|
||||
do { if (write_num(sed,num,base,width) <= -1) return -1; } while (0)
|
||||
|
||||
static int write_str_clearly (
|
||||
qse_sed_t* sed, const qse_char_t* str, qse_size_t len)
|
||||
{
|
||||
const qse_char_t* p = str;
|
||||
const qse_char_t* end = str + len;
|
||||
|
||||
/* TODO: break down long lines.... */
|
||||
while (p < end)
|
||||
{
|
||||
qse_char_t c = *p++;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case QSE_T('\\'):
|
||||
WRITE_STR (sed, QSE_T("\\\\"), 2);
|
||||
break;
|
||||
/*case QSE_T('\0'):
|
||||
WRITE_STR (sed, QSE_T("\\0"), 2);
|
||||
break;*/
|
||||
case QSE_T('\n'):
|
||||
WRITE_STR (sed, QSE_T("$\n"), 2);
|
||||
break;
|
||||
case QSE_T('\a'):
|
||||
WRITE_STR (sed, QSE_T("\\a"), 2);
|
||||
break;
|
||||
case QSE_T('\b'):
|
||||
WRITE_STR (sed, QSE_T("\\b"), 2);
|
||||
break;
|
||||
case QSE_T('\f'):
|
||||
WRITE_STR (sed, QSE_T("\\f"), 2);
|
||||
break;
|
||||
case QSE_T('\r'):
|
||||
WRITE_STR (sed, QSE_T("\\r"), 2);
|
||||
break;
|
||||
case QSE_T('\t'):
|
||||
WRITE_STR (sed, QSE_T("\\t"), 2);
|
||||
break;
|
||||
case QSE_T('\v'):
|
||||
WRITE_STR (sed, QSE_T("\\v"), 2);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if (QSE_ISPRINT(c)) WRITE_CHAR (sed, c);
|
||||
else
|
||||
{
|
||||
qse_size_t i;
|
||||
qse_byte_t* b = (qse_byte_t*)&c;
|
||||
WRITE_CHAR (sed, QSE_T('\\'));
|
||||
for (i = 0; i < QSE_SIZEOF(c)/QSE_SIZEOF(*b); i++)
|
||||
{
|
||||
WRITE_NUM (sed, b[i], 8, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (len > 1 && end[-1] != QSE_T('\n'))
|
||||
WRITE_STR (sed, QSE_T("$\n"), 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int match_a (qse_sed_t* sed, qse_sed_a_t* a)
|
||||
{
|
||||
switch (a->type)
|
||||
@ -1614,11 +1690,10 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
jumpto = sed->cmd.cur + 1;
|
||||
break;
|
||||
|
||||
|
||||
case QSE_SED_CMD_APPEND:
|
||||
if (qse_lda_insert (
|
||||
&sed->text_appended,
|
||||
QSE_LDA_SIZE(&sed->text_appended),
|
||||
&sed->text.appended,
|
||||
QSE_LDA_SIZE(&sed->text.appended),
|
||||
&cmd->u.text, 0) == (qse_size_t)-1)
|
||||
{
|
||||
sed->errnum = QSE_SED_ENOMEM;
|
||||
@ -1669,17 +1744,72 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||
break;
|
||||
|
||||
case QSE_SED_CMD_PRINT_LNUM:
|
||||
if (write_num (sed, sed->eio.in.num) <= -1) return QSE_NULL;
|
||||
if (write_num (sed, sed->eio.in.num, 10, 0) <= -1) return QSE_NULL;
|
||||
if (write_char (sed, QSE_T('\n')) <= -1) return QSE_NULL;
|
||||
break;
|
||||
|
||||
case QSE_SED_CMD_PRINT:
|
||||
n = write_str (sed,
|
||||
n = write_str (
|
||||
sed,
|
||||
QSE_STR_PTR(&sed->eio.in.line),
|
||||
QSE_STR_LEN(&sed->eio.in.line));
|
||||
QSE_STR_LEN(&sed->eio.in.line)
|
||||
);
|
||||
if (n <= -1) return QSE_NULL;
|
||||
break;
|
||||
|
||||
case QSE_SED_CMD_PRINT_CLEARLY:
|
||||
n = write_str_clearly (
|
||||
sed,
|
||||
QSE_STR_PTR(&sed->eio.in.line),
|
||||
QSE_STR_LEN(&sed->eio.in.line)
|
||||
);
|
||||
if (n <= -1) return QSE_NULL;
|
||||
break;
|
||||
|
||||
case QSE_SED_CMD_HOLD:
|
||||
if (qse_str_ncpy (&sed->text.held,
|
||||
QSE_STR_PTR(&sed->eio.in.line),
|
||||
QSE_STR_LEN(&sed->eio.in.line)) == (qse_size_t)-1)
|
||||
{
|
||||
sed->errnum = QSE_SED_ENOMEM;
|
||||
return QSE_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case QSE_SED_CMD_HOLD_APPEND:
|
||||
if (qse_str_ncat (&sed->text.held,
|
||||
QSE_STR_PTR(&sed->eio.in.line),
|
||||
QSE_STR_LEN(&sed->eio.in.line)) == (qse_size_t)-1)
|
||||
{
|
||||
sed->errnum = QSE_SED_ENOMEM;
|
||||
return QSE_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case QSE_SED_CMD_RELEASE:
|
||||
if (qse_str_ncpy (&sed->eio.in.line,
|
||||
QSE_STR_PTR(&sed->text.held),
|
||||
QSE_STR_LEN(&sed->text.held)) == (qse_size_t)-1)
|
||||
{
|
||||
sed->errnum = QSE_SED_ENOMEM;
|
||||
return QSE_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case QSE_SED_CMD_EXCHANGE:
|
||||
qse_str_swap (&sed->eio.in.line, &sed->text.held);
|
||||
break;
|
||||
|
||||
case QSE_SED_CMD_RELEASE_APPEND:
|
||||
if (qse_str_ncat (&sed->eio.in.line,
|
||||
QSE_STR_PTR(&sed->text.held),
|
||||
QSE_STR_LEN(&sed->text.held)) == (qse_size_t)-1)
|
||||
{
|
||||
sed->errnum = QSE_SED_ENOMEM;
|
||||
return QSE_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case QSE_SED_CMD_BRANCH:
|
||||
if (cmd->u.branch.target == QSE_NULL)
|
||||
{
|
||||
@ -1712,6 +1842,14 @@ int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
|
||||
qse_ssize_t n;
|
||||
int ret = 0;
|
||||
|
||||
qse_lda_clear (&sed->text.appended);
|
||||
qse_str_clear (&sed->text.held);
|
||||
if (qse_str_ccat (&sed->text.held, QSE_T('\n')) == (qse_size_t)-1)
|
||||
{
|
||||
sed->errnum = QSE_SED_ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sed->eio.out.f = outf;
|
||||
sed->eio.out.eof = 0;
|
||||
sed->eio.out.len = 0;
|
||||
@ -1766,7 +1904,7 @@ int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
|
||||
if (n <= -1) { ret = -1; goto done; }
|
||||
if (n == 0) goto done;
|
||||
|
||||
qse_lda_clear (&sed->text_appended);
|
||||
qse_lda_clear (&sed->text.appended);
|
||||
|
||||
c = sed->cmd.buf;
|
||||
while (c < sed->cmd.cur)
|
||||
@ -1802,9 +1940,9 @@ int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
|
||||
if (n <= -1) { ret = -1; goto done; }
|
||||
}
|
||||
|
||||
for (i = 0; i < QSE_LDA_SIZE(&sed->text_appended); i++)
|
||||
for (i = 0; i < QSE_LDA_SIZE(&sed->text.appended); i++)
|
||||
{
|
||||
qse_xstr_t* t = QSE_LDA_DPTR(&sed->text_appended, i);
|
||||
qse_xstr_t* t = QSE_LDA_DPTR(&sed->text.appended, i);
|
||||
n = write_str (sed, t->ptr, t->len);
|
||||
if (n <= -1) { ret = -1; goto done; }
|
||||
}
|
||||
|
@ -48,14 +48,9 @@ struct qse_sed_cmd_t
|
||||
{
|
||||
enum
|
||||
{
|
||||
QSE_SED_CMD_PRINT_LNUM = QSE_T('='),
|
||||
QSE_SED_CMD_QUIT = QSE_T('q'),
|
||||
QSE_SED_CMD_QUIT_QUIET = QSE_T('Q'),
|
||||
|
||||
/* delete pattern space */
|
||||
QSE_SED_CMD_DELETE = QSE_T('d'),
|
||||
QSE_SED_CMD_DD = QSE_T('D'),
|
||||
|
||||
/* a \<\n> text - append text */
|
||||
QSE_SED_CMD_APPEND = QSE_T('a'),
|
||||
/* i \<\n> text - insert text */
|
||||
@ -63,18 +58,23 @@ struct qse_sed_cmd_t
|
||||
/* c \<\n> text - change text */
|
||||
QSE_SED_CMD_CHANGE = QSE_T('c'),
|
||||
|
||||
QSE_SED_CMD_H = QSE_T('h'),
|
||||
QSE_SED_CMD_HH = QSE_T('H'),
|
||||
QSE_SED_CMD_G = QSE_T('g'),
|
||||
QSE_SED_CMD_GG = QSE_T('G'),
|
||||
/* list out current line */
|
||||
QSE_SED_CMD_L = QSE_T('l'),
|
||||
/* delete pattern space */
|
||||
QSE_SED_CMD_DELETE = QSE_T('d'),
|
||||
QSE_SED_CMD_DD = QSE_T('D'),
|
||||
|
||||
QSE_SED_CMD_PRINT_LNUM = QSE_T('='),
|
||||
QSE_SED_CMD_PRINT = QSE_T('p'),
|
||||
QSE_SED_CMD_PP = QSE_T('P'),
|
||||
QSE_SED_CMD_PRINT_CLEARLY = QSE_T('l'),
|
||||
|
||||
QSE_SED_CMD_HOLD = QSE_T('h'),
|
||||
QSE_SED_CMD_HOLD_APPEND = QSE_T('H'),
|
||||
QSE_SED_CMD_RELEASE = QSE_T('g'),
|
||||
QSE_SED_CMD_RELEASE_APPEND = QSE_T('G'),
|
||||
QSE_SED_CMD_EXCHANGE = QSE_T('x'),
|
||||
|
||||
QSE_SED_CMD_N = QSE_T('n'),
|
||||
QSE_SED_CMD_NN = QSE_T('N'),
|
||||
QSE_SED_CMD_PRINT = QSE_T('p'),
|
||||
QSE_SED_CMD_PP = QSE_T('P'),
|
||||
/* exchange hold space and pattern space */
|
||||
QSE_SED_CMD_X = QSE_T('x'),
|
||||
|
||||
/* branch */
|
||||
QSE_SED_CMD_BRANCH = QSE_T('b'),
|
||||
|
Loading…
x
Reference in New Issue
Block a user