vi: rearrange functions, no logic changes
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 1 Apr 2019 11:55:27 +0000 (13:55 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 1 Apr 2019 11:55:27 +0000 (13:55 +0200)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
editors/vi.c

index 9bdee5928ef2fb128011aedb0bb7c939022e7e67..40611937113a0a20a2a4517818ff1c552347ccc4 100644 (file)
@@ -483,7 +483,6 @@ struct globals {
 } while (0)
 
 
-static void edit_file(char *); // edit one file
 static void do_cmd(int);       // execute a command
 static int next_tabstop(int);
 static void sync_cursor(char *, int *, int *); // synchronize the screen cursor to dot
@@ -527,7 +526,6 @@ static uintptr_t text_hole_make(char *, int);       // at "p", make a 'size' byte hole
 #define yank_delete(a,b,c,d,e) yank_delete(a,b,c,d)
 #endif
 static char *yank_delete(char *, char *, int, int, int);       // yank text[] into register then delete
-static void show_help(void);   // display some help info
 static void rawmode(void);     // set "raw" mode on tty
 static void cookmode(void);    // return to "cooked" mode on tty
 // sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready)
@@ -610,94 +608,42 @@ static void crash_test();
 static int crashme = 0;
 #endif
 
-static void write1(const char *out)
-{
-       fputs(out, stdout);
-}
-
-int vi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-int vi_main(int argc, char **argv)
+static void show_help(void)
 {
-       int c;
-
-       INIT_G();
-
-#if ENABLE_FEATURE_VI_UNDO
-       /* undo_stack_tail = NULL; - already is */
-#if ENABLE_FEATURE_VI_UNDO_QUEUE
-       undo_queue_state = UNDO_EMPTY;
-       /* undo_q = 0; - already is  */
+       puts("These features are available:"
+#if ENABLE_FEATURE_VI_SEARCH
+       "\n\tPattern searches with / and ?"
 #endif
+#if ENABLE_FEATURE_VI_DOT_CMD
+       "\n\tLast command repeat with ."
 #endif
-
-#if ENABLE_FEATURE_VI_CRASHME
-       srand((long) getpid());
+#if ENABLE_FEATURE_VI_YANKMARK
+       "\n\tLine marking with 'x"
+       "\n\tNamed buffers with \"x"
 #endif
-#ifdef NO_SUCH_APPLET_YET
-       // if we aren't "vi", we are "view"
-       if (ENABLE_FEATURE_VI_READONLY && applet_name[2]) {
-               SET_READONLY_MODE(readonly_mode);
-       }
+#if ENABLE_FEATURE_VI_READONLY
+       //not implemented: "\n\tReadonly if vi is called as \"view\""
+       //redundant: usage text says this too: "\n\tReadonly with -R command line arg"
 #endif
-
-       // autoindent is not default in vim 7.3
-       vi_setops = /*VI_AUTOINDENT |*/ VI_SHOWMATCH | VI_IGNORECASE;
-       //  1-  process $HOME/.exrc file (not inplemented yet)
-       //  2-  process EXINIT variable from environment
-       //  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);
-       }
+#if ENABLE_FEATURE_VI_SET
+       "\n\tSome colon mode commands with :"
 #endif
-       while ((c = getopt(argc, argv, "hCRH" IF_FEATURE_VI_COLON("c:"))) != -1) {
-               switch (c) {
-#if ENABLE_FEATURE_VI_CRASHME
-               case 'C':
-                       crashme = 1;
-                       break;
+#if ENABLE_FEATURE_VI_SETOPTS
+       "\n\tSettable options with \":set\""
 #endif
-#if ENABLE_FEATURE_VI_READONLY
-               case 'R':               // Read-only flag
-                       SET_READONLY_MODE(readonly_mode);
-                       break;
+#if ENABLE_FEATURE_VI_USE_SIGNALS
+       "\n\tSignal catching- ^C"
+       "\n\tJob suspend and resume with ^Z"
 #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;
+#if ENABLE_FEATURE_VI_WIN_RESIZE
+       "\n\tAdapt to window re-sizes"
 #endif
-               case 'H':
-                       show_help();
-                       // fall through
-               default:
-                       bb_show_usage();
-                       return 1;
-               }
-       }
-
-       // The argv array can be used by the ":next"  and ":rewind" commands
-       argv += optind;
-       argc -= optind;
-
-       //----- This is the main file handling loop --------------
-       save_argc = argc;
-       optind = 0;
-       // "Save cursor, use alternate screen buffer, clear screen"
-       write1(ESC"[?1049h");
-       while (1) {
-               edit_file(argv[optind]); // param might be NULL
-               if (++optind >= argc)
-                       break;
-       }
-       // "Use normal screen buffer, restore cursor"
-       write1(ESC"[?1049l");
-       //-----------------------------------------------------------
+       );
+}
 
