#include #include #include #include #include #include #include #include "stdio_impl.h" static pthread_cond_t tyi_cond; static pthread_mutex_t tyi_mutex; #define TYI_BUF_SIZE 1000 static int tyi_buf [TYI_BUF_SIZE]; static unsigned tyi_rptr = 0; static unsigned tyi_fptr = 0; void tty_tyo(int ch) { MAIN_THREAD_EM_ASM((return tyo($0)), (int32_t)ch); } void tty_puts(char *s) { for(;*s;s++)tty_tyo(*s); } void whostate(char *s) { MAIN_THREAD_EM_ASM((whostate(UTF8ToString($0))), s); } static double now (void) { struct timeval tv; gettimeofday(&tv,0); return tv.tv_sec + 1e-6 * tv.tv_usec; } volatile int osint = 0; void tty_intr (int ch) { osint = ch; } void res (char *s) { (void)s; } //char * ta = "(PUTD FIB (QUOTE (LAMBDA (N) ((LESSP N 2) N) (PLUS (FIB (PLUS N -2)) (FIB (PLUS N -1))))))\n"; static char *ta = ""; int tty_have_input (int c) { pthread_mutex_lock (&tyi_mutex); /* hmm */ if (tyi_fptr == TYI_BUF_SIZE) { unsigned i; for (i = tyi_rptr; i < tyi_fptr; i++) tyi_buf[i-tyi_rptr] = tyi_buf[i]; tyi_fptr -= tyi_rptr; tyi_rptr -= tyi_rptr; } if (tyi_fptr < TYI_BUF_SIZE) tyi_buf[tyi_fptr++] = c; pthread_cond_signal (&tyi_cond); pthread_mutex_unlock (&tyi_mutex); return tyi_fptr; } static size_t tty_write(FILE *fp, const unsigned char *buf, size_t n) { unsigned char *p; for (p = fp->wbase; p < fp->wpos; p++) tty_tyo(*p); for (size_t i = 0; i < n; i++) tty_tyo(buf[i]); fp->wpos = fp->wbase; return n; } static size_t tty_read(FILE *fp, unsigned char *buf, size_t n) { static double t0 = -1; int ch; if (n == 0) return 0; /* Huh? */ if (fp == stdin) { fflush(stdout); fflush(stderr); } if(*ta) { ch = (unsigned char)*ta++; tty_tyo(ch); } else { pthread_mutex_lock (&tyi_mutex); if (tyi_rptr >= tyi_fptr) { static char buf [80]; if (t0 < 0) { sprintf (buf, "Waiting for input"); } else { sprintf (buf, "Waiting for input [Last command took %gs]", now() - t0); } t0 = now(); whostate(buf); while (tyi_rptr >= tyi_fptr) { pthread_cond_wait (&tyi_cond, &tyi_mutex); } whostate("Running"); } ch = tyi_buf[tyi_rptr++]; pthread_mutex_unlock (&tyi_mutex); } t0 = now(); if (ch < 0) { fp->flags |= F_EOF; return 0; /* EOF */ } else { *buf = ch; return 1; } } void tty_init (void) /* This is supposed to be called at 'preRun' time. */ { if (0 != pthread_mutex_init(&tyi_mutex, 0)) abort(); if (0 != pthread_cond_init(&tyi_cond, 0)) abort(); stdout->write = tty_write; stderr->write = tty_write; stdin->read = tty_read; }