Newer
Older
emul / emul_repl.c
#include "emul_repl.h"
#include "emul_inst_exec.h"
#include "emul_inst_decipher.h"
#include "emul_io_std.h"
#include <stdio.h>
#include <string.h>
#include <ncurses.h>

#define READ_LINE_MAX 64

static WINDOW *win;

void emul_repl_readline(char input[READ_LINE_MAX]) {
    static int current_line = 0;
    int history = 0;
    int c;
    int i = 0;
    int y, x;
    current_line = emul_inst_dec_get_program_line_max();
    printw(">>");
    refresh();
    noecho();
    cbreak();
    while( (c = getch()) != '\n' ) {
        if (c == 127) { // Delete and back
            if ( i > 0 ) {
                getyx(win, y, x);
                input[--i] = '\0';
                move(y, x-1);
                clrtoeol();
                refresh();
            }
        } else if (c == KEY_UP) {
            if (current_line+history > 0) {
                history--;
                input[0] = '\0';
                emul_inst_dec_get_line(input, current_line+history);
                getyx(win, y, x);
                move(y, 0);
                clrtoeol();
                printw("%d>", current_line+history);
                i = 0;
                while ( input[i] != '\n' && input[i] != '\0') {
                    echochar(input[i++]);
                }
                refresh();
            }
        } else if (c == KEY_DOWN) {
            if (current_line+history < current_line) {
                history++;
                input[0] = '\0';
                emul_inst_dec_get_line(input, current_line+history);
                getyx(win, y, x);
                move(y, 0);
                clrtoeol();
                printw("%d>", current_line+history);
                i = 0;
                while ( input[i] != '\n' && input[i] != '\0') {
                    echochar(input[i++]);
                }
                refresh();
            }
        } else if (c == KEY_RIGHT) {
            // Nothing do
        } else if (c == KEY_LEFT) {
            if ( i > 0 ) {
                getyx(win, y, x);
                input[--i] = '\0';
                move(y, x-1);
                clrtoeol();
                refresh();
            }
        } else {
            input[i++] = c;
            input[i] = '\0';
            printw("%c", c);
            refresh();
        }
    }
    echo();
    clrtoeol();
    printw("\n");
    refresh();
    current_line++;
}

void emul_repl_printline();

void emul_repl_init() {
    emul_inst_exec_init();
    // ウィンドウポインタ取得
    win = emul_getWin();
    keypad(stdscr, TRUE);
}

char *menu[] = {
    "Display help  >>:help",
    "   Exit       >>:exit"
};

void emul_repl_start() {
    char input[READ_LINE_MAX];
    exitcode_t state;
    int y, x;
    char *title = "Wellcome!";
    int i,j;

    emul_repl_init();

    // title
    getmaxyx(win, y, x);
    move(y/2-2, (x-strlen(title))/2);
    printw("%s", title);
    for (i = 0; i < 2; i++) {
        move(y/2+i, (x-strlen(menu[i]))/2);
        printw("%s", menu[i]);
    }
    move(0, 0);
    printw("");
    refresh();
    getch();
    wclear(win);
    refresh();

    while (1) {
        emul_repl_readline(input);
        emul_inst_exec_loadline(input);
        state = emul_inst_exec_run();
        if (state == Failed) {
            emul_out_std_debug("Abend exit\n");
        } else if (state == Success) {
            emul_out_std_debug("Sucsess\n");
            break;
        }
    }
}

void emul_repl_end() {
    emul_inst_exec_end();
}