-       return 0;
+static void write1(const char *out)
+{
+       fputs(out, stdout);
 }
 
 /* read text from file or create an empty buf */
@@ -748,153 +694,6 @@ static ALWAYS_INLINE int query_screen_dimensions(void)
 }
 #endif
 
-static void edit_file(char *fn)
-{
-#if ENABLE_FEATURE_VI_YANKMARK
-#define cur_line edit_file__cur_line
-#endif
-       int c;
-#if ENABLE_FEATURE_VI_USE_SIGNALS
-       int sig;
-#endif
-
-       editing = 1;    // 0 = exit, 1 = one file, 2 = multiple files
-       rawmode();
-       rows = 24;
-       columns = 80;
-       IF_FEATURE_VI_ASK_TERMINAL(G.get_rowcol_error =) query_screen_dimensions();
-#if ENABLE_FEATURE_VI_ASK_TERMINAL
-       if (G.get_rowcol_error /* TODO? && no input on stdin */) {
-               uint64_t k;
-               write1(ESC"[999;999H" ESC"[6n");
-               fflush_all();
-               k = read_key(STDIN_FILENO, readbuffer, /*timeout_ms:*/ 100);
-               if ((int32_t)k == KEYCODE_CURSOR_POS) {
-                       uint32_t rc = (k >> 32);
-                       columns = (rc & 0x7fff);
-                       if (columns > MAX_SCR_COLS)
-                               columns = MAX_SCR_COLS;
-                       rows = ((rc >> 16) & 0x7fff);
-                       if (rows > MAX_SCR_ROWS)
-                               rows = MAX_SCR_ROWS;
-               }
-       }
-#endif
-       new_screen(rows, columns);      // get memory for virtual screen
-       init_text_buffer(fn);
-
-#if ENABLE_FEATURE_VI_YANKMARK
-       YDreg = 26;                     // default Yank/Delete reg
-//     Ureg = 27; - const              // hold orig line for "U" cmd
-       mark[26] = mark[27] = text;     // init "previous context"
-#endif
-
-       last_forward_char = last_input_char = '\0';
-       crow = 0;
-       ccol = 0;
-
-#if ENABLE_FEATURE_VI_USE_SIGNALS
-       signal(SIGWINCH, winch_handler);
-       signal(SIGTSTP, tstp_handler);
-       sig = sigsetjmp(restart, 1);
-       if (sig != 0) {
-               screenbegin = dot = text;
-       }
-       // int_handler() can jump to "restart",
-       // must install handler *after* initializing "restart"
-       signal(SIGINT, int_handler);
-#endif
-
-       cmd_mode = 0;           // 0=command  1=insert  2='R'eplace
-       cmdcnt = 0;
-       tabstop = 8;
-       offset = 0;                     // no horizontal offset
-       c = '\0';
-#if ENABLE_FEATURE_VI_DOT_CMD
-       free(ioq_start);
-       ioq = ioq_start = NULL;
-       lmc_len = 0;
-       adding2q = 0;
-#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++;
-               }
-       }
-#endif
-       redraw(FALSE);                  // dont force every col re-draw
-       //------This is the main Vi cmd handling loop -----------------------
-       while (editing > 0) {
-#if ENABLE_FEATURE_VI_CRASHME
-               if (crashme > 0) {
-                       if ((end - text) > 1) {
-                               crash_dummy();  // generate a random command
-                       } else {
-                               crashme = 0;
-                               string_insert(text, "\n\n#####  Ran out of text to work on.  #####\n\n", NO_UNDO); // insert the string
-                               dot = text;
-                               refresh(FALSE);
-                       }
-               }
-#endif
-               last_input_char = c = get_one_char();   // get a cmd from user
-#if ENABLE_FEATURE_VI_YANKMARK
-               // save a copy of the current line- for the 'U" command
-               if (begin_line(dot) != cur_line) {
-                       cur_line = begin_line(dot);
-                       text_yank(begin_line(dot), end_line(dot), Ureg);
-               }
-#endif
-#if ENABLE_FEATURE_VI_DOT_CMD
-               // These are commands that change text[].
-               // Remember the input for the "." command
-               if (!adding2q && ioq_start == NULL
-                && cmd_mode == 0 // command mode
-                && c > '\0' // exclude NUL and non-ASCII chars
-                && c < 0x7f // (Unicode and such)
-                && strchr(modifying_cmds, c)
-               ) {
-                       start_new_cmd_q(c);
-               }
-#endif
-               do_cmd(c);              // execute the user command
-
-               // poll to see if there is input already waiting. if we are
-               // not able to display output fast enough to keep up, skip
-               // the display update until we catch up with input.
-               if (!readbuffer[0] && mysleep(0) == 0) {
-                       // no input pending - so update output
-                       refresh(FALSE);
-                       show_status_line();
-               }
-#if ENABLE_FEATURE_VI_CRASHME
-               if (crashme > 0)
-                       crash_test();   // test editor variables
-#endif
-       }
-       //-------------------------------------------------------------------
-
-       go_bottom_and_clear_to_eol();
-       cookmode();
-#undef cur_line
-}
-
 //----- The Colon commands -------------------------------------
 #if ENABLE_FEATURE_VI_COLON
 static char *get_one_address(char *p, int *addr)       // get colon addr, if present
