|
|
|
@ -1,5 +1,17 @@ |
|
|
|
|
#include "forth_internal.h" |
|
|
|
|
|
|
|
|
|
struct file_input_spec { |
|
|
|
|
struct fh_input_spec_s spec; |
|
|
|
|
char saved_buffer[INPUT_BUFFER_SIZE]; |
|
|
|
|
FILE *file; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct string_input_spec { |
|
|
|
|
struct fh_input_spec_s spec; |
|
|
|
|
const char *str; |
|
|
|
|
size_t len; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum fh_error fh_push_input(struct fh_thread_s *fh, struct fh_input_spec_s *newinput) |
|
|
|
|
{ |
|
|
|
|
LOG("--- Push input spec ---"); |
|
|
|
@ -70,17 +82,78 @@ enum fh_error fh_pop_input(struct fh_thread_s *fh) |
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct file_input_spec { |
|
|
|
|
struct fh_input_spec_s spec; |
|
|
|
|
char saved_buffer[INPUT_BUFFER_SIZE]; |
|
|
|
|
FILE *file; |
|
|
|
|
}; |
|
|
|
|
static enum fh_error file_save_input(struct fh_thread_s *fh, struct fh_input_spec_s *spec) |
|
|
|
|
{ |
|
|
|
|
enum fh_error rv; |
|
|
|
|
struct file_input_spec *fspec = (void*) spec; |
|
|
|
|
|
|
|
|
|
if (isatty(fileno(fspec->file))) { |
|
|
|
|
TRY(ds_push(fh, 0)); |
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint32_t pos = (uint32_t) ftell(fspec->file); |
|
|
|
|
|
|
|
|
|
TRY(ds_push(fh, spec->linenum)); |
|
|
|
|
TRY(ds_push(fh, fh->inputptr)); |
|
|
|
|
TRY(ds_push(fh, pos - fh->inputlen)); |
|
|
|
|
TRY(ds_push(fh, 3)); |
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct string_input_spec { |
|
|
|
|
struct fh_input_spec_s spec; |
|
|
|
|
const char *str; |
|
|
|
|
size_t len; |
|
|
|
|
}; |
|
|
|
|
static enum fh_error file_restore_input(struct fh_thread_s *fh, struct fh_input_spec_s *spec) |
|
|
|
|
{ |
|
|
|
|
enum fh_error rv; |
|
|
|
|
struct file_input_spec *fspec = (void*) spec; |
|
|
|
|
uint32_t n; |
|
|
|
|
TRY(ds_pop(fh, &n)); |
|
|
|
|
if (n == 3) {
|
|
|
|
|
uint32_t filepos;
|
|
|
|
|
TRY(ds_pop(fh, &filepos)); |
|
|
|
|
fseek(fspec->file, filepos, SEEK_SET); |
|
|
|
|
TRY(ds_pop(fh, &fh->inputptr)); |
|
|
|
|
TRY(ds_pop(fh, &spec->linenum)); |
|
|
|
|
|
|
|
|
|
LOG("file input, restore filepos %d, inptr %d, linenum %d",
|
|
|
|
|
filepos, fh->inputptr, spec->linenum); |
|
|
|
|
|
|
|
|
|
fgets(&fh->heap[INPUTBUF_ADDR], INPUT_BUFFER_SIZE, fspec->file); |
|
|
|
|
TRY(ds_push(fh, 0)); |
|
|
|
|
} else { |
|
|
|
|
LOG("file input, restore nothing, bad N!"); |
|
|
|
|
TRY(ds_push(fh, TOBOOL(1))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static enum fh_error str_save_input(struct fh_thread_s *fh, struct fh_input_spec_s *spec) |
|
|
|
|
{ |
|
|
|
|
enum fh_error rv; |
|
|
|
|
TRY(ds_push(fh, spec->linenum)); |
|
|
|
|
TRY(ds_push(fh, fh->inputptr)); |
|
|
|
|
TRY(ds_push(fh, 2)); |
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static enum fh_error str_restore_input(struct fh_thread_s *fh, struct fh_input_spec_s *spec) |
|
|
|
|
{ |
|
|
|
|
enum fh_error rv; |
|
|
|
|
uint32_t n; |
|
|
|
|
TRY(ds_pop(fh, &n)); |
|
|
|
|
if (n == 2) { |
|
|
|
|
TRY(ds_pop(fh, &fh->inputptr)); |
|
|
|
|
TRY(ds_pop(fh, &spec->linenum)); |
|
|
|
|
|
|
|
|
|
LOG("str input, inptr %d, linenum %d",
|
|
|
|
|
fh->inputptr, spec->linenum); |
|
|
|
|
TRY(ds_push(fh, 0)); |
|
|
|
|
} else { |
|
|
|
|
LOG("str input, restore nothing, bad N!"); |
|
|
|
|
TRY(ds_push(fh, TOBOOL(1))); |
|
|
|
|
} |
|
|
|
|
return FH_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void file_push_prepare(struct fh_thread_s *fh, struct fh_input_spec_s *spec) |
|
|
|
|
{ |
|
|
|
@ -160,26 +233,8 @@ static bool file_refill(struct fh_thread_s *fh, struct fh_input_spec_s *spec) |
|
|
|
|
|
|
|
|
|
static bool str_refill(struct fh_thread_s *fh, struct fh_input_spec_s *spec) |
|
|
|
|
{ |
|
|
|
|
// no refilling, the string exists in its entirety on heap
|
|
|
|
|
return fh->inputptr < fh->inputlen; |
|
|
|
|
// struct string_input_spec *fis = (struct string_input_spec *) spec;
|
|
|
|
|
// fh_input_memmove_leftovers(fh);
|
|
|
|
|
// uint32_t space_left = INPUT_BUFFER_SIZE - fh->inputlen - 1;
|
|
|
|
|
// char *wp = (char *) inputbuf_at(fh, fh->inputptr);
|
|
|
|
|
//
|
|
|
|
|
// uint32_t chars_remaining_in_string = fis->len - fis->readpos;
|
|
|
|
|
// if (chars_remaining_in_string > 0) {
|
|
|
|
|
// if (chars_remaining_in_string < space_left) {
|
|
|
|
|
// space_left = chars_remaining_in_string;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// memcpy(wp, &fis->str[fis->readpos], space_left);
|
|
|
|
|
// *(wp + space_left) = 0;
|
|
|
|
|
// fis->readpos += space_left;
|
|
|
|
|
// fh->inputlen += space_left;
|
|
|
|
|
// return true;
|
|
|
|
|
// } else {
|
|
|
|
|
// return false;
|
|
|
|
|
// }
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void free_filespec(void *p) |
|
|
|
@ -220,6 +275,8 @@ struct fh_input_spec_s *fh_create_input_from_filestruct(FILE *f, const char *cwd |
|
|
|
|
spec->spec.push_prepare = file_push_prepare; |
|
|
|
|
spec->spec.pop_restore = file_pop_restore; |
|
|
|
|
spec->spec.refill_input_buffer = file_refill; |
|
|
|
|
spec->spec.save_input = file_save_input; |
|
|
|
|
spec->spec.restore_input = file_restore_input; |
|
|
|
|
spec->file = f; |
|
|
|
|
if (cwd) { |
|
|
|
|
spec->spec.cwd = strdup(cwd); |
|
|
|
@ -247,6 +304,8 @@ struct fh_input_spec_s *fh_create_input_from_filename(char *path) |
|
|
|
|
spec->spec.push_prepare = file_push_prepare; |
|
|
|
|
spec->spec.pop_restore = file_pop_restore; |
|
|
|
|
spec->spec.refill_input_buffer = file_refill; |
|
|
|
|
spec->spec.save_input = file_save_input; |
|
|
|
|
spec->spec.restore_input = file_restore_input; |
|
|
|
|
spec->file = f; |
|
|
|
|
|
|
|
|
|
char pwd[PATH_MAX+1]; |
|
|
|
@ -275,6 +334,8 @@ struct fh_input_spec_s *fh_create_input_from_string(char *str, size_t len, const |
|
|
|
|
spec->spec.push_prepare = str_push_prepare; |
|
|
|
|
spec->spec.pop_restore = str_pop_restore; |
|
|
|
|
spec->spec.start = str_start; |
|
|
|
|
spec->spec.save_input = str_save_input; |
|
|
|
|
spec->spec.restore_input = str_restore_input; |
|
|
|
|
spec->str = str; |
|
|
|
|
spec->len = len; |
|
|
|
|
spec->spec.cwd = cwd ? strdup(cwd) : NULL; |
|
|
|
|