fix bad end handling in string-input

master
Ondřej Hruška 3 years ago
parent b09bbc4afa
commit 877c98d262
  1. 4
      src/fh_builtins_text.c
  2. 2
      src/fh_input.c
  3. 29
      src/fh_parse.c
  4. 2
      src/fh_runtime.c
  5. 1
      testfiles/combinedtest.f

@ -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; struct fh_instruction_s instr;
if (fh->state == FH_STATE_INTERPRET) { 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)); TRY(ds_push(fh, addr));
} else { } 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.kind = FH_INSTR_ALLOCSTR_C;
instr.data = WORDALIGNED(len + 1); instr.data = WORDALIGNED(len + 1);
fh_heap_write(fh, addr - INSTR_SIZE, &instr, INSTR_SIZE); fh_heap_write(fh, addr - INSTR_SIZE, &instr, INSTR_SIZE);

@ -268,7 +268,7 @@ struct fh_input_spec_s *fh_create_input_from_string(char *str, size_t len, const
return NULL; 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.free_self = free_strspec;
spec->spec.refill_input_buffer = str_refill; spec->spec.refill_input_buffer = str_refill;

@ -6,6 +6,22 @@ static inline bool isnl(char c)
return c == '\n' || c == '\r'; 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 */ /** Process a word read from input */
enum fh_error fh_handle_ascii_word( enum fh_error fh_handle_ascii_word(
struct fh_thread_s *fh, 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 long v = strtol(name, &endptr, base); // if base is 0, this will use auto-detection
if (errno != 0 || (endptr - name) != wordlen) { 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; 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; const char *const rp = ReadPtr;
char *end; const char *end;
size_t length; size_t length;
switch (fh->substate) { switch (fh->substate) {
case FH_SUBSTATE_NONE: case FH_SUBSTATE_NONE:
/* try to read a word */ /* try to read a word */
end = strchr(rp, ' '); size_t maxlen = ReadLen - ReadPos;
end = strnchr(rp, ' ', maxlen);
if (end) { if (end) {
length = end - rp; /* exclude the space */ length = end - rp; /* exclude the space */
} else { } else {
length = strlen(rp); length = strnlen(rp, maxlen);
} }
ReadPos += length + 1; ReadPos += length + 1;
@ -353,7 +370,7 @@ enum fh_error fh_process_line(struct fh_thread_s *fh)
} else if (EQ(rp, "[else]", length)) { } else if (EQ(rp, "[else]", length)) {
if (fh->parse_if_level == 1) { if (fh->parse_if_level == 1) {
// we got here by running the [if] branch // 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--; fh->parse_if_level--;
} }
} else if (EQ(rp, "[then]", length)) { } 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) { } else if (fh->parse_if_level == 0) {
/* eval a word */ /* 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)); TRY(fh_handle_ascii_word(fh, rp, length));
} else { } else {
if (EQ(rp, "\\", length)) { if (EQ(rp, "\\", length)) {

@ -354,7 +354,7 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0)
goto instr; goto instr;
case FH_INSTR_ALLOCSTR_C: 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)); TRY(ds_push(fh, fh->execptr));
fh->execptr += instr->data; fh->execptr += instr->data;
goto instr; goto instr;

@ -1588,7 +1588,6 @@ T{ 25 RN2 EXECUTE -> 33 22 11 0 }T
\ ----------------------------------------------------------------------------- \ -----------------------------------------------------------------------------
TESTING C" TESTING C"
1 debug
T{ : CQ1 C" 123" ; -> }T T{ : CQ1 C" 123" ; -> }T
T{ CQ1 COUNT EVALUATE -> 123 }T T{ CQ1 COUNT EVALUATE -> 123 }T
T{ : CQ2 C" " ; -> }T T{ : CQ2 C" " ; -> }T

Loading…
Cancel
Save