@@ -2563,63 +2362,30 @@ static char *yank_delete(char *start, char *stop, int dist, int yf, int undo)
        if (start > stop) {
                // they are backwards, reverse them
                p = start;
-               start = stop;
-               stop = p;
-       }
-       if (dist <= 0) {
-               // we cannot cross NL boundaries
-               p = start;
-               if (*p == '\n')
-                       return p;
-               // dont go past a NewLine
-               for (; p + 1 <= stop; p++) {
-                       if (p[1] == '\n') {
-                               stop = p;       // "stop" just before NewLine
-                               break;
-                       }
-               }
-       }
-       p = start;
-#if ENABLE_FEATURE_VI_YANKMARK
-       text_yank(start, stop, YDreg);
-#endif
-       if (yf == YANKDEL) {
-               p = text_hole_delete(start, stop, undo);
-       }                                       // delete lines
-       return p;
-}
-
-static void show_help(void)
-{
-       puts("These features are available:"
-#if ENABLE_FEATURE_VI_SEARCH
-       "\n\tPattern searches with / and ?"
-#endif
-#if ENABLE_FEATURE_VI_DOT_CMD
-       "\n\tLast command repeat with ."
-#endif
-#if ENABLE_FEATURE_VI_YANKMARK
-       "\n\tLine marking with 'x"
-       "\n\tNamed buffers with \"x"
-#endif
-#if ENABLE_FEATURE_VI_READONLY
-       //not implemented: "\n\tReadonly if vi is called as \"view\""
-       //redundant: usage text says this too: "\n\tReadonly with -R command line arg"
-#endif
-#if ENABLE_FEATURE_VI_SET
-       "\n\tSome colon mode commands with :"
-#endif
-#if ENABLE_FEATURE_VI_SETOPTS
-       "\n\tSettable options with \":set\""
-#endif
-#if ENABLE_FEATURE_VI_USE_SIGNALS
-       "\n\tSignal catching- ^C"
-       "\n\tJob suspend and resume with ^Z"
-#endif
-#if ENABLE_FEATURE_VI_WIN_RESIZE
-       "\n\tAdapt to window re-sizes"
+               start = stop;
+               stop = p;
+       }
+       if (dist <= 0) {
+               // we cannot cross NL boundaries
+               p = start;
+               if (*p == '\n')
+                       return p;
+               // dont go past a NewLine
+               for (; p + 1 <= stop; p++) {
+                       if (p[1] == '\n') {
+                               stop = p;       // "stop" just before NewLine
+                               break;
+                       }
+               }
+       }
+       p = start;
+#if ENABLE_FEATURE_VI_YANKMARK
+       text_yank(start, stop, YDreg);
 #endif
-       );
+       if (yf == YANKDEL) {
+               p = text_hole_delete(start, stop, undo);
+       }                                       // delete lines
+       return p;
 }
 
 #if ENABLE_FEATURE_VI_DOT_CMD
