https://github.com/JuliaLang/julia
Tip revision: 1e7db5c9e16f989878a742a717679ad990e6f8e8 authored by Julia Windows Test Machine on 18 January 2014, 02:28:22 UTC
Fix a few typos on windows
Fix a few typos on windows
Tip revision: 1e7db5c
repl-basic.c
#include "repl.h"
#include <unistd.h>
static char *stdin_buf = NULL;
static size_t stdin_buf_len = 0;
static size_t stdin_buf_maxlen = 128;
static char *given_prompt=NULL, *prompt_to_use=NULL;
static int callback_en=0;
static void jl_clear_input(void);
#ifdef __WIN32__
static int repl_sigint_handler_installed = 0;
static BOOL WINAPI repl_sigint_handler(DWORD wsig) //This needs winapi types to guarantee __stdcall
{
if (callback_en) {
JL_WRITE(jl_uv_stdout, "^C", 2);
jl_clear_input();
return 1;
}
return 0; // continue to next handler
}
#else
void sigcont_handler(int arg)
{
if (callback_en) {
jl_write(jl_uv_stdout, prompt_to_use, strlen(prompt_to_use));
//jl_write(jl_uv_stdout, stdin_buf, stdin_buf_len); //disabled because the current line was still in the system buffer
}
}
struct sigaction jl_sigint_act = {};
static void repl_sigint_handler(int sig, siginfo_t *info, void *context)
{
if (callback_en) {
JL_WRITE(jl_uv_stdout, "\n", 1);
jl_clear_input();
}
else {
if (jl_sigint_act.sa_flags & SA_SIGINFO) {
jl_sigint_act.sa_sigaction(sig, info, context);
}
else {
void (*f)(int) = jl_sigint_act.sa_handler;
if (f == SIG_DFL)
raise(sig);
else if (f != SIG_IGN)
f(sig);
}
}
}
#endif
void jl_init_repl(int history)
{
stdin_buf = malloc(stdin_buf_maxlen);
stdin_buf_len = 0;
#ifdef __WIN32__
repl_sigint_handler_installed = 0;
#else
jl_sigint_act.sa_sigaction = NULL;
signal(SIGCONT, sigcont_handler);
#endif
}
void jl_prep_terminal(int meta_flag)
{
#ifdef __WIN32__
if (!repl_sigint_handler_installed) {
if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)repl_sigint_handler,1))
repl_sigint_handler_installed = 1;
}
#else
if (jl_sigint_act.sa_sigaction == NULL) {
struct sigaction oldact, repl_sigint_act;
memset(&repl_sigint_act, 0, sizeof(struct sigaction));
sigemptyset(&repl_sigint_act.sa_mask);
repl_sigint_act.sa_sigaction = repl_sigint_handler;
repl_sigint_act.sa_flags = SA_SIGINFO;
if (sigaction(SIGINT, &repl_sigint_act, &oldact) < 0) {
JL_PRINTF(JL_STDERR, "sigaction: %s\n", strerror(errno));
jl_exit(1);
}
if (repl_sigint_act.sa_sigaction != oldact.sa_sigaction &&
jl_sigint_act.sa_sigaction != oldact.sa_sigaction)
jl_sigint_act = oldact;
}
#endif
}
/* Restore the terminal's normal settings and modes. */
void jl_deprep_terminal()
{
callback_en = 0;
}
void jl_input_line_callback(char *input)
{
if (input) {
jl_value_t *ast = jl_parse_input_line(input);
int line_done = !ast || !jl_is_expr(ast) ||
(((jl_expr_t*)ast)->head != jl_incomplete_sym);
if (line_done) {
jl_deprep_terminal();
int doprint = !ends_with_semicolon(input);
stdin_buf[0] = 0; //also sets input[0] == 0
stdin_buf_len = 0;
handle_input(ast, 0, doprint);
}
}
}
void repl_callback_enable(char *prompt)
{
callback_en = 1;
if (given_prompt == NULL || strcmp(prompt, given_prompt)) {
if (given_prompt) free(given_prompt);
given_prompt = strdup(prompt);
if (prompt_to_use) free(prompt_to_use);
// remove \001 and \002
size_t n = strlen(prompt);
prompt_to_use = malloc(n+1);
size_t o=0;
for(size_t i=0; i < n; i++) {
if (prompt[i] > 2)
prompt_to_use[o++] = prompt[i];
}
prompt_to_use[o] = '\0';
}
jl_write(jl_uv_stdout, prompt_to_use, strlen(prompt_to_use));
jl_prep_terminal(1);
}
static void stdin_buf_pushc(char c)
{
if (stdin_buf_len >= stdin_buf_maxlen) {
stdin_buf_maxlen *= 2;
stdin_buf = realloc(stdin_buf, stdin_buf_maxlen);
if (!stdin_buf) {
// we can safely ignore this error and continue, if that is preferred
perror("realloc");
exit(EXIT_FAILURE);
}
}
stdin_buf[stdin_buf_len] = c;
stdin_buf_len++;
}
static void basic_stdin_callback(void)
{
stdin_buf_pushc('\0');
stdin_buf_len--;
jl_input_line_callback(stdin_buf);
}
void jl_read_buffer(unsigned char* base, ssize_t nread)
{
unsigned char *start = base;
int esc = 0;
int newline = 0;
while (*start != 0 && nread > 0) {
if (*start < 32 || *start == 127) {
switch (*start) {
case '\n':
case '\r':
//jl_putc('\n', jl_uv_stdout);
stdin_buf_pushc('\n');
newline = 1;
break;
case '\x03':
JL_WRITE(jl_uv_stdout, "^C\n", 3);
jl_clear_input();
break;
case '\x04':
raise(SIGTERM);
break;
case '\x1A':
#ifndef __WIN32__
raise(SIGTSTP);
#endif
break;
case '\e':
esc = 1;
break;
case 127:
case '\b':
if (stdin_buf_len > 0 && stdin_buf[stdin_buf_len-1] != '\n') {
stdin_buf_len--;
JL_WRITE(jl_uv_stdout,"\b \b",3);
}
}
}
else if (esc == 1) {
if (*start == '[') {
esc = 2;
}
else {
esc = 0;
}
}
else if (esc == 2) {
// for now, we just block all 3 character ctrl signals that I know about
// this misses delete ^[[3~ and possibly others?
esc = 0;
}
else {
stdin_buf_pushc(*start);
}
start++;
nread--;
}
if (newline) basic_stdin_callback();
}
static void jl_clear_input(void)
{
stdin_buf_len = 0;
stdin_buf[0] = 0;
JL_WRITE(jl_uv_stdout,"\n",1);
repl_callback_enable(prompt_to_use);
}