diff --git a/hawk/lib/Hawk.cpp b/hawk/lib/Hawk.cpp index e4c813a5..f1d53c5b 100644 --- a/hawk/lib/Hawk.cpp +++ b/hawk/lib/Hawk.cpp @@ -32,7 +32,6 @@ HAWK_BEGIN_NAMESPACE(HAWK) ///////////////////////////////// - ////////////////////////////////////////////////////////////////// // 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) { hawk_val_t* tmp; + tmp = numeric? hawk_rtx_makenstrvalwithucstr(r->rtx, str): hawk_rtx_makestrvalwithucstr(r->rtx, str); 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) { hawk_val_t* tmp; + tmp = numeric? hawk_rtx_makenstrvalwithbcstr(r->rtx, str): hawk_rtx_makestrvalwithbcstr(r->rtx, str); 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; } +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 () { HAWK_ASSERT (awk != HAWK_NULL); diff --git a/hawk/lib/Hawk.hpp b/hawk/lib/Hawk.hpp index 69335038..95fc1abe 100644 --- a/hawk/lib/Hawk.hpp +++ b/hawk/lib/Hawk.hpp @@ -991,7 +991,7 @@ public: void clear (); - operator hawk_val_t* () const { return val; } + operator hawk_val_t* () const { return this->val; } operator hawk_int_t () const; operator hawk_flt_t () const; operator const hawk_ooch_t* () const; @@ -1001,17 +1001,17 @@ public: hawk_val_t* toVal () const { - return operator hawk_val_t* (); + return this->operator hawk_val_t* (); } hawk_int_t toInt () const { - return operator hawk_int_t (); + return this->operator hawk_int_t (); } 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 @@ -1385,6 +1385,16 @@ public: 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 /// @@ -1462,6 +1472,17 @@ public: /// 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. /// \return integer >= 0 on success, -1 on failure. diff --git a/hawk/lib/hawk-pio.h b/hawk/lib/hawk-pio.h index 94e57f9c..f2183f37 100644 --- a/hawk/lib/hawk-pio.h +++ b/hawk/lib/hawk-pio.h @@ -293,10 +293,18 @@ HAWK_EXPORT hawk_pio_pid_t hawk_pio_getchild ( HAWK_EXPORT hawk_ooi_t hawk_pio_read ( hawk_pio_t* pio, /**< pio object */ hawk_pio_hid_t hid, /**< handle ID */ - void* buf, /**< buffer to fill */ - hawk_oow_t size /**< buffer size */ + void* buf, /**< buffer to fill */ + 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 * from the buffer pointed to by \a data. If #HAWK_PIO_TEXT is used diff --git a/hawk/lib/hawk-prv.h b/hawk/lib/hawk-prv.h index fee25845..65e47267 100644 --- a/hawk/lib/hawk-prv.h +++ b/hawk/lib/hawk-prv.h @@ -392,6 +392,7 @@ struct hawk_rtx_t hawk_ooecs_t line; /* entire line */ hawk_ooecs_t linew; /* line for manipulation, if necessary */ hawk_ooecs_t lineg; /* line buffer for getline */ + hawk_becs_t linegb; /* line buffer for getline mbs */ hawk_val_t* d0; /* $0 */ diff --git a/hawk/lib/hawk.h b/hawk/lib/hawk.h index c1914cfb..e1769143 100644 --- a/hawk/lib/hawk.h +++ b/hawk/lib/hawk.h @@ -619,7 +619,7 @@ enum hawk_rio_cmd_t HAWK_RIO_CMD_CLOSE = 1, /**< close a stream */ HAWK_RIO_CMD_READ = 2, /**< read 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_FLUSH = 6, /**< flush buffered data to a stream */ HAWK_RIO_CMD_NEXT = 7 /**< close the current stream and diff --git a/hawk/lib/pio.c b/hawk/lib/pio.c index 30f62f1c..7fa33062 100644 --- a/hawk/lib/pio.c +++ b/hawk/lib/pio.c @@ -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_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) { #if defined(_WIN32) @@ -2053,7 +2061,7 @@ static hawk_ooi_t pio_write (hawk_pio_t* pio, const void* data, hawk_oow_t size, size = HAWK_TYPE_MAX(hawk_ooi_t) & HAWK_TYPE_MAX(size_t); rewrite: - n = HAWK_WRITE (hnd, data, size); + n = HAWK_WRITE(hnd, data, size); if (n <= -1) { if (errno == EINTR) diff --git a/hawk/lib/rio.c b/hawk/lib/rio.c index 3594f81e..08f38e9b 100644 --- a/hawk/lib/rio.c +++ b/hawk/lib/rio.c @@ -211,7 +211,7 @@ static HAWK_INLINE int resolve_rs (hawk_rtx_t* rtx, hawk_val_t* rs, hawk_oocs_t* break; default: - rrs->ptr = hawk_rtx_valtooocstrdup (rtx, rs, &rrs->len); + rrs->ptr = hawk_rtx_valtooocstrdup(rtx, rs, &rrs->len); if (rrs->ptr == HAWK_NULL) ret = -1; break; } @@ -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[1] != HAWK_NULL); - ret = hawk_rtx_matchrex( - rtx, rtx->gbl.rs[rtx->gbl.ignorecase], - HAWK_OOECS_OOCS(buf), HAWK_OOECS_OOCS(buf), - &match, HAWK_NULL); + ret = hawk_rtx_matchrex(rtx, rtx->gbl.rs[rtx->gbl.ignorecase], HAWK_OOECS_OOCS(buf), HAWK_OOECS_OOCS(buf), &match, HAWK_NULL); if (ret >= 1) { 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; } + +#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) { hawk_rio_arg_t* p; @@ -337,8 +396,8 @@ int hawk_rtx_readio (hawk_rtx_t* rtx, int in_type, const hawk_ooch_t* name, hawk 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. */ + * set by the user handler, we set + * it here to HAWK_EIOIMPL. */ hawk_rtx_seterrnum (rtx, HAWK_NULL, HAWK_EIOIMPL); } @@ -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) { - /* We can return EOF now if the record buffer - * is empty */ + /* We can return EOF now if the record buffer is empty */ ret = 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; } + +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) { hawk_val_type_t vtype; diff --git a/hawk/lib/run.c b/hawk/lib/run.c index 0d8ef89f..89b59e4d 100644 --- a/hawk/lib/run.c +++ b/hawk/lib/run.c @@ -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.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->format.out, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_4; - if (hawk_ooecs_init(&rtx->format.fmt, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_5; + if (hawk_becs_init(&rtx->inrec.linegb, hawk_rtx_getgem(rtx), DEF_BUF_CAPA) <= -1) goto oops_4; + 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.fmt, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_7; + 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_8; 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_htb_setstyle (rtx->named, &style_for_named); 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.inc = 4096 * 2; 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.inc = 4096 * 2; 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)); - 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)); } 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; -oops_11: +oops_12: hawk_rtx_freemem (rtx, rtx->formatmbs.tmp.ptr); -oops_10: +oops_11: hawk_rtx_freemem (rtx, rtx->format.tmp.ptr); -oops_9: +oops_10: hawk_htb_close (rtx->named); -oops_8: +oops_9: hawk_becs_fini (&rtx->formatmbs.fmt); -oops_7: +oops_8: hawk_becs_fini (&rtx->formatmbs.out); -oops_6: +oops_7: hawk_ooecs_fini (&rtx->format.fmt); -oops_5: +oops_6: hawk_ooecs_fini (&rtx->format.out); +oops_5: + hawk_becs_fini (&rtx->inrec.linegb); oops_4: hawk_ooecs_fini (&rtx->inrec.lineg); oops_3: @@ -1074,6 +1077,7 @@ static void fini_rtx (hawk_rtx_t* rtx, int fini_globals) rtx->inrec.flds = HAWK_NULL; rtx->inrec.maxflds = 0; } + hawk_becs_fini (&rtx->inrec.linegb); hawk_ooecs_fini (&rtx->inrec.lineg); hawk_ooecs_fini (&rtx->inrec.linew); hawk_ooecs_fini (&rtx->inrec.line); @@ -1460,28 +1464,19 @@ static hawk_val_t* run_bpae_loop (hawk_rtx_t* rtx) /* start the BEGIN-pattern block-END loop */ hawk_val_t* hawk_rtx_loop (hawk_rtx_t* rtx) { - if (rtx->awk->parse.pragma.startup[0] != '\0') + hawk_val_t* retv = HAWK_NULL; + + rtx->exit_level = EXIT_NONE; + + if (enter_stack_frame(rtx) == 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 */ + retv = run_bpae_loop(rtx); + exit_stack_frame (rtx); } - else - { - hawk_val_t* retv = HAWK_NULL; - rtx->exit_level = EXIT_NONE; - - if (enter_stack_frame(rtx) == 0) - { - retv = run_bpae_loop(rtx); - exit_stack_frame (rtx); - } - - /* reset the exit level */ - rtx->exit_level = EXIT_NONE; - return retv; - } + /* reset the exit level */ + rtx->exit_level = EXIT_NONE; + return retv; } 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; } -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_val_t* v, * tmp; @@ -6805,11 +6800,16 @@ read_console_again: } skip_read: - tmp = hawk_rtx_makeintval (rtx, n); + tmp = hawk_rtx_makeintval(rtx, n); if (!tmp) ADJERR_LOC (rtx, &nde->loc); 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) { int n = run_print(run, (hawk_nde_print_t*)nde); diff --git a/hawk/lib/std.c b/hawk/lib/std.c index d4e476fc..39bd3f5a 100644 --- a/hawk/lib/std.c +++ b/hawk/lib/std.c @@ -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: 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: return hawk_nwio_write((hawk_nwio_t*)riod->handle, data, size); @@ -1848,7 +1851,10 @@ static hawk_ooi_t pio_handler_rest (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_ri } 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: 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: 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: 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; } + 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: return hawk_sio_putoochars((hawk_sio_t*)riod->handle, data, size); diff --git a/hawk/samples/hawk51.cpp b/hawk/samples/hawk51.cpp index 99a4d203..071d0e33 100644 --- a/hawk/samples/hawk51.cpp +++ b/hawk/samples/hawk51.cpp @@ -279,6 +279,9 @@ struct cmdline_t hawk_bch_t* outf; hawk_bch_t* outc; 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) @@ -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++]; + cmdline->argc = 0; while (opt.ind < argc) { 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; } +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[]) { @@ -374,7 +417,7 @@ static int hawk_main (MyHawk& hawk, int argc, hawk_bch_t* argv[]) in = (cmdline.ins)? (MyHawk::Source*)&in_str: (MyHawk::Source*)&in_file; out = (cmdline.outf)? (MyHawk::Source*)&out_file: &MyHawk::Source::NONE; - run = hawk.parse (*in, *out); + run = hawk.parse(*in, *out); if (run == HAWK_NULL) { print_error (hawk); @@ -406,12 +449,22 @@ static int hawk_main (MyHawk& hawk, int argc, hawk_bch_t* argv[]) } 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); + 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; }