implemented a way for a console input handler to indicate medium switching
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-10-05 02:05:19 +09:00
parent 4db3ca157f
commit 50678c4973
6 changed files with 71 additions and 38 deletions

View File

@ -621,8 +621,8 @@ public:
const void* getHandle () const { return this->riod->handle; }
void setHandle (void* handle) { this->riod->handle = handle; }
int getUflags () const { return this->riod->uflags; }
void setUflags (int uflags) { this->riod->uflags = uflags; }
hawk_uint16_t getUflags () const { return this->riod->uflags; }
void setUflags (hawk_uint16_t uflags) { this->riod->uflags = uflags; }
operator Hawk* () const { return this->run->hawk; }
operator hawk_t* () const
@ -811,6 +811,9 @@ public:
virtual int next (Console& io) = 0;
};
bool getSwitched() const { return this->riod->console_switched; }
void setSwitched(bool v) { this->riod->console_switched = v; }
protected:
Console (Run* run, hawk_rio_arg_t* riod);
~Console ();

View File

@ -946,6 +946,11 @@ nextfile:
pair = hawk_map_search(map, ibuf, ibuflen);
if (!pair)
{
if (this->runarg_count < i_argc)
{
this->runarg_index++;
goto nextfile;
}
if (this->runarg_count <= 0) goto console_open_stdin;
return 0;
}
@ -1134,6 +1139,7 @@ hawk_ooi_t HawkStd::readConsole (Console& io, hawk_ooch_t* data, hawk_oow_t size
if (sio) hawk_sio_close(sio);
((Run*)io)->setGlobal(HAWK_GBL_FNR, (hawk_int_t)0);
io.setSwitched(true); // indicates that the console medium switched
}
return nn;
@ -1159,6 +1165,7 @@ hawk_ooi_t HawkStd::readConsoleBytes (Console& io, hawk_bch_t* data, hawk_oow_t
if (sio) hawk_sio_close(sio);
((Run*)io)->setGlobal(HAWK_GBL_FNR, (hawk_int_t)0);
io.setSwitched(true); // indicates that the data comes from a new medium
}
return nn;

View File

@ -756,7 +756,8 @@ struct hawk_rio_arg_t
/* read-write. a user handler can do whatever it likes to do with these. */
void* handle; /**< I/O handle set by a handler */
int uflags; /**< user-flags set by a handler */
hawk_uint16_t uflags; /**< user-flags set by a handler */
hawk_uint16_t console_switched; /**< set by a console handler if it has opened a new underlying medium and continued reading */
/*-- from here down, internal use only --*/
int type;
@ -771,15 +772,15 @@ struct hawk_rio_arg_t
} u;
hawk_oow_t pos;
hawk_oow_t len;
int eof;
int eos;
int mbs;
unsigned int eof: 2;
unsigned int eos: 2;
unsigned int mbs: 2;
} in;
struct
{
int eof;
int eos;
unsigned int eof: 2;
unsigned int eos: 2;
} out;
struct hawk_rio_arg_t* next;

View File

