You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
1.6 KiB
77 lines
1.6 KiB
#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 */ }
|
|
};
|
|
|