From 32afd3aa6039b911816a68972b2366095cb777de Mon Sep 17 00:00:00 2001
From: Denys Vlasenko <vda.linux@googlemail.com>
Date: Sat, 5 Apr 2014 22:57:46 +0200
Subject: vi: some simplifications

function                                             old     new   delta
file_insert                                          301     315     +14
init_text_buffer                                     179     171      -8
colon                                               2889    2878     -11
file_size                                             37       -     -37
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 1/2 up/down: 14/-56)            Total: -42 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
---
 editors/vi.c | 236 ++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 120 insertions(+), 116 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index a978e0fcb..24a9f60a8 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -491,7 +491,6 @@ struct globals {
 } while (0)
 
 
-static int init_text_buffer(char *); // init from file or create new
 static void edit_file(char *);	// edit one file
 static void do_cmd(int);	// execute a command
 static int next_tabstop(int);
@@ -543,7 +542,6 @@ static void cookmode(void);	// return to "cooked" mode on tty
 static int mysleep(int);
 static int readit(void);	// read (maybe cursor) key from stdin
 static int get_one_char(void);	// read 1 char from stdin
-static int file_size(const char *);   // what is the byte size of "fn"
 #if !ENABLE_FEATURE_VI_READONLY
 #define file_insert(fn, p, update_ro_status) file_insert(fn, p)
 #endif
@@ -578,8 +576,8 @@ static char *char_search(char *, const char *, int, int);	// search for pattern
 #if ENABLE_FEATURE_VI_COLON
 static char *get_one_address(char *, int *);	// get colon addr, if present
 static char *get_address(char *, int *, int *);	// get two colon addrs, if present
-static void colon(char *);	// execute the "colon" mode cmds
 #endif
+static void colon(char *);	// execute the "colon" mode cmds
 #if ENABLE_FEATURE_VI_USE_SIGNALS
 static void winch_sig(int);	// catch window size changes
 static void suspend_sig(int);	// catch ctrl-Z
