2022-03-31 17:14:52 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in the
|
|
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
|
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "sed-prv.h"
|
|
|
|
#include "hawk-prv.h"
|
|
|
|
#include "hawk-std.h"
|
|
|
|
|
|
|
|
typedef struct xtn_in_t xtn_in_t;
|
|
|
|
struct xtn_in_t
|
|
|
|
{
|
|
|
|
hawk_sed_iostd_t* ptr;
|
|
|
|
hawk_sed_iostd_t* cur;
|
2022-04-05 10:46:00 +00:00
|
|
|
hawk_oow_t mempos;
|
2022-03-31 17:14:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct xtn_out_t xtn_out_t;
|
|
|
|
struct xtn_out_t
|
|
|
|
{
|
|
|
|
hawk_sed_iostd_t* ptr;
|
2022-04-05 10:46:00 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
hawk_becs_t* be;
|
|
|
|
hawk_uecs_t* ue;
|
|
|
|
} memstr;
|
2022-03-31 17:14:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct xtn_t xtn_t;
|
|
|
|
struct xtn_t
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
xtn_in_t in;
|
|
|
|
hawk_ooch_t last;
|
|
|
|
int newline_squeezed;
|
|
|
|
} s;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
xtn_in_t in;
|
|
|
|
xtn_out_t out;
|
|
|
|
} e;
|
|
|
|
|
|
|
|
hawk_link_t* sio_names;
|
|
|
|
};
|
|
|
|
|
|
|
|
#if defined(HAWK_HAVE_INLINE)
|
|
|
|
static HAWK_INLINE xtn_t* GET_XTN(hawk_sed_t* sed) { return (xtn_t*)((hawk_uint8_t*)hawk_sed_getxtn(sed) - HAWK_SIZEOF(xtn_t)); }
|
|
|
|
#else
|
|
|
|
#define GET_XTN(sed) ((xtn_t*)((hawk_uint8_t*)hawk_sed_getxtn(sed) - HAWK_SIZEOF(xtn_t)))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int int_to_str (hawk_oow_t val, hawk_ooch_t* buf, hawk_oow_t buflen)
|
|
|
|
{
|
|
|
|
hawk_oow_t t;
|
|
|
|
hawk_oow_t rlen = 0;
|
|
|
|
|
|
|
|
t = val;
|
|
|
|
if (t == 0) rlen++;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* non-zero values */
|
|
|
|
if (t < 0) { t = -t; rlen++; }
|
|
|
|
while (t > 0) { rlen++; t /= 10; }
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rlen >= buflen) return -1; /* buffer too small */
|
|
|
|
|
|
|
|
buf[rlen] = HAWK_T('\0');
|
|
|
|
|
|
|
|
t = val;
|
|
|
|
if (t == 0) buf[0] = HAWK_T('0');
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (t < 0) t = -t;
|
|
|
|
|
|
|
|
/* fill in the buffer with digits */
|
|
|
|
while (t > 0)
|
|
|
|
{
|
|
|
|
buf[--rlen] = (hawk_ooch_t)(t % 10) + HAWK_T('0');
|
|
|
|
t /= 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* insert the negative sign if necessary */
|
|
|
|
if (val < 0) buf[--rlen] = HAWK_T('-');
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
hawk_sed_t* hawk_sed_openstd (hawk_oow_t xtnsize, hawk_errnum_t* errnum)
|
|
|
|
{
|
|
|
|
return hawk_sed_openstdwithmmgr (hawk_get_sys_mmgr(), xtnsize, hawk_get_cmgr_by_id(HAWK_CMGR_UTF8), errnum);
|
|
|
|
}
|
|
|
|
|
|
|
|
hawk_sed_t* hawk_sed_openstdwithmmgr (hawk_mmgr_t* mmgr, hawk_oow_t xtnsize, hawk_cmgr_t* cmgr, hawk_errnum_t* errnum)
|
|
|
|
{
|
|
|
|
hawk_sed_t* sed;
|
|
|
|
|
|
|
|
if (!mmgr) mmgr = hawk_get_sys_mmgr();
|
|
|
|
if (!cmgr) cmgr = hawk_get_cmgr_by_id(HAWK_CMGR_UTF8);
|
|
|
|
|
|
|
|
sed = hawk_sed_open(mmgr, HAWK_SIZEOF(xtn_t) + xtnsize, cmgr, errnum);
|
|
|
|
if (!sed) return HAWK_NULL;
|
|
|
|
|
|
|
|
sed->_instsize += HAWK_SIZEOF(xtn_t);
|
|
|
|
|
|
|
|
return sed;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int verify_iostd_in (hawk_sed_t* sed, hawk_sed_iostd_t in[])
|
|
|
|
{
|
|
|
|
hawk_oow_t i;
|
|
|
|
|
|
|
|
if (in[0].type == HAWK_SED_IOSTD_NULL)
|
|
|
|
{
|
|
|
|
/* if 'in' is specified, it must contains at least one
|
|
|
|
* valid entry */
|
2022-04-05 10:46:00 +00:00
|
|
|
hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_EINVAL, "no input handler provided");
|
2022-03-31 17:14:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; in[i].type != HAWK_SED_IOSTD_NULL; i++)
|
|
|
|
{
|
|
|
|
if (in[i].type != HAWK_SED_IOSTD_FILE &&
|
|
|
|
in[i].type != HAWK_SED_IOSTD_FILEB &&
|
|
|
|
in[i].type != HAWK_SED_IOSTD_FILEU &&
|
2022-04-05 10:46:00 +00:00
|
|
|
in[i].type != HAWK_SED_IOSTD_OOCS &&
|
|
|
|
in[i].type != HAWK_SED_IOSTD_BCS &&
|
|
|
|
in[i].type != HAWK_SED_IOSTD_UCS &&
|
2022-03-31 17:14:52 +00:00
|
|
|
in[i].type != HAWK_SED_IOSTD_SIO)
|
|
|
|
{
|
2022-04-05 10:46:00 +00:00
|
|
|
hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_EINVAL, "unsupported input type provided - handler %d type %d", i, in[i].type);
|
2022-03-31 17:14:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static hawk_sio_t* open_sio_file (hawk_sed_t* sed, const hawk_ooch_t* file, int flags)
|
|
|
|
{
|
|
|
|
hawk_sio_t* sio;
|
|
|
|
|
|
|
|
sio = hawk_sio_open(hawk_sed_getgem(sed), 0, file, flags);
|
2022-04-05 10:46:00 +00:00
|
|
|
if (sio == HAWK_NULL)
|
2022-03-31 17:14:52 +00:00
|
|
|
{
|
2022-04-05 10:46:00 +00:00
|
|
|
const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed);
|
|
|
|
hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "unable to open %js - %js", file, bem);
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
|
|
|
return sio;
|
|
|
|
}
|
|
|
|
|
|
|
|
static hawk_oocs_t sio_std_names[] =
|
|
|
|
{
|
|
|
|
{ (hawk_ooch_t*)HAWK_T("stdin"), 5 },
|
|
|
|
{ (hawk_ooch_t*)HAWK_T("stdout"), 6 },
|
|
|
|
{ (hawk_ooch_t*)HAWK_T("stderr"), 6 }
|
|
|
|
};
|
|
|
|
|
|
|
|
static hawk_ooch_t* add_sio_name_with_uchars (hawk_sed_t* sed, const hawk_uch_t* ptr, hawk_oow_t len)
|
|
|
|
{
|
|
|
|
xtn_t* xtn = GET_XTN(sed);
|
|
|
|
hawk_link_t* link;
|
|
|
|
|
|
|
|
/* TODO: duplication check? */
|
|
|
|
|
|
|
|
#if defined(HAWK_OOCH_IS_UCH)
|
|
|
|
link = (hawk_link_t*)hawk_sed_callocmem(sed, HAWK_SIZEOF(*link) + HAWK_SIZEOF(hawk_uch_t) * (len + 1));
|
|
|
|
if (!link) return HAWK_NULL;
|
|
|
|
|
|
|
|
hawk_copy_uchars_to_ucstr_unlimited ((hawk_uch_t*)(link + 1), ptr, len);
|
|
|
|
#else
|
|
|
|
hawk_oow_t bcslen, ucslen;
|
|
|
|
|
|
|
|
ucslen = len;
|
|
|
|
if (hawk_gem_convutobchars(hawk_sed_getgem(sed), ptr, &ucslen, HAWK_NULL, &bcslen) <= -1) return HAWK_NULL;
|
|
|
|
|
|
|
|
link = (hawk_link_t*)hawk_sed_callocmem(sed, HAWK_SIZEOF(*link) + HAWK_SIZEOF(hawk_bch_t) * (bcslen + 1));
|
|
|
|
if (!link) return HAWK_NULL;
|
|
|
|
|
|
|
|
ucslen = len;
|
|
|
|
bcslen = bcslen + 1;
|
|
|
|
hawk_gem_convutobchars (hawk_sed_getgem(sed), ptr, &ucslen, (hawk_bch_t*)(link + 1), &bcslen);
|
|
|
|
((hawk_bch_t*)(link + 1))[bcslen] = '\0';
|
|
|
|
#endif
|
|
|
|
|
|
|
|
link->link = xtn->sio_names;
|
|
|
|
xtn->sio_names = link;
|
|
|
|
|
|
|
|
return (hawk_ooch_t*)(link + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static hawk_ooch_t* add_sio_name_with_bchars (hawk_sed_t* sed, const hawk_bch_t* ptr, hawk_oow_t len)
|
|
|
|
{
|
|
|
|
xtn_t* xtn = GET_XTN(sed);
|
|
|
|
hawk_link_t* link;
|
|
|
|
|
|
|
|
/* TODO: duplication check? */
|
|
|
|
|
|
|
|
#if defined(HAWK_OOCH_IS_UCH)
|
|
|
|
hawk_oow_t bcslen, ucslen;
|
|
|
|
|
|
|
|
bcslen = len;
|
|
|
|
if (hawk_gem_convbtouchars(hawk_sed_getgem(sed), ptr, &bcslen, HAWK_NULL, &ucslen, 0) <= -1) return HAWK_NULL;
|
|
|
|
|
|
|
|
link = (hawk_link_t*)hawk_sed_callocmem(sed, HAWK_SIZEOF(*link) + HAWK_SIZEOF(hawk_uch_t) * (ucslen + 1));
|
|
|
|
if (!link) return HAWK_NULL;
|
|
|
|
|
|
|
|
bcslen = len;
|
|
|
|
ucslen = ucslen + 1;
|
|
|
|
hawk_gem_convbtouchars (hawk_sed_getgem(sed), ptr, &bcslen, (hawk_uch_t*)(link + 1), &ucslen, 0);
|
|
|
|
((hawk_uch_t*)(link + 1))[ucslen] = '\0';
|
|
|
|
|
|
|
|
#else
|
|
|
|
link = (hawk_link_t*)hawk_sed_callocmem(sed, HAWK_SIZEOF(*link) + HAWK_SIZEOF(hawk_bch_t) * (len + 1));
|
|
|
|
if (!link) return HAWK_NULL;
|
|
|
|
|
|
|
|
hawk_copy_bchars_to_bcstr_unlimited ((hawk_bch_t*)(link + 1), ptr, len);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
link->link = xtn->sio_names;
|
|
|
|
xtn->sio_names = link;
|
|
|
|
|
|
|
|
return (hawk_ooch_t*)(link + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void clear_sio_names (hawk_sed_t* sed)
|
|
|
|
{
|
|
|
|
xtn_t* xtn = GET_XTN(sed);
|
|
|
|
hawk_link_t* cur;
|
|
|
|
|
|
|
|
while (xtn->sio_names)
|
|
|
|
{
|
|
|
|
cur = xtn->sio_names;
|
|
|
|
xtn->sio_names = cur->link;
|
|
|
|
hawk_sed_freemem (sed, cur);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static hawk_sio_t* open_sio_std (hawk_sed_t* sed, hawk_sio_std_t std, int flags)
|
|
|
|
{
|
|
|
|
hawk_sio_t* sio;
|
|
|
|
|
|
|
|
sio = hawk_sio_openstd(hawk_sed_getgem(sed), 0, std, flags);
|
2022-06-09 13:53:01 +00:00
|
|
|
if (sio == HAWK_NULL)
|
|
|
|
{
|
|
|
|
const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed);
|
|
|
|
hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "unable to open %js - %js", &sio_std_names[std], bem);
|
|
|
|
}
|
2022-03-31 17:14:52 +00:00
|
|
|
return sio;
|
|
|
|
}
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
static void set_eiofil_for_iostd (hawk_sed_t* sed, hawk_sed_iostd_t* io)
|
|
|
|
{
|
2022-06-09 13:53:01 +00:00
|
|
|
const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed);
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
HAWK_ASSERT (io->type == HAWK_SED_IOSTD_FILE || io->type == HAWK_SED_IOSTD_FILEB || io->type == HAWK_SED_IOSTD_FILEU);
|
|
|
|
|
|
|
|
if (io->u.file.path) /* file, fileb, fileu are union members. checking file.path regardless of io->type must be safe */
|
|
|
|
{
|
|
|
|
switch (io->type)
|
|
|
|
{
|
|
|
|
#if defined(HAWK_OOCH_IS_BCH)
|
|
|
|
case HAWK_SED_IOSTD_FILE:
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_FILEB:
|
2022-06-09 13:53:01 +00:00
|
|
|
hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "I/O error with file '%hs' - %js", io->u.fileb.path, bem);
|
2022-04-05 10:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
#if defined(HAWK_OOCH_IS_UCH)
|
|
|
|
case HAWK_SED_IOSTD_FILE:
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_FILEU:
|
2022-06-09 13:53:01 +00:00
|
|
|
hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "I/O error with file '%ls' - %js", io->u.fileu.path, bem);
|
2022-04-05 10:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
HAWK_ASSERT (!"should never happen - unknown file I/O type");
|
|
|
|
hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINVAL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-06-09 13:53:01 +00:00
|
|
|
hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "I/O error with file '%js' - %js", &sio_std_names[HAWK_SIO_STDIN], bem);
|
2022-04-05 10:46:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-03-31 17:14:52 +00:00
|
|
|
static void close_main_stream (hawk_sed_t* sed, hawk_sed_io_arg_t* arg, hawk_sed_iostd_t* io)
|
|
|
|
{
|
|
|
|
switch (io->type)
|
|
|
|
{
|
|
|
|
case HAWK_SED_IOSTD_FILE:
|
|
|
|
case HAWK_SED_IOSTD_FILEB:
|
|
|
|
case HAWK_SED_IOSTD_FILEU:
|
|
|
|
hawk_sio_close (arg->handle);
|
|
|
|
break;
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
case HAWK_SED_IOSTD_OOCS:
|
|
|
|
case HAWK_SED_IOSTD_BCS:
|
|
|
|
case HAWK_SED_IOSTD_UCS:
|
|
|
|
/* for input, there is nothing to do here.
|
|
|
|
* for output, closing xtn->e.out.memstr is required. but put it to hawk_awk_execstd().
|
2022-03-31 17:14:52 +00:00
|
|
|
*/
|
|
|
|
break;
|
|
|
|
|
|
|
|
case HAWK_SED_IOSTD_SIO:
|
|
|
|
/* nothing to do */
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/* do nothing */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static int open_input_stream (hawk_sed_t* sed, hawk_sed_io_arg_t* arg, hawk_sed_iostd_t* io, xtn_in_t* base)
|
|
|
|
{
|
|
|
|
xtn_t* xtn = GET_XTN(sed);
|
|
|
|
|
|
|
|
HAWK_ASSERT (io != HAWK_NULL);
|
|
|
|
switch (io->type)
|
|
|
|
{
|
|
|
|
#if defined(HAWK_OOCH_IS_BCH)
|
|
|
|
case HAWK_SED_IOSTD_FILE:
|
|
|
|
HAWK_ASSERT (&io->u.fileb.path == &io->u.file.path);
|
|
|
|
HAWK_ASSERT (&io->u.fileb.cmgr == &io->u.file.cmgr);
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_FILEB:
|
|
|
|
{
|
|
|
|
hawk_sio_t* sio;
|
|
|
|
hawk_ooch_t* path;
|
|
|
|
|
|
|
|
if (io->u.fileb.path == HAWK_NULL ||
|
|
|
|
(io->u.fileb.path[0] == '-' && io->u.fileb.path[1] == '\0'))
|
|
|
|
{
|
|
|
|
sio = open_sio_std(sed, HAWK_SIO_STDIN, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
path = add_sio_name_with_bchars(sed, io->u.fileb.path, hawk_count_bcstr(io->u.fileb.path));
|
|
|
|
if (path == HAWK_NULL) return -1;
|
|
|
|
sio = open_sio_file(sed, path, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR);
|
|
|
|
}
|
|
|
|
if (sio == HAWK_NULL) return -1;
|
|
|
|
|
|
|
|
if (io->u.fileb.cmgr) hawk_sio_setcmgr (sio, io->u.fileb.cmgr);
|
|
|
|
arg->handle = sio;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(HAWK_OOCH_IS_UCH)
|
|
|
|
case HAWK_SED_IOSTD_FILE:
|
|
|
|
HAWK_ASSERT (&io->u.fileu.path == &io->u.file.path);
|
|
|
|
HAWK_ASSERT (&io->u.fileu.cmgr == &io->u.file.cmgr);
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_FILEU:
|
|
|
|
{
|
|
|
|
hawk_sio_t* sio;
|
|
|
|
hawk_ooch_t* path;
|
|
|
|
|
|
|
|
if (io->u.fileu.path == HAWK_NULL ||
|
|
|
|
(io->u.fileu.path[0] == '-' && io->u.fileu.path[1] == '\0'))
|
|
|
|
{
|
|
|
|
sio = open_sio_std(sed, HAWK_SIO_STDIN, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
path = add_sio_name_with_uchars(sed, io->u.fileu.path, hawk_count_ucstr(io->u.fileu.path));
|
|
|
|
if (path == HAWK_NULL) return -1;
|
|
|
|
sio = open_sio_file(sed, path, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR);
|
|
|
|
}
|
|
|
|
if (sio == HAWK_NULL) return -1;
|
|
|
|
|
|
|
|
if (io->u.fileu.cmgr) hawk_sio_setcmgr (sio, io->u.fileu.cmgr);
|
|
|
|
arg->handle = sio;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
case HAWK_SED_IOSTD_OOCS:
|
|
|
|
case HAWK_SED_IOSTD_BCS:
|
|
|
|
case HAWK_SED_IOSTD_UCS:
|
2022-03-31 17:14:52 +00:00
|
|
|
/* don't store anything to arg->handle */
|
|
|
|
base->mempos = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case HAWK_SED_IOSTD_SIO:
|
|
|
|
arg->handle = io->u.sio;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
HAWK_ASSERT (!"should never happen - io-type must be one of SIO,FILE,FILEB,FILEU,STR");
|
|
|
|
hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINTERN);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (base == &xtn->s.in)
|
|
|
|
{
|
|
|
|
/* reset script location */
|
2022-04-05 10:46:00 +00:00
|
|
|
switch (io->type)
|
2022-03-31 17:14:52 +00:00
|
|
|
{
|
2022-04-05 10:46:00 +00:00
|
|
|
case HAWK_SED_IOSTD_FILE:
|
|
|
|
if (io->u.fileb.path)
|
|
|
|
{
|
|
|
|
hawk_sed_setcompid (sed, io->u.file.path);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
compid_stdin:
|
|
|
|
hawk_sed_setcompid (sed, sio_std_names[HAWK_SIO_STDIN].ptr);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case HAWK_SED_IOSTD_FILEB:
|
|
|
|
if (!io->u.fileb.path) goto compid_stdin;
|
|
|
|
hawk_sed_setcompidwithbcstr (sed, io->u.fileb.path);
|
|
|
|
break;
|
2022-03-31 17:14:52 +00:00
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
case HAWK_SED_IOSTD_FILEU:
|
|
|
|
if (!io->u.fileu.path) goto compid_stdin;
|
|
|
|
hawk_sed_setcompid (sed, sio_std_names[HAWK_SIO_STDIN].ptr);
|
|
|
|
break;
|
2022-03-31 17:14:52 +00:00
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
hawk_ooch_t buf[64];
|
|
|
|
|
|
|
|
/* format an identifier to be something like M#1, S#5 */
|
|
|
|
buf[0] = (io->type == HAWK_SED_IOSTD_OOCS ||
|
|
|
|
io->type == HAWK_SED_IOSTD_BCS ||
|
|
|
|
io->type == HAWK_SED_IOSTD_UCS)? HAWK_T('M'): HAWK_T('S');
|
|
|
|
buf[1] = HAWK_T('#');
|
|
|
|
int_to_str (io - xtn->s.in.ptr, &buf[2], HAWK_COUNTOF(buf) - 2);
|
|
|
|
|
|
|
|
/* don't care about failure int_to_str() though it's not
|
|
|
|
* likely to happen */
|
|
|
|
hawk_sed_setcompid (sed, buf);
|
|
|
|
break;
|
|
|
|
}
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
|
|
|
sed->src.loc.line = 1;
|
|
|
|
sed->src.loc.colm = 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int open_output_stream (hawk_sed_t* sed, hawk_sed_io_arg_t* arg, hawk_sed_iostd_t* io)
|
|
|
|
{
|
|
|
|
xtn_t* xtn = GET_XTN(sed);
|
|
|
|
|
|
|
|
HAWK_ASSERT (io != HAWK_NULL);
|
|
|
|
switch (io->type)
|
|
|
|
{
|
|
|
|
#if defined(HAWK_OOCH_IS_BCH)
|
|
|
|
case HAWK_SED_IOSTD_FILE:
|
|
|
|
HAWK_ASSERT (&io->u.fileb.path == &io->u.file.path);
|
|
|
|
HAWK_ASSERT (&io->u.fileb.cmgr == &io->u.file.cmgr);
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_FILEB:
|
|
|
|
{
|
|
|
|
hawk_sio_t* sio;
|
|
|
|
hawk_ooch_t* path;
|
|
|
|
|
|
|
|
if (io->u.fileb.path == HAWK_NULL ||
|
|
|
|
(io->u.fileb.path[0] == HAWK_T('-') && io->u.fileb.path[1] == HAWK_T('\0')))
|
|
|
|
{
|
|
|
|
sio = open_sio_std(
|
|
|
|
sed, HAWK_SIO_STDOUT,
|
|
|
|
HAWK_SIO_WRITE |
|
|
|
|
HAWK_SIO_CREATE |
|
|
|
|
HAWK_SIO_TRUNCATE |
|
|
|
|
HAWK_SIO_IGNOREECERR |
|
|
|
|
HAWK_SIO_LINEBREAK
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
path = add_sio_name_with_bchars(sed, io->u.fileb.path, hawk_count_bcstr(io->u.fileb.path));
|
|
|
|
if (path == HAWK_NULL) return -1;
|
|
|
|
sio = open_sio_file(
|
|
|
|
sed, path,
|
|
|
|
HAWK_SIO_WRITE |
|
|
|
|
HAWK_SIO_CREATE |
|
|
|
|
HAWK_SIO_TRUNCATE |
|
|
|
|
HAWK_SIO_IGNOREECERR
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (sio == HAWK_NULL) return -1;
|
|
|
|
if (io->u.fileb.cmgr) hawk_sio_setcmgr (sio, io->u.fileb.cmgr);
|
|
|
|
arg->handle = sio;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(HAWK_OOCH_IS_UCH)
|
|
|
|
case HAWK_SED_IOSTD_FILE:
|
|
|
|
HAWK_ASSERT (&io->u.fileu.path == &io->u.file.path);
|
|
|
|
HAWK_ASSERT (&io->u.fileu.cmgr == &io->u.file.cmgr);
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_FILEU:
|
|
|
|
{
|
|
|
|
hawk_sio_t* sio;
|
|
|
|
hawk_ooch_t* path;
|
|
|
|
|
|
|
|
if (io->u.fileu.path == HAWK_NULL ||
|
|
|
|
(io->u.fileu.path[0] == HAWK_T('-') && io->u.fileu.path[1] == HAWK_T('\0')))
|
|
|
|
{
|
|
|
|
sio = open_sio_std(
|
|
|
|
sed, HAWK_SIO_STDOUT,
|
|
|
|
HAWK_SIO_WRITE |
|
|
|
|
HAWK_SIO_CREATE |
|
|
|
|
HAWK_SIO_TRUNCATE |
|
|
|
|
HAWK_SIO_IGNOREECERR |
|
|
|
|
HAWK_SIO_LINEBREAK
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
path = add_sio_name_with_uchars(sed, io->u.fileu.path, hawk_count_ucstr(io->u.fileu.path));
|
|
|
|
if (path == HAWK_NULL) return -1;
|
|
|
|
sio = open_sio_file(
|
|
|
|
sed, path,
|
|
|
|
HAWK_SIO_WRITE |
|
|
|
|
HAWK_SIO_CREATE |
|
|
|
|
HAWK_SIO_TRUNCATE |
|
|
|
|
HAWK_SIO_IGNOREECERR
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (sio == HAWK_NULL) return -1;
|
|
|
|
if (io->u.fileu.cmgr) hawk_sio_setcmgr (sio, io->u.fileu.cmgr);
|
|
|
|
arg->handle = sio;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
#if defined(HAWK_OOCH_IS_BCH)
|
|
|
|
case HAWK_SED_IOSTD_OOCS:
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_BCS:
|
|
|
|
xtn->e.out.memstr.be = hawk_becs_open(hawk_sed_getgem(sed), 0, 512);
|
|
|
|
if (xtn->e.out.memstr.be == HAWK_NULL) return -1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
#if defined(HAWK_OOCH_IS_UCH)
|
|
|
|
case HAWK_SED_IOSTD_OOCS:
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_UCS:
|
2022-03-31 17:14:52 +00:00
|
|
|
/* don't store anything to arg->handle */
|
2022-04-05 10:46:00 +00:00
|
|
|
xtn->e.out.memstr.ue = hawk_uecs_open(hawk_sed_getgem(sed), 0, 512);
|
|
|
|
if (xtn->e.out.memstr.ue == HAWK_NULL) return -1;
|
2022-03-31 17:14:52 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case HAWK_SED_IOSTD_SIO:
|
|
|
|
arg->handle = io->u.sio;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
HAWK_ASSERT (!"should never happen - io-type must be one of SIO,FILE,FILEB,FILEU,STR");
|
|
|
|
hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINTERN);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
|
2022-03-31 17:14:52 +00:00
|
|
|
static hawk_ooi_t read_input_stream (hawk_sed_t* sed, hawk_sed_io_arg_t* arg, hawk_ooch_t* buf, hawk_oow_t len, xtn_in_t* base)
|
|
|
|
{
|
|
|
|
xtn_t* xtn = GET_XTN(sed);
|
|
|
|
hawk_sed_iostd_t* io, * next;
|
|
|
|
void* old, * new;
|
|
|
|
hawk_ooi_t n = 0;
|
|
|
|
|
|
|
|
if (len > HAWK_TYPE_MAX(hawk_ooi_t)) len = HAWK_TYPE_MAX(hawk_ooi_t);
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
io = base->cur;
|
|
|
|
|
|
|
|
if (base == &xtn->s.in && xtn->s.newline_squeezed)
|
|
|
|
{
|
|
|
|
xtn->s.newline_squeezed = 0;
|
|
|
|
goto open_next;
|
|
|
|
}
|
|
|
|
|
|
|
|
HAWK_ASSERT (io != HAWK_NULL);
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
if (io->type == HAWK_SED_IOSTD_OOCS)
|
2022-03-31 17:14:52 +00:00
|
|
|
{
|
2022-04-05 10:46:00 +00:00
|
|
|
iostd_oocs:
|
2022-03-31 17:14:52 +00:00
|
|
|
n = 0;
|
2022-04-05 10:46:00 +00:00
|
|
|
while (base->mempos < io->u.oocs.len && n < len)
|
|
|
|
buf[n++] = io->u.oocs.ptr[base->mempos++];
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
2022-04-05 10:46:00 +00:00
|
|
|
else if (io->type == HAWK_SED_IOSTD_BCS)
|
|
|
|
{
|
|
|
|
#if defined(HAWK_OOCH_IS_BCH)
|
|
|
|
goto iostd_oocs;
|
|
|
|
#else
|
|
|
|
int m;
|
|
|
|
hawk_oow_t mbslen, wcslen;
|
|
|
|
|
|
|
|
mbslen = io->u.bcs.len - base->mempos;
|
|
|
|
wcslen = len;
|
|
|
|
if ((m = hawk_conv_bchars_to_uchars_with_cmgr(&io->u.bcs.ptr[base->mempos], &mbslen, buf, &wcslen, hawk_sed_getcmgr(sed), 0)) <= -1 && m != -2)
|
|
|
|
{
|
|
|
|
hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EECERR);
|
|
|
|
n = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
base->mempos += mbslen;
|
|
|
|
n = wcslen;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (io->type == HAWK_SED_IOSTD_UCS)
|
|
|
|
{
|
|
|
|
#if defined(HAWK_OOCH_IS_UCH)
|
|
|
|
goto iostd_oocs;
|
|
|
|
#else
|
|
|
|
int m;
|
|
|
|
hawk_oow_t mbslen, wcslen;
|
|
|
|
|
|
|
|
wcslen = io->u.ucs.len - base->mempos;
|
|
|
|
mbslen = len;
|
|
|
|
if ((m = hawk_conv_uchars_to_bchars_with_cmgr(&io->u.ucs.ptr[base->mempos], &wcslen, buf, &mbslen, hawk_sed_getcmgr(sed))) <= -1 && m != -2)
|
|
|
|
{
|
|
|
|
hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EECERR);
|
|
|
|
n = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
base->mempos += mbslen;
|
|
|
|
n = mbslen;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
2022-03-31 17:14:52 +00:00
|
|
|
{
|
2022-04-05 10:46:00 +00:00
|
|
|
n = hawk_sio_getoochars(arg->handle, buf, len);
|
2022-03-31 17:14:52 +00:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
2022-04-05 10:46:00 +00:00
|
|
|
set_eiofil_for_iostd (sed, io);
|
|
|
|
break;
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
2022-04-05 10:46:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (n != 0)
|
|
|
|
{
|
|
|
|
if (base == &xtn->s.in)
|
2022-03-31 17:14:52 +00:00
|
|
|
{
|
2022-04-05 10:46:00 +00:00
|
|
|
xtn->s.last = buf[n - 1];
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2022-04-05 10:46:00 +00:00
|
|
|
|
2022-03-31 17:14:52 +00:00
|
|
|
/* ============================================= */
|
|
|
|
/* == end of file on the current input stream == */
|
|
|
|
/* ============================================= */
|
|
|
|
|
|
|
|
if (base == &xtn->s.in && xtn->s.last != HAWK_T('\n'))
|
|
|
|
{
|
|
|
|
/* TODO: different line termination convension */
|
|
|
|
buf[0] = HAWK_T('\n');
|
|
|
|
n = 1;
|
|
|
|
xtn->s.newline_squeezed = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
open_next:
|
|
|
|
next = base->cur + 1;
|
|
|
|
if (next->type == HAWK_SED_IOSTD_NULL)
|
|
|
|
{
|
2022-04-05 10:46:00 +00:00
|
|
|
/* no next stream available - return 0 */
|
2022-03-31 17:14:52 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
old = arg->handle;
|
|
|
|
|
|
|
|
/* try to open the next input stream */
|
|
|
|
if (open_input_stream(sed, arg, next, base) <= -1)
|
|
|
|
{
|
|
|
|
/* failed to open the next input stream */
|
2022-04-05 10:46:00 +00:00
|
|
|
set_eiofil_for_iostd (sed, next);
|
2022-03-31 17:14:52 +00:00
|
|
|
n = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* successfuly opened the next input stream */
|
|
|
|
new = arg->handle;
|
|
|
|
|
|
|
|
arg->handle = old;
|
|
|
|
|
|
|
|
/* close the previous stream */
|
|
|
|
close_main_stream (sed, arg, io);
|
|
|
|
|
|
|
|
arg->handle = new;
|
|
|
|
|
|
|
|
base->cur++;
|
|
|
|
}
|
|
|
|
while (1);
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static hawk_ooi_t s_in (hawk_sed_t* sed, hawk_sed_io_cmd_t cmd, hawk_sed_io_arg_t* arg, hawk_ooch_t* buf, hawk_oow_t len)
|
|
|
|
{
|
|
|
|
xtn_t* xtn = GET_XTN(sed);
|
|
|
|
|
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case HAWK_SED_IO_OPEN:
|
|
|
|
{
|
|
|
|
if (open_input_stream(sed, arg, xtn->s.in.cur, &xtn->s.in) <= -1) return -1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
case HAWK_SED_IO_CLOSE:
|
|
|
|
{
|
|
|
|
close_main_stream (sed, arg, xtn->s.in.cur);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
case HAWK_SED_IO_READ:
|
|
|
|
{
|
|
|
|
return read_input_stream(sed, arg, buf, len, &xtn->s.in);
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
HAWK_ASSERT (!"should never happen - cmd must be one of OPEN,CLOSE,READ");
|
|
|
|
hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINTERN);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static hawk_ooi_t x_in (hawk_sed_t* sed, hawk_sed_io_cmd_t cmd, hawk_sed_io_arg_t* arg, hawk_ooch_t* buf, hawk_oow_t len)
|
|
|
|
{
|
|
|
|
hawk_sio_t* sio;
|
|
|
|
xtn_t* xtn = GET_XTN(sed);
|
|
|
|
|
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case HAWK_SED_IO_OPEN:
|
|
|
|
{
|
|
|
|
if (arg->path == HAWK_NULL)
|
|
|
|
{
|
2022-04-05 14:26:21 +00:00
|
|
|
/* main data stream */
|
2022-03-31 17:14:52 +00:00
|
|
|
if (xtn->e.in.ptr == HAWK_NULL)
|
|
|
|
{
|
2022-04-05 14:26:21 +00:00
|
|
|
/* HAWK_NULL passed into hawk_sed_exec() for input. open stdin */
|
2022-03-31 17:14:52 +00:00
|
|
|
sio = open_sio_std(sed, HAWK_SIO_STDIN, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR);
|
|
|
|
if (sio == HAWK_NULL) return -1;
|
|
|
|
arg->handle = sio;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-04-05 14:26:21 +00:00
|
|
|
/* use the input stream handlers passed to hawk_sed_exec() */
|
2022-03-31 17:14:52 +00:00
|
|
|
if (open_input_stream(sed, arg, xtn->e.in.cur, &xtn->e.in) <= -1) return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-04-05 14:26:21 +00:00
|
|
|
/* sub-stream */
|
2022-03-31 17:14:52 +00:00
|
|
|
sio = open_sio_file(sed, arg->path, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR);
|
|
|
|
if (sio == HAWK_NULL) return -1;
|
|
|
|
arg->handle = sio;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
case HAWK_SED_IO_CLOSE:
|
|
|
|
{
|
|
|
|
if (arg->path == HAWK_NULL)
|
|
|
|
{
|
|
|
|
/* main data stream */
|
|
|
|
if (xtn->e.in.ptr == HAWK_NULL)
|
|
|
|
hawk_sio_close (arg->handle);
|
|
|
|
else
|
|
|
|
close_main_stream (sed, arg, xtn->e.in.cur);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hawk_sio_close (arg->handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
case HAWK_SED_IO_READ:
|
|
|
|
{
|
|
|
|
if (arg->path == HAWK_NULL)
|
|
|
|
{
|
|
|
|
/* main data stream */
|
|
|
|
if (xtn->e.in.ptr == HAWK_NULL)
|
|
|
|
{
|
|
|
|
hawk_ooi_t n;
|
|
|
|
n = hawk_sio_getoochars(arg->handle, buf, len);
|
2022-04-05 14:26:21 +00:00
|
|
|
if (n <= -1)
|
|
|
|
{
|
|
|
|
const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed);
|
|
|
|
hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "unable to read '%js' - %js", &sio_std_names[HAWK_SIO_STDIN], bem);
|
|
|
|
}
|
2022-03-31 17:14:52 +00:00
|
|
|
return n;
|
|
|
|
}
|
|
|
|
else
|
2022-04-05 14:26:21 +00:00
|
|
|
{
|
2022-03-31 17:14:52 +00:00
|
|
|
return read_input_stream(sed, arg, buf, len, &xtn->e.in);
|
2022-04-05 14:26:21 +00:00
|
|
|
}
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hawk_ooi_t n;
|
|
|
|
n = hawk_sio_getoochars(arg->handle, buf, len);
|
|
|
|
if (n <= -1)
|
|
|
|
{
|
2022-04-05 14:26:21 +00:00
|
|
|
const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed);
|
|
|
|
hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "unable to read '%js' - %js", arg->path, bem);
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
HAWK_ASSERT (!"should never happen - cmd must be one of OPEN,CLOSE,READ");
|
|
|
|
hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINTERN);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static hawk_ooi_t x_out (
|
|
|
|
hawk_sed_t* sed, hawk_sed_io_cmd_t cmd, hawk_sed_io_arg_t* arg,
|
|
|
|
hawk_ooch_t* dat, hawk_oow_t len)
|
|
|
|
{
|
|
|
|
xtn_t* xtn = GET_XTN(sed);
|
|
|
|
hawk_sio_t* sio;
|
|
|
|
|
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case HAWK_SED_IO_OPEN:
|
|
|
|
{
|
|
|
|
if (arg->path == HAWK_NULL)
|
|
|
|
{
|
|
|
|
/* main data stream */
|
|
|
|
|
|
|
|
if (xtn->e.out.ptr == HAWK_NULL)
|
|
|
|
{
|
|
|
|
/* HAWK_NULL passed into hawk_sed_execstd() for output */
|
|
|
|
sio = open_sio_std(
|
|
|
|
sed, HAWK_SIO_STDOUT,
|
|
|
|
HAWK_SIO_WRITE |
|
|
|
|
HAWK_SIO_CREATE |
|
|
|
|
HAWK_SIO_TRUNCATE |
|
|
|
|
HAWK_SIO_IGNOREECERR |
|
|
|
|
HAWK_SIO_LINEBREAK
|
|
|
|
);
|
|
|
|
if (sio == HAWK_NULL) return -1;
|
|
|
|
arg->handle = sio;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (open_output_stream(sed, arg, xtn->e.out.ptr) <= -1) return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
|
|
|
|
sio = open_sio_file(
|
|
|
|
sed, arg->path,
|
|
|
|
HAWK_SIO_WRITE |
|
|
|
|
HAWK_SIO_CREATE |
|
|
|
|
HAWK_SIO_TRUNCATE |
|
|
|
|
HAWK_SIO_IGNOREECERR
|
|
|
|
);
|
|
|
|
if (sio == HAWK_NULL) return -1;
|
|
|
|
arg->handle = sio;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
case HAWK_SED_IO_CLOSE:
|
|
|
|
{
|
|
|
|
if (arg->path == HAWK_NULL)
|
|
|
|
{
|
|
|
|
if (xtn->e.out.ptr == HAWK_NULL)
|
|
|
|
hawk_sio_close (arg->handle);
|
|
|
|
else
|
|
|
|
close_main_stream (sed, arg, xtn->e.out.ptr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hawk_sio_close (arg->handle);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
case HAWK_SED_IO_WRITE:
|
|
|
|
{
|
|
|
|
if (arg->path == HAWK_NULL)
|
|
|
|
{
|
|
|
|
/* main data stream */
|
|
|
|
if (xtn->e.out.ptr == HAWK_NULL)
|
|
|
|
{
|
|
|
|
hawk_ooi_t n;
|
|
|
|
n = hawk_sio_putoochars(arg->handle, dat, len);
|
|
|
|
if (n <= -1) hawk_sed_seterror (sed, HAWK_NULL, HAWK_SED_EIOFIL, &sio_std_names[HAWK_SIO_STDOUT]);
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hawk_sed_iostd_t* io = xtn->e.out.ptr;
|
2022-04-05 10:46:00 +00:00
|
|
|
switch (io->type)
|
2022-03-31 17:14:52 +00:00
|
|
|
{
|
2022-04-05 10:46:00 +00:00
|
|
|
#if defined(HAWK_OOCH_IS_BCH)
|
|
|
|
case HAWK_SED_IOSTD_OOCS:
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_BCS:
|
|
|
|
if (len > HAWK_TYPE_MAX(hawk_ooi_t)) len = HAWK_TYPE_MAX(hawk_ooi_t);
|
|
|
|
#if defined(HAWK_OOCH_IS_BCH)
|
|
|
|
if (hawk_becs_ncat(xtn->e.out.memstr.be, dat, len) == (hawk_oow_t)-1) return -1;
|
|
|
|
#else
|
|
|
|
if (hawk_becs_ncatuchars(xtn->e.out.memstr.be, dat, len, HAWK_NULL) == (hawk_oow_t)-1) return -1;
|
|
|
|
#endif
|
|
|
|
return len;
|
|
|
|
|
|
|
|
#if defined(HAWK_OOCH_IS_UCH)
|
|
|
|
case HAWK_SED_IOSTD_OOCS:
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_UCS:
|
|
|
|
if (len > HAWK_TYPE_MAX(hawk_ooi_t)) len = HAWK_TYPE_MAX(hawk_ooi_t);
|
|
|
|
#if defined(HAWK_OOCH_IS_UCH)
|
|
|
|
if (hawk_uecs_ncat(xtn->e.out.memstr.ue, dat, len) == (hawk_oow_t)-1) return -1;
|
|
|
|
#else
|
|
|
|
if (hawk_uecs_ncatbchars(xtn->e.out.memstr.ue, dat, len, HAWK_NULL, 1) == (hawk_oow_t)-1) return -1;
|
|
|
|
#endif
|
|
|
|
return len;
|
|
|
|
|
|
|
|
default:
|
2022-04-05 14:26:21 +00:00
|
|
|
{
|
|
|
|
hawk_ooi_t n;
|
|
|
|
n = hawk_sio_putoochars(arg->handle, dat, len);
|
|
|
|
if (n <= -1) set_eiofil_for_iostd (sed, io);
|
|
|
|
return n;
|
|
|
|
}
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hawk_ooi_t n;
|
|
|
|
n = hawk_sio_putoochars(arg->handle, dat, len);
|
|
|
|
if (n <= -1)
|
|
|
|
{
|
2022-04-05 14:26:21 +00:00
|
|
|
const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed);
|
|
|
|
hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "unable to write '%js' - %js", arg->path, bem);
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
HAWK_ASSERT (!"should never happen - cmd must be one of OPEN,CLOSE,WRITE");
|
|
|
|
hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINTERN);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int hawk_sed_compstd (hawk_sed_t* sed, hawk_sed_iostd_t in[], hawk_oow_t* count)
|
|
|
|
{
|
|
|
|
xtn_t* xtn = GET_XTN(sed);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (in == HAWK_NULL)
|
|
|
|
{
|
|
|
|
/* it requires a valid array unlike hawk_sed_execstd(). */
|
2022-04-05 10:46:00 +00:00
|
|
|
hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_EINVAL, "no input handler provided");
|
|
|
|
if (count) *count = 0;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verify_iostd_in(sed, in) <= -1)
|
|
|
|
{
|
|
|
|
if (count) *count = 0;
|
2022-03-31 17:14:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
HAWK_MEMSET (&xtn->s, 0, HAWK_SIZEOF(xtn->s));
|
|
|
|
xtn->s.in.ptr = in;
|
|
|
|
xtn->s.in.cur = in;
|
|
|
|
|
|
|
|
ret = hawk_sed_comp(sed, s_in);
|
|
|
|
|
|
|
|
if (count) *count = xtn->s.in.cur - xtn->s.in.ptr;
|
|
|
|
|
|
|
|
clear_sio_names (sed);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int hawk_sed_execstd (hawk_sed_t* sed, hawk_sed_iostd_t in[], hawk_sed_iostd_t* out)
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
xtn_t* xtn = GET_XTN(sed);
|
|
|
|
|
|
|
|
if (in && verify_iostd_in(sed, in) <= -1) return -1;
|
|
|
|
|
|
|
|
if (out)
|
|
|
|
{
|
|
|
|
if (out->type != HAWK_SED_IOSTD_FILE &&
|
|
|
|
out->type != HAWK_SED_IOSTD_FILEB &&
|
|
|
|
out->type != HAWK_SED_IOSTD_FILEU &&
|
2022-04-05 10:46:00 +00:00
|
|
|
out->type != HAWK_SED_IOSTD_OOCS &&
|
2022-03-31 17:14:52 +00:00
|
|
|
out->type != HAWK_SED_IOSTD_SIO)
|
|
|
|
{
|
|
|
|
hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
HAWK_MEMSET (&xtn->e, 0, HAWK_SIZEOF(xtn->e));
|
|
|
|
xtn->e.in.ptr = in;
|
|
|
|
xtn->e.in.cur = in;
|
|
|
|
xtn->e.out.ptr = out;
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
n = hawk_sed_exec(sed, x_in, x_out);
|
2022-03-31 17:14:52 +00:00
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
if (out && out->type == HAWK_SED_IOSTD_OOCS)
|
2022-03-31 17:14:52 +00:00
|
|
|
{
|
2022-04-05 10:46:00 +00:00
|
|
|
switch (out->type)
|
2022-03-31 17:14:52 +00:00
|
|
|
{
|
2022-04-05 10:46:00 +00:00
|
|
|
#if defined(HAWK_OOCH_IS_BCH)
|
|
|
|
case HAWK_SED_IOSTD_OOCS:
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_BCS:
|
|
|
|
if (n >= 0)
|
|
|
|
{
|
|
|
|
HAWK_ASSERT (xtn->e.out.memstr.be != HAWK_NULL);
|
|
|
|
hawk_becs_yield (xtn->e.out.memstr.be, &out->u.bcs, 0);
|
|
|
|
}
|
|
|
|
if (xtn->e.out.memstr.be) hawk_becs_close (xtn->e.out.memstr.be);
|
|
|
|
break;
|
|
|
|
|
|
|
|
#if defined(HAWK_OOCH_IS_UCH)
|
|
|
|
case HAWK_SED_IOSTD_OOCS:
|
|
|
|
#endif
|
|
|
|
case HAWK_SED_IOSTD_UCS:
|
|
|
|
if (n >= 0)
|
|
|
|
{
|
|
|
|
HAWK_ASSERT (xtn->e.out.memstr.ue != HAWK_NULL);
|
|
|
|
hawk_uecs_yield (xtn->e.out.memstr.ue, &out->u.ucs, 0);
|
|
|
|
}
|
|
|
|
if (xtn->e.out.memstr.ue) hawk_uecs_close (xtn->e.out.memstr.ue);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/* don't handle other types */
|
|
|
|
break;
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
2022-04-05 10:46:00 +00:00
|
|
|
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
clear_sio_names (sed);
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
int hawk_sed_compstdfile (hawk_sed_t* sed, const hawk_ooch_t* file, hawk_cmgr_t* cmgr)
|
|
|
|
{
|
|
|
|
hawk_sed_iostd_t in[2];
|
|
|
|
|
|
|
|
in[0].type = HAWK_SED_IOSTD_FILE;
|
|
|
|
in[0].u.file.path = file;
|
|
|
|
in[0].u.file.cmgr = cmgr;
|
|
|
|
in[1].type = HAWK_SED_IOSTD_NULL;
|
|
|
|
|
|
|
|
return hawk_sed_compstd(sed, in, HAWK_NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
int hawk_sed_compstdfileb (hawk_sed_t* sed, const hawk_bch_t* file, hawk_cmgr_t* cmgr)
|
|
|
|
{
|
|
|
|
hawk_sed_iostd_t in[2];
|
|
|
|
|
|
|
|
in[0].type = HAWK_SED_IOSTD_FILEB;
|
|
|
|
in[0].u.fileb.path = file;
|
|
|
|
in[0].u.fileb.cmgr = cmgr;
|
|
|
|
in[1].type = HAWK_SED_IOSTD_NULL;
|
|
|
|
|
|
|
|
return hawk_sed_compstd(sed, in, HAWK_NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
int hawk_sed_compstdfileu (hawk_sed_t* sed, const hawk_uch_t* file, hawk_cmgr_t* cmgr)
|
|
|
|
{
|
|
|
|
hawk_sed_iostd_t in[2];
|
|
|
|
|
|
|
|
in[0].type = HAWK_SED_IOSTD_FILEU;
|
|
|
|
in[0].u.fileu.path = file;
|
|
|
|
in[0].u.fileu.cmgr = cmgr;
|
|
|
|
in[1].type = HAWK_SED_IOSTD_NULL;
|
|
|
|
|
|
|
|
return hawk_sed_compstd(sed, in, HAWK_NULL);
|
|
|
|
}
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
int hawk_sed_compstdoocstr (hawk_sed_t* sed, const hawk_ooch_t* script)
|
2022-03-31 17:14:52 +00:00
|
|
|
{
|
|
|
|
hawk_sed_iostd_t in[2];
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
in[0].type = HAWK_SED_IOSTD_OOCS;
|
|
|
|
in[0].u.oocs.ptr = (hawk_ooch_t*)script;
|
|
|
|
in[0].u.oocs.len = hawk_count_oocstr(script);
|
2022-03-31 17:14:52 +00:00
|
|
|
in[1].type = HAWK_SED_IOSTD_NULL;
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
return hawk_sed_compstd(sed, in, HAWK_NULL);
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
int hawk_sed_compstdoocs (hawk_sed_t* sed, const hawk_oocs_t* script)
|
2022-03-31 17:14:52 +00:00
|
|
|
{
|
|
|
|
hawk_sed_iostd_t in[2];
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
in[0].type = HAWK_SED_IOSTD_OOCS;
|
|
|
|
in[0].u.oocs = *script;
|
2022-03-31 17:14:52 +00:00
|
|
|
in[1].type = HAWK_SED_IOSTD_NULL;
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
return hawk_sed_compstd(sed, in, HAWK_NULL);
|
2022-03-31 17:14:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int hawk_sed_execstdfile (hawk_sed_t* sed, const hawk_ooch_t* infile, const hawk_ooch_t* outfile, hawk_cmgr_t* cmgr)
|
|
|
|
{
|
|
|
|
hawk_sed_iostd_t in[2];
|
|
|
|
hawk_sed_iostd_t out;
|
|
|
|
hawk_sed_iostd_t* pin = HAWK_NULL, * pout = HAWK_NULL;
|
|
|
|
|
|
|
|
if (infile)
|
|
|
|
{
|
|
|
|
in[0].type = HAWK_SED_IOSTD_FILE;
|
|
|
|
in[0].u.file.path = infile;
|
|
|
|
in[0].u.file.cmgr = cmgr;
|
|
|
|
in[1].type = HAWK_SED_IOSTD_NULL;
|
|
|
|
pin = in;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (outfile)
|
|
|
|
{
|
|
|
|
out.type = HAWK_SED_IOSTD_FILE;
|
|
|
|
out.u.file.path = outfile;
|
|
|
|
out.u.file.cmgr = cmgr;
|
|
|
|
pout = &out;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hawk_sed_execstd(sed, pin, pout);
|
|
|
|
}
|
|
|
|
|
|
|
|
int hawk_sed_execstdxstr (hawk_sed_t* sed, const hawk_oocs_t* instr, hawk_oocs_t* outstr, hawk_cmgr_t* cmgr)
|
|
|
|
{
|
|
|
|
hawk_sed_iostd_t in[2];
|
|
|
|
hawk_sed_iostd_t out;
|
|
|
|
int n;
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
in[0].type = HAWK_SED_IOSTD_OOCS;
|
|
|
|
in[0].u.oocs = *instr;
|
2022-03-31 17:14:52 +00:00
|
|
|
in[1].type = HAWK_SED_IOSTD_NULL;
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
out.type = HAWK_SED_IOSTD_OOCS;
|
2022-03-31 17:14:52 +00:00
|
|
|
|
|
|
|
n = hawk_sed_execstd(sed, in, &out);
|
|
|
|
|
2022-04-05 10:46:00 +00:00
|
|
|
if (n >= 0) *outstr = out.u.oocs;
|
2022-03-31 17:14:52 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|