void *connection_handler(void *socket_desc) { repl_t *repl = make_repl(); repl->current_prompt = form_prompt(repl->current_ns, false); repl->session_id = ++session_id_counter; int sock = *(int *) socket_desc; ssize_t read_size; char client_message[4096]; write(sock, repl->current_prompt, strlen(repl->current_prompt)); while ((read_size = recv(sock, client_message, 4095, 0)) > 0) { sock_to_write_to = sock; cljs_set_print_sender(&socket_sender); client_message[read_size] = '\0'; process_line(repl, strdup(client_message)); cljs_set_print_sender(NULL); sock_to_write_to = 0; write(sock, repl->current_prompt, strlen(repl->current_prompt)); } free(socket_desc); return NULL; }
void run_cmdline_loop(repl_t *repl, JSContextRef ctx) { while (true) { char *input_line = NULL; if (config.dumb_terminal) { display_prompt(repl->current_prompt); input_line = get_input(); if (input_line == NULL) { // Ctrl-D pressed printf("\n"); break; } } else { // Handle prints while processing linenoise input if (cljs_engine_ready) { cljs_set_print_sender(ctx, &linenoisePrintNow); } // If *print-newline* is off, we need to emit a newline now, otherwise // the linenoise prompt and line editing will overwrite any printed // output on the current line. if (cljs_engine_ready && !cljs_print_newline(ctx)) { fprintf(stdout, "\n"); } char *line = linenoise(repl->current_prompt, prompt_ansi_code_for_theme(config.theme), repl->indent_space_count); // Reset printing handler back if (cljs_engine_ready) { cljs_set_print_sender(ctx, NULL); } repl->indent_space_count = 0; if (line == NULL) { if (errno == EAGAIN) { // Ctrl-C errno = 0; repl->input = NULL; empty_previous_lines(repl); repl->current_prompt = form_prompt(repl->current_ns, false); printf("\n"); continue; } else { // Ctrl-D exit_value = EXIT_SUCCESS_INTERNAL; break; } } input_line = line; } bool break_out = process_line(repl, ctx, input_line); if (break_out) { break; } } }
int run_repl() { repl_t *repl = make_repl(); s_repl = repl; repl->current_ns = strdup("cljs.user"); repl->current_prompt = form_prompt(repl->current_ns, false); // Per-type initialization if (!config.dumb_terminal) { char *home = getenv("HOME"); if (home != NULL) { char history_name[] = ".planck_history"; size_t len = strlen(home) + strlen(history_name) + 2; repl->history_path = malloc(len * sizeof(char)); snprintf(repl->history_path, len, "%s/%s", home, history_name); linenoiseHistoryLoad(repl->history_path); exit_value = load_keymap(home); if (exit_value != EXIT_SUCCESS) { return exit_value; } } linenoiseSetMultiLine(1); linenoiseSetCompletionCallback(completion); linenoiseSetHighlightCallback(highlight); linenoiseSetHighlightCancelCallback(highlight_cancel); } if (!config.dumb_terminal) { cljs_set_print_sender(&linenoisePrintNow); } if (config.socket_repl_port) { pthread_t thread; pthread_create(&thread, NULL, accept_connections, NULL); } run_cmdline_loop(repl); return exit_value; }