Browse Source

tinyrl mass refactoring. Unfinished. Buildable

Serj Kalichev 3 months ago
parent
commit
611ba9d1ab

+ 2 - 1
bin/klish/Makefile.am

@@ -8,4 +8,5 @@ bin_klish_klish_SOURCES = \
 	bin/klish/klish.c
 
 bin_klish_klish_LDADD = \
-	libklish.la
+	libklish.la \
+	libtinyrl.la

+ 19 - 2
bin/klish/interactive.c

@@ -2,16 +2,19 @@
 #include <stdio.h>
 #include <assert.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #include <faux/faux.h>
 #include <faux/eloop.h>
 #include <klish/ktp.h>
 #include <klish/ktp_session.h>
+#include <tinyrl/tinyrl.h>
 
 
 // Context for main loop
 typedef struct ctx_s {
 	ktp_session_t *ktp;
+	tinyrl_t *tinyrl;
 } ctx_t;
 
 
@@ -24,21 +27,35 @@ int klish_interactive_shell(ktp_session_t *ktp)
 {
 	ctx_t ctx = {};
 	faux_eloop_t *eloop = NULL;
+	tinyrl_t *tinyrl = NULL;
+	int stdin_flags = 0;
 
 	assert(ktp);
 	if (!ktp)
 		return -1;
 
-	// Don't stop interactive loop on each answer
-	ktp_session_set_stop_on_answer(ktp, BOOL_FALSE);
+	// Set stdin to O_NONBLOCK mode
+	stdin_flags = fcntl(STDIN_FILENO, F_GETFL, 0);
+	fcntl(STDIN_FILENO, F_SETFL, stdin_flags | O_NONBLOCK);
+
+	tinyrl = tinyrl_new(stdin, stdout, 0, NULL);
 
 	ctx.ktp = ktp;
+	ctx.tinyrl = tinyrl;
 
+	// Don't stop interactive loop on each answer
+	ktp_session_set_stop_on_answer(ktp, BOOL_FALSE);
 	ktp_session_set_cb(ktp, KTP_SESSION_CB_CMD_ACK, cmd_ack_cb, &ctx);
 	eloop = ktp_session_eloop(ktp);
 	faux_eloop_add_fd(eloop, STDIN_FILENO, POLLIN, stdin_cb, &ctx);
 	faux_eloop_loop(eloop);
 
+	// Cleanup
+	tinyrl_free(tinyrl);
+
+	// Restore stdin mode
+	fcntl(STDIN_FILENO, F_SETFL, stdin_flags);
+
 	return 0;
 }
 

+ 1 - 1
tinyrl/hist.h

@@ -12,7 +12,7 @@ typedef faux_list_node_t hist_node_t;
 
 C_DECL_BEGIN
 
-hist_t *hist_new(size_t stifle, const char *hist_fname);
+hist_t *hist_new(const char *hist_fname, size_t stifle);
 void hist_free(hist_t *hist);
 
 void hist_add(hist_t *hist, const char *line);

+ 1 - 1
tinyrl/hist/hist.c

@@ -42,7 +42,7 @@ static int hist_kcompare(const void *key, const void *list_item)
 
 
 
