From c219d073cacc4f6bc63d4a2fd872a7c1dfbacfa4 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 20 May 2024 18:19:45 +0900 Subject: [PATCH] experimental gets --- lib/hcl.h | 2 ++ lib/prim.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/lib/hcl.h b/lib/hcl.h index b9ffbd8..7530706 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -1356,6 +1356,8 @@ struct hcl_io_udiarg_t hcl_uint8_t buf[HCL_MBLEN_MAX]; hcl_oow_t len; } rsd; /* residue bytes for HCL_IO_READ_BYTES */ + + int eof_reached; }; typedef struct hcl_io_udoarg_t hcl_io_udoarg_t; diff --git a/lib/prim.c b/lib/prim.c index e6918fd..b8eab1f 100644 --- a/lib/prim.c +++ b/lib/prim.c @@ -241,7 +241,7 @@ static int get_udi_char (hcl_t* hcl, hcl_ooch_t* ch) curinp = &hcl->io.udi_arg; - #if defined(HCL_OOCH_IS_UCH) +#if defined(HCL_OOCH_IS_UCH) if (curinp->byte_oriented) { hcl_cmgr_t* cmgr; @@ -269,6 +269,7 @@ static int get_udi_char (hcl_t* hcl, hcl_ooch_t* ch) hcl_seterrbfmt (hcl, HCL_EECERR, "incomplete byte sequence in input stream"); return -1; } + curinp->eof_reached = 1; return 0; } @@ -293,7 +294,6 @@ static int get_udi_char (hcl_t* hcl, hcl_ooch_t* ch) n = cmgr->bctouc((const hcl_bch_t*)inpptr, inplen, &c); if (n == 0) /* invalid sequence */ { - /* TODO: more accurate location of the invalid byte sequence */ hcl_seterrbfmt (hcl, HCL_EECERR, "invalid byte sequence in input stream"); return -1; } @@ -325,7 +325,6 @@ static int get_udi_char (hcl_t* hcl, hcl_ooch_t* ch) x = hcl->io.udi_rdr(hcl, HCL_IO_READ, curinp); if (x <= -1) { - /* TODO: more accurate location of failure */ const hcl_ooch_t* orgmsg = hcl_backuperrmsg(hcl); hcl_seterrbfmt (hcl, HCL_ERRNUM(hcl), "unable to read input stream - %js", orgmsg); return -1; @@ -333,6 +332,7 @@ static int get_udi_char (hcl_t* hcl, hcl_ooch_t* ch) if (curinp->xlen <= 0) { /* got EOF from an included stream */ + curinp->eof_reached++; return 0; } @@ -346,7 +346,6 @@ static int get_udi_char (hcl_t* hcl, hcl_ooch_t* ch) } #endif - curinp->b.pos += taken; #if defined(HCL_OOCH_IS_UCH) curinp->rsd.len = 0; /* clear up the residue byte buffer. needed for byte reading only */ @@ -383,6 +382,7 @@ static int get_udi_byte (hcl_t* hcl, hcl_uint8_t* bt) if (curinp->xlen <= 0) { /* got EOF from an included stream */ + curinp->eof_reached++; return 0; } @@ -424,6 +424,80 @@ static hcl_pfrc_t pf_getch (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) return HCL_PF_SUCCESS; } +static hcl_pfrc_t pf_gets (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) +{ + hcl_io_udiarg_t* curinp; + hcl_oop_t v; + + curinp = &hcl->io.udi_arg; + if (curinp->eof_reached) + { + v = hcl->_nil; + } + else + { + int n; + hcl_ooch_t ch; + hcl_ooch_t buf[10]; + hcl_ooch_t* ptr; + hcl_oow_t len, capa; + + ptr = buf; + len = 0; + capa = HCL_COUNTOF(buf); + while (1) + { + n = get_udi_char(hcl, &ch); + if (n <= -1) return HCL_PF_FAILURE; + if (n == 0) break; + + if (len >= capa) + { + hcl_ooch_t* tmp; + hcl_oow_t newcapa; + + newcapa = capa + HCL_COUNTOF(buf); + if (ptr == buf) + { + tmp = hcl_allocmem(hcl, HCL_SIZEOF(*ptr) * newcapa); + if (HCL_UNLIKELY(!tmp)) return HCL_PF_FAILURE; + HCL_MEMCPY (tmp, buf, HCL_SIZEOF(buf)); + } + else + { + tmp = hcl_reallocmem(hcl, ptr, HCL_SIZEOF(*ptr) * newcapa); + if (HCL_UNLIKELY(!tmp)) + { + hcl_freemem(hcl, ptr); + return HCL_PF_FAILURE; + } + } + + ptr = tmp; + capa = newcapa; + } + ptr[len++] = ch; + if (ch == '\n') break; /* TODO: don't hardcode EOL */ + } + + if (len <= 0) + { + HCL_ASSERT (hcl, ptr == buf); + v = hcl->_nil; + } + else + { + v = hcl_makestring(hcl, ptr, len, 0); + if (ptr != buf) hcl_freemem(hcl, ptr); + if (HCL_UNLIKELY(!v)) return HCL_PF_FAILURE; + } + + } + + HCL_STACK_SETRET (hcl, nargs, v); + return HCL_PF_SUCCESS; +} + static hcl_pfrc_t pf_scanf (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) { if (hcl_scfmtcallstack(hcl, nargs) <= -1) @@ -1134,6 +1208,7 @@ static pf_t builtin_prims[] = { 0, 0, pf_getbyte, 7, { 'g','e','t','b','y','t','e' } }, { 0, 0, pf_getch, 5, { 'g','e','t','c','h' } }, + { 0, 0, pf_gets, 4, { 'g','e','t','s' } }, { 0, HCL_TYPE_MAX(hcl_oow_t), pf_log, 3, { 'l','o','g' } }, { 1, HCL_TYPE_MAX(hcl_oow_t), pf_logf, 4, { 'l','o','g','f' } }, { 1, HCL_TYPE_MAX(hcl_oow_t), pf_printf, 6, { 'p','r','i','n','t','f' } },