parent
2632f748b1
commit
5724ac4273
@ -0,0 +1,77 @@ |
||||
#include "forth_internal.h" |
||||
|
||||
#include <unistd.h> |
||||
#include <termios.h> |
||||
|
||||
static char getch() { |
||||
char buf = 0; |
||||
struct termios old = {0}; |
||||
if (tcgetattr(0, &old) < 0) |
||||
perror("tcsetattr()"); |
||||
old.c_lflag &= ~ICANON; |
||||
old.c_lflag &= ~ECHO; |
||||
old.c_cc[VMIN] = 1; |
||||
old.c_cc[VTIME] = 0; |
||||
if (tcsetattr(0, TCSANOW, &old) < 0) |
||||
perror("tcsetattr ICANON"); |
||||
if (read(0, &buf, 1) < 0) |
||||
perror ("read()"); |
||||
old.c_lflag |= ICANON; |
||||
old.c_lflag |= ECHO; |
||||
if (tcsetattr(0, TCSADRAIN, &old) < 0) |
||||
perror ("tcsetattr ~ICANON"); |
||||
return (buf); |
||||
} |
||||
|
||||
|
||||
static enum fh_error w_key(struct fh_thread_s *fh, const struct fh_word_s *w) |
||||
{ |
||||
(void) w; |
||||
enum fh_error rv; |
||||
uint32_t a; |
||||
|
||||
a = getch(); |
||||
|
||||
TRY(ds_push(fh, a)); |
||||
return FH_OK; |
||||
} |
||||
|
||||
static inline bool iscrlf(char c) { |
||||
return c == '\r' || c == '\n'; |
||||
} |
||||
|
||||
static enum fh_error w_accept(struct fh_thread_s *fh, const struct fh_word_s *w) |
||||
{ |
||||
(void) w; |
||||
enum fh_error rv; |
||||
uint32_t abuf; |
||||
uint32_t count; |
||||
|
||||
TRY(ds_pop(fh, &count)); |
||||
TRY(ds_pop(fh, &abuf)); |
||||
|
||||
char *s = fgets(&fh->heap[abuf], count, stdin); |
||||
if (!s) { |
||||
LOGE("Error reading stdin!"); |
||||
count = 0; |
||||
} else { |
||||
count = strnlen(s, count); |
||||
// remove the newline
|
||||
if(count > 0) { |
||||
char *end = s + (count - 1); |
||||
while (iscrlf(*end)) { |
||||
end--; |
||||
count--; |
||||
} |
||||
} |
||||
} |
||||
|
||||
TRY(ds_push(fh, count)); |
||||
return FH_OK; |
||||
} |
||||
|
||||
const struct name_and_handler fh_builtins_stdin[] = { |
||||
{"key", w_key, 0, 0}, |
||||
{"accept", w_accept, 0, 0}, |
||||
{ /* end marker */ } |
||||
}; |
Loading…
Reference in new issue