@ -165,7 +165,7 @@ static int find_rio_in (
p->in.eof = 0;
p->in.eos = 0;
*/
p->in.mbs = mbs_if_new;
p->in.mbs = !!mbs_if_new;
/* request to open the stream */
x = handler(rtx, HAWK_RIO_CMD_OPEN, p, HAWK_NULL, 0);
@ -453,14 +453,16 @@ int hawk_rtx_readio (hawk_rtx_t* rtx, hawk_in_type_t in_type, const hawk_ooch_t*
break;
}
/* used for console only. but reset it regardless of the stream type.
* it must be faster than checking the type and resetting it */
p->console_switched = 0;
x = handler(rtx, HAWK_RIO_CMD_READ, p, p->in.u.buf, HAWK_COUNTOF(p->in.u.buf));
if (x <= -1)
{
ret = -1;
break;
}
if (x == 0)
else if (x == 0)
{
/* EOF reached */
p->in.eof = 1;
@ -508,6 +510,18 @@ int hawk_rtx_readio (hawk_rtx_t* rtx, hawk_in_type_t in_type, const hawk_ooch_t*
p->in.len = x;
p->in.pos = 0;
/* the new data is a chunk from a new underlying stream.
* let's end the record even if it didn't match RS yet.
* for example, `hawk -v RS=separator -f script f1.txt f2.txt`
* the console handler is invoked over all the specified files.
* if `separator` is not found when the end of `f1.txt` is reached,
* `f2.txt` is opened and read. When the handler returns the
* first part of the second file, it must indicate this special
* condition. if it's not indicated, it goes on without breaking
* the record at the end of the first file.
*/
if (p->console_switched) break;
}
if (rrs.ptr == HAWK_NULL)
@ -820,6 +834,7 @@ int hawk_rtx_readiobytes (hawk_rtx_t* rtx, hawk_in_type_t in_type, const hawk_oo
break;
}
p->console_switched = 0;
x = handler(rtx, HAWK_RIO_CMD_READ_BYTES, p, p->in.u.bbuf, HAWK_COUNTOF(p->in.u.bbuf));
if (x <= -1)
{
@ -875,6 +890,10 @@ int hawk_rtx_readiobytes (hawk_rtx_t* rtx, hawk_in_type_t in_type, const hawk_oo
p->in.len = x;
p->in.pos = 0;
/* the new data is a chunk from a new underlying medium.
* let's end the record even if it didn't match RS yet. */
if (p->console_switched) break;
}
if (rrs.ptr == HAWK_NULL)

View File

@ -2621,6 +2621,7 @@ static hawk_ooi_t hawk_rio_console (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_ri
/* reset FNR to 0 here since the caller doesn't know that the file has changed. */
hawk_rtx_setgbl(rtx, HAWK_GBL_FNR, hawk_rtx_makeintval(rtx, 0));
riod->console_switched = 1;
}
if (nn <= -1) set_rio_error(rtx, HAWK_EREAD, HAWK_T("unable to read"), hawk_sio_getpath((hawk_sio_t*)riod->handle));
@ -2646,7 +2647,9 @@ static hawk_ooi_t hawk_rio_console (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_ri
}
if (sio) hawk_sio_close(sio);
hawk_rtx_setgbl(rtx, HAWK_GBL_FNR, hawk_rtx_makeintval(rtx, 0));
riod->console_switched = 1;
}
if (nn <= -1) set_rio_error(rtx, HAWK_EREAD, HAWK_T("unable to read"), hawk_sio_getpath((hawk_sio_t*)riod->handle));
@ -2887,7 +2890,7 @@ static int build_environ (hawk_rtx_t* rtx, int gbl_id, env_char_t* envarr[])
kptr = hawk_rtx_dupbtoucstr(rtx, envarr[count], &klen, 1);
vptr = hawk_rtx_dupbtoucstr(rtx, eq + 1, &vlen, 1);
if (HAWK_UNLIKELY(!kptr || !vptr))
if (HAWK_UNLIKELY(!kptr) || HAWK_UNLIKELY(!vptr))
{
if (kptr) hawk_rtx_freemem(rtx, kptr);
if (vptr) hawk_rtx_freemem(rtx, vptr);
@ -2904,7 +2907,7 @@ static int build_environ (hawk_rtx_t* rtx, int gbl_id, env_char_t* envarr[])
kptr = hawk_rtx_duputobcstr(rtx, envarr[count], &klen);
vptr = hawk_rtx_duputobcstr(rtx, eq + 1, &vlen);
if (HAWK_UNLIKELY(!kptr || !vptr))
if (HAWK_UNLIKELY(!kptr) || HAWK_UNLIKELY(!vptr))
{
if (kptr) hawk_rtx_freemem(rtx, kptr);
if (vptr) hawk_rtx_freeme(rtx, vptr):
@ -2967,7 +2970,7 @@ static int build_environ (hawk_rtx_t* rtx, int gbl_id, env_char_t* envarr[])
}
}
if (hawk_rtx_setgbl(rtx, gbl_id, v_env) == -1)
if (hawk_rtx_setgbl(rtx, gbl_id, v_env) <= -1)
{
hawk_rtx_refdownval(rtx, v_env);
return -1;

View File

@ -481,11 +481,11 @@ static int hawk_main (MyHawk& hawk, int argc, hawk_bch_t* argv[])
if (hawk.exec(&ret, cmdline.argv, cmdline.argc) <= -1)
{
print_error(hawk);
free_args_for_exec(&cmdline);
return -1;
}
free_args_for_exec(&cmdline);
return 0;
}