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;
    void emul_repl_show_history() {
	int max_y, max_x;
	input[0] = '\0';
	emul_inst_dec_get_line(input, current_line+history);
	getyx(win, y, x);
	// 1行削除
	move(y, 0);
	clrtoeol();
	// ヒストリ番号表示
	getmaxyx(win, max_y, max_x);
	move(y, max_x-8);
	printw("L[%5d]", current_line+history);
	// ヒストリ表示および格納
	move(y, 0);
	printw(">>");
	i = 0;
	while ( input[i] != '\n' && input[i] != '\0') {
	echochar(input[i++]);
	}
	refresh();
    }
    current_line = emul_inst_dec_get_program_line_max();
    printw(">>");
    refresh();
    noecho();
    cbreak();
    while( (c = getch()) != '\n' ) {
        if (c == 127 || c == KEY_BACKSPACE) { // 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--;
		emul_repl_show_history();
            }
        } else if (c == KEY_DOWN) {
            if (current_line+history < current_line) {
                history++;
		emul_repl_show_history();
            }
        } 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();
}