@@ -4495,3 +4261,235 @@ static void crash_test()
        }
 }
 #endif
+
+static void edit_file(char *fn)
+{
+#if ENABLE_FEATURE_VI_YANKMARK
+#define cur_line edit_file__cur_line
+#endif
+       int c;
+#if ENABLE_FEATURE_VI_USE_SIGNALS
+       int sig;
+#endif
+
+       editing = 1;    // 0 = exit, 1 = one file, 2 = multiple files
+       rawmode();
+       rows = 24;
+       columns = 80;
+       IF_FEATURE_VI_ASK_TERMINAL(G.get_rowcol_error =) query_screen_dimensions();
+#if ENABLE_FEATURE_VI_ASK_TERMINAL
+       if (G.get_rowcol_error /* TODO? && no input on stdin */) {
+               uint64_t k;
+               write1(ESC"[999;999H" ESC"[6n");
+               fflush_all();
+               k = read_key(STDIN_FILENO, readbuffer, /*timeout_ms:*/ 100);
+               if ((int32_t)k == KEYCODE_CURSOR_POS) {
+                       uint32_t rc = (k >> 32);
+                       columns = (rc & 0x7fff);
+                       if (columns > MAX_SCR_COLS)
+                               columns = MAX_SCR_COLS;
+                       rows = ((rc >> 16) & 0x7fff);
+                       if (rows > MAX_SCR_ROWS)
+                               rows = MAX_SCR_ROWS;
+               }
+       }
+#endif
+       new_screen(rows, columns);      // get memory for virtual screen
+       init_text_buffer(fn);
+
+#if ENABLE_FEATURE_VI_YANKMARK
+       YDreg = 26;                     // default Yank/Delete reg
+//     Ureg = 27; - const              // hold orig line for "U" cmd
+       mark[26] = mark[27] = text;     // init "previous context"
+#endif
+
+       last_forward_char = last_input_char = '\0';
+       crow = 0;
+       ccol = 0;
+
+#if ENABLE_FEATURE_VI_USE_SIGNALS
+       signal(SIGWINCH, winch_handler);
+       signal(SIGTSTP, tstp_handler);
+       sig = sigsetjmp(restart, 1);
+       if (sig != 0) {
+               screenbegin = dot = text;
+       }
+       // int_handler() can jump to "restart",
+       // must install handler *after* initializing "restart"
+       signal(SIGINT, int_handler);
+#endif
+
+       cmd_mode = 0;           // 0=command  1=insert  2='R'eplace
+       cmdcnt = 0;
+       tabstop = 8;
+       offset = 0;                     // no horizontal offset
+       c = '\0';
+#if ENABLE_FEATURE_VI_DOT_CMD
+       free(ioq_start);
+       ioq = ioq_start = NULL;
+       lmc_len = 0;
+       adding2q = 0;
+#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++;
+               }
+       }
+#endif
+       redraw(FALSE);                  // dont force every col re-draw
+       //------This is the main Vi cmd handling loop -----------------------
+       while (editing > 0) {
+#if ENABLE_FEATURE_VI_CRASHME
+               if (crashme > 0) {
+                       if ((end - text) > 1) {
+                               crash_dummy();  // generate a random command
+                       } else {
+                               crashme = 0;
+                               string_insert(text, "\n\n#####  Ran out of text to work on.  #####\n\n", NO_UNDO); // insert the string
+                               dot = text;
+                               refresh(FALSE);
+                       }
+               }
+#endif
+               last_input_char = c = get_one_char();   // get a cmd from user
+#if ENABLE_FEATURE_VI_YANKMARK
+               // save a copy of the current line- for the 'U" command
+               if (begin_line(dot) != cur_line) {
+                       cur_line = begin_line(dot);
+                       text_yank(begin_line(dot), end_line(dot), Ureg);
+               }
+#endif
+#if ENABLE_FEATURE_VI_DOT_CMD
+               // These are commands that change text[].
+               // Remember the input for the "." command
+               if (!adding2q && ioq_start == NULL
+                && cmd_mode == 0 // command mode
+                && c > '\0' // exclude NUL and non-ASCII chars
+                && c < 0x7f // (Unicode and such)
+                && strchr(modifying_cmds, c)
+               ) {
+                       start_new_cmd_q(c);
+               }
+#endif
+               do_cmd(c);              // execute the user command
+
+               // poll to see if there is input already waiting. if we are
+               // not able to display output fast enough to keep up, skip
+               // the display update until we catch up with input.
+               if (!readbuffer[0] && mysleep(0) == 0) {
+                       // no input pending - so update output
+                       refresh(FALSE);
+                       show_status_line();
+               }
+#if ENABLE_FEATURE_VI_CRASHME
+               if (crashme > 0)
+                       crash_test();   // test editor variables
+#endif
+       }
+       //-------------------------------------------------------------------
+
+       go_bottom_and_clear_to_eol();
+       cookmode();
+#undef cur_line
+}
+
+int vi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int vi_main(int argc, char **argv)
+{
+       int c;
+
+       INIT_G();
+
+#if ENABLE_FEATURE_VI_UNDO
+       /* undo_stack_tail = NULL; - already is */
+#if ENABLE_FEATURE_VI_UNDO_QUEUE
+       undo_queue_state = UNDO_EMPTY;
+       /* undo_q = 0; - already is  */
+#endif
+#endif
+
+#if ENABLE_FEATURE_VI_CRASHME
+       srand((long) getpid());
+#endif
+#ifdef NO_SUCH_APPLET_YET
+       // if we aren't "vi", we are "view"
+       if (ENABLE_FEATURE_VI_READONLY && applet_name[2]) {
+               SET_READONLY_MODE(readonly_mode);
+       }
+#endif
+
+       // autoindent is not default in vim 7.3
+       vi_setops = /*VI_AUTOINDENT |*/ VI_SHOWMATCH | VI_IGNORECASE;
+       //  1-  process $HOME/.exrc file (not inplemented yet)
+       //  2-  process EXINIT variable from environment
+       //  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, "hCRH" IF_FEATURE_VI_COLON("c:"))) != -1) {
+               switch (c) {
+#if ENABLE_FEATURE_VI_CRASHME
+               case 'C':
+                       crashme = 1;
+                       break;
+#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;
+               }
+       }
+
+       // The argv array can be used by the ":next"  and ":rewind" commands
+       argv += optind;
+       argc -= optind;
+
+       //----- This is the main file handling loop --------------
+       save_argc = argc;
+       optind = 0;
+       // "Save cursor, use alternate screen buffer, clear screen"
+       write1(ESC"[?1049h");
+       while (1) {
+               edit_file(argv[optind]); // param might be NULL
+               if (++optind >= argc)
+                       break;
+       }
+       // "Use normal screen buffer, restore cursor"
+       write1(ESC"[?1049l");
+       //-----------------------------------------------------------
+
+       return 0;
+}