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 <[email protected]>
---
 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
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to