summaryrefslogtreecommitdiff
path: root/editors/vi.c
diff options
context:
space:
mode:
authorRon Yorston2021-08-19 16:59:36 +0100
committerDenys Vlasenko2021-08-20 15:26:09 +0200
commitf07772f19e29cf44a14c108935afb5668e38fac3 (patch)
treeb02e85e854e0ad13747ba98e0036d6b2948bc0fe /editors/vi.c
parent29b53ef03fc7ddd3ba27898d77a900a2f184aa0d (diff)
downloadbusybox-f07772f19e29cf44a14c108935afb5668e38fac3.zip
busybox-f07772f19e29cf44a14c108935afb5668e38fac3.tar.gz
vi: changes to handling of -c and EXINIT
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> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'editors/vi.c')
-rw-r--r--editors/vi.c123
1 files changed, 65 insertions, 58 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 3e1bd08..cc4f6bd 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