From 877c98d2626313eff99ef40ba5c692f2d59a2b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sat, 27 Nov 2021 00:04:12 +0100 Subject: [PATCH] fix bad end handling in string-input --- src/fh_builtins_text.c | 4 ++-- src/fh_input.c | 2 +- src/fh_parse.c | 29 +++++++++++++++++++++++------ src/fh_runtime.c | 2 +- testfiles/combinedtest.f | 1 - 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/fh_builtins_text.c b/src/fh_builtins_text.c index 649d22c..b86ed20 100644 --- a/src/fh_builtins_text.c +++ b/src/fh_builtins_text.c @@ -243,10 +243,10 @@ static enum fh_error w_c_quote(struct fh_thread_s *fh, const struct fh_word_s *w struct fh_instruction_s instr; if (fh->state == FH_STATE_INTERPRET) { - LOG("Interpret a c-string alloc: \"%.*s\"", (int) len, start); + LOG("Interpret a c-string alloc: \"%.*s\", %d", (int) len, start, len); TRY(ds_push(fh, addr)); } else { - LOG("Compile a c-string: \"%.*s\"", (int) len, start); + LOG("Compile a c-string: \"%.*s\", %d", (int) len, start, len); instr.kind = FH_INSTR_ALLOCSTR_C; instr.data = WORDALIGNED(len + 1); fh_heap_write(fh, addr - INSTR_SIZE, &instr, INSTR_SIZE); diff --git a/src/fh_input.c b/src/fh_input.c index 5b3a957..f66f43c 100644 --- a/src/fh_input.c +++ b/src/fh_input.c @@ -268,7 +268,7 @@ struct fh_input_spec_s *fh_create_input_from_string(char *str, size_t len, const return NULL; } - LOG("Evaluating: \"%.*s\"", (int)len, str); + LOG("Evaluating string: \"%.*s\", len %d", (int)len, str, len); spec->spec.free_self = free_strspec; spec->spec.refill_input_buffer = str_refill; diff --git a/src/fh_parse.c b/src/fh_parse.c index b03645f..b6ddf03 100644 --- a/src/fh_parse.c +++ b/src/fh_parse.c @@ -6,6 +6,22 @@ static inline bool isnl(char c) return c == '\n' || c == '\r'; } +static const char * strnchr(const char* s, char c, size_t len) +{ + while (len > 0) { + char x = *s; + if (!x) { + break; + } + if (x == c) { + return s; + } + s++; + len--; + } + return NULL; +} + /** Process a word read from input */ enum fh_error fh_handle_ascii_word( struct fh_thread_s *fh, @@ -44,7 +60,7 @@ enum fh_error fh_handle_ascii_word( long v = strtol(name, &endptr, base); // if base is 0, this will use auto-detection if (errno != 0 || (endptr - name) != wordlen) { - LOGE("Unknown word and fail to parse as number: \"%.*s\"", (int) wordlen, name); + LOGE("Unknown word and fail to parse as number: \"%.*s\", len %d", (int) wordlen, name, wordlen); return FH_ERR_UNKNOWN_WORD; } @@ -322,16 +338,17 @@ enum fh_error fh_process_line(struct fh_thread_s *fh) const char *const rp = ReadPtr; - char *end; + const char *end; size_t length; switch (fh->substate) { case FH_SUBSTATE_NONE: /* try to read a word */ - end = strchr(rp, ' '); + size_t maxlen = ReadLen - ReadPos; + end = strnchr(rp, ' ', maxlen); if (end) { length = end - rp; /* exclude the space */ } else { - length = strlen(rp); + length = strnlen(rp, maxlen); } ReadPos += length + 1; @@ -353,7 +370,7 @@ enum fh_error fh_process_line(struct fh_thread_s *fh) } else if (EQ(rp, "[else]", length)) { if (fh->parse_if_level == 1) { // we got here by running the [if] branch - LOG("\x1b[32m[else] end of false skip\x1b[m"); + LOG("\x1b[3m[else] end of false skip\x1b[m"); fh->parse_if_level--; } } else if (EQ(rp, "[then]", length)) { @@ -369,7 +386,7 @@ enum fh_error fh_process_line(struct fh_thread_s *fh) } } else if (fh->parse_if_level == 0) { /* eval a word */ - //LOG("Handle \"%.*s\"", (int) length, rp); + LOG("Handle \"%.*s\", len %d", (int) length, rp, length); TRY(fh_handle_ascii_word(fh, rp, length)); } else { if (EQ(rp, "\\", length)) { diff --git a/src/fh_runtime.c b/src/fh_runtime.c index 5359c96..131dcc9 100644 --- a/src/fh_runtime.c +++ b/src/fh_runtime.c @@ -354,7 +354,7 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0) goto instr; case FH_INSTR_ALLOCSTR_C: - LOG("\x1b[35mExec: alloc-str-c\x1b[m \"%.*s\"", fh->heap[fh->execptr], fh_str_at(fh, fh->execptr + 1)); + LOG("\x1b[35mExec: alloc-str-c\x1b[m \"%.*s\", %d", fh->heap[fh->execptr], fh_str_at(fh, fh->execptr + 1), fh->heap[fh->execptr]); TRY(ds_push(fh, fh->execptr)); fh->execptr += instr->data; goto instr; diff --git a/testfiles/combinedtest.f b/testfiles/combinedtest.f index 12f940e..8bd3662 100644 --- a/testfiles/combinedtest.f +++ b/testfiles/combinedtest.f @@ -1588,7 +1588,6 @@ T{ 25 RN2 EXECUTE -> 33 22 11 0 }T \ ----------------------------------------------------------------------------- TESTING C" -1 debug T{ : CQ1 C" 123" ; -> }T T{ CQ1 COUNT EVALUATE -> 123 }T T{ : CQ2 C" " ; -> }T