Пример #1
0
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;
}
Пример #2
0
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;
        }
    }
}
Пример #3
0
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;
}