still a long way to finish sed
This commit is contained in:
parent
93ea3e255a
commit
5cddfbb7ef
@ -121,11 +121,27 @@ struct qse_sed_t
|
|||||||
/* io data for execution */
|
/* io data for execution */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
qse_sed_iof_t f;
|
struct
|
||||||
qse_char_t buf[2048];
|
{
|
||||||
qse_size_t len;
|
qse_sed_iof_t f;
|
||||||
qse_size_t pos;
|
|
||||||
qse_str_t line;
|
qse_char_t buf[2048];
|
||||||
|
qse_size_t len;
|
||||||
|
int eof;
|
||||||
|
} out;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
qse_sed_iof_t f;
|
||||||
|
|
||||||
|
qse_char_t buf[2048];
|
||||||
|
qse_size_t len;
|
||||||
|
qse_size_t pos;
|
||||||
|
int eof;
|
||||||
|
|
||||||
|
qse_str_t line;
|
||||||
|
qse_size_t num;
|
||||||
|
} in;
|
||||||
} eio;
|
} eio;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -217,7 +233,8 @@ int qse_sed_compile (
|
|||||||
|
|
||||||
int qse_sed_execute (
|
int qse_sed_execute (
|
||||||
qse_sed_t* sed,
|
qse_sed_t* sed,
|
||||||
qse_sed_iof_t iof
|
qse_sed_iof_t inf,
|
||||||
|
qse_sed_iof_t outf
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -1197,11 +1197,11 @@ static int read_char (qse_sed_t* sed, qse_char_t* c)
|
|||||||
{
|
{
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
|
|
||||||
if (sed->eio.pos >= sed->eio.len)
|
if (sed->eio.in.pos >= sed->eio.in.len)
|
||||||
{
|
{
|
||||||
n = sed->eio.f (
|
n = sed->eio.in.f (
|
||||||
sed, QSE_SED_IO_READ,
|
sed, QSE_SED_IO_READ,
|
||||||
sed->eio.buf, QSE_COUNTOF(sed->eio.buf)
|
sed->eio.in.buf, QSE_COUNTOF(sed->eio.in.buf)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
@ -1212,11 +1212,11 @@ static int read_char (qse_sed_t* sed, qse_char_t* c)
|
|||||||
|
|
||||||
if (n == 0) return 0; /* end of file */
|
if (n == 0) return 0; /* end of file */
|
||||||
|
|
||||||
sed->eio.len = n;
|
sed->eio.in.len = n;
|
||||||
sed->eio.pos = 0;
|
sed->eio.in.pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*c = sed->eio.buf[sed->eio.pos++];
|
*c = sed->eio.in.buf[sed->eio.in.pos++];
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1225,7 +1225,16 @@ static int read_line (qse_sed_t* sed)
|
|||||||
qse_char_t c;
|
qse_char_t c;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
qse_str_clear (&sed->eio.line);
|
qse_str_clear (&sed->eio.in.line);
|
||||||
|
if (sed->eio.in.eof)
|
||||||
|
{
|
||||||
|
/* no more input detected in the previous read.
|
||||||
|
* set eof back to 0 here so that read_char() is called
|
||||||
|
* if read_line() is called again. that way, the result
|
||||||
|
* of subsequent calls counts on read_char(). */
|
||||||
|
sed->eio.in.eof = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -1233,65 +1242,206 @@ static int read_line (qse_sed_t* sed)
|
|||||||
if (n == -1) return -1;
|
if (n == -1) return -1;
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
|
if (QSE_STR_LEN(&sed->eio.in.line) == 0) return 0;
|
||||||
|
sed->eio.in.eof = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == QSE_T('\n'))
|
if (qse_str_ccat (&sed->eio.in.line, c) == -1)
|
||||||
{
|
{
|
||||||
|
sed->errnum = QSE_SED_ENOMEM;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c == QSE_T('\n')) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sed->eio.in.num++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t iof)
|
static int flush (qse_sed_t* sed)
|
||||||
|
{
|
||||||
|
qse_size_t pos = 0;
|
||||||
|
qse_ssize_t n;
|
||||||
|
|
||||||
|
while (sed->eio.out.len > 0)
|
||||||
|
{
|
||||||
|
n = sed->eio.out.f (
|
||||||
|
sed, QSE_SED_IO_WRITE,
|
||||||
|
&sed->eio.out.buf[pos], sed->eio.out.len
|
||||||
|
);
|
||||||
|
|
||||||
|
if (n <= -1)
|
||||||
|
{
|
||||||
|
sed->errnum = QSE_SED_EIOUSR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
/* reached the end of file */
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += n;
|
||||||
|
sed->eio.out.len -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_char (qse_sed_t* sed, qse_char_t c)
|
||||||
|
{
|
||||||
|
sed->eio.out.buf[sed->eio.out.len++] = c;
|
||||||
|
if (c == QSE_T('\n') ||
|
||||||
|
sed->eio.out.len >= QSE_COUNTOF(sed->eio.out.buf))
|
||||||
|
{
|
||||||
|
return flush (sed);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_num (qse_sed_t* sed, qse_size_t x)
|
||||||
|
{
|
||||||
|
qse_size_t last = x % 10;
|
||||||
|
qse_size_t y = 0, dig = 0;
|
||||||
|
|
||||||
|
if (x < 0)
|
||||||
|
{
|
||||||
|
if (write_char (sed, QSE_T('-')) == -1) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = x / 10;
|
||||||
|
if (x < 0) x = -x;
|
||||||
|
|
||||||
|
while (x > 0)
|
||||||
|
{
|
||||||
|
y = y * 10 + (x % 10);
|
||||||
|
x = x / 10;
|
||||||
|
dig++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (y > 0)
|
||||||
|
{
|
||||||
|
if (write_char (sed, (y % 10) + QSE_T('0')) == -1) return -1;
|
||||||
|
y = y / 10;
|
||||||
|
dig--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (dig > 0)
|
||||||
|
{
|
||||||
|
dig--;
|
||||||
|
if (write_char (sed, QSE_T('0')) == -1) return -1;
|
||||||
|
}
|
||||||
|
if (last < 0) last = -last;
|
||||||
|
if (write_char (sed, last + QSE_T('0')) == -1) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_address (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd)
|
||||||
|
{
|
||||||
|
switch (cmd->type)
|
||||||
|
{
|
||||||
|
case QSE_SED_CMD_EQ:
|
||||||
|
if (write_num (sed, sed->eio.in.num) == -1) return -1;
|
||||||
|
if (write_char (sed, QSE_T('\n')) == -1) return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_SED_CMD_Q:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_SED_CMD_QQ:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qse_sed_execute (qse_sed_t* sed, qse_sed_iof_t inf, qse_sed_iof_t outf)
|
||||||
{
|
{
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (qse_str_init (&sed->eio.line, QSE_MMGR(sed), 256) == QSE_NULL)
|
sed->eio.out.f = outf;
|
||||||
|
sed->eio.out.eof = 0;
|
||||||
|
sed->eio.out.len = 0;
|
||||||
|
|
||||||
|
sed->eio.in.f = inf;
|
||||||
|
sed->eio.in.eof = 0;
|
||||||
|
sed->eio.in.len = 0;
|
||||||
|
sed->eio.in.pos = 0;
|
||||||
|
sed->eio.in.num = 0;
|
||||||
|
if (qse_str_init (&sed->eio.in.line, QSE_MMGR(sed), 256) == QSE_NULL)
|
||||||
{
|
{
|
||||||
sed->errnum = QSE_SED_ENOMEM;
|
sed->errnum = QSE_SED_ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = iof (sed, QSE_SED_IO_OPEN, QSE_NULL, 0);
|
n = sed->eio.in.f (sed, QSE_SED_IO_OPEN, QSE_NULL, 0);
|
||||||
if (n == 0) goto done; /* EOF reached upon opening a stream */
|
|
||||||
if (n == -1)
|
if (n == -1)
|
||||||
{
|
{
|
||||||
ret = -1;
|
ret = -1;
|
||||||
sed->errnum = QSE_SED_EIOUSR;
|
sed->errnum = QSE_SED_EIOUSR;
|
||||||
goto done;
|
goto done3;
|
||||||
|
}
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
/* EOF reached upon opening an input stream.
|
||||||
|
* no data to process. this is success */
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = sed->eio.out.f (sed, QSE_SED_IO_OPEN, QSE_NULL, 0);
|
||||||
|
if (n == -1)
|
||||||
|
{
|
||||||
|
ret = -1;
|
||||||
|
sed->errnum = QSE_SED_EIOUSR;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
/* still don't know if we will write something.
|
||||||
|
* just mark EOF on the output stream and continue */
|
||||||
|
sed->eio.out.eof = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sed->eio.f = iof;
|
|
||||||
sed->eio.len = 0;
|
|
||||||
sed->eio.pos = 0;
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
qse_sed_cmd_t* c;
|
||||||
|
|
||||||
|
if (read_line (sed) == -1) { ret = -1; goto done; }
|
||||||
|
|
||||||
|
c = sed->cmd.buf;
|
||||||
|
while (c < sed->cmd.cur)
|
||||||
|
{
|
||||||
|
n = test_address (sed, c);
|
||||||
|
if (n <= -1) { ret = -1; goto done; }
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exec_cmd (sed, c) == -1) { ret = -1; goto done; }
|
||||||
|
|
||||||
|
/* TODO: if exec_cmd jumped change c.... */
|
||||||
|
c++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
iof (sed, QSE_SED_IO_CLOSE, QSE_NULL, 0);
|
sed->eio.out.f (sed, QSE_SED_IO_CLOSE, QSE_NULL, 0);
|
||||||
qse_str_fini (&sed->eio.line);
|
done2:
|
||||||
|
sed->eio.in.f (sed, QSE_SED_IO_CLOSE, QSE_NULL, 0);
|
||||||
|
done3:
|
||||||
|
qse_str_fini (&sed->eio.in.line);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#if 0
|
|
||||||
qse_sed_cmd_t* c = sed->cmd.buf;
|
|
||||||
|
|
||||||
while (c < sed->cmd.cur)
|
|
||||||
{
|
|
||||||
qse_printf (QSE_T(">>> %c\n"), c->type);
|
|
||||||
|
|
||||||
switch (c->type)
|
|
||||||
{
|
|
||||||
case QSE_CMD_
|
|
||||||
}
|
|
||||||
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,51 @@
|
|||||||
#include <qse/utl/main.h>
|
#include <qse/utl/main.h>
|
||||||
#include <qse/cmn/str.h>
|
#include <qse/cmn/str.h>
|
||||||
|
|
||||||
static qse_ssize_t io (
|
static qse_ssize_t in (
|
||||||
qse_sed_t* sed, qse_sed_io_cmd_t cmd, qse_char_t* buf, qse_size_t len)
|
qse_sed_t* sed, qse_sed_io_cmd_t cmd, qse_char_t* buf, qse_size_t len)
|
||||||
{
|
{
|
||||||
return 0;
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case QSE_SED_IO_OPEN:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case QSE_SED_IO_CLOSE:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case QSE_SED_IO_READ:
|
||||||
|
{
|
||||||
|
qse_cint_t c;
|
||||||
|
c = qse_fgetc (QSE_STDIN);
|
||||||
|
if (c == QSE_CHAR_EOF) return 0;
|
||||||
|
buf[0] = c;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static qse_ssize_t out (
|
||||||
|
qse_sed_t* sed, qse_sed_io_cmd_t cmd, qse_char_t* buf, qse_size_t len)
|
||||||
|
{
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case QSE_SED_IO_OPEN:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case QSE_SED_IO_CLOSE:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case QSE_SED_IO_WRITE:
|
||||||
|
{
|
||||||
|
qse_size_t i = 0;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
qse_fputc (buf[i], QSE_STDOUT);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sed_main (int argc, qse_char_t* argv[])
|
int sed_main (int argc, qse_char_t* argv[])
|
||||||
@ -60,8 +101,13 @@ int sed_main (int argc, qse_char_t* argv[])
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qse_sed_execute (sed, io) == -1)
|
if (qse_sed_execute (sed, in, out) == -1)
|
||||||
{
|
{
|
||||||
|
qse_fprintf (QSE_STDERR,
|
||||||
|
QSE_T("cannot execute - %s\n"),
|
||||||
|
qse_sed_geterrmsg(sed)
|
||||||
|
);
|
||||||
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user