[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH 1/2] vi: changes to handling of -c and EXINIT
From:       Ron Yorston <rmy () pobox ! com>
Date:       2021-08-19 15:59:36
Message-ID: 611e7fe8.13dMcFLWmtT/su6I%rmy () pobox ! com
[Download RAW message or body]

Rewrite handling of command line arguments so any number of -c
commands will be processed.  Previously only two -c commands
were allowed (or one if EXINIT was set).

Process commands from EXINIT before the first file is read into
memory, as specified by POSIX.

function                                             old     new   delta
run_cmds                                               -      77     +77
.rodata                                           108410  108411      +1
vi_main                                              305     268     -37
edit_file                                            816     764     -52
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/2 up/down: 78/-89)            Total: -11 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
---
 editors/vi.c | 123 +++++++++++++++++++++++++++------------------------
 1 file changed, 65 insertions(+), 58 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index 3e1bd0820..cc4f6bde7 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -201,6 +201,7 @@
 
 // the CRASHME code is unmaintained, and doesn't currently build
 #define ENABLE_FEATURE_VI_CRASHME 0
+#define IF_FEATURE_VI_CRASHME(...)
 
 
 #if ENABLE_LOCALE_SUPPORT
@@ -403,7 +404,7 @@ struct globals {
 	int cindex;               // saved character index for up/down motion
 	smallint keep_index;      // retain saved character index
 #if ENABLE_FEATURE_VI_COLON
-	char *initial_cmds[3];  // currently 2 entries, NULL terminated
+	llist_t *initial_cmds;
 #endif
 	// Should be just enough to hold a key sequence,
 	// but CRASHME mode uses it as generated command buffer too
@@ -4708,6 +4709,21 @@ static void crash_test()
 }
 #endif
 
+#if ENABLE_FEATURE_VI_COLON
+static void run_cmds(char *p)
+{
+	while (p) {
+		char *q = p;
+		p = strchr(q, '\n');
+		if (p)
+			while (*p == '\n')
+				*p++ = '\0';
+		if (strlen(q) < MAX_INPUT_LEN)
+			colon(q);
+	}
+}
+#endif
+
 static void edit_file(char *fn)
 {
 #if ENABLE_FEATURE_VI_YANKMARK
@@ -4778,25 +4794,8 @@ static void edit_file(char *fn)
 #endif
 
 #if ENABLE_FEATURE_VI_COLON
-	{
-		char *p, *q;
-		int n = 0;
-
-		while ((p = initial_cmds[n]) != NULL) {
-			do {
-				q = p;
-				p = strchr(q, '\n');
-				if (p)
-					while (*p == '\n')
-						*p++ = '\0';
-				if (*q)
-					colon(q);
-			} while (p);
-			free(initial_cmds[n]);
-			initial_cmds[n] = NULL;
-			n++;
-		}
-	}
+	while (initial_cmds)
+		run_cmds((char *)llist_pop(&initial_cmds));
 #endif
 	redraw(FALSE);			// dont force every col re-draw
 	//------This is the main Vi cmd handling loop -----------------------
@@ -4859,10 +4858,29 @@ static void edit_file(char *fn)
 #undef cur_line
 }
 
+#define VI_OPTSTR \
+	IF_FEATURE_VI_CRASHME("C") \
+	IF_FEATURE_VI_COLON("c:*") \
+	"Hh" \
+	IF_FEATURE_VI_READONLY("R")
+
+enum {
+	IF_FEATURE_VI_CRASHME(OPTBIT_C,)
+	IF_FEATURE_VI_COLON(OPTBIT_c,)
+	OPTBIT_H,
+	OPTBIT_h,
+	IF_FEATURE_VI_READONLY(OPTBIT_R,)
+	OPT_C = IF_FEATURE_VI_CRASHME(	(1 << OPTBIT_C)) + 0,
+	OPT_c = IF_FEATURE_VI_COLON(	(1 << OPTBIT_c)) + 0,
+	OPT_H = 1 << OPTBIT_H,
+	OPT_h = 1 << OPTBIT_h,
+	OPT_R = IF_FEATURE_VI_READONLY(	(1 << OPTBIT_R)) + 0,
+};
+
 int vi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int vi_main(int argc, char **argv)
 {
-	int c;
+	int opts;
 
 	INIT_G();
 
@@ -4886,50 +4904,39 @@ int vi_main(int argc, char **argv)
 
 	// 0: all of our options are disabled by default in vim
 	//vi_setops = 0;
-	//  1-  process EXINIT variable from environment
-	//  2-  if EXINIT is unset process $HOME/.exrc file (not inplemented yet)
-	//  3-  process command line args
-#if ENABLE_FEATURE_VI_COLON
-	{
-		char *p = getenv("EXINIT");
-		if (p && *p)
-			initial_cmds[0] = xstrndup(p, MAX_INPUT_LEN);
-	}
-#endif
-	while ((c = getopt(argc, argv,
-#if ENABLE_FEATURE_VI_CRASHME
-			"C"
-#endif
-			"RHh" IF_FEATURE_VI_COLON("c:"))) != -1) {
-		switch (c) {
+	opts = getopt32(argv, VI_OPTSTR IF_FEATURE_VI_COLON(, &initial_cmds));
+
 #if ENABLE_FEATURE_VI_CRASHME
-		case 'C':
-			crashme = 1;
-			break;
+	if (opts & OPT_C)
+		crashme = 1;
 #endif
-#if ENABLE_FEATURE_VI_READONLY
-		case 'R':		// Read-only flag
-			SET_READONLY_MODE(readonly_mode);
-			break;
-#endif
-#if ENABLE_FEATURE_VI_COLON
-		case 'c':		// cmd line vi command
-			if (*optarg)
-				initial_cmds[initial_cmds[0] != NULL] = xstrndup(optarg, MAX_INPUT_LEN);
-			break;
-#endif
-		case 'H':
-			show_help();
-			// fall through
-		default:
-			bb_show_usage();
-			return 1;
-		}
+	if (opts & OPT_R)
+		SET_READONLY_MODE(readonly_mode);
+	if (opts & OPT_H)
+		show_help();
+	if (opts & (OPT_H | OPT_h)) {
+		bb_show_usage();
+		return 1;
 	}
 
 	argv += optind;
 	cmdline_filecnt = argc - optind;
 
+	//  1-  process EXINIT variable from environment
+	//  2-  if EXINIT is unset process $HOME/.exrc file (not implemented yet)
+	//  3-  process command line args
+#if ENABLE_FEATURE_VI_COLON
+	{
+		const char *exinit = getenv("EXINIT");
+
+		if (exinit) {
+			char *cmds = xstrdup(exinit);
+			init_text_buffer(NULL);
+			run_cmds(cmds);
+			free(cmds);
+		}
+	}
+#endif
 	// "Save cursor, use alternate screen buffer, clear screen"
 	write1(ESC"[?1049h");
 	// This is the main file handling loop
-- 
2.31.1

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic