/** * TODO file description * * Created on 2021/11/21. */ #ifndef FORTH_FH_INPUT_H #define FORTH_FH_INPUT_H struct fh_thread_s; struct fh_input_spec_s; /** Refill the input buffer, returns false on failure / EOF */ typedef bool (*fh_input_refill_t)(struct fh_thread_s *fh, struct fh_input_spec_s *spec); /** Spec free func */ typedef void (*fh_input_free_t)(void *spec); typedef void (*fh_input_void_method_t)(struct fh_thread_s *fh, struct fh_input_spec_s *spec); typedef enum fh_error (*fh_input_error_method_t)(struct fh_thread_s *fh, struct fh_input_spec_s *spec); struct fh_input_spec_s { struct fh_input_spec_s *previous; fh_input_refill_t refill_input_buffer; fh_input_void_method_t start; fh_input_free_t free_self; fh_input_void_method_t push_prepare; fh_input_void_method_t pop_restore; fh_input_error_method_t save_input; fh_input_error_method_t restore_input; uint32_t linenum; int32_t source_id; char *cwd; // CWD of the input, used for relative includes. malloc'd (strdup) // saved values, filled when pushing uint32_t saved_inputaddr; uint32_t saved_inputptr; uint32_t saved_inputlen; uint32_t saved_execptr; enum fh_state saved_state; }; /** * Push current input spec and state, replace with new one */ enum fh_error fh_push_input(struct fh_thread_s *fh, struct fh_input_spec_s *newinput); /** * Discard current input spec, restore previous. * fh->input will be NULL if this was the topmost one */ enum fh_error fh_pop_input(struct fh_thread_s *fh); struct fh_input_spec_s *fh_create_input_from_filename(char *path); struct fh_input_spec_s *fh_create_input_from_filestruct(FILE *f, const char *path); struct fh_input_spec_s *fh_create_input_from_string(char *str, size_t len, const char *cwd); // cwd is strduped. void fh_input_teardown(struct fh_thread_s *fh); #endif //FORTH_FH_INPUT_H