-hist_t *hist_new(size_t stifle, const char *hist_fname)
+hist_t *hist_new(const char *hist_fname, size_t stifle)
 {
 	hist_t *hist = faux_zmalloc(sizeof(hist_t));
 	if (!hist)

+ 11 - 8
tinyrl/tinyrl.h

@@ -59,17 +59,20 @@ typedef int tinyrl_keypress_fn_t(tinyrl_t *instance, int key);
  */
 typedef bool_t tinyrl_key_func_t(tinyrl_t * instance, int key);
 
-/* exported functions */
-extern tinyrl_t *tinyrl_new(FILE * instream,
-			    FILE * outstream,
-			    unsigned stifle,
-			    tinyrl_completion_func_t * complete_fn);
 
-/*lint -esym(534,tinyrl_printf)  Ignoring return value of function */
-extern int tinyrl_printf(const tinyrl_t * instance, const char *fmt, ...);
 
-extern void tinyrl_delete(tinyrl_t * instance);
 
+tinyrl_t *tinyrl_new(FILE *istream, FILE *ostream,
+	const char *hist_fname, size_t hist_stifle);
+void tinyrl_free(tinyrl_t *tinyrl);
+
+
+
+
+
+
+/*lint -esym(534,tinyrl_printf)  Ignoring return value of function */
+extern int tinyrl_printf(const tinyrl_t * instance, const char *fmt, ...);
 
 extern const char *tinyrl__get_prompt(const tinyrl_t * instance);
 extern void tinyrl__set_prompt(tinyrl_t *instance, const char *prompt);

+ 2 - 1
tinyrl/tinyrl/Makefile.am

@@ -1,3 +1,4 @@
 libtinyrl_la_SOURCES += \
-	tinyrl/tinyrl/utf8.c
+	tinyrl/tinyrl/utf8.c \
+	tinyrl/tinyrl/keys.c \
 	tinyrl/tinyrl/tinyrl.c

+ 325 - 0
tinyrl/tinyrl/keys.c

@@ -0,0 +1,325 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <faux/faux.h>
+#include <faux/str.h>
+
+#include "private.h"
+
+
+bool_t tinyrl_key_default(tinyrl_t * tinyrl, int key)
+{
+	bool_t result = BOOL_FALSE;
+/*
+	if (key > 31) {
+		char tmp[2];
+		tmp[0] = (key & 0xFF), tmp[1] = '\0';
+		// inject tinyrl text into the buffer 
+		result = tinyrl_insert_text(tinyrl, tmp);
+	} else {
+		// Call the external hotkey analyzer 
+		if (tinyrl->hotkey_fn)
+			tinyrl->hotkey_fn(tinyrl, key);
+	}
+*/
+	return result;
+}
+
+
+bool_t tinyrl_key_interrupt(tinyrl_t * tinyrl, int key)
+{
+/*
+	tinyrl_crlf(tinyrl);
+	tinyrl_delete_text(tinyrl, 0, tinyrl->end);
+	tinyrl->done = BOOL_TRUE;
+	// keep the compiler happy 
+	key = key;
+*/
+	return BOOL_TRUE;
+}
+
+
+bool_t tinyrl_key_start_of_line(tinyrl_t * tinyrl, int key)
+{
+/*
+	// set the insertion point to the start of the line 
+	tinyrl->point = 0;
+	// keep the compiler happy 
+	key = key;
+*/
+	return BOOL_TRUE;
+}
+
+
+bool_t tinyrl_key_end_of_line(tinyrl_t * tinyrl, int key)
+{
+/*
+	// set the insertion point to the end of the line 
+	tinyrl->point = tinyrl->end;
+	// keep the compiler happy 
+	key = key;
+*/
+	return BOOL_TRUE;
+}
+
+
+bool_t tinyrl_key_kill(tinyrl_t * tinyrl, int key)
+{
+/*
+	// release any old kill string 
+	lub_string_free(tinyrl->kill_string);
+
+	// store the killed string 
+	tinyrl->kill_string = lub_string_dup(&tinyrl->buffer[tinyrl->point]);
+
+	// delete the text to the end of the line 
+	tinyrl_delete_text(tinyrl, tinyrl->point, tinyrl->end);
+	// keep the compiler happy 
+	key = key;
+*/
+	return BOOL_TRUE;
+}
+
+
+bool_t tinyrl_key_yank(tinyrl_t * tinyrl, int key)
+{
+	bool_t result = BOOL_FALSE;
+/*
+	if (tinyrl->kill_string) {
+		// insert the kill string at the current insertion point 
+		result = tinyrl_insert_text(tinyrl, tinyrl->kill_string);
+	}
+	// keep the compiler happy 
+	key = key;
+*/
+	return result;
+}
+
+
+bool_t tinyrl_key_crlf(tinyrl_t * tinyrl, int key)
+{
+/*
+	tinyrl_crlf(tinyrl);
+	tinyrl->done = BOOL_TRUE;
+	// keep the compiler happy 
+	key = key;
+*/
+	return BOOL_TRUE;
+}
+
+
+bool_t tinyrl_key_up(tinyrl_t * tinyrl, int key)
+{
+	bool_t result = BOOL_FALSE;
+/*
+	tinyrl_history_entry_t *entry = NULL;
+	if (tinyrl->line == tinyrl->buffer) {
+		// go to the last history entry 
+		entry = tinyrl_history_getlast(tinyrl->history, &tinyrl->hist_iter);
+	} else {
+		// already traversing the history list so get previous 
+		entry = tinyrl_history_getprevious(&tinyrl->hist_iter);
+	}
+	if (entry) {
+		// display the entry moving the insertion point
+		 * to the end of the line 
+		 
+		tinyrl->line = tinyrl_history_entry__get_line(entry);
+		tinyrl->point = tinyrl->end = strlen(tinyrl->line);
+		result = BOOL_TRUE;
+	}
+	// keep the compiler happy 
+	key = key;
+*/
+	return result;
+}
+
+
+bool_t tinyrl_key_down(tinyrl_t * tinyrl, int key)
+{
+	bool_t result = BOOL_FALSE;
+/*
+	if (tinyrl->line != tinyrl->buffer) {
+		// we are not already at the bottom 
+		// the iterator will have been set up by the key_up() function 
+		tinyrl_history_entry_t *entry =
+		    tinyrl_history_getnext(&tinyrl->hist_iter);
+		if (!entry) {
+			// nothing more in the history list 
+			tinyrl->line = tinyrl->buffer;
+		} else {
+			tinyrl->line = tinyrl_history_entry__get_line(entry);
+		}
+		// display the entry moving the insertion point
+		// to the end of the line 
+		tinyrl->point = tinyrl->end = strlen(tinyrl->line);
+		result = BOOL_TRUE;
+	}
+	// keep the compiler happy 
+	key = key;
+*/
+	return result;
+}
+
+
+bool_t tinyrl_key_left(tinyrl_t * tinyrl, int key)
+{
+	bool_t result = BOOL_FALSE;
+/*
+	if (tinyrl->point > 0) {
+		tinyrl->point--;
+		utf8_point_left(tinyrl);
+		result = BOOL_TRUE;
+	}
+	// keep the compiler happy 
+	key = key;
+*/
+	return result;
+}
+
+
+bool_t tinyrl_key_right(tinyrl_t * tinyrl, int key)
+{
+	bool_t result = BOOL_FALSE;
+/*
+	if (tinyrl->point < tinyrl->end) {
+		tinyrl->point++;
+		utf8_point_right(tinyrl);
+		result = BOOL_TRUE;
+	}
+	// keep the compiler happy 
+	key = key;
+*/
+	return result;
+}
+
+
+bool_t tinyrl_key_backspace(tinyrl_t *tinyrl, int key)
+{
+	bool_t result = BOOL_FALSE;
+/*
+	if (tinyrl->point) {
+		unsigned int end = --tinyrl->point;
+		utf8_point_left(tinyrl);
+		tinyrl_delete_text(tinyrl, tinyrl->point, end);
+		result = BOOL_TRUE;
+	}
+	// keep the compiler happy 
+	key = key;
+*/
+	return result;
+}
+
+
+bool_t tinyrl_key_backword(tinyrl_t *tinyrl, int key)
+{
+	bool_t result = BOOL_FALSE;
+/*
+    // remove current whitespace before cursor 
+	while (tinyrl->point > 0 && isspace(tinyrl->line[tinyrl->point - 1]))
+        tinyrl_key_backspace(tinyrl, KEY_BS);
+
+    // delete word before cusor 
+	while (tinyrl->point > 0 && !isspace(tinyrl->line[tinyrl->point - 1]))
+        tinyrl_key_backspace(tinyrl, KEY_BS);
+
+	result = BOOL_TRUE;
+
+	// keep the compiler happy 
+	key = key;
+*/
+	return result;
+}
+
+bool_t tinyrl_key_delete(tinyrl_t * tinyrl, int key)
+{
+	bool_t result = BOOL_FALSE;
+/*
+	if (tinyrl->point < tinyrl->end) {
+		unsigned int begin = tinyrl->point++;
+		utf8_point_right(tinyrl);
+		tinyrl_delete_text(tinyrl, begin, tinyrl->point - 1);
+		result = BOOL_TRUE;
+	}
+	// keep the compiler happy 
+	key = key;
+*/
+	return result;
+}
+
+
+bool_t tinyrl_key_clear_screen(tinyrl_t * tinyrl, int key)
+{
+/*
+	tinyrl_vt100_clear_screen(tinyrl->term);
+	tinyrl_vt100_cursor_home(tinyrl->term);
+	tinyrl_reset_line_state(tinyrl);
+
+	// keep the compiler happy 
+	key = key;
+	tinyrl = tinyrl;
+*/
+	return BOOL_TRUE;
+}
+
+
+bool_t tinyrl_key_erase_line(tinyrl_t * tinyrl, int key)
+{
+/*	unsigned int end;
+
+	// release any old kill string 
+	lub_string_free(tinyrl->kill_string);
+
+	if (!tinyrl->point) {
+		tinyrl->kill_string = NULL;
+		return BOOL_TRUE;
+	}
+
+	end = tinyrl->point - 1;
+
+	// store the killed string 
+	tinyrl->kill_string = malloc(tinyrl->point + 1);
+	memcpy(tinyrl->kill_string, tinyrl->buffer, tinyrl->point);
+	tinyrl->kill_string[tinyrl->point] = '\0';
+
+	// delete the text from the start of the line 
+	tinyrl_delete_text(tinyrl, 0, end);
+	tinyrl->point = 0;
+
+	// keep the compiler happy 
+	key = key;
+	tinyrl = tinyrl;
+*/
+	return BOOL_TRUE;
+}
+
+
+bool_t tinyrl_key_tab(tinyrl_t * tinyrl, int key)
+{
+	bool_t result = BOOL_FALSE;
+/*
+	tinyrl_match_e status = tinyrl_complete_with_extensions(tinyrl);
+
+	switch (status) {
+	case TINYRL_COMPLETED_MATCH:
+	case TINYRL_MATCH:
+		// everything is OK with the world... 
+		result = tinyrl_insert_text(tinyrl, " ");
+		break;
+	case TINYRL_NO_MATCH:
+	case TINYRL_MATCH_WITH_EXTENSIONS:
+	case TINYRL_AMBIGUOUS:
+	case TINYRL_COMPLETED_AMBIGUOUS:
+		// oops don't change the result and let the bell ring 
+		break;
+	}
+	// keep the compiler happy 
+	key = key;
+*/
+	return result;
+}

+ 22 - 4
tinyrl/tinyrl/private.h

@@ -7,11 +7,31 @@
 #include "tinyrl/tinyrl.h"
 
 
+// UTF-8 functions
 ssize_t utf8_to_wchar(const char *sp, unsigned long *sym_out);
 bool_t utf8_wchar_is_cjk(unsigned long sym);
 char *utf8_move_left(const char *line, char *cur_pos);
 char *utf8_move_right(const char *line, char *cur_pos);
 
+// Keys
+bool_t tinyrl_key_default(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_interrupt(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_start_of_line(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_end_of_line(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_kill(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_yank(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_crlf(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_up(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_down(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_left(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_right(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_backspace(tinyrl_t *tinyrl, int key);
+bool_t tinyrl_key_backword(tinyrl_t *tinyrl, int key);
+bool_t tinyrl_key_delete(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_clear_screen(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_erase_line(tinyrl_t * tinyrl, int key);
+bool_t tinyrl_key_tab(tinyrl_t * tinyrl, int key);
+
 
 /* define the class member data and virtual methods */
 struct _tinyrl {
@@ -28,7 +48,6 @@ struct _tinyrl {
 	unsigned point;
 	unsigned end;
 	tinyrl_completion_func_t *attempted_completion_function;
-	tinyrl_timeout_fn_t *timeout_fn; /* timeout callback */
 	tinyrl_keypress_fn_t *keypress_fn; /* keypress callback */
 	int state;
 #define RL_STATE_COMPLETING (0x00000001)
@@ -37,8 +56,7 @@ struct _tinyrl {
 	tinyrl_key_func_t *handlers[NUM_HANDLERS];
 	tinyrl_key_func_t *hotkey_fn;
 
-//	tinyrl_history_t *history;
-//	tinyrl_history_iterator_t hist_iter;
+	hist_t *hist; // History object
 	vt100_t *term;
 	void *context;		/* context supplied by caller
 				 * to tinyrl_readline()
@@ -52,6 +70,6 @@ struct _tinyrl {
 	unsigned int last_point; /* hold record of the previous
 				cursor position for redisplay purposes */
 	unsigned int last_line_size; /* The length of last_buffer */
-	unsigned int last_width; /* Last terminal width. For resize */
+	unsigned int width; /* Last terminal width. For resize */
 	bool_t utf8;		/* Is the encoding UTF-8 */
 };

+ 87 - 375
tinyrl/tinyrl/tinyrl.c

@@ -10,12 +10,93 @@
 #include <errno.h>
 #include <unistd.h>
 
+#include <faux/faux.h>
 #include <faux/str.h>
 
 #include "private.h"
 
 
-static void tty_set_raw_mode(tinyrl_t *tinyrl)
+tinyrl_t *tinyrl_new(FILE *istream, FILE *ostream,
+	const char *hist_fname, size_t hist_stifle)
+{
+	tinyrl_t *tinyrl = NULL;
+	int i = 0;
+
+	tinyrl = faux_zmalloc(sizeof(tinyrl_t));
+	if (!tinyrl)
+		return NULL;
+
+	// Key handlers
+	for (i = 0; i < NUM_HANDLERS; i++) {
+		tinyrl->handlers[i] = tinyrl_key_default;
+	}
+	tinyrl->handlers[KEY_CR] = tinyrl_key_crlf;
+	tinyrl->handlers[KEY_LF] = tinyrl_key_crlf;
+	tinyrl->handlers[KEY_ETX] = tinyrl_key_interrupt;
+	tinyrl->handlers[KEY_DEL] = tinyrl_key_backspace;
+	tinyrl->handlers[KEY_BS] = tinyrl_key_backspace;
+	tinyrl->handlers[KEY_EOT] = tinyrl_key_delete;
+	tinyrl->handlers[KEY_FF] = tinyrl_key_clear_screen;
+	tinyrl->handlers[KEY_NAK] = tinyrl_key_erase_line;
+	tinyrl->handlers[KEY_SOH] = tinyrl_key_start_of_line;
+	tinyrl->handlers[KEY_ENQ] = tinyrl_key_end_of_line;
+	tinyrl->handlers[KEY_VT] = tinyrl_key_kill;
+	tinyrl->handlers[KEY_EM] = tinyrl_key_yank;
+	tinyrl->handlers[KEY_HT] = tinyrl_key_tab;
+	tinyrl->handlers[KEY_ETB] = tinyrl_key_backword;
+
+	tinyrl->line = NULL;
+	tinyrl->max_line_length = 0;
+	tinyrl->prompt = NULL;
+	tinyrl->prompt_size = 0;
+	tinyrl->buffer = NULL;
+	tinyrl->buffer_size = 0;
+	tinyrl->done = BOOL_FALSE;
+	tinyrl->completion_over = BOOL_FALSE;
+	tinyrl->point = 0;
+	tinyrl->end = 0;
+	tinyrl->attempted_completion_function = NULL;
+	tinyrl->keypress_fn = NULL;
+	tinyrl->hotkey_fn = NULL;
+	tinyrl->state = 0;
+	tinyrl->kill_string = NULL;
+	tinyrl->echo_char = '\0';
+	tinyrl->echo_enabled = BOOL_TRUE;
+	tinyrl->last_buffer = NULL;
+	tinyrl->last_point = 0;
+	tinyrl->last_line_size = 0;
+	tinyrl->utf8 = BOOL_FALSE;
+
+	// VT100 terminal
+	tinyrl->term = vt100_new(istream, ostream);
+	tinyrl->width = vt100_width(tinyrl->term);
+
+	// History object
+	tinyrl->hist = hist_new(hist_fname, hist_stifle);
+
+	return tinyrl;
+}
+
+
+void tinyrl_free(tinyrl_t *tinyrl)
+{
+	assert(tinyrl);
+	if (!tinyrl)
+		return;
+
+	hist_free(tinyrl->hist);
+	vt100_free(tinyrl->term);
+
+	faux_str_free(tinyrl->buffer);
+	faux_str_free(tinyrl->kill_string);
+	faux_str_free(tinyrl->last_buffer);
+	faux_str_free(tinyrl->prompt);
+
+	faux_free(tinyrl);
+}
+
+
+static void tty_raw_mode(tinyrl_t *tinyrl)
 {
 	struct termios new_termios = {};
 	FILE *istream = NULL;
@@ -81,266 +162,6 @@ static int tinyrl_timeout_default(tinyrl_t *tinyrl)
 	return -1;
 }
 
-/*----------------------------------------------------------------------- */
-static bool_t tinyrl_key_default(tinyrl_t * tinyrl, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (key > 31) {
-		char tmp[2];
-		tmp[0] = (key & 0xFF), tmp[1] = '\0';
-		/* inject tinyrl text into the buffer */
-		result = tinyrl_insert_text(tinyrl, tmp);
-	} else {
-		/* Call the external hotkey analyzer */
-		if (tinyrl->hotkey_fn)
-			tinyrl->hotkey_fn(tinyrl, key);
-	}
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_interrupt(tinyrl_t * tinyrl, int key)
-{
-	tinyrl_crlf(tinyrl);
-	tinyrl_delete_text(tinyrl, 0, tinyrl->end);
-	tinyrl->done = BOOL_TRUE;
-	/* keep the compiler happy */
-	key = key;
-
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_start_of_line(tinyrl_t * tinyrl, int key)
-{
-	/* set the insertion point to the start of the line */
-	tinyrl->point = 0;
-	/* keep the compiler happy */
-	key = key;
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_end_of_line(tinyrl_t * tinyrl, int key)
-{
-	/* set the insertion point to the end of the line */
-	tinyrl->point = tinyrl->end;
-	/* keep the compiler happy */
-	key = key;
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_kill(tinyrl_t * tinyrl, int key)
-{
-	/* release any old kill string */
-	lub_string_free(tinyrl->kill_string);
-
-	/* store the killed string */
-	tinyrl->kill_string = lub_string_dup(&tinyrl->buffer[tinyrl->point]);
-
-	/* delete the text to the end of the line */
-	tinyrl_delete_text(tinyrl, tinyrl->point, tinyrl->end);
-	/* keep the compiler happy */
-	key = key;
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_yank(tinyrl_t * tinyrl, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (tinyrl->kill_string) {
-		/* insert the kill string at the current insertion point */
-		result = tinyrl_insert_text(tinyrl, tinyrl->kill_string);
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_crlf(tinyrl_t * tinyrl, int key)
-{
-	tinyrl_crlf(tinyrl);
-	tinyrl->done = BOOL_TRUE;
-	/* keep the compiler happy */
-	key = key;
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_up(tinyrl_t * tinyrl, int key)
-{
-	bool_t result = BOOL_FALSE;
-	tinyrl_history_entry_t *entry = NULL;
-	if (tinyrl->line == tinyrl->buffer) {
-		/* go to the last history entry */
-		entry = tinyrl_history_getlast(tinyrl->history, &tinyrl->hist_iter);
-	} else {
-		/* already traversing the history list so get previous */
-		entry = tinyrl_history_getprevious(&tinyrl->hist_iter);
-	}
-	if (entry) {
-		/* display the entry moving the insertion point
-		 * to the end of the line 
-		 */
-		tinyrl->line = tinyrl_history_entry__get_line(entry);
-		tinyrl->point = tinyrl->end = strlen(tinyrl->line);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_down(tinyrl_t * tinyrl, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (tinyrl->line != tinyrl->buffer) {
-		/* we are not already at the bottom */
-		/* the iterator will have been set up by the key_up() function */
-		tinyrl_history_entry_t *entry =
-		    tinyrl_history_getnext(&tinyrl->hist_iter);
-		if (!entry) {
-			/* nothing more in the history list */
-			tinyrl->line = tinyrl->buffer;
-		} else {
-			tinyrl->line = tinyrl_history_entry__get_line(entry);
-		}
-		/* display the entry moving the insertion point
-		 * to the end of the line 
-		 */
-		tinyrl->point = tinyrl->end = strlen(tinyrl->line);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_left(tinyrl_t * tinyrl, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (tinyrl->point > 0) {
-		tinyrl->point--;
-		utf8_point_left(tinyrl);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_right(tinyrl_t * tinyrl, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (tinyrl->point < tinyrl->end) {
-		tinyrl->point++;
-		utf8_point_right(tinyrl);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_backspace(tinyrl_t *tinyrl, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (tinyrl->point) {
-		unsigned int end = --tinyrl->point;
-		utf8_point_left(tinyrl);
-		tinyrl_delete_text(tinyrl, tinyrl->point, end);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_backword(tinyrl_t *tinyrl, int key)
-{
-	bool_t result = BOOL_FALSE;
-
-    /* remove current whitespace before cursor */
-	while (tinyrl->point > 0 && isspace(tinyrl->line[tinyrl->point - 1]))
-        tinyrl_key_backspace(tinyrl, KEY_BS);
-
-    /* delete word before cusor */
-	while (tinyrl->point > 0 && !isspace(tinyrl->line[tinyrl->point - 1]))
-        tinyrl_key_backspace(tinyrl, KEY_BS);
-
-	result = BOOL_TRUE;
-
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_delete(tinyrl_t * tinyrl, int key)
-{
-	bool_t result = BOOL_FALSE;
-	if (tinyrl->point < tinyrl->end) {
-		unsigned int begin = tinyrl->point++;
-		utf8_point_right(tinyrl);
-		tinyrl_delete_text(tinyrl, begin, tinyrl->point - 1);
-		result = BOOL_TRUE;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_clear_screen(tinyrl_t * tinyrl, int key)
-{
-	tinyrl_vt100_clear_screen(tinyrl->term);
-	tinyrl_vt100_cursor_home(tinyrl->term);
-	tinyrl_reset_line_state(tinyrl);
-
-	/* keep the compiler happy */
-	key = key;
-	tinyrl = tinyrl;
-	return BOOL_TRUE;
-}
-
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_erase_line(tinyrl_t * tinyrl, int key)
-{
-	unsigned int end;
-
-	/* release any old kill string */
-	lub_string_free(tinyrl->kill_string);
-
-	if (!tinyrl->point) {
-		tinyrl->kill_string = NULL;
-		return BOOL_TRUE;
-	}
-
-	end = tinyrl->point - 1;
-
-	/* store the killed string */
-	tinyrl->kill_string = malloc(tinyrl->point + 1);
-	memcpy(tinyrl->kill_string, tinyrl->buffer, tinyrl->point);
-	tinyrl->kill_string[tinyrl->point] = '\0';
-
-	/* delete the text from the start of the line */
-	tinyrl_delete_text(tinyrl, 0, end);
-	tinyrl->point = 0;
-
-	/* keep the compiler happy */
-	key = key;
-	tinyrl = tinyrl;
-
-	return BOOL_TRUE;
-}/*-------------------------------------------------------- */
 
 static bool_t tinyrl_escape_seq(tinyrl_t *tinyrl, const char *esc_seq)
 {
@@ -379,103 +200,6 @@ static bool_t tinyrl_escape_seq(tinyrl_t *tinyrl, const char *esc_seq)
 	return result;
 }
 
-/*-------------------------------------------------------- */
-static bool_t tinyrl_key_tab(tinyrl_t * tinyrl, int key)
-{
-	bool_t result = BOOL_FALSE;
-	tinyrl_match_e status = tinyrl_complete_with_extensions(tinyrl);
-
-	switch (status) {
-	case TINYRL_COMPLETED_MATCH:
-	case TINYRL_MATCH:
-		/* everything is OK with the world... */
-		result = tinyrl_insert_text(tinyrl, " ");
-		break;
-	case TINYRL_NO_MATCH:
-	case TINYRL_MATCH_WITH_EXTENSIONS:
-	case TINYRL_AMBIGUOUS:
-	case TINYRL_COMPLETED_AMBIGUOUS:
-		/* oops don't change the result and let the bell ring */
-		break;
-	}
-	/* keep the compiler happy */
-	key = key;
-	return result;
-}
-
-/*-------------------------------------------------------- */
-static void tinyrl_fini(tinyrl_t * tinyrl)
-{
-	/* delete the history session */
-	tinyrl_history_delete(tinyrl->history);
-
-	/* delete the terminal session */
-	tinyrl_vt100_delete(tinyrl->term);
-
-	/* free up any dynamic strings */
-	lub_string_free(tinyrl->buffer);
-	lub_string_free(tinyrl->kill_string);
-	lub_string_free(tinyrl->last_buffer);
-	lub_string_free(tinyrl->prompt);
-}
-
-/*-------------------------------------------------------- */
-static void tinyrl_init(tinyrl_t * tinyrl, FILE * istream, FILE * ostream,
-	unsigned int stifle, tinyrl_completion_func_t * complete_fn)
-{
-	int i;
-
-	for (i = 0; i < NUM_HANDLERS; i++) {
-		tinyrl->handlers[i] = tinyrl_key_default;
-	}
-	/* Default handlers */
-	tinyrl->handlers[KEY_CR] = tinyrl_key_crlf;
-	tinyrl->handlers[KEY_LF] = tinyrl_key_crlf;
-	tinyrl->handlers[KEY_ETX] = tinyrl_key_interrupt;
-	tinyrl->handlers[KEY_DEL] = tinyrl_key_backspace;
-	tinyrl->handlers[KEY_BS] = tinyrl_key_backspace;
-	tinyrl->handlers[KEY_EOT] = tinyrl_key_delete;
-	tinyrl->handlers[KEY_FF] = tinyrl_key_clear_screen;
-	tinyrl->handlers[KEY_NAK] = tinyrl_key_erase_line;
-	tinyrl->handlers[KEY_SOH] = tinyrl_key_start_of_line;
-	tinyrl->handlers[KEY_ENQ] = tinyrl_key_end_of_line;
-	tinyrl->handlers[KEY_VT] = tinyrl_key_kill;
-	tinyrl->handlers[KEY_EM] = tinyrl_key_yank;
-	tinyrl->handlers[KEY_HT] = tinyrl_key_tab;
-	tinyrl->handlers[KEY_ETB] = tinyrl_key_backword;
-
-	tinyrl->line = NULL;
-	tinyrl->max_line_length = 0;
-	tinyrl->prompt = NULL;
-	tinyrl->prompt_size = 0;
-	tinyrl->buffer = NULL;
-	tinyrl->buffer_size = 0;
-	tinyrl->done = BOOL_FALSE;
-	tinyrl->completion_over = BOOL_FALSE;
-	tinyrl->point = 0;
-	tinyrl->end = 0;
-	tinyrl->attempted_completion_function = complete_fn;
-	tinyrl->timeout_fn = tinyrl_timeout_default;
-	tinyrl->keypress_fn = NULL;
-	tinyrl->hotkey_fn = NULL;
-	tinyrl->state = 0;
-	tinyrl->kill_string = NULL;
-	tinyrl->echo_char = '\0';
-	tinyrl->echo_enabled = BOOL_TRUE;
-	tinyrl->last_buffer = NULL;
-	tinyrl->last_point = 0;
-	tinyrl->last_line_size = 0;
-	tinyrl->utf8 = BOOL_FALSE;
-
-	/* create the vt100 terminal */
-	tinyrl->term = tinyrl_vt100_new(NULL, ostream);
-	tinyrl__set_istream(tinyrl, istream);
-	tinyrl->last_width = tinyrl_vt100__get_width(tinyrl->term);
-
-	/* create the history */
-	tinyrl->history = tinyrl_history_new(stifle);
-}
-
 /*-------------------------------------------------------- */
 int tinyrl_printf(const tinyrl_t * tinyrl, const char *fmt, ...)
 {
@@ -489,18 +213,6 @@ int tinyrl_printf(const tinyrl_t * tinyrl, const char *fmt, ...)
 	return len;
 }
 
-/*-------------------------------------------------------- */
-void tinyrl_delete(tinyrl_t * tinyrl)
-{
-	assert(tinyrl);
-	if (tinyrl) {
-		/* let the object tidy itself up */
-		tinyrl_fini(tinyrl);
-
-		/* release the memory associate with tinyrl instance */
-		free(tinyrl);
-	}
-}
 
 /*-------------------------------------------------------- */
 
@@ -558,7 +270,7 @@ void tinyrl_multi_crlf(const tinyrl_t * tinyrl)
 	unsigned int count = utf8_nsyms(tinyrl, tinyrl->last_buffer, tinyrl->last_point);
 
 	tinyrl_internal_position(tinyrl, tinyrl->prompt_len + line_len,
-		- (line_len - count), tinyrl->last_width);
+		- (line_len - count), tinyrl->width);
 	tinyrl_crlf(tinyrl);
 	tinyrl_vt100_oflush(tinyrl->term);
 }
@@ -573,7 +285,7 @@ void tinyrl_redisplay(tinyrl_t * tinyrl)
 	int cols;
 
 	/* Prepare print position */
-	if (tinyrl->last_buffer && (width == tinyrl->last_width)) {
+	if (tinyrl->last_buffer && (width == tinyrl->width)) {
 		unsigned int eq_len = 0;
 		/* If line and last line have the equal chars at begining */
 		eq_chars = lub_string_equal_part(tinyrl->line, tinyrl->last_buffer,
@@ -584,7 +296,7 @@ void tinyrl_redisplay(tinyrl_t * tinyrl)
 			count - eq_len, width);
 	} else {
 		/* Prepare to resize */
-		if (width != tinyrl->last_width) {
+		if (width != tinyrl->width) {
 			tinyrl_vt100_next_line(tinyrl->term);
 			tinyrl_vt100_erase_down(tinyrl->term);
 		}
@@ -616,7 +328,7 @@ void tinyrl_redisplay(tinyrl_t * tinyrl)
 	lub_string_free(tinyrl->last_buffer);
 	tinyrl->last_buffer = lub_string_dup(tinyrl->line);
 	tinyrl->last_point = tinyrl->point;
-	tinyrl->last_width = width;
+	tinyrl->width = width;
 	tinyrl->last_line_size = line_size;
 }
 
@@ -683,7 +395,7 @@ static char *internal_readline(tinyrl_t * tinyrl,
 		char *esc_p = esc_seq;
 
 		/* Set the terminal into raw mode */
-		tty_set_raw_mode(tinyrl);
+		tty_raw_mode(tinyrl);
 		tinyrl_reset_line_state(tinyrl);
 
 		while (!tinyrl->done) {

+ 1 - 1
tinyrl/tinyrl/utf8.c

@@ -216,7 +216,7 @@ char *utf8_move_right(const char *line, char *cur_pos)
 
 /** @brief Counts number of printable symbols within UTF-8 string
  *
- * One printable symol can consist of several UTF-8 bytes.
+ * One printable symbol can consist of several UTF-8 bytes.
  * CJK UTF-8 character can occupy 2 printable positions.
  *
  * @param [in] str UTF-8 string.

+ 1 - 3
tinyrl/vt100.h

@@ -68,7 +68,7 @@ typedef enum {
 
 // Return values from vt100_getchar()
 #define VT100_RET_EOF -1
-#define VT100_RET_TIMEOUT -2
+#define VT100_RET_EMPTY -2
 #define VT100_RET_ERR -3
 
 
@@ -81,8 +81,6 @@ FILE *vt100_istream(const vt100_t *vt100);
 void vt100_set_istream(vt100_t *vt100, FILE *istream);
 FILE *vt100_ostream(const vt100_t *vt100);
 void vt100_set_ostream(vt100_t *vt100, FILE *ostream);
-int  vt100_timeout(vt100_t *vt100);
-void vt100_set_timeout(vt100_t *vt100, int timeout);
 
 size_t vt100_width(const vt100_t *vt100);
 size_t vt100_height(const vt100_t *vt100);

+ 5 - 57
tinyrl/vt100/vt100.c

@@ -15,7 +15,6 @@
 struct vt100_s {
 	FILE *istream;
 	FILE *ostream;
-	int timeout; // Input timeout in seconds
 };
 
 
@@ -53,8 +52,6 @@ vt100_t *vt100_new(FILE *istream, FILE *ostream)
 	// Initialize
 	vt100->istream = istream;
 	vt100->ostream = ostream;
-	vt100->timeout = -1; // No timeout by default
-
 
 	return vt100;
 }
@@ -102,24 +99,6 @@ void vt100_set_ostream(vt100_t *vt100, FILE *ostream)
 }
 
 
-int vt100_timeout(vt100_t *vt100)
-{
-	if (!vt100)
-		return -1;
-
-	return vt100->timeout;
-}
-
-
-void vt100__set_timeout(vt100_t *vt100, int timeout)
-{
-	if (!vt100)
-		return;
-
-	vt100->timeout = timeout;
-}
-
-
 vt100_esc_e vt100_esc_decode(const vt100_t *vt100, const char *esc_seq)
 {
 	vt100_esc_e result = VT100_UNKNOWN;
@@ -168,48 +147,17 @@ int vt100_vprintf(const vt100_t *vt100, const char *fmt, va_list args)
 int vt100_getchar(const vt100_t *vt100)
 {
 	unsigned char c = 0;
-	int istream_fd = -1;
-	fd_set rfds = {};
-	struct timeval tv = {};
-	int retval = 0;
 	ssize_t res = VT100_RET_ERR;
 
 	if (!vt100 || !vt100->istream)
 		return VT100_RET_ERR;
 
-	istream_fd = fileno(vt100->istream);
-
-	// Simple variant
-	// Just wait for the input if no timeout specified
-	if (vt100->timeout <= 0) {
-		while (((res = read(istream_fd, &c, 1)) < 0) &&
-			(EAGAIN == errno));
-		// EOF or error
-		if (res < 0)
-			return VT100_RET_ERR;
-		if (0 == res)
-			return VT100_RET_EOF;
-		return c;
-	}
-
-	// Variant with timeout
-	// Set timeout for the select()
-	FD_ZERO(&rfds);
-	FD_SET(istream_fd, &rfds);
-	tv.tv_sec = vt100->timeout;
-	tv.tv_usec = 0;
-	while (((retval = select(istream_fd + 1, &rfds, NULL, NULL, &tv)) < 0) &&
-		(EAGAIN == errno));
-	// Error or timeout
-	if (retval < 0)
-		return VT100_RET_ERR;
-	if (0 == retval)
-		return VT100_RET_TIMEOUT;
-
-	res = read(istream_fd, &c, 1);
-	// EOF or error
-	if (res < 0)
+	res = read(fileno(vt100->istream), &c, 1);
+	if (res < 0) {
+		if (EAGAIN == errno)
+			return VT100_RET_EMPTY; // Non-blocking read
 		return VT100_RET_ERR;
+	}
 	if (0 == res)
 		return VT100_RET_EOF;