aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-08-19 16:59:36 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-08-20 15:26:09 +0200
commitf07772f19e29cf44a14c108935afb5668e38fac3 (patch)
treeb02e85e854e0ad13747ba98e0036d6b2948bc0fe
parent29b53ef03fc7ddd3ba27898d77a900a2f184aa0d (diff)
downloadbusybox-w32-f07772f19e29cf44a14c108935afb5668e38fac3.tar.gz
busybox-w32-f07772f19e29cf44a14c108935afb5668e38fac3.tar.bz2
busybox-w32-f07772f19e29cf44a14c108935afb5668e38fac3.zip
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>
-rw-r--r--editors/vi.c123
1 files 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 @@
201 201
202// the CRASHME code is unmaintained, and doesn't currently build 202// the CRASHME code is unmaintained, and doesn't currently build
203#define ENABLE_FEATURE_VI_CRASHME 0 203#define ENABLE_FEATURE_VI_CRASHME 0
204#define IF_FEATURE_VI_CRASHME(...)
204 205
205 206
206#if ENABLE_LOCALE_SUPPORT 207#if ENABLE_LOCALE_SUPPORT
@@ -403,7 +404,7 @@ struct globals {
403 int cindex; // saved character index for up/down motion 404 int cindex; // saved character index for up/down motion
404 smallint keep_index; // retain saved character index 405 smallint keep_index; // retain saved character index
405#if ENABLE_FEATURE_VI_COLON 406#if ENABLE_FEATURE_VI_COLON
406 char *initial_cmds[3]; // currently 2 entries, NULL terminated 407 llist_t *initial_cmds;
407#endif 408#endif
408 // Should be just enough to hold a key sequence, 409 // Should be just enough to hold a key sequence,
409 // but CRASHME mode uses it as generated command buffer too 410 // but CRASHME mode uses it as generated command buffer too
@@ -4708,6 +4709,21 @@ static void crash_test()
4708} 4709}
4709#endif 4710#endif
4710 4711
4712#if ENABLE_FEATURE_VI_COLON
4713static void run_cmds(char *p)
4714{
4715 while (p) {
4716 char *q = p;
4717 p = strchr(q, '\n');
4718 if (p)
4719 while (*p == '\n')
4720 *p++ = '\0';
4721 if (strlen(q) < MAX_INPUT_LEN)
4722 colon(q);
4723 }
4724}
4725#endif
4726
4711static void edit_file(char *fn) 4727static void edit_file(char *fn)
4712{ 4728{
4713#if ENABLE_FEATURE_VI_YANKMARK 4729#if ENABLE_FEATURE_VI_YANKMARK
@@ -4778,25 +4794,8 @@ static void edit_file(char *fn)
4778#endif 4794#endif
4779 4795
4780#if ENABLE_FEATURE_VI_COLON 4796#if ENABLE_FEATURE_VI_COLON
4781 { 4797 while (initial_cmds)
4782 char *p, *q; 4798 run_cmds((char *)llist_pop(&initial_cmds));
4783 int n = 0;
4784
4785 while ((p = initial_cmds[n]) != NULL) {
4786 do {
4787 q = p;
4788 p = strchr(q, '\n');
4789 if (p)
4790 while (*p == '\n')
4791 *p++ = '\0';
4792 if (*q)
4793 colon(q);
4794 } while (p);
4795 free(initial_cmds[n]);
4796 initial_cmds[n] = NULL;
4797 n++;
4798 }
4799 }
4800#endif 4799#endif
4801 redraw(FALSE); // dont force every col re-draw 4800 redraw(FALSE); // dont force every col re-draw
4802 //------This is the main Vi cmd handling loop ----------------------- 4801 //------This is the main Vi cmd handling loop -----------------------
@@ -4859,10 +4858,29 @@ static void edit_file(char *fn)
4859#undef cur_line 4858#undef cur_line
4860} 4859}
4861 4860
4861#define VI_OPTSTR \
4862 IF_FEATURE_VI_CRASHME("C") \
4863 IF_FEATURE_VI_COLON("c:*") \
4864 "Hh" \
4865 IF_FEATURE_VI_READONLY("R")
4866
4867enum {
4868 IF_FEATURE_VI_CRASHME(OPTBIT_C,)
4869 IF_FEATURE_VI_COLON(OPTBIT_c,)
4870 OPTBIT_H,
4871 OPTBIT_h,
4872 IF_FEATURE_VI_READONLY(OPTBIT_R,)
4873 OPT_C = IF_FEATURE_VI_CRASHME( (1 << OPTBIT_C)) + 0,
4874 OPT_c = IF_FEATURE_VI_COLON( (1 << OPTBIT_c)) + 0,
4875 OPT_H = 1 << OPTBIT_H,
4876 OPT_h = 1 << OPTBIT_h,
4877 OPT_R = IF_FEATURE_VI_READONLY( (1 << OPTBIT_R)) + 0,
4878};
4879
4862int vi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 4880int vi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
4863int vi_main(int argc, char **argv) 4881int vi_main(int argc, char **argv)
4864{ 4882{
4865 int c; 4883 int opts;
4866 4884
4867 INIT_G(); 4885 INIT_G();
4868 4886
@@ -4886,50 +4904,39 @@ int vi_main(int argc, char **argv)
4886 4904
4887 // 0: all of our options are disabled by default in vim 4905 // 0: all of our options are disabled by default in vim
4888 //vi_setops = 0; 4906 //vi_setops = 0;
4889 // 1- process EXINIT variable from environment 4907 opts = getopt32(argv, VI_OPTSTR IF_FEATURE_VI_COLON(, &initial_cmds));
4890 // 2- if EXINIT is unset process $HOME/.exrc file (not inplemented yet) 4908
4891 // 3- process command line args
4892#if ENABLE_FEATURE_VI_COLON
4893 {
4894 char *p = getenv("EXINIT");
4895 if (p && *p)
4896 initial_cmds[0] = xstrndup(p, MAX_INPUT_LEN);
4897 }
4898#endif
4899 while ((c = getopt(argc, argv,
4900#if ENABLE_FEATURE_VI_CRASHME
4901 "C"
4902#endif
4903 "RHh" IF_FEATURE_VI_COLON("c:"))) != -1) {
4904 switch (c) {
4905#if ENABLE_FEATURE_VI_CRASHME 4909#if ENABLE_FEATURE_VI_CRASHME
4906 case 'C': 4910 if (opts & OPT_C)
4907 crashme = 1; 4911 crashme = 1;
4908 break;
4909#endif 4912#endif
4910#if ENABLE_FEATURE_VI_READONLY 4913 if (opts & OPT_R)
4911 case 'R': // Read-only flag 4914 SET_READONLY_MODE(readonly_mode);
4912 SET_READONLY_MODE(readonly_mode); 4915 if (opts & OPT_H)
4913 break; 4916 show_help();
4914#endif 4917 if (opts & (OPT_H | OPT_h)) {
4915#if ENABLE_FEATURE_VI_COLON 4918 bb_show_usage();
4916 case 'c': // cmd line vi command 4919 return 1;
4917 if (*optarg)
4918 initial_cmds[initial_cmds[0] != NULL] = xstrndup(optarg, MAX_INPUT_LEN);
4919 break;
4920#endif
4921 case 'H':
4922 show_help();
4923 // fall through
4924 default:
4925 bb_show_usage();
4926 return 1;
4927 }
4928 } 4920 }
4929 4921
4930 argv += optind; 4922 argv += optind;
4931 cmdline_filecnt = argc - optind; 4923 cmdline_filecnt = argc - optind;
4932 4924
4925 // 1- process EXINIT variable from environment
4926 // 2- if EXINIT is unset process $HOME/.exrc file (not implemented yet)
4927 // 3- process command line args
4928#if ENABLE_FEATURE_VI_COLON
4929 {
4930 const char *exinit = getenv("EXINIT");
4931
4932 if (exinit) {
4933 char *cmds = xstrdup(exinit);
4934 init_text_buffer(NULL);
4935 run_cmds(cmds);
4936 free(cmds);
4937 }
4938 }
4939#endif
4933 // "Save cursor, use alternate screen buffer, clear screen" 4940 // "Save cursor, use alternate screen buffer, clear screen"
4934 write1(ESC"[?1049h"); 4941 write1(ESC"[?1049h");
4935 // This is the main file handling loop 4942 // This is the main file handling loop