@@ -725,32 +723,29 @@ int vi_main(int argc, char **argv)
 static int init_text_buffer(char *fn)
 {
 	int rc;
-	int size = file_size(fn);	// file size. -1 means does not exist.
 
 	flush_undo_data();
+	modified_count = 0;
+	last_modified_count = -1;
+#if ENABLE_FEATURE_VI_YANKMARK
+	/* init the marks */
+	memset(mark, 0, sizeof(mark));
+#endif
 
 	/* allocate/reallocate text buffer */
 	free(text);
-	text_size = size + 10240;
+	text_size = 10240;
 	screenbegin = dot = end = text = xzalloc(text_size);
 
 	if (fn != current_filename) {
 		free(current_filename);
 		current_filename = xstrdup(fn);
 	}
-	if (size < 0) {
+	rc = file_insert(fn, text, 1);
+	if (rc < 0) {
 		// file doesnt exist. Start empty buf with dummy line
 		char_insert(text, '\n', NO_UNDO);
-		rc = 0;
-	} else {
-		rc = file_insert(fn, text, 1);
 	}
-	modified_count = 0;
-	last_modified_count = -1;
-#if ENABLE_FEATURE_VI_YANKMARK
-	/* init the marks. */
-	memset(mark, 0, sizeof(mark));
-#endif
 	return rc;
 }
 
@@ -1018,13 +1013,71 @@ static void setops(const char *args, const char *opname, int flg_no,
 }
 #endif
 
+#endif /* FEATURE_VI_COLON */
+
 // buf must be no longer than MAX_INPUT_LEN!
 static void colon(char *buf)
 {
+#if !ENABLE_FEATURE_VI_COLON
+	/* Simple ":cmd" handler with minimal set of commands */
+	char *p = buf;
+	int cnt;
+
+	if (*p == ':')
+		p++;
+	cnt = strlen(p);
+	if (cnt == 0)
+		return;
+	if (strncmp(p, "quit", cnt) == 0
+	 || strncmp(p, "q!", cnt) == 0
+	) {
+		if (modified_count && p[1] != '!') {
+			status_line_bold("No write since last change (:%s! overrides)", p);
+		} else {
+			editing = 0;
+		}
+		return;
+	}
+	if (strncmp(p, "write", cnt) == 0
+	 || strncmp(p, "wq", cnt) == 0
+	 || strncmp(p, "wn", cnt) == 0
+	 || (p[0] == 'x' && !p[1])
+	) {
+		cnt = file_write(current_filename, text, end - 1);
+		if (cnt < 0) {
+			if (cnt == -1)
+				status_line_bold("Write error: %s", strerror(errno));
+		} else {
+			modified_count = 0;
+			last_modified_count = -1;
+			status_line("'%s' %dL, %dC",
+				current_filename,
+				count_lines(text, end - 1), cnt
+			);
+			if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
+			 || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
+			) {
+				editing = 0;
+			}
+		}
+		return;
+	}
+	if (strncmp(p, "file", cnt) == 0) {
+		last_status_cksum = 0;	// force status update
+		return;
+	}
+	if (sscanf(p, "%d", &cnt) > 0) {
+		dot = find_line(cnt);
+		dot_skip_over_ws();
+		return;
+	}
+	not_implemented(p);
+#else
+
 	char c, *orig_buf, *buf1, *q, *r;
 	char *fn, cmd[MAX_INPUT_LEN], args[MAX_INPUT_LEN];
-	int i, l, li, ch, b, e;
-	int useforce, forced = FALSE;
+	int i, l, li, b, e;
+	int useforce;
 
 	// :3154	// if (-e line 3154) goto it  else stay put
 	// :4,33w! foo	// write a portion of buffer to file "foo"
@@ -1046,7 +1099,7 @@ static void colon(char *buf)
 	if (*buf == ':')
 		buf++;			// move past the ':'
 
-	li = ch = i = 0;
+	li = i = 0;
 	b = e = -1;
 	q = text;			// assume 1,$ for the range
 	r = end - 1;
@@ -1127,6 +1180,8 @@ static void colon(char *buf)
 		dot = yank_delete(q, r, 1, YANKDEL, ALLOW_UNDO);	// save, then delete lines
 		dot_skip_over_ws();
 	} else if (strncmp(cmd, "edit", i) == 0) {	// Edit a file
+		int size;
+
 		// don't edit, if the current file has been modified
 		if (modified_count && !useforce) {
 			status_line_bold("No write since last change (:%s! overrides)", cmd);
@@ -1144,8 +1199,7 @@ static void colon(char *buf)
 			goto ret;
 		}
 
-		if (init_text_buffer(fn) < 0)
-			goto ret;
+		size = init_text_buffer(fn);
 
 #if ENABLE_FEATURE_VI_YANKMARK
 		if (Ureg >= 0 && Ureg < 28) {
@@ -1161,12 +1215,14 @@ static void colon(char *buf)
 		li = count_lines(text, end - 1);
 		status_line("'%s'%s"
 			IF_FEATURE_VI_READONLY("%s")
-			" %dL, %dC", current_filename,
-			(file_size(fn) < 0 ? " [New file]" : ""),
+			" %dL, %dC",
+			current_filename,
+			(size < 0 ? " [New file]" : ""),
 			IF_FEATURE_VI_READONLY(
 				((readonly_mode) ? " [Readonly]" : ""),
 			)
-			li, ch);
+			li, (int)(end - text)
+		);
 	} else if (strncmp(cmd, "file", i) == 0) {	// what File is this
 		if (b != -1 || e != -1) {
 			status_line_bold("No address allowed on this command");
@@ -1255,6 +1311,8 @@ static void colon(char *buf)
 		}
 		editing = 0;
 	} else if (strncmp(cmd, "read", i) == 0) {	// read file into text[]
+		int size;
+
 		fn = args;
 		if (!fn[0]) {
 			status_line_bold("No filename given");
@@ -1268,23 +1326,24 @@ static void colon(char *buf)
 			q = next_line(q);
 		{ // dance around potentially-reallocated text[]
 			uintptr_t ofs = q - text;
-			ch = file_insert(fn, q, 0);
+			size = file_insert(fn, q, /*update_ro:*/ 0);
 			q = text + ofs;
 		}
-		if (ch < 0)
+		if (size < 0)
 			goto ret;	// nothing was inserted
 		// how many lines in text[]?
-		li = count_lines(q, q + ch - 1);
+		li = count_lines(q, q + size - 1);
 		status_line("'%s'"
 			IF_FEATURE_VI_READONLY("%s")
-			" %dL, %dC", fn,
+			" %dL, %dC",
+			fn,
 			IF_FEATURE_VI_READONLY((readonly_mode ? " [Readonly]" : ""),)
-			li, ch);
-		if (ch > 0) {
+			li, size
+		);
+		if (size > 0) {
 			// if the insert is before "dot" then we need to update
 			if (q <= dot)
-				dot += ch;
-			// modified_count++;
+				dot += size;
 		}
 	} else if (strncmp(cmd, "rewind", i) == 0) {	// rewind cmd line args
 		if (modified_count && !useforce) {
@@ -1409,6 +1468,9 @@ static void colon(char *buf)
 	        || strncmp(cmd, "wn", i) == 0
 	        || (cmd[0] == 'x' && !cmd[1])
 	) {
+		int size;
+		//int forced = FALSE;
+
 		// is there a file name to write to?
 		if (args[0]) {
 			fn = args;
@@ -1421,34 +1483,33 @@ static void colon(char *buf)
 #endif
 		// how many lines in text[]?
 		li = count_lines(q, r);
-		ch = r - q + 1;
-		// see if file exists- if not, its just a new file request
-		if (useforce) {
+		size = r - q + 1;
+		//if (useforce) {
 			// if "fn" is not write-able, chmod u+w
 			// sprintf(syscmd, "chmod u+w %s", fn);
 			// system(syscmd);
-			forced = TRUE;
-		}
+			// forced = TRUE;
+		//}
 		l = file_write(fn, q, r);
-		if (useforce && forced) {
+		//if (useforce && forced) {
 			// chmod u-w
 			// sprintf(syscmd, "chmod u-w %s", fn);
 			// system(syscmd);
-			forced = FALSE;
-		}
+			// forced = FALSE;
+		//}
 		if (l < 0) {
 			if (l == -1)
 				status_line_bold_errno(fn);
 		} else {
 			status_line("'%s' %dL, %dC", fn, li, l);
-			if (q == text && r == end - 1 && l == ch) {
+			if (q == text && r == end - 1 && l == size) {
 				modified_count = 0;
 				last_modified_count = -1;
 			}
 			if ((cmd[0] == 'x' || cmd[1] == 'q' || cmd[1] == 'n'
 			    || cmd[0] == 'X' || cmd[1] == 'Q' || cmd[1] == 'N'
 			    )
-			 && l == ch
+			 && l == size
 			) {
 				editing = 0;
 			}
@@ -1475,9 +1536,8 @@ static void colon(char *buf)
  colon_s_fail:
 	status_line(":s expression missing delimiters");
 #endif
-}
-
 #endif /* FEATURE_VI_COLON */
+}
 
 static void Hit_Return(void)
 {
@@ -2851,17 +2911,6 @@ static char *get_input_line(const char *prompt)
 #undef buf
 }
 
-static int file_size(const char *fn) // what is the byte size of "fn"
-{
-	struct stat st_buf;
-	int cnt;
-
-	cnt = -1;
-	if (fn && stat(fn, &st_buf) == 0)	// see if file exists
-		cnt = (int) st_buf.st_size;
-	return cnt;
-}
-
 // might reallocate text[]!
 static int file_insert(const char *fn, char *p, int update_ro_status)
 {
@@ -2869,42 +2918,40 @@ static int file_insert(const char *fn, char *p, int update_ro_status)
 	int fd, size;
 	struct stat statbuf;
 
-	/* Validate file */
-	if (stat(fn, &statbuf) < 0) {
-		status_line_bold_errno(fn);
-		goto fi0;
-	}
-	if (!S_ISREG(statbuf.st_mode)) {
-		// This is not a regular file
-		status_line_bold("'%s' is not a regular file", fn);
-		goto fi0;
-	}
 	if (p < text || p > end) {
 		status_line_bold("Trying to insert file outside of memory");
-		goto fi0;
+		return cnt;
 	}
 
-	// read file to buffer
 	fd = open(fn, O_RDONLY);
 	if (fd < 0) {
 		status_line_bold_errno(fn);
-		goto fi0;
+		return cnt;
+	}
+
+	/* Validate file */
+	if (fstat(fd, &statbuf) < 0) {
+		status_line_bold_errno(fn);
+		goto fi;
+	}
+	if (!S_ISREG(statbuf.st_mode)) {
+		status_line_bold("'%s' is not a regular file", fn);
+		goto fi;
 	}
 	size = (statbuf.st_size < INT_MAX ? (int)statbuf.st_size : INT_MAX);
 	p += text_hole_make(p, size);
-	cnt = safe_read(fd, p, size);
+	cnt = full_read(fd, p, size);
 	if (cnt < 0) {
 		status_line_bold_errno(fn);
 		p = text_hole_delete(p, p + size - 1, NO_UNDO);	// un-do buffer insert
 	} else if (cnt < size) {
-		// There was a partial read, shrink unused space text[]
-		p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO);	// un-do buffer insert
+		// There was a partial read, shrink unused space
+		p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO);
 		status_line_bold("can't read '%s'", fn);
 	}
-//	if (cnt >= size)
-//		modified_count++;
+ fi:
 	close(fd);
- fi0:
+
 #if ENABLE_FEATURE_VI_READONLY
 	if (update_ro_status
 	 && ((access(fn, W_OK) < 0) ||
@@ -3821,50 +3868,7 @@ static void do_cmd(int c)
 		break;
 	case ':':			// :- the colon mode commands
 		p = get_input_line(":");	// get input line- use "status line"
-#if ENABLE_FEATURE_VI_COLON
 		colon(p);		// execute the command
-#else
-		if (*p == ':')
-			p++;				// move past the ':'
-		cnt = strlen(p);
-		if (cnt <= 0)
-			break;
-		if (strncmp(p, "quit", cnt) == 0
-		 || strncmp(p, "q!", cnt) == 0   // delete lines
-		) {
-			if (modified_count && p[1] != '!') {
-				status_line_bold("No write since last change (:%s! overrides)", p);
-			} else {
-				editing = 0;
-			}
-		} else if (strncmp(p, "write", cnt) == 0
-		        || strncmp(p, "wq", cnt) == 0
-		        || strncmp(p, "wn", cnt) == 0
-		        || (p[0] == 'x' && !p[1])
-		) {
-			cnt = file_write(current_filename, text, end - 1);
-			if (cnt < 0) {
-				if (cnt == -1)
-					status_line_bold("Write error: %s", strerror(errno));
-			} else {
-				modified_count = 0;
-				last_modified_count = -1;
-				status_line("'%s' %dL, %dC", current_filename, count_lines(text, end - 1), cnt);
-				if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
-				 || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
-				) {
-					editing = 0;
-				}
-			}
-		} else if (strncmp(p, "file", cnt) == 0) {
-			last_status_cksum = 0;	// force status update
-		} else if (sscanf(p, "%d", &j) > 0) {
-			dot = find_line(j);		// go to line # j
-			dot_skip_over_ws();
-		} else {		// unrecognized cmd
-			not_implemented(p);
-		}
-#endif /* !FEATURE_VI_COLON */
 		break;
 	case '<':			// <- Left  shift something
 	case '>':			// >- Right shift something
-- 
cgit v1.2.3-55-g6feb