Browse Source

tinyrl: Key delete and backspace

Serj Kalichev 1 year ago
parent
commit
c3a547e73e
4 changed files with 125 additions and 353 deletions
  1. 63 56
      tinyrl/tinyrl/keys.c
  2. 19 18
      tinyrl/tinyrl/private.h
  3. 25 255
      tinyrl/tinyrl/tinyrl.c
  4. 18 24
      tinyrl/tinyrl/utf8.c

+ 63 - 56
tinyrl/tinyrl/keys.c

@@ -12,7 +12,7 @@
 #include "private.h"
 #include "private.h"
 
 
 
 
-bool_t tinyrl_key_default(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_default(tinyrl_t *tinyrl, char key)
 {
 {
 	if (key > 31) {
 	if (key > 31) {
 		// Inject new char to the line
 		// Inject new char to the line
@@ -27,44 +27,44 @@ bool_t tinyrl_key_default(tinyrl_t * tinyrl, char key)
 }
 }
 
 
 
 
-bool_t tinyrl_key_interrupt(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_interrupt(tinyrl_t *tinyrl, char key)
 {
 {
-/*
-	tinyrl_crlf(tinyrl);
-	tinyrl_delete_text(tinyrl, 0, tinyrl->end);
-	tinyrl->done = BOOL_TRUE;
-	// keep the compiler happy 
+//	tinyrl_crlf(tinyrl);
+//	tinyrl->done = BOOL_TRUE;
+	tinyrl_line_delete(tinyrl, 0, tinyrl->line.len);
+
+	// Happy compiler
 	key = key;
 	key = key;
-*/
+
 	return BOOL_TRUE;
 	return BOOL_TRUE;
 }
 }
 
 
 
 
-bool_t tinyrl_key_start_of_line(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_start_of_line(tinyrl_t *tinyrl, char key)
 {
 {
-/*
-	// set the insertion point to the start of the line 
-	tinyrl->point = 0;
-	// keep the compiler happy 
+	// Set current position to the start of the line
+	tinyrl->line.pos = 0;
+
+	// Happy compiler
 	key = key;
 	key = key;
-*/
+
 	return BOOL_TRUE;
 	return BOOL_TRUE;
 }
 }
 
 
 
 
-bool_t tinyrl_key_end_of_line(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_end_of_line(tinyrl_t *tinyrl, char key)
 {
 {
-/*
-	// set the insertion point to the end of the line 
-	tinyrl->point = tinyrl->end;
-	// keep the compiler happy 
+	// Set current position to the end of the line
+	tinyrl->line.pos = tinyrl->line.len;
+
+	// Happy compiler
 	key = key;
 	key = key;
-*/
+
 	return BOOL_TRUE;
 	return BOOL_TRUE;
 }
 }
 
 
 
 
-bool_t tinyrl_key_kill(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_kill(tinyrl_t *tinyrl, char key)
 {
 {
 /*
 /*
 	// release any old kill string 
 	// release any old kill string 
@@ -82,7 +82,7 @@ bool_t tinyrl_key_kill(tinyrl_t * tinyrl, char key)
 }
 }
 
 
 
 
-bool_t tinyrl_key_yank(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_yank(tinyrl_t *tinyrl, char key)
 {
 {
 	bool_t result = BOOL_FALSE;
 	bool_t result = BOOL_FALSE;
 /*
 /*
@@ -97,7 +97,7 @@ bool_t tinyrl_key_yank(tinyrl_t * tinyrl, char key)
 }
 }
 
 
 
 
-bool_t tinyrl_key_crlf(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_crlf(tinyrl_t *tinyrl, char key)
 {
 {
 /*
 /*
 	tinyrl_crlf(tinyrl);
 	tinyrl_crlf(tinyrl);
@@ -109,7 +109,7 @@ bool_t tinyrl_key_crlf(tinyrl_t * tinyrl, char key)
 }
 }
 
 
 
 
-bool_t tinyrl_key_up(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_up(tinyrl_t *tinyrl, char key)
 {
 {
 	bool_t result = BOOL_FALSE;
 	bool_t result = BOOL_FALSE;
 /*
 /*
@@ -136,7 +136,7 @@ bool_t tinyrl_key_up(tinyrl_t * tinyrl, char key)
 }
 }
 
 
 
 
-bool_t tinyrl_key_down(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_down(tinyrl_t *tinyrl, char key)
 {
 {
 	bool_t result = BOOL_FALSE;
 	bool_t result = BOOL_FALSE;
 /*
 /*
@@ -163,7 +163,7 @@ bool_t tinyrl_key_down(tinyrl_t * tinyrl, char key)
 }
 }
 
 
 
 
-bool_t tinyrl_key_left(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_left(tinyrl_t *tinyrl, char key)
 {
 {
 	bool_t result = BOOL_FALSE;
 	bool_t result = BOOL_FALSE;
 /*
 /*
@@ -179,7 +179,7 @@ bool_t tinyrl_key_left(tinyrl_t * tinyrl, char key)
 }
 }
 
 
 
 
-bool_t tinyrl_key_right(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_right(tinyrl_t *tinyrl, char key)
 {
 {
 	bool_t result = BOOL_FALSE;
 	bool_t result = BOOL_FALSE;
 /*
 /*
@@ -197,18 +197,41 @@ bool_t tinyrl_key_right(tinyrl_t * tinyrl, char key)
 
 
 bool_t tinyrl_key_backspace(tinyrl_t *tinyrl, char key)
 bool_t tinyrl_key_backspace(tinyrl_t *tinyrl, char 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;
+	if (tinyrl->line.pos == 0)
+		return BOOL_TRUE;
+
+	if (tinyrl->utf8) {
+		off_t new_pos = 0;
+		new_pos = utf8_move_left(tinyrl->line.str, tinyrl->line.pos);
+		tinyrl_line_delete(tinyrl, new_pos, tinyrl->line.pos - new_pos);
+	} else {
+		tinyrl_line_delete(tinyrl, tinyrl->line.pos - 1, 1);
 	}
 	}
-	// keep the compiler happy 
+
+	// Happy compiler
 	key = key;
 	key = key;
-*/
-	return result;
+
+	return BOOL_TRUE;
+}
+
+
+bool_t tinyrl_key_delete(tinyrl_t *tinyrl, char key)
+{
+	if (tinyrl->line.pos == tinyrl->line.len)
+		return BOOL_TRUE;
+
+	if (tinyrl->utf8) {
+		off_t new_pos = 0;
+		new_pos = utf8_move_right(tinyrl->line.str, tinyrl->line.pos);
+		tinyrl_line_delete(tinyrl, tinyrl->line.pos, new_pos - tinyrl->line.pos);
+	} else {
+		tinyrl_line_delete(tinyrl, tinyrl->line.pos, 1);
+	}
+
+	// Happy compiler
+	key = key;
+
+	return BOOL_TRUE;
 }
 }
 
 
 
 
@@ -232,24 +255,8 @@ bool_t tinyrl_key_backword(tinyrl_t *tinyrl, char key)
 	return result;
 	return result;
 }
 }
 
 
-bool_t tinyrl_key_delete(tinyrl_t * tinyrl, char 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, char key)
+bool_t tinyrl_key_clear_screen(tinyrl_t *tinyrl, char key)
 {
 {
 /*
 /*
 	tinyrl_vt100_clear_screen(tinyrl->term);
 	tinyrl_vt100_clear_screen(tinyrl->term);
@@ -264,7 +271,7 @@ bool_t tinyrl_key_clear_screen(tinyrl_t * tinyrl, char key)
 }
 }
 
 
 
 
-bool_t tinyrl_key_erase_line(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_erase_line(tinyrl_t *tinyrl, char key)
 {
 {
 /*	unsigned int end;
 /*	unsigned int end;
 
 
@@ -295,7 +302,7 @@ bool_t tinyrl_key_erase_line(tinyrl_t * tinyrl, char key)
 }
 }
 
 
 
 
-bool_t tinyrl_key_tab(tinyrl_t * tinyrl, char key)
+bool_t tinyrl_key_tab(tinyrl_t *tinyrl, char key)
 {
 {
 	bool_t result = BOOL_FALSE;
 	bool_t result = BOOL_FALSE;
 /*
 /*

+ 19 - 18
tinyrl/tinyrl/private.h

@@ -10,32 +10,33 @@
 // UTF-8 functions
 // UTF-8 functions
 ssize_t utf8_to_wchar(const char *sp, unsigned long *sym_out);
 ssize_t utf8_to_wchar(const char *sp, unsigned long *sym_out);
 bool_t utf8_wchar_is_cjk(unsigned long sym);
 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);
+off_t utf8_move_left(const char *line, off_t cur_pos);
+off_t utf8_move_right(const char *line, off_t cur_pos);
 
 
 // Keys
 // Keys
-bool_t tinyrl_key_default(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_interrupt(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_start_of_line(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_end_of_line(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_kill(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_yank(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_crlf(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_up(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_down(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_left(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_right(tinyrl_t * tinyrl, char key);
+bool_t tinyrl_key_default(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_interrupt(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_start_of_line(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_end_of_line(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_kill(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_yank(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_crlf(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_up(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_down(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_left(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_right(tinyrl_t *tinyrl, char key);
 bool_t tinyrl_key_backspace(tinyrl_t *tinyrl, char key);
 bool_t tinyrl_key_backspace(tinyrl_t *tinyrl, char key);
 bool_t tinyrl_key_backword(tinyrl_t *tinyrl, char key);
 bool_t tinyrl_key_backword(tinyrl_t *tinyrl, char key);
-bool_t tinyrl_key_delete(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_clear_screen(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_erase_line(tinyrl_t * tinyrl, char key);
-bool_t tinyrl_key_tab(tinyrl_t * tinyrl, char key);
+bool_t tinyrl_key_delete(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_clear_screen(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_erase_line(tinyrl_t *tinyrl, char key);
+bool_t tinyrl_key_tab(tinyrl_t *tinyrl, char key);
 
 
 // Tinyrl
 // Tinyrl
+bool_t tinyrl_esc_seq(tinyrl_t *tinyrl, const char *esc_seq);
 bool_t tinyrl_line_extend(tinyrl_t *tinyrl, size_t len);
 bool_t tinyrl_line_extend(tinyrl_t *tinyrl, size_t len);
 bool_t tinyrl_line_insert(tinyrl_t *tinyrl, const char *text, size_t len);
 bool_t tinyrl_line_insert(tinyrl_t *tinyrl, const char *text, size_t len);
-bool_t tinyrl_esc_seq(tinyrl_t *tinyrl, const char *esc_seq);
+bool_t tinyrl_line_delete(tinyrl_t *tinyrl, off_t start, size_t len);
 
 
 
 
 typedef struct line_s {
 typedef struct line_s {

+ 25 - 255
tinyrl/tinyrl/tinyrl.c

@@ -305,9 +305,10 @@ static bool_t process_char(tinyrl_t *tinyrl, char key)
 	// For non UTF-8 encoding the utf8_cont is always 0.
 	// For non UTF-8 encoding the utf8_cont is always 0.
 	// For UTF-8 it's 0 when one-byte symbol or we get
 	// For UTF-8 it's 0 when one-byte symbol or we get
 	// all bytes for the current multibyte character
 	// all bytes for the current multibyte character
-//	if (!utf8_cont)
-//		tinyrl_redisplay(tinyrl);
-printf("%s\n", tinyrl->line.str);
+	if (!tinyrl->utf8_cont) {
+		//tinyrl_redisplay(tinyrl);
+		printf("%s\n", tinyrl->line.str);
+	}
 
 
 	return BOOL_TRUE;
 	return BOOL_TRUE;
 }
 }
@@ -432,6 +433,27 @@ bool_t tinyrl_line_insert(tinyrl_t *tinyrl, const char *text, size_t len)
 }
 }
 
 
 
 
+bool_t tinyrl_line_delete(tinyrl_t *tinyrl, off_t start, size_t len)
+{
+	if (start >= tinyrl->line.len)
+		return BOOL_TRUE;
+
+	if ((start + len) >= tinyrl->line.len) {
+		tinyrl->line.len = start;
+	} else {
+		memmove(tinyrl->line.str + start,
+			tinyrl->line.str + start + len,
+			tinyrl->line.len - (start + len));
+		tinyrl->line.len -= len;
+	}
+
+	tinyrl->line.pos = start;
+	tinyrl->line.str[tinyrl->line.len] = '\0';
+
+	return BOOL_TRUE;
+}
+
+
 #if 0
 #if 0
 
 
 /*----------------------------------------------------------------------- */
 /*----------------------------------------------------------------------- */
@@ -576,210 +598,6 @@ void tinyrl_redisplay(tinyrl_t * tinyrl)
 }
 }
 
 
 
 
-static char *internal_insertline(tinyrl_t * tinyrl, char *buffer)
-{
-	char *p;
-	char *s = buffer;
-
-	/* strip any spurious '\r' or '\n' */
-	if ((p = strchr(buffer, '\r')))
-		*p = '\0';
-	if ((p = strchr(buffer, '\n')))
-		*p = '\0';
-	/* skip any whitespace at the beginning of the line */
-	if (0 == tinyrl->point) {
-		while (*s && isspace(*s))
-			s++;
-	}
-	if (*s) {
-		/* append tinyrl string to the input buffer */
-		(void)tinyrl_insert_text(tinyrl, s);
-	}
-	/* echo the command to the output stream */
-	tinyrl_redisplay(tinyrl);
-
-	return s;
-}
-
-/*----------------------------------------------------------------------- */
-static char *internal_readline(tinyrl_t * tinyrl,
-	void *context, const char *str)
-{
-	FILE *istream = tinyrl_vt100__get_istream(tinyrl->term);
-	char *result = NULL;
-	int lerrno = 0;
-
-	tinyrl->done = BOOL_FALSE;
-	tinyrl->point = 0;
-	tinyrl->end = 0;
-	tinyrl->buffer = lub_string_dup("");
-	tinyrl->buffer_size = strlen(tinyrl->buffer);
-	tinyrl->line = tinyrl->buffer;
-	tinyrl->context = context;
-
-	/* Interactive session */
-	if (isatty(fileno(tinyrl->istream)) && !str) {
-		unsigned int utf8_cont = 0; /* UTF-8 continue bytes */
-		unsigned int esc_cont = 0; /* Escape sequence continues */
-		char esc_seq[10]; /* Buffer for ESC sequence */
-		char *esc_p = esc_seq;
-
-		/* Set the terminal into raw mode */
-		tty_raw_mode(tinyrl);
-		tinyrl_reset_line_state(tinyrl);
-
-		while (!tinyrl->done) {
-			int key;
-
-			key = tinyrl_getchar(tinyrl);
-
-			/* Error || EOF || Timeout */
-			if (key < 0) {
-				if ((VT100_TIMEOUT == key) &&
-					!tinyrl->timeout_fn(tinyrl))
-					continue;
-				/* It's time to finish the session */
-				tinyrl->done = BOOL_TRUE;
-				tinyrl->line = NULL;
-				lerrno = ENOENT;
-				continue;
-			}
-
-			/* Real key pressed */
-			/* Common callback for any key */
-			if (tinyrl->keypress_fn)
-				tinyrl->keypress_fn(tinyrl, key);
-
-			/* Check for ESC sequence. It's a special case. */
-			if (!esc_cont && (key == KEY_ESC)) {
-				esc_cont = 1; /* Start ESC sequence */
-				esc_p = esc_seq;
-				continue;
-			}
-			if (esc_cont) {
-				/* Broken sequence */
-				if (esc_p >= (esc_seq + sizeof(esc_seq) - 1)) {
-					esc_cont = 0;
-					continue;
-				}
-				/* Dump the control sequence into sequence buffer
-				   ANSI standard control sequences will end
-				   with a character between 64 - 126 */
-				*esc_p = key & 0xff;
-				esc_p++;
-				/* tinyrl is an ANSI control sequence terminator code */
-				if ((key != '[') && (key > 63)) {
-					*esc_p = '\0';
-					tinyrl_escape_seq(tinyrl, esc_seq);
-					esc_cont = 0;
-					tinyrl_redisplay(tinyrl);
-				}
-				continue;
-			}
-
-			/* Call the handler for tinyrl key */
-			if (!tinyrl->handlers[key](tinyrl, key))
-				tinyrl_ding(tinyrl);
-			if (tinyrl->done) /* Some handler set the done flag */
-				continue; /* It will break the loop */
-
-			if (tinyrl->utf8) {
-				if (!(UTF8_7BIT_MASK & key)) /* ASCII char */
-					utf8_cont = 0;
-				else if (utf8_cont && (UTF8_10 == (key & UTF8_MASK))) /* Continue byte */
-					utf8_cont--;
-				else if (UTF8_11 == (key & UTF8_MASK)) { /* First byte of multibyte char */
-					/* Find out number of char's bytes */
-					int b = key;
-					utf8_cont = 0;
-					while ((utf8_cont < 6) && (UTF8_10 != (b & UTF8_MASK))) {
-						utf8_cont++;
-						b = b << 1;
-					}
-				}
-			}
-			/* For non UTF-8 encoding the utf8_cont is always 0.
-			   For UTF-8 it's 0 when one-byte symbol or we get
-			   all bytes for the current multibyte character. */
-			if (!utf8_cont)
-				tinyrl_redisplay(tinyrl);
-		}
-		/* If the last character in the line (other than NULL)
-		   is a space remove it. */
-		if (tinyrl->end && tinyrl->line && isspace(tinyrl->line[tinyrl->end - 1]))
-			tinyrl_delete_text(tinyrl, tinyrl->end - 1, tinyrl->end);
-		/* Restores the terminal mode */
-		tty_restore_mode(tinyrl);
-
-	/* Non-interactive session */
-	} else {
-		char *s = NULL, buffer[80];
-		size_t len = sizeof(buffer);
-		char *tmp = NULL;
-
-		/* manually reset the line state without redisplaying */
-		lub_string_free(tinyrl->last_buffer);
-		tinyrl->last_buffer = NULL;
-
-		if (str) {
-			tmp = lub_string_dup(str);
-			internal_insertline(tinyrl, tmp);
-		} else {
-			while (istream && (sizeof(buffer) == len) &&
-				(s = fgets(buffer, sizeof(buffer), istream))) {
-				s = internal_insertline(tinyrl, buffer);
-				len = strlen(buffer) + 1; /* account for the '\0' */
-			}
-			if (!s || ((tinyrl->line[0] == '\0') && feof(istream))) {
-				/* time to finish the session */
-				tinyrl->line = NULL;
-				lerrno = ENOENT;
-			}
-		}
-
-		/*
-		 * check against fgets returning null as either error or end of file.
-		 * tinyrl is a measure to stop potential task spin on encountering an
-		 * error from fgets.
-		 */
-		if (tinyrl->line && !tinyrl->handlers[KEY_LF](tinyrl, KEY_LF)) {
-			/* an issue has occured */
-			tinyrl->line = NULL;
-			lerrno = ENOEXEC;
-		}
-		if (str)
-			lub_string_free(tmp);
-	}
-	/*
-	 * duplicate the string for return to the client 
-	 * we have to duplicate as we may be referencing a
-	 * history entry or our internal buffer
-	 */
-	result = tinyrl->line ? lub_string_dup(tinyrl->line) : NULL;
-
-	/* free our internal buffer */
-	free(tinyrl->buffer);
-	tinyrl->buffer = NULL;
-
-	if (!result)
-		errno = lerrno; /* get saved errno */
-	return result;
-}
-
-/*----------------------------------------------------------------------- */
-char *tinyrl_readline(tinyrl_t * tinyrl, void *context)
-{
-	return internal_readline(tinyrl, context, NULL);
-}
-
-/*----------------------------------------------------------------------- */
-char *tinyrl_forceline(tinyrl_t * tinyrl, void *context, const char *line)
-{
-	return internal_readline(tinyrl, context, line);
-}
-
-
-
 /*----------------------------------------------------------------------- */
 /*----------------------------------------------------------------------- */
 /* 
 /* 
  * A convenience function for displaying a list of strings in columnar
  * A convenience function for displaying a list of strings in columnar
@@ -823,54 +641,6 @@ void tinyrl_display_matches(const tinyrl_t *tinyrl,
 	}
 	}
 }
 }
 
 
-/*----------------------------------------------------------------------- */
-/*
- * Delete the text between start and end in the current line. (inclusive)
- * tinyrl adjusts the rl_point and rl_end indexes appropriately.
- */
-void tinyrl_delete_text(tinyrl_t * tinyrl, unsigned int start, unsigned int end)
-{
-	unsigned int delta;
-
-	/*
-	 * If the client wants to change the line ensure that the line and buffer
-	 * references are in sync
-	 */
-	changed_line(tinyrl);
-
-	/* make sure we play it safe */
-	if (start > end) {
-		unsigned int tmp = end;
-		start = end;
-		end = tmp;
-	}
-	if (end > tinyrl->end)
-		end = tinyrl->end;
-
-	delta = (end - start) + 1;
-
-	/* move any text which is left */
-	memmove(&tinyrl->buffer[start],
-		&tinyrl->buffer[start + delta], tinyrl->end - end);
-
-	/* now adjust the indexs */
-	if (tinyrl->point >= start) {
-		if (tinyrl->point > end) {
-			/* move the insertion point back appropriately */
-			tinyrl->point -= delta;
-		} else {
-			/* move the insertion point to the start */
-			tinyrl->point = start;
-		}
-	}
-	if (tinyrl->end > end)
-		tinyrl->end -= delta;
-	else
-		tinyrl->end = start;
-	/* put a terminator at the end of the buffer */
-	tinyrl->buffer[tinyrl->end] = '\0';
-}
-
 
 
 /*-------------------------------------------------------- */
 /*-------------------------------------------------------- */
 /*
 /*

+ 18 - 24
tinyrl/tinyrl/utf8.c

@@ -168,23 +168,21 @@ bool_t utf8_wchar_is_cjk(unsigned long sym)
  *
  *
  * @param [in] line UTF-8 string.
  * @param [in] line UTF-8 string.
  * @param [in] cur_pos Current position within UTF-8 string.
  * @param [in] cur_pos Current position within UTF-8 string.
- * @return Position (pointer) of previous UTF-8 character or NULL on error.
+ * @return Position of previous UTF-8 character or NULL on error.
  */
  */
-char *utf8_move_left(const char *line, char *cur_pos)
+off_t utf8_move_left(const char *line, off_t cur_pos)
 {
 {
-	char *pos = cur_pos;
+	const char *pos = line + cur_pos;
 
 
-	if (!line || !pos)
-		return NULL;
-	if (line > pos)
-		return NULL;
+	if (!line)
+		return 0;
 	if (pos == line)
 	if (pos == line)
-		return pos; // It's already leftmost position
-	pos--;
-	while ((pos > line) && (UTF8_10 == (*pos & UTF8_MASK)))
+		return cur_pos; // It's already leftmost position
+	do {
 		pos--;
 		pos--;
+	} while ((pos > line) && (UTF8_10 == (*pos & UTF8_MASK)));
 
 
-	return pos;
+	return pos - line;
 }
 }
 
 
 
 
@@ -192,25 +190,21 @@ char *utf8_move_left(const char *line, char *cur_pos)
  *
  *
  * @param [in] line UTF-8 string.
  * @param [in] line UTF-8 string.
  * @param [in] cur_pos Current position within UTF-8 string.
  * @param [in] cur_pos Current position within UTF-8 string.
- * @return Position (pointer) of next UTF-8 character or NULL on error.
+ * @return Position of next UTF-8 character or NULL on error.
  */
  */
-
-
-char *utf8_move_right(const char *line, char *cur_pos)
+off_t utf8_move_right(const char *line, off_t cur_pos)
 {
 {
-	char *pos = cur_pos;
+	const char *pos = line + cur_pos;
 
 
-	if (!line || !pos)
-		return NULL;
-	if (line > pos)
-		return NULL;
+	if (!line)
+		return 0;
 	if (*pos == '\0')
 	if (*pos == '\0')
-		return pos; // It's already rightmost position
-	pos++;
-	while ((*pos != '\0') && (UTF8_10 == (*pos & UTF8_MASK)))
+		return cur_pos; // It's already rightmost position
+	do {
 		pos++;
 		pos++;
+	} while ((*pos != '\0') && (UTF8_10 == (*pos & UTF8_MASK)));
 
 
-	return pos;
+	return pos - line;
 }
 }