added Hawk::exec()

This commit is contained in:
hyung-hwan 2020-01-14 09:10:47 +00:00
parent 3e86ce4ab2
commit 32344f2c0c
10 changed files with 571 additions and 57 deletions

View File

@ -32,7 +32,6 @@
HAWK_BEGIN_NAMESPACE(HAWK) HAWK_BEGIN_NAMESPACE(HAWK)
///////////////////////////////// /////////////////////////////////
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// Mmged // Mmged
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
@ -732,6 +731,7 @@ int Hawk::Value::setStr (const hawk_uch_t* str, bool numeric)
int Hawk::Value::setStr (Run* r, const hawk_uch_t* str, bool numeric) int Hawk::Value::setStr (Run* r, const hawk_uch_t* str, bool numeric)
{ {
hawk_val_t* tmp; hawk_val_t* tmp;
tmp = numeric? hawk_rtx_makenstrvalwithucstr(r->rtx, str): tmp = numeric? hawk_rtx_makenstrvalwithucstr(r->rtx, str):
hawk_rtx_makestrvalwithucstr(r->rtx, str); hawk_rtx_makestrvalwithucstr(r->rtx, str);
if (tmp == HAWK_NULL) if (tmp == HAWK_NULL)
@ -784,6 +784,7 @@ int Hawk::Value::setStr (const hawk_bch_t* str, bool numeric)
int Hawk::Value::setStr (Run* r, const hawk_bch_t* str, bool numeric) int Hawk::Value::setStr (Run* r, const hawk_bch_t* str, bool numeric)
{ {
hawk_val_t* tmp; hawk_val_t* tmp;
tmp = numeric? hawk_rtx_makenstrvalwithbcstr(r->rtx, str): tmp = numeric? hawk_rtx_makenstrvalwithbcstr(r->rtx, str):
hawk_rtx_makestrvalwithbcstr(r->rtx, str); hawk_rtx_makestrvalwithbcstr(r->rtx, str);
if (tmp == HAWK_NULL) if (tmp == HAWK_NULL)
@ -1770,6 +1771,12 @@ int Hawk::call (const hawk_uch_t* name, Value* ret, const Value* args, hawk_oow_
return 0; return 0;
} }
int Hawk::exec (Value* ret, const Value* args, hawk_oow_t nargs)
{
return (this->runctx.rtx->awk->parse.pragma.startup[0] != '\0')?
this->call(this->runctx.rtx->awk->parse.pragma.startup, ret, args, nargs): this->loop(ret);
}
void Hawk::halt () void Hawk::halt ()
{ {
HAWK_ASSERT (awk != HAWK_NULL); HAWK_ASSERT (awk != HAWK_NULL);

View File

@ -991,7 +991,7 @@ public:
void clear (); void clear ();
operator hawk_val_t* () const { return val; } operator hawk_val_t* () const { return this->val; }
operator hawk_int_t () const; operator hawk_int_t () const;
operator hawk_flt_t () const; operator hawk_flt_t () const;
operator const hawk_ooch_t* () const; operator const hawk_ooch_t* () const;
@ -1001,17 +1001,17 @@ public:
hawk_val_t* toVal () const hawk_val_t* toVal () const
{ {
return operator hawk_val_t* (); return this->operator hawk_val_t* ();
} }
hawk_int_t toInt () const hawk_int_t toInt () const
{ {
return operator hawk_int_t (); return this->operator hawk_int_t ();
} }
hawk_flt_t toFlt () const hawk_flt_t toFlt () const
{ {
return operator hawk_flt_t (); return this->operator hawk_flt_t ();
} }
const hawk_ooch_t* toStr (hawk_oow_t* len) const const hawk_ooch_t* toStr (hawk_oow_t* len) const
@ -1385,6 +1385,16 @@ public:
hawk_oow_t nargs ///< number of arguments hawk_oow_t nargs ///< number of arguments
); );
///
/// The exec() function is the same as loop() if no @pragma startup
/// is specified. It is the same as call() if it is specifed
///
int exec (
Value* ret, ///< return value holder
const Value* args, ///< argument array
hawk_oow_t nargs ///< number of arguments
);
/// ///
/// The halt() function makes request to abort execution /// The halt() function makes request to abort execution
/// ///
@ -1462,6 +1472,17 @@ public:
/// ///
void clearArguments (); void clearArguments ();
hawk_oow_t getArgumentCount () const
{
return this->runarg.len;
}
const hawk_ooch_t* getArgument (hawk_oow_t index, hawk_oow_t* len = HAWK_NULL) const
{
if (len) *len = this->runarg.ptr[index].len;
return this->runarg.ptr[index].ptr;
}
/// ///
/// The addGlobal() function registers an intrinsic global variable. /// The addGlobal() function registers an intrinsic global variable.
/// \return integer >= 0 on success, -1 on failure. /// \return integer >= 0 on success, -1 on failure.

View File

@ -297,6 +297,14 @@ HAWK_EXPORT hawk_ooi_t hawk_pio_read (
hawk_oow_t size /**< buffer size */ hawk_oow_t size /**< buffer size */
); );
HAWK_EXPORT hawk_ooi_t hawk_pio_readbytes (
hawk_pio_t* pio, /**< pio object */
hawk_pio_hid_t hid, /**< handle ID */
void* buf, /**< buffer to fill */
hawk_oow_t size /**< buffer size */
);
/** /**
* The hawk_pio_write() function writes up \a size bytes/characters * The hawk_pio_write() function writes up \a size bytes/characters
* from the buffer pointed to by \a data. If #HAWK_PIO_TEXT is used * from the buffer pointed to by \a data. If #HAWK_PIO_TEXT is used

View File

@ -392,6 +392,7 @@ struct hawk_rtx_t
hawk_ooecs_t line; /* entire line */ hawk_ooecs_t line; /* entire line */
hawk_ooecs_t linew; /* line for manipulation, if necessary */ hawk_ooecs_t linew; /* line for manipulation, if necessary */
hawk_ooecs_t lineg; /* line buffer for getline */ hawk_ooecs_t lineg; /* line buffer for getline */
hawk_becs_t linegb; /* line buffer for getline mbs */
hawk_val_t* d0; /* $0 */ hawk_val_t* d0; /* $0 */

View File

@ -619,7 +619,7 @@ enum hawk_rio_cmd_t
HAWK_RIO_CMD_CLOSE = 1, /**< close a stream */ HAWK_RIO_CMD_CLOSE = 1, /**< close a stream */
HAWK_RIO_CMD_READ = 2, /**< read a stream */ HAWK_RIO_CMD_READ = 2, /**< read a stream */
HAWK_RIO_CMD_WRITE = 3, /**< write to a stream */ HAWK_RIO_CMD_WRITE = 3, /**< write to a stream */
/*HAWK_RIO_CMD_READ_BYTES = 4,*/ HAWK_RIO_CMD_READ_BYTES = 4,
HAWK_RIO_CMD_WRITE_BYTES = 5, HAWK_RIO_CMD_WRITE_BYTES = 5,
HAWK_RIO_CMD_FLUSH = 6, /**< flush buffered data to a stream */ HAWK_RIO_CMD_FLUSH = 6, /**< flush buffered data to a stream */
HAWK_RIO_CMD_NEXT = 7 /**< close the current stream and HAWK_RIO_CMD_NEXT = 7 /**< close the current stream and

View File

@ -1993,6 +1993,14 @@ hawk_ooi_t hawk_pio_read (hawk_pio_t* pio, hawk_pio_hid_t hid, void* buf, hawk_o
hawk_tio_read(pio->pin[hid].tio, buf, size); hawk_tio_read(pio->pin[hid].tio, buf, size);
} }
hawk_ooi_t hawk_pio_readbytes (hawk_pio_t* pio, hawk_pio_hid_t hid, void* buf, hawk_oow_t size)
{
return (pio->pin[hid].tio == HAWK_NULL)?
pio_read(pio, buf, size, pio->pin[hid].handle):
hawk_tio_readbchars(pio->pin[hid].tio, buf, size);
}
static hawk_ooi_t pio_write (hawk_pio_t* pio, const void* data, hawk_oow_t size, hawk_pio_hnd_t hnd) static hawk_ooi_t pio_write (hawk_pio_t* pio, const void* data, hawk_oow_t size, hawk_pio_hnd_t hnd)
{ {
#if defined(_WIN32) #if defined(_WIN32)

View File

@ -227,10 +227,7 @@ static HAWK_INLINE int match_long_rs (hawk_rtx_t* rtx, hawk_ooecs_t* buf, hawk_r
HAWK_ASSERT (rtx->gbl.rs[0] != HAWK_NULL); HAWK_ASSERT (rtx->gbl.rs[0] != HAWK_NULL);
HAWK_ASSERT (rtx->gbl.rs[1] != HAWK_NULL); HAWK_ASSERT (rtx->gbl.rs[1] != HAWK_NULL);
ret = hawk_rtx_matchrex( ret = hawk_rtx_matchrex(rtx, rtx->gbl.rs[rtx->gbl.ignorecase], HAWK_OOECS_OOCS(buf), HAWK_OOECS_OOCS(buf), &match, HAWK_NULL);
rtx, rtx->gbl.rs[rtx->gbl.ignorecase],
HAWK_OOECS_OOCS(buf), HAWK_OOECS_OOCS(buf),
&match, HAWK_NULL);
if (ret >= 1) if (ret >= 1)
{ {
if (p->in.eof) if (p->in.eof)
@ -279,6 +276,68 @@ static HAWK_INLINE int match_long_rs (hawk_rtx_t* rtx, hawk_ooecs_t* buf, hawk_r
return ret; return ret;
} }
#if 0
static HAWK_INLINE int match_long_rs_bytes (hawk_rtx_t* rtx, hawk_becs_t* buf, hawk_rio_arg_t* p)
{
hawk_oocs_t match;
int ret;
HAWK_ASSERT (rtx->gbl.rs[0] != HAWK_NULL);
HAWK_ASSERT (rtx->gbl.rs[1] != HAWK_NULL);
ret = hawk_rtx_matchrex(rtx, rtx->gbl.rs[rtx->gbl.ignorecase], HAWK_BECS_OOCS(buf), HAWK_BECS_OOCS(buf), &match, HAWK_NULL);
if (ret >= 1)
{
if (p->in.eof)
{
/* when EOF is reached, the record buffer
* is not added with a new character. It's
* just called again with the same record buffer
* as the previous call to this function.
* A match in this case must end at the end of
* the current record buffer */
HAWK_ASSERT (HAWK_BECS_PTR(buf) + HAWK_BECS_LEN(buf) == match.ptr + match.len);
/* drop the RS part. no extra character after RS to drop
* because we're at EOF and the EOF condition didn't
* add a new character to the buffer before the call
* to this function.
*/
HAWK_BECS_LEN(buf) -= match.len;
}
else
{
/* If the match is found before the end of the current buffer,
* I see it as the longest match. A match ending at the end
* of the buffer is not indeterministic as we don't have the
* full input yet.
*/
const hawk_ooch_t* be = HAWK_BECS_PTR(buf) + HAWK_BECS_LEN(buf);
const hawk_ooch_t* me = match.ptr + match.len;
if (me < be)
{
/* the match ends before the ending boundary.
* it must be the longest match. drop the RS part
* and the characters after RS. */
HAWK_BECS_LEN(buf) -= match.len + (be - me);
p->in.pos -= (be - me);
}
else
{
/* the match is at the ending boundary. switch to no match */
ret = 0;
}
}
}
return ret;
}
#endif
int hawk_rtx_readio (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk_ooecs_t* buf) int hawk_rtx_readio (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk_ooecs_t* buf)
{ {
hawk_rio_arg_t* p; hawk_rio_arg_t* p;
@ -353,8 +412,7 @@ int hawk_rtx_readio (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk
if (HAWK_OOECS_LEN(buf) == 0) if (HAWK_OOECS_LEN(buf) == 0)
{ {
/* We can return EOF now if the record buffer /* We can return EOF now if the record buffer is empty */
* is empty */
ret = 0; ret = 0;
} }
else if (rrs.ptr && rrs.len == 0) else if (rrs.ptr && rrs.len == 0)
@ -598,6 +656,331 @@ int hawk_rtx_readio (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk
return ret; return ret;
} }
int hawk_rtx_readiobytes (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk_becs_t* buf)
{
#if 0
hawk_rio_arg_t* p;
hawk_rio_impl_t handler;
int ret;
hawk_val_t* rs;
hawk_oocs_t rrs;
hawk_oow_t line_len = 0;
hawk_bch_t c = '\0', pc;
if (find_rio_in(rtx, in_type, name, &p, &handler) <= -1) return -1;
if (p->in.eos) return 0; /* no more streams left */
/* ready to read a record(typically a line). clear the buffer. */
hawk_becs_clear (buf);
/* get the record separator */
rs = hawk_rtx_getgbl(rtx, HAWK_GBL_RS);
hawk_rtx_refupval (rtx, rs);
if (resolve_rs(rtx, rs, &rrs) <= -1)
{
hawk_rtx_refdownval (rtx, rs);
return -1;
}
ret = 1;
/* call the I/O handler */
while (1)
{
if (p->in.pos >= p->in.len)
{
hawk_ooi_t x;
/* no more data in the read buffer.
* let the I/O handler read more */
if (p->in.eof)
{
/* it has reached EOF at the previous call. */
if (HAWK_BECS_LEN(buf) == 0)
{
/* we return EOF if the record buffer is empty */
ret = 0;
}
break;
}
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOERR);
x = handler(rtx, HAWK_RIO_CMD_READ_BYTES, p, p->in.buf, HAWK_COUNTOF(p->in.buf));
if (x <= -1)
{
if (hawk_rtx_geterrnum(rtx) == HAWK_ENOERR)
{
/* if the error number has not been
* set by the user handler, we set
* it here to HAWK_EIOIMPL. */
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL);
}
ret = -1;
break;
}
if (x == 0)
{
/* EOF reached */
p->in.eof = 1;
if (HAWK_BECS_LEN(buf) == 0)
{
/* We can return EOF now if the record buffer is empty */
ret = 0;
}
else if (rrs.ptr && rrs.len == 0)
{
/* TODO: handle different line terminator */
/* drop the line terminator from the record
* if RS is a blank line and EOF is reached. */
if (HAWK_BECS_LASTCHAR(buf) == HAWK_T'\n')
{
HAWK_BECS_LEN(buf) -= 1;
if (rtx->awk->opt.trait & HAWK_CRLF)
{
/* drop preceding CR */
if (HAWK_BECS_LEN(buf) > 0 && HAWK_BECS_LASTCHAR(buf) == '\r') HAWK_BECS_LEN(buf) -= 1;
}
}
}
else if (rrs.len >= 2)
{
/* When RS is multiple characters, it should
* check for the match at the end of the
* input stream also because the previous
* match could fail as it didn't end at the
* desired position to be the longest match.
* At EOF, the match at the end is considered
* the longest as there are no more characters
* left */
int n = match_long_rs_bytes(rtx, buf, p);
if (n != 0)
{
if (n <= -1) ret = -1;
break;
}
}
break;
}
p->in.len = x;
p->in.pos = 0;
}
if (rrs.ptr == HAWK_NULL)
{
hawk_oow_t start_pos = p->in.pos;
hawk_oow_t end_pos, tmp;
do
{
pc = c;
c = p->in.buf[p->in.pos++];
end_pos = p->in.pos;
/* TODO: handle different line terminator */
/* separate by a new line */
if (c == '\n')
{
end_pos--;
if (pc == '\r')
{
if (end_pos > start_pos)
{
/* CR is the part of the read buffer.
* decrementing the end_pos variable can
* simply drop it */
end_pos--;
}
else
{
/* CR must have come from the previous
* read. drop CR that must be found at
* the end of the record buffer. */
HAWK_ASSERT (end_pos == start_pos);
HAWK_ASSERT (HAWK_BECS_LEN(buf) > 0);
HAWK_ASSERT (HAWK_BECS_LASTCHAR(buf) == '\r');
HAWK_BECS_LEN(buf)--;
}
}
break;
}
}
while (p->in.pos < p->in.len);
tmp = hawk_becs_ncat(buf, &p->in.buf[start_pos], end_pos - start_pos);
if (tmp == (hawk_oow_t)-1)
{
ret = -1;
break;
}
if (end_pos < p->in.len) break; /* RS found */
}
else if (rrs.len == 0)
{
int done = 0;
do
{
pc = c;
c = p->in.buf[p->in.pos++];
/* TODO: handle different line terminator */
/* separate by a blank line */
if (c == HAWK_T('\n'))
{
if (pc == HAWK_T('\r') && HAWK_BECS_LEN(buf) > 0)
{
/* shrink the line length and the record
* by dropping of CR before NL */
HAWK_ASSERT (line_len > 0);
line_len--;
/* we don't drop CR from the record buffer
* if we're in CRLF mode. POINT-X */
if (!(rtx->awk->opt.trait & HAWK_CRLF))
HAWK_BECS_LEN(buf) -= 1;
}
if (line_len == 0)
{
/* we got a blank line */
if (rtx->awk->opt.trait & HAWK_CRLF)
{
if (HAWK_BECS_LEN(buf) > 0 && HAWK_BECS_LASTCHAR(buf) == HAWK_T('\r'))
{
/* drop CR not dropped in POINT-X above */
HAWK_BECS_LEN(buf) -= 1;
}
if (HAWK_BECS_LEN(buf) <= 0)
{
/* if the record is empty when a blank
* line is encountered, the line
* terminator should not be added to
* the record */
continue;
}
/* drop NL */
HAWK_BECS_LEN(buf) -= 1;
/* drop preceding CR */
if (HAWK_BECS_LEN(buf) > 0 && HAWK_BECS_LASTCHAR(buf) == HAWK_T('\r')) HAWK_BECS_LEN(buf) -= 1;
}
else
{
if (HAWK_BECS_LEN(buf) <= 0)
{
/* if the record is empty when a blank
* line is encountered, the line
* terminator should not be added to
* the record */
continue;
}
/* drop NL of the previous line */
HAWK_BECS_LEN(buf) -= 1; /* simply drop NL */
}
done = 1;
break;
}
line_len = 0;
}
else line_len++;
if (hawk_becs_ccat(buf, c) == (hawk_oow_t)-1)
{
ret = -1;
done = 1;
break;
}
}
while (p->in.pos < p->in.len);
if (done) break;
}
else if (rrs.len == 1)
{
hawk_oow_t start_pos = p->in.pos;
hawk_oow_t end_pos, tmp;
do
{
c = p->in.buf[p->in.pos++];
end_pos = p->in.pos;
if (c == rrs.ptr[0])
{
end_pos--;
break;
}
}
while (p->in.pos < p->in.len);
tmp = hawk_becs_ncat(buf, &p->in.buf[start_pos], end_pos - start_pos);
if (tmp == (hawk_oow_t)-1)
{
ret = -1;
break;
}
if (end_pos < p->in.len) break; /* RS found */
}
else
{
hawk_oow_t tmp;
int n;
/* if RS is composed of multiple characters,
* I perform the matching after having added the
* current character 'c' to the record buffer 'buf'
* to find the longest match. If a match found ends
* one character before this character just added
* to the buffer, it is the longest match.
*/
tmp = hawk_becs_ncat(buf, &p->in.buf[p->in.pos], p->in.len - p->in.pos);
if (tmp == (hawk_oow_t)-1)
{
ret = -1;
break;
}
p->in.pos = p->in.len;
n = match_long_rs(rtx, buf, p);
if (n != 0)
{
if (n <= -1) ret = -1;
break;
}
}
}
if (rrs.ptr && HAWK_RTX_GETVALTYPE (rtx, rs) != HAWK_VAL_STR) hawk_rtx_freemem (rtx, rrs.ptr);
hawk_rtx_refdownval (rtx, rs);
return ret;
#else
hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_ENOIMPL);
return -1;
#endif
}
int hawk_rtx_writeioval (hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* name, hawk_val_t* v) int hawk_rtx_writeioval (hawk_rtx_t* rtx, int out_type, const hawk_ooch_t* name, hawk_val_t* v)
{ {
hawk_val_type_t vtype; hawk_val_type_t vtype;

View File

@ -916,31 +916,32 @@ static int init_rtx (hawk_rtx_t* rtx, hawk_t* awk, hawk_rio_cbs_t* rio)
if (hawk_ooecs_init(&rtx->inrec.line, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_1; if (hawk_ooecs_init(&rtx->inrec.line, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_1;
if (hawk_ooecs_init(&rtx->inrec.linew, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_2; if (hawk_ooecs_init(&rtx->inrec.linew, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_2;
if (hawk_ooecs_init(&rtx->inrec.lineg, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_3; if (hawk_ooecs_init(&rtx->inrec.lineg, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_3;
if (hawk_ooecs_init(&rtx->format.out, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_4; if (hawk_becs_init(&rtx->inrec.linegb, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_4;
if (hawk_ooecs_init(&rtx->format.fmt, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_5; if (hawk_ooecs_init(&rtx->format.out, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_5;
if (hawk_ooecs_init(&rtx->format.fmt, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_6;
if (hawk_becs_init(&rtx->formatmbs.out, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_6; if (hawk_becs_init(&rtx->formatmbs.out, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_7;
if (hawk_becs_init(&rtx->formatmbs.fmt, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_7; if (hawk_becs_init(&rtx->formatmbs.fmt, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_8;
rtx->named = hawk_htb_open(hawk_rtx_getgem(rtx), HAWK_SIZEOF(rtx), 1024, 70, HAWK_SIZEOF(hawk_ooch_t), 1); rtx->named = hawk_htb_open(hawk_rtx_getgem(rtx), HAWK_SIZEOF(rtx), 1024, 70, HAWK_SIZEOF(hawk_ooch_t), 1);
if (!rtx->named) goto oops_8; if (!rtx->named) goto oops_9;
*(hawk_rtx_t**)hawk_htb_getxtn(rtx->named) = rtx; *(hawk_rtx_t**)hawk_htb_getxtn(rtx->named) = rtx;
hawk_htb_setstyle (rtx->named, &style_for_named); hawk_htb_setstyle (rtx->named, &style_for_named);
rtx->format.tmp.ptr = (hawk_ooch_t*)hawk_rtx_allocmem(rtx, 4096 * HAWK_SIZEOF(hawk_ooch_t)); rtx->format.tmp.ptr = (hawk_ooch_t*)hawk_rtx_allocmem(rtx, 4096 * HAWK_SIZEOF(hawk_ooch_t));
if (!rtx->format.tmp.ptr) goto oops_9; /* the error is set on the awk object after this jump is made */ if (!rtx->format.tmp.ptr) goto oops_10; /* the error is set on the awk object after this jump is made */
rtx->format.tmp.len = 4096; rtx->format.tmp.len = 4096;
rtx->format.tmp.inc = 4096 * 2; rtx->format.tmp.inc = 4096 * 2;
rtx->formatmbs.tmp.ptr = (hawk_bch_t*)hawk_rtx_allocmem(rtx, 4096 * HAWK_SIZEOF(hawk_bch_t)); rtx->formatmbs.tmp.ptr = (hawk_bch_t*)hawk_rtx_allocmem(rtx, 4096 * HAWK_SIZEOF(hawk_bch_t));
if (!rtx->formatmbs.tmp.ptr) goto oops_10; if (!rtx->formatmbs.tmp.ptr) goto oops_11;
rtx->formatmbs.tmp.len = 4096; rtx->formatmbs.tmp.len = 4096;
rtx->formatmbs.tmp.inc = 4096 * 2; rtx->formatmbs.tmp.inc = 4096 * 2;
if (rtx->awk->tree.chain_size > 0) if (rtx->awk->tree.chain_size > 0)
{ {
rtx->pattern_range_state = (hawk_oob_t*)hawk_rtx_allocmem(rtx, rtx->awk->tree.chain_size * HAWK_SIZEOF(hawk_oob_t)); rtx->pattern_range_state = (hawk_oob_t*)hawk_rtx_allocmem(rtx, rtx->awk->tree.chain_size * HAWK_SIZEOF(hawk_oob_t));
if (!rtx->pattern_range_state) goto oops_11; if (!rtx->pattern_range_state) goto oops_12;
HAWK_MEMSET (rtx->pattern_range_state, 0, rtx->awk->tree.chain_size * HAWK_SIZEOF(hawk_oob_t)); HAWK_MEMSET (rtx->pattern_range_state, 0, rtx->awk->tree.chain_size * HAWK_SIZEOF(hawk_oob_t));
} }
else rtx->pattern_range_state = HAWK_NULL; else rtx->pattern_range_state = HAWK_NULL;
@ -962,20 +963,22 @@ static int init_rtx (hawk_rtx_t* rtx, hawk_t* awk, hawk_rio_cbs_t* rio)
return 0; return 0;
oops_11: oops_12:
hawk_rtx_freemem (rtx, rtx->formatmbs.tmp.ptr); hawk_rtx_freemem (rtx, rtx->formatmbs.tmp.ptr);
oops_10: oops_11:
hawk_rtx_freemem (rtx, rtx->format.tmp.ptr); hawk_rtx_freemem (rtx, rtx->format.tmp.ptr);
oops_9: oops_10:
hawk_htb_close (rtx->named); hawk_htb_close (rtx->named);
oops_8: oops_9:
hawk_becs_fini (&rtx->formatmbs.fmt); hawk_becs_fini (&rtx->formatmbs.fmt);
oops_7: oops_8:
hawk_becs_fini (&rtx->formatmbs.out); hawk_becs_fini (&rtx->formatmbs.out);
oops_6: oops_7:
hawk_ooecs_fini (&rtx->format.fmt); hawk_ooecs_fini (&rtx->format.fmt);
oops_5: oops_6:
hawk_ooecs_fini (&rtx->format.out); hawk_ooecs_fini (&rtx->format.out);
oops_5:
hawk_becs_fini (&rtx->inrec.linegb);
oops_4: oops_4:
hawk_ooecs_fini (&rtx->inrec.lineg); hawk_ooecs_fini (&rtx->inrec.lineg);
oops_3: oops_3:
@ -1074,6 +1077,7 @@ static void fini_rtx (hawk_rtx_t* rtx, int fini_globals)
rtx->inrec.flds = HAWK_NULL; rtx->inrec.flds = HAWK_NULL;
rtx->inrec.maxflds = 0; rtx->inrec.maxflds = 0;
} }
hawk_becs_fini (&rtx->inrec.linegb);
hawk_ooecs_fini (&rtx->inrec.lineg); hawk_ooecs_fini (&rtx->inrec.lineg);
hawk_ooecs_fini (&rtx->inrec.linew); hawk_ooecs_fini (&rtx->inrec.linew);
hawk_ooecs_fini (&rtx->inrec.line); hawk_ooecs_fini (&rtx->inrec.line);
@ -1459,14 +1463,6 @@ static hawk_val_t* run_bpae_loop (hawk_rtx_t* rtx)
/* start the BEGIN-pattern block-END loop */ /* start the BEGIN-pattern block-END loop */
hawk_val_t* hawk_rtx_loop (hawk_rtx_t* rtx) hawk_val_t* hawk_rtx_loop (hawk_rtx_t* rtx)
{
if (rtx->awk->parse.pragma.startup[0] != '\0')
{
/* @pragma startup xxxx specified.
* divert hawk_rtx_loop() to call the specified function */
return hawk_rtx_callwithoocstrarr(rtx, rtx->awk->parse.pragma.startup, HAWK_NULL, 0); /* TODO: pass argument */
}
else
{ {
hawk_val_t* retv = HAWK_NULL; hawk_val_t* retv = HAWK_NULL;
@ -1482,7 +1478,6 @@ hawk_val_t* hawk_rtx_loop (hawk_rtx_t* rtx)
rtx->exit_level = EXIT_NONE; rtx->exit_level = EXIT_NONE;
return retv; return retv;
} }
}
hawk_val_t* hawk_rtx_execwithucstrarr (hawk_rtx_t* rtx, const hawk_uch_t* args[], hawk_oow_t nargs) hawk_val_t* hawk_rtx_execwithucstrarr (hawk_rtx_t* rtx, const hawk_uch_t* args[], hawk_oow_t nargs)
{ {
@ -6678,7 +6673,7 @@ static hawk_val_t* eval_pos (hawk_rtx_t* rtx, hawk_nde_t* nde)
return v; return v;
} }
static hawk_val_t* eval_getline (hawk_rtx_t* rtx, hawk_nde_t* nde) static hawk_val_t* __eval_getline (hawk_rtx_t* rtx, hawk_nde_t* nde, int mbs)
{ {
hawk_nde_getline_t* p; hawk_nde_getline_t* p;
hawk_val_t* v, * tmp; hawk_val_t* v, * tmp;
@ -6810,6 +6805,11 @@ skip_read:
return tmp; return tmp;
} }
static hawk_val_t* eval_getline (hawk_rtx_t* rtx, hawk_nde_t* nde)
{
return __eval_getline(rtx, nde, 0);
}
static hawk_val_t* eval_print (hawk_rtx_t* run, hawk_nde_t* nde) static hawk_val_t* eval_print (hawk_rtx_t* run, hawk_nde_t* nde)
{ {
int n = run_print(run, (hawk_nde_print_t*)nde); int n = run_print(run, (hawk_nde_print_t*)nde);

View File

@ -1716,6 +1716,9 @@ static hawk_ooi_t nwio_handler_rest (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_r
case HAWK_RIO_CMD_READ: case HAWK_RIO_CMD_READ:
return hawk_nwio_read((hawk_nwio_t*)riod->handle, data, size); return hawk_nwio_read((hawk_nwio_t*)riod->handle, data, size);
case HAWK_RIO_CMD_READBYTES:
return hawk_nwio_readbytes(((hawk_nwio_t*)riod->handle, data, size);
case HAWK_RIO_CMD_WRITE: case HAWK_RIO_CMD_WRITE:
return hawk_nwio_write((hawk_nwio_t*)riod->handle, data, size); return hawk_nwio_write((hawk_nwio_t*)riod->handle, data, size);
@ -1850,6 +1853,9 @@ static hawk_ooi_t pio_handler_rest (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_ri
case HAWK_RIO_CMD_READ: case HAWK_RIO_CMD_READ:
return hawk_pio_read((hawk_pio_t*)riod->handle, HAWK_PIO_OUT, data, size); return hawk_pio_read((hawk_pio_t*)riod->handle, HAWK_PIO_OUT, data, size);
case HAWK_RIO_CMD_READ_BYTES:
return hawk_pio_readbytes((hawk_pio_t*)riod->handle, HAWK_PIO_IN, data, size);
case HAWK_RIO_CMD_WRITE: case HAWK_RIO_CMD_WRITE:
return hawk_pio_write((hawk_pio_t*)riod->handle, HAWK_PIO_IN, data, size); return hawk_pio_write((hawk_pio_t*)riod->handle, HAWK_PIO_IN, data, size);
@ -1967,6 +1973,9 @@ static hawk_ooi_t awk_rio_file (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_rio_ar
case HAWK_RIO_CMD_READ: case HAWK_RIO_CMD_READ:
return hawk_sio_getoochars((hawk_sio_t*)riod->handle, data, size); return hawk_sio_getoochars((hawk_sio_t*)riod->handle, data, size);
case HAWK_RIO_CMD_READ_BYTES:
return hawk_sio_getbchars((hawk_sio_t*)riod->handle, data, size);
case HAWK_RIO_CMD_WRITE: case HAWK_RIO_CMD_WRITE:
return hawk_sio_putoochars((hawk_sio_t*)riod->handle, data, size); return hawk_sio_putoochars((hawk_sio_t*)riod->handle, data, size);
@ -2225,6 +2234,30 @@ static hawk_ooi_t awk_rio_console (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_rio
return nn; return nn;
} }
case HAWK_RIO_CMD_READ_BYTES:
{
hawk_ooi_t nn;
while ((nn = hawk_sio_getbchars((hawk_sio_t*)riod->handle, data, size)) == 0)
{
int n;
hawk_sio_t* sio = (hawk_sio_t*)riod->handle;
n = open_rio_console(rtx, riod);
if (n <= -1) return -1;
if (n == 0)
{
/* no more input console */
return 0;
}
if (sio) hawk_sio_close (sio);
}
return nn;
}
case HAWK_RIO_CMD_WRITE: case HAWK_RIO_CMD_WRITE:
return hawk_sio_putoochars((hawk_sio_t*)riod->handle, data, size); return hawk_sio_putoochars((hawk_sio_t*)riod->handle, data, size);

View File

@ -279,6 +279,9 @@ struct cmdline_t
hawk_bch_t* outf; hawk_bch_t* outf;
hawk_bch_t* outc; hawk_bch_t* outc;
hawk_bch_t* fs; hawk_bch_t* fs;
HAWK::Hawk::Value* argv;
int argc;
}; };
static int handle_cmdline (MyHawk& awk, int argc, hawk_bch_t* argv[], cmdline_t* cmdline) static int handle_cmdline (MyHawk& awk, int argc, hawk_bch_t* argv[], cmdline_t* cmdline)
@ -331,6 +334,7 @@ static int handle_cmdline (MyHawk& awk, int argc, hawk_bch_t* argv[], cmdline_t*
if (opt.ind < argc && !cmdline->inf) cmdline->ins = argv[opt.ind++]; if (opt.ind < argc && !cmdline->inf) cmdline->ins = argv[opt.ind++];
cmdline->argc = 0;
while (opt.ind < argc) while (opt.ind < argc)
{ {
if (awk.addArgument(argv[opt.ind++]) <= -1) if (awk.addArgument(argv[opt.ind++]) <= -1)
@ -349,6 +353,45 @@ static int handle_cmdline (MyHawk& awk, int argc, hawk_bch_t* argv[], cmdline_t*
return 1; return 1;
} }
static void free_args_for_exec (cmdline_t* cmdline)
{
if (cmdline->argv)
{
delete[] cmdline->argv;
cmdline->argv = HAWK_NULL;
}
cmdline->argc = 0;
}
static int make_args_for_exec (cmdline_t* cmdline, MyHawk& hawk, MyHawk::Run* run)
{
try
{
cmdline->argc = 0;
cmdline->argv = HAWK_NULL;
hawk_oow_t count = hawk.getArgumentCount();
cmdline->argv = new HAWK::Hawk::Value[count - 1];
for (hawk_oow_t i = 1; i < count; i++)
{
if (cmdline->argv[i - 1].setStr(run, hawk.getArgument(i)) <= -1)
{
free_args_for_exec (cmdline);
return -1;
}
cmdline->argc++;
}
}
catch (...)
{
free_args_for_exec (cmdline);
hawk.setError (HAWK_ENOMEM);
return -1;
}
return 0;
}
static int hawk_main (MyHawk& hawk, int argc, hawk_bch_t* argv[]) static int hawk_main (MyHawk& hawk, int argc, hawk_bch_t* argv[])
{ {
@ -406,12 +449,22 @@ static int hawk_main (MyHawk& hawk, int argc, hawk_bch_t* argv[])
} }
MyHawk::Value ret; MyHawk::Value ret;
if (hawk.loop(&ret) <= -1)
if (make_args_for_exec(&cmdline, hawk, run) <= -1) // data made here is not uself if hawk.loop() invoked in hawk.exec().
{ {
print_error (hawk); print_error (hawk);
return -1; return -1;
} }
//if (hawk.loop(&ret) <= -1)
if (hawk.exec(&ret, cmdline.argv, cmdline.argc) <= -1)
{
print_error (hawk);
return -1;
}
free_args_for_exec (&cmdline);
return 0; return 0;
} }