remove accumulated stray trailing whitespace
[oweals/busybox.git] / editors / vi.c
index 1e8f3835d4277dd7ea8f67ad48bee5ead8c98e66..fcd139310717f5815f46d51431a6e0c8c4de9ffb 100644 (file)
@@ -1,4 +1,4 @@
-/* vi: set sw=8 ts=8: */
+/* vi: set sw=4 ts=4: */
 /*
  * tiny vi.c: A small 'vi' clone
  * Copyright (C) 2000, 2001 Sterling Huxley <sterling@europa.com>
@@ -6,14 +6,6 @@
  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
  */
 
-/*
- * To compile for standalone use:
- *     gcc -Wall -Os -s -DSTANDALONE -o vi vi.c
- *       or
- *     gcc -Wall -Os -s -DSTANDALONE -DCONFIG_FEATURE_VI_CRASHME -o vi vi.c            # include testing features
- *     strip vi
- */
-
 /*
  * Things To Do:
  *     EXINIT
@@ -21,7 +13,6 @@
  *     add magic to search     /foo.*bar
  *     add :help command
  *     :map macros
- *     how about mode lines:   vi: set sw=8 ts=8:
  *     if mark[] values were line numbers rather than pointers
  *        it would be easier to change the mark when add/delete lines
  *     More intelligence in refresh()
  *     An "ex" line oriented mode- maybe using "cmdedit"
  */
 
-//----  Feature --------------  Bytes to implement
-#ifdef STANDALONE
-#define vi_main                        main
-#define CONFIG_FEATURE_VI_COLON        // 4288
-#define CONFIG_FEATURE_VI_YANKMARK     // 1408
-#define CONFIG_FEATURE_VI_SEARCH       // 1088
-#define CONFIG_FEATURE_VI_USE_SIGNALS  // 1056
-#define CONFIG_FEATURE_VI_DOT_CMD      //  576
-#define CONFIG_FEATURE_VI_READONLY     //  128
-#define CONFIG_FEATURE_VI_SETOPTS      //  576
-#define CONFIG_FEATURE_VI_SET  //  224
-#define CONFIG_FEATURE_VI_WIN_RESIZE   //  256  WIN_RESIZE
-// To test editor using CRASHME:
-//    vi -C filename
-// To stop testing, wait until all to text[] is deleted, or
-//    Ctrl-Z and kill -9 %1
-// while in the editor Ctrl-T will toggle the crashme function on and off.
-//#define CONFIG_FEATURE_VI_CRASHME            // randomly pick commands to execute
-#endif                                                 /* STANDALONE */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <termios.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <regex.h>
-#include <ctype.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdarg.h>
-#ifndef STANDALONE
-#include "busybox.h"
-#define vi_Version BB_VER " " BB_BT
-#else
-#define vi_Version "standalone"
-#endif                                                 /* STANDALONE */
+#include "libbb.h"
+
+#define ENABLE_FEATURE_VI_CRASHME 0
 
-#ifdef CONFIG_LOCALE_SUPPORT
+#if ENABLE_LOCALE_SUPPORT
 #define Isprint(c) isprint((c))
 #else
-#define Isprint(c) ( (c) >= ' ' && (c) != 127 && (c) != ((unsigned char)'\233') )
+/* 0x9b is Meta-ESC */
+#define Isprint(c) ((unsigned char)(c) >= ' ' && (c) != 0x7f && (unsigned char)(c) != 0x9b)
 #endif
 
-#ifndef TRUE
-#define TRUE                   ((int)1)
-#define FALSE                  ((int)0)
-#endif                                                 /* TRUE */
-#define MAX_SCR_COLS           BUFSIZ
+enum {
+       MAX_LINELEN = CONFIG_FEATURE_VI_MAX_LEN,
+       MAX_SCR_COLS = CONFIG_FEATURE_VI_MAX_LEN,
+};
 
 // Misc. non-Ascii keys that report an escape sequence
-#define VI_K_UP                        128     // cursor key Up
-#define VI_K_DOWN              129     // cursor key Down
-#define VI_K_RIGHT             130     // Cursor Key Right
-#define VI_K_LEFT              131     // cursor key Left
-#define VI_K_HOME              132     // Cursor Key Home
-#define VI_K_END               133     // Cursor Key End
-#define VI_K_INSERT            134     // Cursor Key Insert
-#define VI_K_PAGEUP            135     // Cursor Key Page Up
-#define VI_K_PAGEDOWN          136     // Cursor Key Page Down
-#define VI_K_FUN1              137     // Function Key F1
-#define VI_K_FUN2              138     // Function Key F2
-#define VI_K_FUN3              139     // Function Key F3
-#define VI_K_FUN4              140     // Function Key F4
-#define VI_K_FUN5              141     // Function Key F5
-#define VI_K_FUN6              142     // Function Key F6
-#define VI_K_FUN7              143     // Function Key F7
-#define VI_K_FUN8              144     // Function Key F8
-#define VI_K_FUN9              145     // Function Key F9
-#define VI_K_FUN10             146     // Function Key F10
-#define VI_K_FUN11             147     // Function Key F11
-#define VI_K_FUN12             148     // Function Key F12
+#define VI_K_UP                        (char)128       // cursor key Up
+#define VI_K_DOWN              (char)129       // cursor key Down
+#define VI_K_RIGHT             (char)130       // Cursor Key Right
+#define VI_K_LEFT              (char)131       // cursor key Left
+#define VI_K_HOME              (char)132       // Cursor Key Home
+#define VI_K_END               (char)133       // Cursor Key End
+#define VI_K_INSERT            (char)134       // Cursor Key Insert
+#define VI_K_PAGEUP            (char)135       // Cursor Key Page Up
+#define VI_K_PAGEDOWN          (char)136       // Cursor Key Page Down
+#define VI_K_FUN1              (char)137       // Function Key F1
+#define VI_K_FUN2              (char)138       // Function Key F2
+#define VI_K_FUN3              (char)139       // Function Key F3
+#define VI_K_FUN4              (char)140       // Function Key F4
+#define VI_K_FUN5              (char)141       // Function Key F5
+#define VI_K_FUN6              (char)142       // Function Key F6
+#define VI_K_FUN7              (char)143       // Function Key F7
+#define VI_K_FUN8              (char)144       // Function Key F8
+#define VI_K_FUN9              (char)145       // Function Key F9
+#define VI_K_FUN10             (char)146       // Function Key F10
+#define VI_K_FUN11             (char)147       // Function Key F11
+#define VI_K_FUN12             (char)148       // Function Key F12
 
 /* vt102 typical ESC sequence */
 /* terminal standout start/normal ESC sequence */
@@ -138,10 +88,12 @@ enum {
        S_TO_WS = 2,            // used in skip_thing() for moving "dot"
        S_OVER_WS = 3,          // used in skip_thing() for moving "dot"
        S_END_PUNCT = 4,        // used in skip_thing() for moving "dot"
-       S_END_ALNUM = 5         // used in skip_thing() for moving "dot"
+       S_END_ALNUM = 5,        // used in skip_thing() for moving "dot"
 };
 
-typedef unsigned char Byte;
+/* vi.c expects chars to be unsigned. */
+/* busybox build system provides that, but it's better */
+/* to audit and fix the source */
 
 static int vi_setops;
 #define VI_AUTOINDENT 1
@@ -155,76 +107,100 @@ static int vi_setops;
 #define err_method (vi_setops & VI_ERR_METHOD)
 
 
-static int editing;            // >0 while we are editing a file
-static int cmd_mode;           // 0=command  1=insert 2=replace
-static int file_modified;      // buffer contents changed
-static int last_file_modified = -1;
-static int fn_start;           // index of first cmd line file name
-static int save_argc;          // how many file names on cmd line
-static int cmdcnt;             // repetition count
-static fd_set rfds;            // use select() for small sleeps
-static struct timeval tv;      // use select() for small sleeps
-static int rows, columns;      // the terminal screen is this size
-static int crow, ccol, offset; // cursor is on Crow x Ccol with Horz Ofset
-static Byte *status_buffer;    // mesages to the user
+static smallint editing;        // >0 while we are editing a file
+                                // [code audit says "can be 0 or 1 only"]
+static smallint cmd_mode;       // 0=command  1=insert 2=replace
+static smallint file_modified;  // buffer contents changed
+static smallint last_file_modified = -1;
+static int fn_start;            // index of first cmd line file name
+static int save_argc;           // how many file names on cmd line
+static int cmdcnt;              // repetition count
+static int rows, columns;       // the terminal screen is this size
+static int crow, ccol, offset;  // cursor is on Crow x Ccol with Horz Ofset
+static char *status_buffer;     // mesages to the user
 #define STATUS_BUFFER_LEN  200
 static int have_status_msg;     // is default edit status needed?
+                                // [don't make smallint!]
 static int last_status_cksum;   // hash of current status line
-static Byte *cfn;              // previous, current, and next file name
-static Byte *text, *end, *textend;     // pointers to the user data in memory
-static Byte *screen;           // pointer to the virtual screen buffer
-static int screensize;         //            and its size
-static Byte *screenbegin;      // index into text[], of top line on the screen
-static Byte *dot;              // where all the action takes place
+static char *cfn;               // previous, current, and next file name
+//static char *text, *end;        // pointers to the user data in memory
+static char *screen;            // pointer to the virtual screen buffer
+static int screensize;          //            and its size
+static char *screenbegin;       // index into text[], of top line on the screen
+//static char *dot;               // where all the action takes place
 static int tabstop;
-static struct termios term_orig, term_vi;      // remember what the cooked mode was
-static Byte erase_char;         // the users erase character
-static Byte last_input_char;    // last char read from user
-static Byte last_forward_char;  // last char searched for with 'f'
+static char erase_char;         // the users erase character
+static char last_input_char;    // last char read from user
+static char last_forward_char;  // last char searched for with 'f'
 
-#ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
+#if ENABLE_FEATURE_VI_READONLY
+static smallint vi_readonly, readonly;
+#endif
+#if ENABLE_FEATURE_VI_DOT_CMD
+static smallint adding2q;              // are we currently adding user input to q
+static char *last_modifying_cmd;       // last modifying cmd for "."
+static char *ioq, *ioq_start;           // pointer to string for get_one_char to "read"
+#endif
+#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
 static int last_row;           // where the cursor was last moved to
-#endif                                                 /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
-#ifdef CONFIG_FEATURE_VI_USE_SIGNALS
-static jmp_buf restart;                // catch_sig()
-#endif                                                 /* CONFIG_FEATURE_VI_USE_SIGNALS */
-#if defined(CONFIG_FEATURE_VI_USE_SIGNALS) || defined(CONFIG_FEATURE_VI_CRASHME)
+#endif
+#if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME
 static int my_pid;
 #endif
-#ifdef CONFIG_FEATURE_VI_DOT_CMD
-static int adding2q;           // are we currently adding user input to q
-static Byte *last_modifying_cmd;       // last modifying cmd for "."
-static Byte *ioq, *ioq_start;  // pointer to string for get_one_char to "read"
-#endif                                                 /* CONFIG_FEATURE_VI_DOT_CMD */
-#if    defined(CONFIG_FEATURE_VI_DOT_CMD) || defined(CONFIG_FEATURE_VI_YANKMARK)
-static Byte *modifying_cmds;   // cmds that modify text[]
-#endif                                                 /* CONFIG_FEATURE_VI_DOT_CMD || CONFIG_FEATURE_VI_YANKMARK */
-#ifdef CONFIG_FEATURE_VI_READONLY
-static int vi_readonly, readonly;
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
-#ifdef CONFIG_FEATURE_VI_YANKMARK
-static Byte *reg[28];          // named register a-z, "D", and "U" 0-25,26,27
-static int YDreg, Ureg;                // default delete register and orig line for "U"
-static Byte *mark[28];         // user marks points somewhere in text[]-  a-z and previous context ''
-static Byte *context_start, *context_end;
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
-#ifdef CONFIG_FEATURE_VI_SEARCH
-static Byte *last_search_pattern;      // last pattern from a '/' or '?' search
-#endif                                                 /* CONFIG_FEATURE_VI_SEARCH */
-
-
-static void edit_file(Byte *); // edit one file
-static void do_cmd(Byte);      // execute a command
-static void sync_cursor(Byte *, int *, int *); // synchronize the screen cursor to dot
-static Byte *begin_line(Byte *);       // return pointer to cur line B-o-l
-static Byte *end_line(Byte *); // return pointer to cur line E-o-l
-static Byte *prev_line(Byte *);        // return pointer to prev line B-o-l
-static Byte *next_line(Byte *);        // return pointer to next line B-o-l
-static Byte *end_screen(void); // get pointer to last char on screen
-static int count_lines(Byte *, Byte *);        // count line from start to stop
-static Byte *find_line(int);   // find begining of line #li
-static Byte *move_to_col(Byte *, int); // move "p" to column l
-static int isblnk(Byte);       // is the char a blank or tab
+#if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK
+static char *modifying_cmds;            // cmds that modify text[]
+#endif
+#if ENABLE_FEATURE_VI_SEARCH
+static char *last_search_pattern;      // last pattern from a '/' or '?' search
+#endif
+
+/* Moving biggest data to malloced space... */
+struct globals {
+       /* many references - keep near the top of globals */
+       char *text, *end;       // pointers to the user data in memory
+       char *dot;              // where all the action takes place
+#if ENABLE_FEATURE_VI_YANKMARK
+       char *reg[28];          // named register a-z, "D", and "U" 0-25,26,27
+       int YDreg, Ureg;        // default delete register and orig line for "U"
+       char *mark[28];         // user marks points somewhere in text[]-  a-z and previous context ''
+       char *context_start, *context_end;
+#endif
+       /* a few references only */
+#if ENABLE_FEATURE_VI_USE_SIGNALS
+       jmp_buf restart;                // catch_sig()
+#endif
+       struct termios term_orig, term_vi;      // remember what the cooked mode was
+#if ENABLE_FEATURE_VI_COLON
+       char *initial_cmds[3];  // currently 2 entries, NULL terminated
+#endif
+};
+#define G (*ptr_to_globals)
+#define text           (G.text          )
+#define end            (G.end           )
+#define dot            (G.dot           )
+#define reg            (G.reg           )
+#define YDreg          (G.YDreg         )
+#define Ureg           (G.Ureg          )
+#define mark           (G.mark          )
+#define context_start  (G.context_start )
+#define context_end    (G.context_end   )
+#define restart        (G.restart       )
+#define term_orig      (G.term_orig     )
+#define term_vi        (G.term_vi       )
+#define initial_cmds   (G.initial_cmds  )
+
+static void edit_file(char *); // edit one file
+static void do_cmd(char);      // execute a command
+static void sync_cursor(char *, int *, int *); // synchronize the screen cursor to dot
+static char *begin_line(char *);       // return pointer to cur line B-o-l
+static char *end_line(char *); // return pointer to cur line E-o-l
+static char *prev_line(char *);        // return pointer to prev line B-o-l
+static char *next_line(char *);        // return pointer to next line B-o-l
+static char *end_screen(void); // get pointer to last char on screen
+static int count_lines(char *, char *);        // count line from start to stop
+static char *find_line(int);   // find begining of line #li
+static char *move_to_col(char *, int); // move "p" to column l
+static int isblnk(char);       // is the char a blank or tab
 static void dot_left(void);    // move dot left- dont leave line
 static void dot_right(void);   // move dot right- dont leave line
 static void dot_begin(void);   // move dot to B-o-l
@@ -234,27 +210,32 @@ static void dot_prev(void);       // move dot to prev line B-o-l
 static void dot_scroll(int, int);      // move the screen up or down
 static void dot_skip_over_ws(void);    // move dot pat WS
 static void dot_delete(void);  // delete the char at 'dot'
-static Byte *bound_dot(Byte *);        // make sure  text[0] <= P < "end"
-static Byte *new_screen(int, int);     // malloc virtual screen memory
-static Byte *new_text(int);    // malloc memory for text[] buffer
-static Byte *char_insert(Byte *, Byte);        // insert the char c at 'p'
-static Byte *stupid_insert(Byte *, Byte);      // stupidly insert the char c at 'p'
-static Byte find_range(Byte **, Byte **, Byte);        // return pointers for an object
-static int st_test(Byte *, int, int, Byte *);  // helper for skip_thing()
-static Byte *skip_thing(Byte *, int, int, int);        // skip some object
-static Byte *find_pair(Byte *, Byte);  // find matching pair ()  []  {}
-static Byte *text_hole_delete(Byte *, Byte *); // at "p", delete a 'size' byte hole
-static Byte *text_hole_make(Byte *, int);      // at "p", make a 'size' byte hole
-static Byte *yank_delete(Byte *, Byte *, int, int);    // yank text[] into register then delete
+static char *bound_dot(char *);        // make sure  text[0] <= P < "end"
+static char *new_screen(int, int);     // malloc virtual screen memory
+static char *new_text(int);    // malloc memory for text[] buffer
+static char *char_insert(char *, char);        // insert the char c at 'p'
+static char *stupid_insert(char *, char);      // stupidly insert the char c at 'p'
+static char find_range(char **, char **, char);        // return pointers for an object
+static int st_test(char *, int, int, char *);  // helper for skip_thing()
+static char *skip_thing(char *, int, int, int);        // skip some object
+static char *find_pair(char *, char);  // find matching pair ()  []  {}
+static char *text_hole_delete(char *, char *); // at "p", delete a 'size' byte hole
+static char *text_hole_make(char *, int);      // at "p", make a 'size' byte hole
+static char *yank_delete(char *, char *, 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
 static int mysleep(int);       // sleep for 'h' 1/100 seconds
-static Byte readit(void);      // read (maybe cursor) key from stdin
-static Byte get_one_char(void);        // read 1 char from stdin
-static int file_size(const Byte *);   // what is the byte size of "fn"
-static int file_insert(Byte *, Byte *, int);
-static int file_write(Byte *, Byte *, Byte *);
+static char readit(void);      // read (maybe cursor) key from stdin
+static char get_one_char(void);        // read 1 char from stdin
+static int file_size(const char *);   // what is the byte size of "fn"
+static int file_insert(char *, char *);
+#if ENABLE_FEATURE_VI_READONLY
+static void update_ro_status(const char *);
+#else
+static ALWAYS_INLINE void update_ro_status(const char *name) {}
+#endif
+static int file_write(char *, char *, char *);
 static void place_cursor(int, int, int);
 static void screen_erase(void);
 static void clear_to_eol(void);
@@ -265,56 +246,52 @@ static void flash(int);           // flash the terminal screen
 static void show_status_line(void);    // put a message on the bottom line
 static void psb(const char *, ...);     // Print Status Buf
 static void psbs(const char *, ...);    // Print Status Buf in standout mode
-static void ni(Byte *);                // display messages
+static void ni(const char *);          // display messages
 static int format_edit_status(void);   // format file status on status line
 static void redraw(int);       // force a full screen refresh
-static void format_line(Byte*, Byte*, int);
+static void format_line(char*, char*, int);
 static void refresh(int);      // update the terminal from screen[]
 
 static void Indicate_Error(void);       // use flash or beep to indicate error
 #define indicate_error(c) Indicate_Error()
 static void Hit_Return(void);
 
-#ifdef CONFIG_FEATURE_VI_SEARCH
-static Byte *char_search(Byte *, Byte *, int, int);    // search for pattern starting at p
-static int mycmp(Byte *, Byte *, int); // string cmp based in "ignorecase"
-#endif                                                 /* CONFIG_FEATURE_VI_SEARCH */
-#ifdef CONFIG_FEATURE_VI_COLON
-static Byte *get_one_address(Byte *, int *);   // get colon addr, if present
-static Byte *get_address(Byte *, int *, int *);        // get two colon addrs, if present
-static void colon(Byte *);     // execute the "colon" mode cmds
-#endif                                                 /* CONFIG_FEATURE_VI_COLON */
-#ifdef CONFIG_FEATURE_VI_USE_SIGNALS
+#if ENABLE_FEATURE_VI_SEARCH
+static char *char_search(char *, const char *, int, int);      // search for pattern starting at p
+static int mycmp(const char *, const char *, int);     // string cmp based in "ignorecase"
+#endif
+#if ENABLE_FEATURE_VI_COLON
+static char *get_one_address(char *, int *);   // get colon addr, if present
+static char *get_address(char *, int *, int *);        // get two colon addrs, if present
+static void colon(char *);     // execute the "colon" mode cmds
+#endif
+#if ENABLE_FEATURE_VI_USE_SIGNALS
 static void winch_sig(int);    // catch window size changes
 static void suspend_sig(int);  // catch ctrl-Z
 static void catch_sig(int);     // catch ctrl-C and alarm time-outs
-static void core_sig(int);     // catch a core dump signal
-#endif                                                 /* CONFIG_FEATURE_VI_USE_SIGNALS */
-#ifdef CONFIG_FEATURE_VI_DOT_CMD
-static void start_new_cmd_q(Byte);     // new queue for command
+#endif
+#if ENABLE_FEATURE_VI_DOT_CMD
+static void start_new_cmd_q(char);     // new queue for command
 static void end_cmd_q(void);   // stop saving input chars
-#else                                                  /* CONFIG_FEATURE_VI_DOT_CMD */
-#define end_cmd_q()
-#endif                                                 /* CONFIG_FEATURE_VI_DOT_CMD */
-#ifdef CONFIG_FEATURE_VI_WIN_RESIZE
-static void window_size_get(int);      // find out what size the window is
-#endif                                                 /* CONFIG_FEATURE_VI_WIN_RESIZE */
-#ifdef CONFIG_FEATURE_VI_SETOPTS
-static void showmatching(Byte *);      // show the matching pair ()  []  {}
-#endif                                                 /* CONFIG_FEATURE_VI_SETOPTS */
-#if defined(CONFIG_FEATURE_VI_YANKMARK) || defined(CONFIG_FEATURE_VI_SEARCH) || defined(CONFIG_FEATURE_VI_CRASHME)
-static Byte *string_insert(Byte *, Byte *);    // insert the string at 'p'
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK || CONFIG_FEATURE_VI_SEARCH || CONFIG_FEATURE_VI_CRASHME */
-#ifdef CONFIG_FEATURE_VI_YANKMARK
-static Byte *text_yank(Byte *, Byte *, int);   // save copy of "p" into a register
-static Byte what_reg(void);            // what is letter of current YDreg
-static void check_context(Byte);       // remember context for '' command
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
-#ifdef CONFIG_FEATURE_VI_CRASHME
+#else
+#define end_cmd_q() ((void)0)
+#endif
+#if ENABLE_FEATURE_VI_SETOPTS
+static void showmatching(char *);      // show the matching pair ()  []  {}
+#endif
+#if ENABLE_FEATURE_VI_YANKMARK || (ENABLE_FEATURE_VI_COLON && ENABLE_FEATURE_VI_SEARCH) || ENABLE_FEATURE_VI_CRASHME
+static char *string_insert(char *, char *);    // insert the string at 'p'
+#endif
+#if ENABLE_FEATURE_VI_YANKMARK
+static char *text_yank(char *, char *, int);   // save copy of "p" into a register
+static char what_reg(void);            // what is letter of current YDreg
+static void check_context(char);       // remember context for '' command
+#endif
+#if ENABLE_FEATURE_VI_CRASHME
 static void crash_dummy();
 static void crash_test();
 static int crashme = 0;
-#endif                                                 /* CONFIG_FEATURE_VI_CRASHME */
+#endif
 
 
 static void write1(const char *out)
@@ -322,61 +299,78 @@ static void write1(const char *out)
        fputs(out, stdout);
 }
 
+int vi_main(int argc, char **argv);
 int vi_main(int argc, char **argv)
 {
        int c;
        RESERVE_CONFIG_BUFFER(STATUS_BUFFER, STATUS_BUFFER_LEN);
 
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
        int i;
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
-#if defined(CONFIG_FEATURE_VI_USE_SIGNALS) || defined(CONFIG_FEATURE_VI_CRASHME)
+#endif
+#if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME
        my_pid = getpid();
 #endif
-#ifdef CONFIG_FEATURE_VI_CRASHME
-       (void) srand((long) my_pid);
-#endif                                                 /* CONFIG_FEATURE_VI_CRASHME */
 
-       status_buffer = (Byte *)STATUS_BUFFER;
+       PTR_TO_GLOBALS = xzalloc(sizeof(G));
+
+#if ENABLE_FEATURE_VI_CRASHME
+       srand((long) my_pid);
+#endif
+
+       status_buffer = STATUS_BUFFER;
        last_status_cksum = 0;
 
-#ifdef CONFIG_FEATURE_VI_READONLY
+#if ENABLE_FEATURE_VI_READONLY
        vi_readonly = readonly = FALSE;
        if (strncmp(argv[0], "view", 4) == 0) {
                readonly = TRUE;
                vi_readonly = TRUE;
        }
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
+#endif
        vi_setops = VI_AUTOINDENT | VI_SHOWMATCH | VI_IGNORECASE | VI_ERR_METHOD;
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
        for (i = 0; i < 28; i++) {
                reg[i] = 0;
        }                                       // init the yank regs
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
-#if defined(CONFIG_FEATURE_VI_DOT_CMD) || defined(CONFIG_FEATURE_VI_YANKMARK)
-       modifying_cmds = (Byte *) "aAcCdDiIJoOpPrRsxX<>~";      // cmds modifying text[]
-#endif                                                 /* CONFIG_FEATURE_VI_DOT_CMD */
+#endif
+#if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK
+       modifying_cmds = (char *) "aAcCdDiIJoOpPrRsxX<>~";      // cmds modifying text[]
+#endif
 
-       //  1-  process $HOME/.exrc file
+       //  1-  process $HOME/.exrc file (not inplemented yet)
        //  2-  process EXINIT variable from environment
        //  3-  process command line args
-       while ((c = getopt(argc, argv, "hCR")) != -1) {
+#if ENABLE_FEATURE_VI_COLON
+       {
+               char *p = getenv("EXINIT");
+               if (p && *p)
+                       initial_cmds[0] = xstrdup(p);
+       }
+#endif
+       while ((c = getopt(argc, argv, "hCR" USE_FEATURE_VI_COLON("c:"))) != -1) {
                switch (c) {
-#ifdef CONFIG_FEATURE_VI_CRASHME
+#if ENABLE_FEATURE_VI_CRASHME
                case 'C':
                        crashme = 1;
                        break;
-#endif                                                 /* CONFIG_FEATURE_VI_CRASHME */
-#ifdef CONFIG_FEATURE_VI_READONLY
+#endif
+#if ENABLE_FEATURE_VI_READONLY
                case 'R':               // Read-only flag
                        readonly = TRUE;
                        vi_readonly = TRUE;
                        break;
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
+#endif
                        //case 'r':     // recover flag-  ignore- we don't use tmp file
                        //case 'x':     // encryption flag- ignore
                        //case 'c':     // execute command first
+#if ENABLE_FEATURE_VI_COLON
+               case 'c':               // cmd line vi command
+                       if (*optarg)
+                               initial_cmds[initial_cmds[0] != 0] = xstrdup(optarg);
+                       break;
                        //case 'h':     // help -- just use default
+#endif
                default:
                        show_help();
                        return 1;
@@ -390,48 +384,39 @@ int vi_main(int argc, char **argv)
 
        //----- This is the main file handling loop --------------
        if (optind >= argc) {
-               editing = 1;    // 0= exit,  1= one file,  2= multiple files
+               editing = 1;    // 0= exit,  1= one file,  2 = multiple files
                edit_file(0);
        } else {
                for (; optind < argc; optind++) {
-                       editing = 1;    // 0=exit, 1=one file, 2+ =many files
+                       editing = 1;    // 0=exit, 1=one file, 2+ = many files
                        free(cfn);
-                       cfn = (Byte *) bb_xstrdup(argv[optind]);
+                       cfn = xstrdup(argv[optind]);
                        edit_file(cfn);
                }
        }
        //-----------------------------------------------------------
 
-       return (0);
+       return 0;
 }
 
-#ifdef CONFIG_FEATURE_VI_WIN_RESIZE
-//----- See what the window size currently is --------------------
-static inline void window_size_get(int fd)
+static void edit_file(char * fn)
 {
-       get_terminal_width_height(fd, &columns, &rows);
-}
-#endif                                                 /* CONFIG_FEATURE_VI_WIN_RESIZE */
-
-static void edit_file(Byte * fn)
-{
-       Byte c;
+       char c;
        int cnt, size, ch;
 
-#ifdef CONFIG_FEATURE_VI_USE_SIGNALS
+#if ENABLE_FEATURE_VI_USE_SIGNALS
        int sig;
-#endif                                                 /* CONFIG_FEATURE_VI_USE_SIGNALS */
-#ifdef CONFIG_FEATURE_VI_YANKMARK
-       static Byte *cur_line;
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+#endif
+#if ENABLE_FEATURE_VI_YANKMARK
+       static char *cur_line;
+#endif
 
        rawmode();
        rows = 24;
        columns = 80;
-       ch= -1;
-#ifdef CONFIG_FEATURE_VI_WIN_RESIZE
-       window_size_get(0);
-#endif                                                 /* CONFIG_FEATURE_VI_WIN_RESIZE */
+       ch = -1;
+       if (ENABLE_FEATURE_VI_WIN_RESIZE)
+               get_terminal_width_height(0, &columns, &rows);
        new_screen(rows, columns);      // get memory for virtual screen
 
        cnt = file_size(fn);    // file size
@@ -439,54 +424,36 @@ static void edit_file(Byte * fn)
        new_text(size);         // get a text[] buffer
        screenbegin = dot = end = text;
        if (fn != 0) {
-               ch= file_insert(fn, text, cnt);
+               ch = file_insert(fn, text);
+               update_ro_status(fn);
        }
        if (ch < 1) {
-               (void) char_insert(text, '\n'); // start empty buf with dummy line
+               char_insert(text, '\n');        // start empty buf with dummy line
        }
        file_modified = 0;
        last_file_modified = -1;
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
        YDreg = 26;                     // default Yank/Delete reg
        Ureg = 27;                      // hold orig line for "U" cmd
        for (cnt = 0; cnt < 28; cnt++) {
                mark[cnt] = 0;
        }                                       // init the marks
        mark[26] = mark[27] = text;     // init "previous context"
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+#endif
 
        last_forward_char = last_input_char = '\0';
        crow = 0;
        ccol = 0;
 
-#ifdef CONFIG_FEATURE_VI_USE_SIGNALS
+#if ENABLE_FEATURE_VI_USE_SIGNALS
        catch_sig(0);
-       core_sig(0);
        signal(SIGWINCH, winch_sig);
        signal(SIGTSTP, suspend_sig);
        sig = setjmp(restart);
        if (sig != 0) {
-               const char *msg = "";
-
-               if (sig == SIGWINCH)
-                       msg = "(window resize)";
-               if (sig == SIGHUP)
-                       msg = "(hangup)";
-               if (sig == SIGINT)
-                       msg = "(interrupt)";
-               if (sig == SIGTERM)
-                       msg = "(terminate)";
-               if (sig == SIGBUS)
-                       msg = "(bus error)";
-               if (sig == SIGSEGV)
-                       msg = "(I tried to touch invalid memory)";
-               if (sig == SIGALRM)
-                       msg = "(alarm)";
-
-               psbs("-- caught signal %d %s--", sig, msg);
                screenbegin = dot = text;
        }
-#endif                                                 /* CONFIG_FEATURE_VI_USE_SIGNALS */
+#endif
 
        editing = 1;
        cmd_mode = 0;           // 0=command  1=insert  2='R'eplace
@@ -494,45 +461,66 @@ static void edit_file(Byte * fn)
        tabstop = 8;
        offset = 0;                     // no horizontal offset
        c = '\0';
-#ifdef CONFIG_FEATURE_VI_DOT_CMD
+#if ENABLE_FEATURE_VI_DOT_CMD
        free(last_modifying_cmd);
        free(ioq_start);
-       ioq = ioq_start = last_modifying_cmd = 0;
+       ioq = ioq_start = last_modifying_cmd = NULL;
        adding2q = 0;
-#endif                                                 /* CONFIG_FEATURE_VI_DOT_CMD */
+#endif
        redraw(FALSE);                  // dont force every col re-draw
        show_status_line();
 
+#if ENABLE_FEATURE_VI_COLON
+       {
+               char *p, *q;
+               int n = 0;
+
+               while ((p = initial_cmds[n])) {
+                       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
        //------This is the main Vi cmd handling loop -----------------------
        while (editing > 0) {
-#ifdef CONFIG_FEATURE_VI_CRASHME
+#if ENABLE_FEATURE_VI_CRASHME
                if (crashme > 0) {
                        if ((end - text) > 1) {
                                crash_dummy();  // generate a random command
                        } else {
                                crashme = 0;
-                               dot =
-                                       string_insert(text, (Byte *) "\n\n#####  Ran out of text to work on.  #####\n\n");      // insert the string
+                               dot = string_insert(text, "\n\n#####  Ran out of text to work on.  #####\n\n"); // insert the string
                                refresh(FALSE);
                        }
                }
-#endif                                                 /* CONFIG_FEATURE_VI_CRASHME */
+#endif
                last_input_char = c = get_one_char();   // get a cmd from user
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#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                                                 /* CONFIG_FEATURE_VI_YANKMARK */
-#ifdef CONFIG_FEATURE_VI_DOT_CMD
+#endif
+#if ENABLE_FEATURE_VI_DOT_CMD
                // These are commands that change text[].
                // Remember the input for the "." command
                if (!adding2q && ioq_start == 0
-                       && strchr((char *) modifying_cmds, c) != NULL) {
+                && strchr(modifying_cmds, c)
+               ) {
                        start_new_cmd_q(c);
                }
-#endif                                                 /* CONFIG_FEATURE_VI_DOT_CMD */
+#endif
                do_cmd(c);              // execute the user command
                //
                // poll to see if there is input already waiting. if we are
@@ -543,10 +531,10 @@ static void edit_file(Byte * fn)
                        refresh(FALSE);
                        show_status_line();
                }
-#ifdef CONFIG_FEATURE_VI_CRASHME
+#if ENABLE_FEATURE_VI_CRASHME
                if (crashme > 0)
                        crash_test();   // test editor variables
-#endif                                                 /* CONFIG_FEATURE_VI_CRASHME */
+#endif
        }
        //-------------------------------------------------------------------
 
@@ -556,25 +544,25 @@ static void edit_file(Byte * fn)
 }
 
 //----- The Colon commands -------------------------------------
-#ifdef CONFIG_FEATURE_VI_COLON
-static Byte *get_one_address(Byte * p, int *addr)      // get colon addr, if present
+#if ENABLE_FEATURE_VI_COLON
+static char *get_one_address(char * p, int *addr)      // get colon addr, if present
 {
        int st;
-       Byte *q;
+       char *q;
 
-#ifdef CONFIG_FEATURE_VI_YANKMARK
-       Byte c;
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
-#ifdef CONFIG_FEATURE_VI_SEARCH
-       Byte *pat, buf[BUFSIZ];
-#endif                                                 /* CONFIG_FEATURE_VI_SEARCH */
+#if ENABLE_FEATURE_VI_YANKMARK
+       char c;
+#endif
+#if ENABLE_FEATURE_VI_SEARCH
+       char *pat, buf[MAX_LINELEN];
+#endif
 
        *addr = -1;                     // assume no addr
        if (*p == '.') {        // the current line
                p++;
                q = begin_line(dot);
                *addr = count_lines(text, q);
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
        } else if (*p == '\'') {        // is this a mark addr
                p++;
                c = tolower(*p);
@@ -582,13 +570,13 @@ static Byte *get_one_address(Byte * p, int *addr) // get colon addr, if present
                if (c >= 'a' && c <= 'z') {
                        // we have a mark
                        c = c - 'a';
-                       q = mark[(int) c];
+                       q = mark[(unsigned char) c];
                        if (q != NULL) {        // is mark valid
                                *addr = count_lines(text, q);   // count lines
                        }
                }
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
-#ifdef CONFIG_FEATURE_VI_SEARCH
+#endif
+#if ENABLE_FEATURE_VI_SEARCH
        } else if (*p == '/') { // a search pattern
                q = buf;
                for (p++; *p; p++) {
@@ -597,7 +585,7 @@ static Byte *get_one_address(Byte * p, int *addr)   // get colon addr, if present
                        *q++ = *p;
                        *q = '\0';
                }
-               pat = (Byte *) bb_xstrdup((char *) buf);        // save copy of pattern
+               pat = xstrdup(buf);     // save copy of pattern
                if (*p == '/')
                        p++;
                q = char_search(dot, pat, FORWARD, FULL);
@@ -605,22 +593,22 @@ static Byte *get_one_address(Byte * p, int *addr) // get colon addr, if present
                        *addr = count_lines(text, q);
                }
                free(pat);
-#endif                                                 /* CONFIG_FEATURE_VI_SEARCH */
+#endif
        } else if (*p == '$') { // the last line in file
                p++;
                q = begin_line(end - 1);
                *addr = count_lines(text, q);
        } else if (isdigit(*p)) {       // specific line number
-               sscanf((char *) p, "%d%n", addr, &st);
+               sscanf(p, "%d%n", addr, &st);
                p += st;
        } else {                        // I don't reconise this
                // unrecognised address- assume -1
                *addr = -1;
        }
-       return (p);
+       return p;
 }
 
-static Byte *get_address(Byte *p, int *b, int *e)      // get two colon addrs, if present
+static char *get_address(char *p, int *b, int *e)      // get two colon addrs, if present
 {
        //----- get the address' i.e., 1,3   'a,'b  -----
        // get FIRST addr, if present
@@ -642,36 +630,36 @@ static Byte *get_address(Byte *p, int *b, int *e) // get two colon addrs, if pre
                // get SECOND addr, if present
                p = get_one_address(p, e);
        }
-ga0:
+ ga0:
        while (isblnk(*p))
                p++;                            // skip over trailing spaces
-       return (p);
+       return p;
 }
 
-#ifdef CONFIG_FEATURE_VI_SETOPTS
-static void setops(const Byte *args, const char *opname, int flg_no,
+#if ENABLE_FEATURE_VI_SET && ENABLE_FEATURE_VI_SETOPTS
+static void setops(const char *args, const char *opname, int flg_no,
                        const char *short_opname, int opt)
 {
-       const char *a = (char *) args + flg_no;
+       const char *a = args + flg_no;
        int l = strlen(opname) - 1; /* opname have + ' ' */
 
-       if (strncasecmp(a, opname, l) == 0 ||
-                       strncasecmp(a, short_opname, 2) == 0) {
-               if(flg_no)
+       if (strncasecmp(a, opname, l) == 0
+        || strncasecmp(a, short_opname, 2) == 0
+       ) {
+               if (flg_no)
                        vi_setops &= ~opt;
-                else
+               else
                        vi_setops |= opt;
        }
 }
 #endif
 
-static void colon(Byte * buf)
+static void colon(char * buf)
 {
-       Byte c, *orig_buf, *buf1, *q, *r;
-       Byte *fn, cmd[BUFSIZ], args[BUFSIZ];
-       int i, l, li, ch, st, b, e;
+       char c, *orig_buf, *buf1, *q, *r;
+       char *fn, cmd[MAX_LINELEN], args[MAX_LINELEN];
+       int i, l, li, ch, b, e;
        int useforce = FALSE, forced = FALSE;
-       struct stat st_buf;
 
        // :3154        // if (-e line 3154) goto it  else stay put
        // :4,33w! foo  // write a portion of buffer to file "foo"
@@ -688,19 +676,19 @@ static void colon(Byte * buf)
        // :!<cmd>      // run <cmd> then return
        //
 
-       if (strlen((char *) buf) <= 0)
+       if (!buf[0])
                goto vc1;
        if (*buf == ':')
                buf++;                  // move past the ':'
 
-       li = st = ch = i = 0;
+       li = ch = i = 0;
        b = e = -1;
        q = text;                       // assume 1,$ for the range
        r = end - 1;
        li = count_lines(text, end - 1);
        fn = cfn;                       // default to current file
-       memset(cmd, '\0', BUFSIZ);      // clear cmd[]
-       memset(args, '\0', BUFSIZ);     // clear args[]
+       memset(cmd, '\0', MAX_LINELEN); // clear cmd[]
+       memset(args, '\0', MAX_LINELEN);        // clear args[]
 
        // look for optional address(es)  :.  :1  :1,9   :'q,'a   :%
        buf = get_address(buf, &b, &e);
@@ -718,8 +706,8 @@ static void colon(Byte * buf)
        // get any ARGuments
        while (isblnk(*buf))
                buf++;
-       strcpy((char *) args, (char *) buf);
-       buf1 = (Byte*)last_char_is((char *)cmd, '!');
+       strcpy(args, buf);
+       buf1 = last_char_is(cmd, '!');
        if (buf1) {
                useforce = TRUE;
                *buf1 = '\0';   // get rid of !
@@ -741,48 +729,53 @@ static void colon(Byte * buf)
                li = e - b + 1;
        }
        // ------------ now look for the command ------------
-       i = strlen((char *) cmd);
+       i = strlen(cmd);
        if (i == 0) {           // :123CR goto line #123
                if (b >= 0) {
                        dot = find_line(b);     // what line is #b
                        dot_skip_over_ws();
                }
-       } else if (strncmp((char *) cmd, "!", 1) == 0) {        // run a cmd
+       }
+#if ENABLE_FEATURE_ALLOW_EXEC
+       else if (strncmp(cmd, "!", 1) == 0) {   // run a cmd
                // :!ls   run the <cmd>
-               (void) alarm(0);                // wait for input- no alarms
+               alarm(0);               // wait for input- no alarms
                place_cursor(rows - 1, 0, FALSE);       // go to Status line
                clear_to_eol();                 // clear the line
                cookmode();
-               system((char*)(orig_buf+1));            // run the cmd
+               system(orig_buf + 1);           // run the cmd
                rawmode();
                Hit_Return();                   // let user see results
-               (void) alarm(3);                // done waiting for input
-       } else if (strncmp((char *) cmd, "=", i) == 0) {        // where is the address
+               alarm(3);               // done waiting for input
+       }
+#endif
+       else if (strncmp(cmd, "=", i) == 0) {   // where is the address
                if (b < 0) {    // no addr given- use defaults
                        b = e = count_lines(text, dot);
                }
                psb("%d", b);
-       } else if (strncasecmp((char *) cmd, "delete", i) == 0) {       // delete lines
+       } else if (strncasecmp(cmd, "delete", i) == 0) {        // delete lines
                if (b < 0) {    // no addr given- use defaults
                        q = begin_line(dot);    // assume .,. for the range
                        r = end_line(dot);
                }
                dot = yank_delete(q, r, 1, YANKDEL);    // save, then delete lines
                dot_skip_over_ws();
-       } else if (strncasecmp((char *) cmd, "edit", i) == 0) { // Edit a file
+       } else if (strncasecmp(cmd, "edit", i) == 0) {  // Edit a file
                int sr;
+               struct stat st_buf;
                sr= 0;
                // don't edit, if the current file has been modified
                if (file_modified && ! useforce) {
                        psbs("No write since last change (:edit! overrides)");
                        goto vc1;
                }
-               if (strlen((char*)args) > 0) {
+               if (args[0]) {
                        // the user supplied a file name
-                       fn= args;
-               } else if (cfn != 0 && strlen((char*)cfn) > 0) {
+                       fn = args;
+               } else if (cfn && cfn[0]) {
                        // no user supplied name- use the current filename
-                       fn= cfn;
+                       fn = cfn;
                        goto vc5;
                } else {
                        // no user file name, no current name- punt
@@ -791,13 +784,14 @@ static void colon(Byte * buf)
                }
 
                // see if file exists- if not, its just a new file request
-               if ((sr=stat((char*)fn, &st_buf)) < 0) {
+               sr = stat(fn, &st_buf);
+               if (sr < 0) {
                        // This is just a request for a new file creation.
                        // The file_insert below will fail but we get
                        // an empty buffer with a file name.  Then the "write"
                        // command can do the create.
                } else {
-                       if ((st_buf.st_mode & (S_IFREG)) == 0) {
+                       if ((st_buf.st_mode & S_IFREG) == 0) {
                                // This is not a regular file
                                psbs("\"%s\" is not a regular file", fn);
                                goto vc1;
@@ -811,26 +805,27 @@ static void colon(Byte * buf)
 
                // There is a read-able regular file
                // make this the current file
-               q = (Byte *) bb_xstrdup((char *) fn);   // save the cfn
+               q = xstrdup(fn);        // save the cfn
                free(cfn);              // free the old name
                cfn = q;                        // remember new cfn
 
        vc5:
+ vc5:
                // delete all the contents of text[]
                new_text(2 * file_size(fn));
                screenbegin = dot = end = text;
 
                // insert new file
-               ch = file_insert(fn, text, file_size(fn));
+               ch = file_insert(fn, text);
+               update_ro_status(fn);
 
                if (ch < 1) {
                        // start empty buf with dummy line
-                       (void) char_insert(text, '\n');
-                       ch= 1;
+                       char_insert(text, '\n');
+                       ch = 1;
                }
                file_modified = 0;
                last_file_modified = -1;
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
                if (Ureg >= 0 && Ureg < 28 && reg[Ureg] != 0) {
                        free(reg[Ureg]);        //   free orig line reg- for 'U'
                        reg[Ureg]= 0;
@@ -842,33 +837,33 @@ static void colon(Byte * buf)
                for (li = 0; li < 28; li++) {
                        mark[li] = 0;
                }                               // init the marks
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+#endif
                // how many lines in text[]?
                li = count_lines(text, end - 1);
                psb("\"%s\"%s"
-#ifdef CONFIG_FEATURE_VI_READONLY
+#if ENABLE_FEATURE_VI_READONLY
                        "%s"
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
+#endif
                        " %dL, %dC", cfn,
                        (sr < 0 ? " [New file]" : ""),
-#ifdef CONFIG_FEATURE_VI_READONLY
+#if ENABLE_FEATURE_VI_READONLY
                        ((vi_readonly || readonly) ? " [Read only]" : ""),
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
+#endif
                        li, ch);
-       } else if (strncasecmp((char *) cmd, "file", i) == 0) { // what File is this
+       } else if (strncasecmp(cmd, "file", i) == 0) {  // what File is this
                if (b != -1 || e != -1) {
-                       ni((Byte *) "No address allowed on this command");
+                       ni("No address allowed on this command");
                        goto vc1;
                }
-               if (strlen((char *) args) > 0) {
+               if (args[0]) {
                        // user wants a new filename
                        free(cfn);
-                       cfn = (Byte *) bb_xstrdup((char *) args);
+                       cfn = xstrdup(args);
                } else {
                        // user wants file status info
                        last_status_cksum = 0;  // force status update
                }
-       } else if (strncasecmp((char *) cmd, "features", i) == 0) {     // what features are available
+       } else if (strncasecmp(cmd, "features", i) == 0) {      // what features are available
                // print out values of all features
                place_cursor(rows - 1, 0, FALSE);       // go to Status line, bottom of screen
                clear_to_eol(); // clear the line
@@ -876,7 +871,7 @@ static void colon(Byte * buf)
                show_help();
                rawmode();
                Hit_Return();
-       } else if (strncasecmp((char *) cmd, "list", i) == 0) { // literal print line
+       } else if (strncasecmp(cmd, "list", i) == 0) {  // literal print line
                if (b < 0) {    // no addr given- use defaults
                        q = begin_line(dot);    // assume .,. for the range
                        r = end_line(dot);
@@ -888,7 +883,7 @@ static void colon(Byte * buf)
                        int c_is_no_print;
 
                        c = *q;
-                       c_is_no_print = c > 127 && !Isprint(c);
+                       c_is_no_print = (c & 0x80) && !Isprint(c);
                        if (c_is_no_print) {
                                c = '.';
                                standout_start();
@@ -897,21 +892,22 @@ static void colon(Byte * buf)
                                write1("$\r");
                        } else if (c < ' ' || c == 127) {
                                putchar('^');
-                               if(c == 127)
+                               if (c == 127)
                                        c = '?';
-                                else
-                               c += '@';
+                               else
+                                       c += '@';
                        }
                        putchar(c);
                        if (c_is_no_print)
                                standout_end();
                }
-#ifdef CONFIG_FEATURE_VI_SET
        vc2:
-#endif                                                 /* CONFIG_FEATURE_VI_SET */
+#if ENABLE_FEATURE_VI_SET
+ vc2:
+#endif
                Hit_Return();
-       } else if ((strncasecmp((char *) cmd, "quit", i) == 0) ||       // Quit
-                          (strncasecmp((char *) cmd, "next", i) == 0)) {       // edit next file
+       } else if (strncasecmp(cmd, "quit", i) == 0 // Quit
+               || strncasecmp(cmd, "next", i) == 0 // edit next file
+       ) {
                if (useforce) {
                        // force end of argv list
                        if (*cmd == 'q') {
@@ -936,9 +932,9 @@ static void colon(Byte * buf)
                        goto vc1;
                }
                editing = 0;
-       } else if (strncasecmp((char *) cmd, "read", i) == 0) { // read file into text[]
+       } else if (strncasecmp(cmd, "read", i) == 0) {  // read file into text[]
                fn = args;
-               if (strlen((char *) fn) <= 0) {
+               if (!fn[0]) {
                        psbs("No filename given");
                        goto vc1;
                }
@@ -948,25 +944,15 @@ static void colon(Byte * buf)
                // read after current line- unless user said ":0r foo"
                if (b != 0)
                        q = next_line(q);
-#ifdef CONFIG_FEATURE_VI_READONLY
-               l= readonly;                    // remember current files' status
-#endif
-               ch = file_insert(fn, q, file_size(fn));
-#ifdef CONFIG_FEATURE_VI_READONLY
-               readonly= l;
-#endif
+               ch = file_insert(fn, q);
                if (ch < 0)
                        goto vc1;       // nothing was inserted
                // how many lines in text[]?
                li = count_lines(q, q + ch - 1);
                psb("\"%s\""
-#ifdef CONFIG_FEATURE_VI_READONLY
-                       "%s"
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
+                       USE_FEATURE_VI_READONLY("%s")
                        " %dL, %dC", fn,
-#ifdef CONFIG_FEATURE_VI_READONLY
-                       ((vi_readonly || readonly) ? " [Read only]" : ""),
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
+                       USE_FEATURE_VI_READONLY(((vi_readonly || readonly) ? " [Read only]" : ""),)
                        li, ch);
                if (ch > 0) {
                        // if the insert is before "dot" then we need to update
@@ -974,7 +960,7 @@ static void colon(Byte * buf)
                                dot += ch;
                        file_modified++;
                }
-       } else if (strncasecmp((char *) cmd, "rewind", i) == 0) {       // rewind cmd line args
+       } else if (strncasecmp(cmd, "rewind", i) == 0) {        // rewind cmd line args
                if (file_modified && ! useforce) {
                        psbs("No write since last change (:rewind! overrides)");
                } else {
@@ -982,15 +968,19 @@ static void colon(Byte * buf)
                        optind = fn_start - 1;
                        editing = 0;
                }
-#ifdef CONFIG_FEATURE_VI_SET
-       } else if (strncasecmp((char *) cmd, "set", i) == 0) {  // set or clear features
+#if ENABLE_FEATURE_VI_SET
+       } else if (strncasecmp(cmd, "set", i) == 0) {   // set or clear features
+#if ENABLE_FEATURE_VI_SETOPTS
+               char *argp;
+#endif
                i = 0;                  // offset into args
-               if (strlen((char *) args) == 0) {
+               // only blank is regarded as args delmiter. What about tab '\t' ?
+               if (!args[0] || strcasecmp(args, "all") == 0) {
                        // print out values of all options
                        place_cursor(rows - 1, 0, FALSE);       // go to Status line, bottom of screen
                        clear_to_eol(); // clear the line
                        printf("----------------------------------------\r\n");
-#ifdef CONFIG_FEATURE_VI_SETOPTS
+#if ENABLE_FEATURE_VI_SETOPTS
                        if (!autoindent)
                                printf("no");
                        printf("autoindent ");
@@ -1004,27 +994,35 @@ static void colon(Byte * buf)
                                printf("no");
                        printf("showmatch ");
                        printf("tabstop=%d ", tabstop);
-#endif                                                 /* CONFIG_FEATURE_VI_SETOPTS */
+#endif
                        printf("\r\n");
                        goto vc2;
                }
-               if (strncasecmp((char *) args, "no", 2) == 0)
-                       i = 2;          // ":set noautoindent"
-#ifdef CONFIG_FEATURE_VI_SETOPTS
-               setops(args, "autoindent ", i, "ai", VI_AUTOINDENT);
-               setops(args, "flash ", i, "fl", VI_ERR_METHOD);
-               setops(args, "ignorecase ", i, "ic", VI_IGNORECASE);
-               setops(args, "showmatch ", i, "ic", VI_SHOWMATCH);
-               if (strncasecmp((char *) args + i, "tabstop=%d ", 7) == 0) {
-                       sscanf(strchr((char *) args + i, '='), "=%d", &ch);
-                       if (ch > 0 && ch < columns - 1)
-                               tabstop = ch;
-               }
-#endif                                                 /* CONFIG_FEATURE_VI_SETOPTS */
-#endif                                                 /* CONFIG_FEATURE_VI_SET */
-#ifdef CONFIG_FEATURE_VI_SEARCH
-       } else if (strncasecmp((char *) cmd, "s", 1) == 0) {    // substitute a pattern with a replacement pattern
-               Byte *ls, *F, *R;
+#if ENABLE_FEATURE_VI_SETOPTS
+               argp = args;
+               while (*argp) {
+                       if (strncasecmp(argp, "no", 2) == 0)
+                               i = 2;          // ":set noautoindent"
+                       setops(argp, "autoindent ", i, "ai", VI_AUTOINDENT);
+                       setops(argp, "flash ", i, "fl", VI_ERR_METHOD);
+                       setops(argp, "ignorecase ", i, "ic", VI_IGNORECASE);
+                       setops(argp, "showmatch ", i, "ic", VI_SHOWMATCH);
+                       /* tabstopXXXX */
+                       if (strncasecmp(argp + i, "tabstop=%d ", 7) == 0) {
+                               sscanf(strchr(argp + i, '='), "tabstop=%d" + 7, &ch);
+                               if (ch > 0 && ch < columns - 1)
+                                       tabstop = ch;
+                       }
+                       while (*argp && *argp != ' ')
+                               argp++; // skip to arg delimiter (i.e. blank)
+                       while (*argp && *argp == ' ')
+                               argp++; // skip all delimiting blanks
+               }
+#endif /* FEATURE_VI_SETOPTS */
+#endif /* FEATURE_VI_SET */
+#if ENABLE_FEATURE_VI_SEARCH
+       } else if (strncasecmp(cmd, "s", 1) == 0) {     // substitute a pattern with a replacement pattern
+               char *ls, *F, *R;
                int gflag;
 
                // F points to the "find" pattern
@@ -1033,10 +1031,10 @@ static void colon(Byte * buf)
                gflag = 0;              // global replace flag
                c = orig_buf[1];        // what is the delimiter
                F = orig_buf + 2;       // start of "find"
-               R = (Byte *) strchr((char *) F, c);     // middle delimiter
+               R = strchr(F, c);       // middle delimiter
                if (!R) goto colon_s_fail;
                *R++ = '\0';    // terminate "find"
-               buf1 = (Byte *) strchr((char *) R, c);
+               buf1 = strchr(R, c);
                if (!buf1) goto colon_s_fail;
                *buf1++ = '\0'; // terminate "replace"
                if (*buf1 == 'g') {     // :s/foo/bar/g
@@ -1052,40 +1050,41 @@ static void colon(Byte * buf)
                        e = b;          // maybe :.s/foo/bar/
                for (i = b; i <= e; i++) {      // so, :20,23 s \0 find \0 replace \0
                        ls = q;         // orig line start
                vc4:
+ vc4:
                        buf1 = char_search(q, F, FORWARD, LIMITED);     // search cur line only for "find"
-                       if (buf1 != NULL) {
-                               // we found the "find" pattern- delete it
-                               (void) text_hole_delete(buf1, buf1 + strlen((char *) F) - 1);
+                       if (buf1) {
+                               // we found the "find" pattern - delete it
+                               text_hole_delete(buf1, buf1 + strlen(F) - 1);
                                // inset the "replace" patern
-                               (void) string_insert(buf1, R);  // insert the string
+                               string_insert(buf1, R); // insert the string
                                // check for "global"  :s/foo/bar/g
                                if (gflag == 1) {
-                                       if ((buf1 + strlen((char *) R)) < end_line(ls)) {
-                                               q = buf1 + strlen((char *) R);
+                                       if ((buf1 + strlen(R)) < end_line(ls)) {
+                                               q = buf1 + strlen(R);
                                                goto vc4;       // don't let q move past cur line
                                        }
                                }
                        }
                        q = next_line(ls);
                }
-#endif                                                 /* CONFIG_FEATURE_VI_SEARCH */
-       } else if (strncasecmp((char *) cmd, "version", i) == 0) {      // show software version
-               psb("%s", vi_Version);
-       } else if (strncasecmp((char *) cmd, "write", i) == 0           // write text to file
-                       || strncasecmp((char *) cmd, "wq", i) == 0
-                       || strncasecmp((char *) cmd, "wn", i) == 0
-                       || strncasecmp((char *) cmd, "x", i) == 0) {
+#endif /* FEATURE_VI_SEARCH */
+       } else if (strncasecmp(cmd, "version", i) == 0) {  // show software version
+               psb("%s", BB_VER " " BB_BT);
+       } else if (strncasecmp(cmd, "write", i) == 0  // write text to file
+               || strncasecmp(cmd, "wq", i) == 0
+               || strncasecmp(cmd, "wn", i) == 0
+               || strncasecmp(cmd, "x", i) == 0
+       ) {
                // is there a file name to write to?
-               if (strlen((char *) args) > 0) {
+               if (args[0]) {
                        fn = args;
                }
-#ifdef CONFIG_FEATURE_VI_READONLY
-               if ((vi_readonly || readonly) && ! useforce) {
+#if ENABLE_FEATURE_VI_READONLY
+               if ((vi_readonly || readonly) && !useforce) {
                        psbs("\"%s\" File is read only", fn);
                        goto vc3;
                }
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
+#endif
                // how many lines in text[]?
                li = count_lines(q, r);
                ch = r - q + 1;
@@ -1118,11 +1117,11 @@ static void colon(Byte * buf)
                                editing = 0;
                        }
                }
-#ifdef CONFIG_FEATURE_VI_READONLY
        vc3:;
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
-#ifdef CONFIG_FEATURE_VI_YANKMARK
-       } else if (strncasecmp((char *) cmd, "yank", i) == 0) { // yank lines
+#if ENABLE_FEATURE_VI_READONLY
+ vc3:;
+#endif
+#if ENABLE_FEATURE_VI_YANKMARK
+       } else if (strncasecmp(cmd, "yank", i) == 0) {  // yank lines
                if (b < 0) {    // no addr given- use defaults
                        q = begin_line(dot);    // assume .,. for the range
                        r = end_line(dot);
@@ -1130,22 +1129,22 @@ static void colon(Byte * buf)
                text_yank(q, r, YDreg);
                li = count_lines(q, r);
                psb("Yank %d lines (%d chars) into [%c]",
-                       li, strlen((char *) reg[YDreg]), what_reg());
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+                               li, strlen(reg[YDreg]), what_reg());
+#endif
        } else {
                // cmd unknown
-               ni((Byte *) cmd);
+               ni(cmd);
        }
 vc1:
+ vc1:
        dot = bound_dot(dot);   // make sure "dot" is valid
        return;
-#ifdef CONFIG_FEATURE_VI_SEARCH
-colon_s_fail:
+#if ENABLE_FEATURE_VI_SEARCH
+ colon_s_fail:
        psb(":s expression missing delimiters");
 #endif
 }
 
-#endif                                                 /* CONFIG_FEATURE_VI_COLON */
+#endif /* FEATURE_VI_COLON */
 
 static void Hit_Return(void)
 {
@@ -1160,24 +1159,22 @@ static void Hit_Return(void)
 }
 
 //----- Synchronize the cursor to Dot --------------------------
-static void sync_cursor(Byte * d, int *row, int *col)
+static void sync_cursor(char * d, int *row, int *col)
 {
-       Byte *beg_cur, *end_cur;        // begin and end of "d" line
-       Byte *beg_scr, *end_scr;        // begin and end of screen
-       Byte *tp;
+       char *beg_cur;  // begin and end of "d" line
+       char *end_scr;  // begin and end of screen
+       char *tp;
        int cnt, ro, co;
 
        beg_cur = begin_line(d);        // first char of cur line
-       end_cur = end_line(d);  // last char of cur line
 
-       beg_scr = end_scr = screenbegin;        // first char of screen
        end_scr = end_screen(); // last char of screen
 
        if (beg_cur < screenbegin) {
                // "d" is before  top line on screen
                // how many lines do we have to move
                cnt = count_lines(beg_cur, screenbegin);
        sc1:
+ sc1:
                screenbegin = beg_cur;
                if (cnt > (rows - 1) / 2) {
                        // we moved too many lines. put "dot" in middle of screen
@@ -1251,51 +1248,51 @@ static void sync_cursor(Byte * d, int *row, int *col)
 }
 
 //----- Text Movement Routines ---------------------------------
-static Byte *begin_line(Byte * p) // return pointer to first char cur line
+static char *begin_line(char * p) // return pointer to first char cur line
 {
        while (p > text && p[-1] != '\n')
                p--;                    // go to cur line B-o-l
-       return (p);
+       return p;
 }
 
-static Byte *end_line(Byte * p) // return pointer to NL of cur line line
+static char *end_line(char * p) // return pointer to NL of cur line line
 {
        while (p < end - 1 && *p != '\n')
                p++;                    // go to cur line E-o-l
-       return (p);
+       return p;
 }
 
-static inline Byte *dollar_line(Byte * p) // return pointer to just before NL line
+static inline char *dollar_line(char * p) // return pointer to just before NL line
 {
        while (p < end - 1 && *p != '\n')
                p++;                    // go to cur line E-o-l
        // Try to stay off of the Newline
        if (*p == '\n' && (p - begin_line(p)) > 0)
                p--;
-       return (p);
+       return p;
 }
 
-static Byte *prev_line(Byte * p) // return pointer first char prev line
+static char *prev_line(char * p) // return pointer first char prev line
 {
        p = begin_line(p);      // goto begining of cur line
        if (p[-1] == '\n' && p > text)
                p--;                    // step to prev line
        p = begin_line(p);      // goto begining of prev line
-       return (p);
+       return p;
 }
 
-static Byte *next_line(Byte * p) // return pointer first char next line
+static char *next_line(char * p) // return pointer first char next line
 {
        p = end_line(p);
        if (*p == '\n' && p < end - 1)
                p++;                    // step to next line
-       return (p);
+       return p;
 }
 
 //----- Text Information Routines ------------------------------
-static Byte *end_screen(void)
+static char *end_screen(void)
 {
-       Byte *q;
+       char *q;
        int cnt;
 
        // find new bottom line
@@ -1303,12 +1300,12 @@ static Byte *end_screen(void)
        for (cnt = 0; cnt < rows - 2; cnt++)
                q = next_line(q);
        q = end_line(q);
-       return (q);
+       return q;
 }
 
-static int count_lines(Byte * start, Byte * stop) // count line from start to stop
+static int count_lines(char * start, char * stop) // count line from start to stop
 {
-       Byte *q;
+       char *q;
        int cnt;
 
        if (stop < start) {     // start and stop are backwards- reverse them
@@ -1322,17 +1319,17 @@ static int count_lines(Byte * start, Byte * stop) // count line from start to st
                if (*q == '\n')
                        cnt++;
        }
-       return (cnt);
+       return cnt;
 }
 
-static Byte *find_line(int li) // find begining of line #li
+static char *find_line(int li) // find begining of line #li
 {
-       Byte *q;
+       char *q;
 
        for (q = text; li > 1; li--) {
                q = next_line(q);
        }
-       return (q);
+       return q;
 }
 
 //----- Dot Movement Routines ----------------------------------
@@ -1358,7 +1355,7 @@ static void dot_end(void)
        dot = end_line(dot);    // return pointer to last char cur line
 }
 
-static Byte *move_to_col(Byte * p, int l)
+static char *move_to_col(char * p, int l)
 {
        int co;
 
@@ -1374,7 +1371,7 @@ static Byte *move_to_col(Byte * p, int l)
                        co++;           // display as ^X, use 2 columns
                }
        } while (++co <= l && p++ < end);
-       return (p);
+       return p;
 }
 
 static void dot_next(void)
@@ -1389,7 +1386,7 @@ static void dot_prev(void)
 
 static void dot_scroll(int cnt, int dir)
 {
-       Byte *q;
+       char *q;
 
        for (; cnt > 0; cnt--) {
                if (dir < 0) {
@@ -1420,10 +1417,10 @@ static void dot_skip_over_ws(void)
 
 static void dot_delete(void)   // delete the char at 'dot'
 {
-       (void) text_hole_delete(dot, dot);
+       text_hole_delete(dot, dot);
 }
 
-static Byte *bound_dot(Byte * p) // make sure  text[0] <= P < "end"
+static char *bound_dot(char * p) // make sure  text[0] <= P < "end"
 {
        if (p >= end && end > text) {
                p = end - 1;
@@ -1433,7 +1430,7 @@ static Byte *bound_dot(Byte * p) // make sure  text[0] <= P < "end"
                p = text;
                indicate_error('2');
        }
-       return (p);
+       return p;
 }
 
 //----- Helper Utility Routines --------------------------------
@@ -1449,63 +1446,62 @@ static Byte *bound_dot(Byte * p) // make sure  text[0] <= P < "end"
  * DO NOT COUNT NEWLINE AS WHITESPACE
  */
 
-static Byte *new_screen(int ro, int co)
+static char *new_screen(int ro, int co)
 {
        int li;
 
        free(screen);
        screensize = ro * co + 8;
-       screen = (Byte *) xmalloc(screensize);
+       screen = xmalloc(screensize);
        // initialize the new screen. assume this will be a empty file.
        screen_erase();
        //   non-existent text[] lines start with a tilde (~).
        for (li = 1; li < ro - 1; li++) {
                screen[(li * co) + 0] = '~';
        }
-       return (screen);
+       return screen;
 }
 
-static Byte *new_text(int size)
+static char *new_text(int size)
 {
        if (size < 10240)
                size = 10240;   // have a minimum size for new files
        free(text);
-       text = (Byte *) xmalloc(size + 8);
+       text = xmalloc(size + 8);
        memset(text, '\0', size);       // clear new text[]
        //text += 4;            // leave some room for "oops"
-       textend = text + size - 1;
-       //textend -= 4;         // leave some root for "oops"
-       return (text);
+       return text;
 }
 
-#ifdef CONFIG_FEATURE_VI_SEARCH
-static int mycmp(Byte * s1, Byte * s2, int len)
+#if ENABLE_FEATURE_VI_SEARCH
+static int mycmp(const char * s1, const char * s2, int len)
 {
        int i;
 
-       i = strncmp((char *) s1, (char *) s2, len);
-#ifdef CONFIG_FEATURE_VI_SETOPTS
+       i = strncmp(s1, s2, len);
+#if ENABLE_FEATURE_VI_SETOPTS
        if (ignorecase) {
-               i = strncasecmp((char *) s1, (char *) s2, len);
+               i = strncasecmp(s1, s2, len);
        }
-#endif                                                 /* CONFIG_FEATURE_VI_SETOPTS */
-       return (i);
+#endif
+       return i;
 }
 
-static Byte *char_search(Byte * p, Byte * pat, int dir, int range)     // search for pattern starting at p
+// search for pattern starting at p
+static char *char_search(char * p, const char * pat, int dir, int range)
 {
 #ifndef REGEX_SEARCH
-       Byte *start, *stop;
+       char *start, *stop;
        int len;
 
-       len = strlen((char *) pat);
+       len = strlen(pat);
        if (dir == FORWARD) {
                stop = end - 1; // assume range is p - end-1
                if (range == LIMITED)
                        stop = next_line(p);    // range is to next line
                for (start = p; start < stop; start++) {
                        if (mycmp(start, pat, len) == 0) {
-                               return (start);
+                               return start;
                        }
                }
        } else if (dir == BACK) {
@@ -1514,13 +1510,13 @@ static Byte *char_search(Byte * p, Byte * pat, int dir, int range)      // search for
                        stop = prev_line(p);    // range is to prev line
                for (start = p - len; start >= stop; start--) {
                        if (mycmp(start, pat, len) == 0) {
-                               return (start);
+                               return start;
                        }
                }
        }
        // pattern not found
-       return (NULL);
-#else                                                  /*REGEX_SEARCH */
+       return NULL;
+#else /* REGEX_SEARCH */
        char *q;
        struct re_pattern_buffer preg;
        int i;
@@ -1547,7 +1543,7 @@ static Byte *char_search(Byte * p, Byte * pat, int dir, int range)        // search for
        // RANGE could be negative if we are searching backwards
        range = q - p;
 
-       q = (char *) re_compile_pattern(pat, strlen((char *) pat), &preg);
+       q = re_compile_pattern(pat, strlen(pat), &preg);
        if (q != 0) {
                // The pattern was not compiled
                psbs("bad search pattern: \"%s\": %s", pat, q);
@@ -1574,18 +1570,18 @@ static Byte *char_search(Byte * p, Byte * pat, int dir, int range)      // search for
                p = 0;
                i = 0;                  // return NULL if pattern not found
        }
 cs1:
+ cs1:
        if (dir == FORWARD) {
                p = p + i;
        } else {
                p = p - i;
        }
-       return (p);
-#endif                                                 /*REGEX_SEARCH */
+       return p;
+#endif /* REGEX_SEARCH */
 }
-#endif                                                 /* CONFIG_FEATURE_VI_SEARCH */
+#endif /* FEATURE_VI_SEARCH */
 
-static Byte *char_insert(Byte * p, Byte c) // insert the char c at 'p'
+static char *char_insert(char * p, char c) // insert the char c at 'p'
 {
        if (c == 22) {          // Is this an ctrl-V?
                p = stupid_insert(p, '^');      // use ^ to indicate literal next
@@ -1600,7 +1596,7 @@ static Byte *char_insert(Byte * p, Byte c) // insert the char c at 'p'
                cmdcnt = 0;
                end_cmd_q();    // stop adding to q
                last_status_cksum = 0;  // force status update
-               if ((p[-1] != '\n') && (dot>text)) {
+               if ((p[-1] != '\n') && (dot > text)) {
                        p--;
                }
        } else if (c == erase_char || c == 8 || c == 127) { // Is this a BS
@@ -1611,30 +1607,30 @@ static Byte *char_insert(Byte * p, Byte c) // insert the char c at 'p'
                }
        } else {
                // insert a char into text[]
-               Byte *sp;               // "save p"
+               char *sp;               // "save p"
 
                if (c == 13)
                        c = '\n';       // translate \r to \n
                sp = p;                 // remember addr of insert
                p = stupid_insert(p, c);        // insert the char
-#ifdef CONFIG_FEATURE_VI_SETOPTS
+#if ENABLE_FEATURE_VI_SETOPTS
                if (showmatch && strchr(")]}", *sp) != NULL) {
                        showmatching(sp);
                }
                if (autoindent && c == '\n') {  // auto indent the new line
-                       Byte *q;
+                       char *q;
 
                        q = prev_line(p);       // use prev line as templet
                        for (; isblnk(*q); q++) {
                                p = stupid_insert(p, *q);       // insert the char
                        }
                }
-#endif                                                 /* CONFIG_FEATURE_VI_SETOPTS */
+#endif
        }
-       return (p);
+       return p;
 }
 
-static Byte *stupid_insert(Byte * p, Byte c) // stupidly insert the char c at 'p'
+static char *stupid_insert(char * p, char c) // stupidly insert the char c at 'p'
 {
        p = text_hole_make(p, 1);
        if (p != 0) {
@@ -1642,12 +1638,12 @@ static Byte *stupid_insert(Byte * p, Byte c) // stupidly insert the char c at 'p
                file_modified++;        // has the file been modified
                p++;
        }
-       return (p);
+       return p;
 }
 
-static Byte find_range(Byte ** start, Byte ** stop, Byte c)
+static char find_range(char ** start, char ** stop, char c)
 {
-       Byte *save_dot, *p, *q;
+       char *save_dot, *p, *q;
        int cnt;
 
        save_dot = dot;
@@ -1699,12 +1695,12 @@ static Byte find_range(Byte ** start, Byte ** stop, Byte c)
                *stop = p;
        }
        dot = save_dot;
-       return (c);
+       return c;
 }
 
-static int st_test(Byte * p, int type, int dir, Byte * tested)
+static int st_test(char * p, int type, int dir, char * tested)
 {
-       Byte c, c0, ci;
+       char c, c0, ci;
        int test, inc;
 
        inc = dir;
@@ -1733,12 +1729,12 @@ static int st_test(Byte * p, int type, int dir, Byte * tested)
                test = ((isalnum(c)) || c == '_');
        }
        *tested = c;
-       return (test);
+       return test;
 }
 
-static Byte *skip_thing(Byte * p, int linecnt, int dir, int type)
+static char *skip_thing(char * p, int linecnt, int dir, int type)
 {
-       Byte c;
+       char c;
 
        while (st_test(p, type, dir, &c)) {
                // make sure we limit search to correct number of lines
@@ -1750,13 +1746,13 @@ static Byte *skip_thing(Byte * p, int linecnt, int dir, int type)
                        break;
                p += dir;               // move to next char
        }
-       return (p);
+       return p;
 }
 
 // find matching char of pair  ()  []  {}
-static Byte *find_pair(Byte * p, Byte c)
+static char *find_pair(char * p, char c)
 {
-       Byte match, *q;
+       char match, *q;
        int dir, level;
 
        match = ')';
@@ -1796,14 +1792,14 @@ static Byte *find_pair(Byte * p, Byte c)
        }
        if (level != 0)
                q = NULL;               // indicate no match
-       return (q);
+       return q;
 }
 
-#ifdef CONFIG_FEATURE_VI_SETOPTS
+#if ENABLE_FEATURE_VI_SETOPTS
 // show the matching char of a pair,  ()  []  {}
-static void showmatching(Byte * p)
+static void showmatching(char * p)
 {
-       Byte *q, *save_dot;
+       char *q, *save_dot;
 
        // we found half of a pair
        q = find_pair(p, *p);   // get loc of matching char
@@ -1814,17 +1810,17 @@ static void showmatching(Byte * p)
                save_dot = dot; // remember where we are
                dot = q;                // go to new loc
                refresh(FALSE); // let the user see it
-               (void) mysleep(40);     // give user some time
+               mysleep(40);    // give user some time
                dot = save_dot; // go back to old loc
                refresh(FALSE);
        }
 }
-#endif                                                 /* CONFIG_FEATURE_VI_SETOPTS */
+#endif /* FEATURE_VI_SETOPTS */
 
 //  open a hole in text[]
-static Byte *text_hole_make(Byte * p, int size)        // at "p", make a 'size' byte hole
+static char *text_hole_make(char * p, int size)        // at "p", make a 'size' byte hole
 {
-       Byte *src, *dest;
+       char *src, *dest;
        int cnt;
 
        if (size <= 0)
@@ -1838,14 +1834,14 @@ static Byte *text_hole_make(Byte * p, int size) // at "p", make a 'size' byte ho
        memset(p, ' ', size);   // clear new hole
        end = end + size;       // adjust the new END
        file_modified++;        // has the file been modified
 thm0:
-       return (p);
+ thm0:
+       return p;
 }
 
 //  close a hole in text[]
-static Byte *text_hole_delete(Byte * p, Byte * q) // delete "p" thru "q", inclusive
+static char *text_hole_delete(char * p, char * q) // delete "p" thru "q", inclusive
 {
-       Byte *src, *dest;
+       char *src, *dest;
        int cnt, hole_size;
 
        // move forwards, from beginning
@@ -1867,23 +1863,23 @@ static Byte *text_hole_delete(Byte * p, Byte * q) // delete "p" thru "q", inclus
        if (memmove(dest, src, cnt) != dest) {
                psbs("can't delete the character");
        }
 thd_atend:
+ thd_atend:
        end = end - hole_size;  // adjust the new END
        if (dest >= end)
                dest = end - 1; // make sure dest in below end-1
        if (end <= text)
                dest = end = text;      // keep pointers valid
        file_modified++;        // has the file been modified
 thd0:
-       return (dest);
+ thd0:
+       return dest;
 }
 
 // copy text into register, then delete text.
 // if dist <= 0, do not include, or go past, a NewLine
 //
-static Byte *yank_delete(Byte * start, Byte * stop, int dist, int yf)
+static char *yank_delete(char * start, char * stop, int dist, int yf)
 {
-       Byte *p;
+       char *p;
 
        // make sure start <= stop
        if (start > stop) {
@@ -1893,10 +1889,10 @@ static Byte *yank_delete(Byte * start, Byte * stop, int dist, int yf)
                stop = p;
        }
        if (dist <= 0) {
-               // we can not cross NL boundaries
+               // we cannot cross NL boundaries
                p = start;
                if (*p == '\n')
-                       return (p);
+                       return p;
                // dont go past a NewLine
                for (; p + 1 <= stop; p++) {
                        if (p[1] == '\n') {
@@ -1906,93 +1902,92 @@ static Byte *yank_delete(Byte * start, Byte * stop, int dist, int yf)
                }
        }
        p = start;
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
        text_yank(start, stop, YDreg);
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+#endif
        if (yf == YANKDEL) {
                p = text_hole_delete(start, stop);
        }                                       // delete lines
-       return (p);
+       return p;
 }
 
 static void show_help(void)
 {
        puts("These features are available:"
-#ifdef CONFIG_FEATURE_VI_SEARCH
+#if ENABLE_FEATURE_VI_SEARCH
        "\n\tPattern searches with / and ?"
-#endif                                                 /* CONFIG_FEATURE_VI_SEARCH */
-#ifdef CONFIG_FEATURE_VI_DOT_CMD
+#endif
+#if ENABLE_FEATURE_VI_DOT_CMD
        "\n\tLast command repeat with \'.\'"
-#endif                                                 /* CONFIG_FEATURE_VI_DOT_CMD */
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#endif
+#if ENABLE_FEATURE_VI_YANKMARK
        "\n\tLine marking with  'x"
        "\n\tNamed buffers with  \"x"
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
-#ifdef CONFIG_FEATURE_VI_READONLY
+#endif
+#if ENABLE_FEATURE_VI_READONLY
        "\n\tReadonly if vi is called as \"view\""
        "\n\tReadonly with -R command line arg"
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
-#ifdef CONFIG_FEATURE_VI_SET
+#endif
+#if ENABLE_FEATURE_VI_SET
        "\n\tSome colon mode commands with \':\'"
-#endif                                                 /* CONFIG_FEATURE_VI_SET */
-#ifdef CONFIG_FEATURE_VI_SETOPTS
+#endif
+#if ENABLE_FEATURE_VI_SETOPTS
        "\n\tSettable options with \":set\""
-#endif                                                 /* CONFIG_FEATURE_VI_SETOPTS */
-#ifdef CONFIG_FEATURE_VI_USE_SIGNALS
+#endif
+#if ENABLE_FEATURE_VI_USE_SIGNALS
        "\n\tSignal catching- ^C"
        "\n\tJob suspend and resume with ^Z"
-#endif                                                 /* CONFIG_FEATURE_VI_USE_SIGNALS */
-#ifdef CONFIG_FEATURE_VI_WIN_RESIZE
+#endif
+#if ENABLE_FEATURE_VI_WIN_RESIZE
        "\n\tAdapt to window re-sizes"
-#endif                                                 /* CONFIG_FEATURE_VI_WIN_RESIZE */
+#endif
        );
 }
 
-static inline void print_literal(Byte * buf, Byte * s) // copy s to buf, convert unprintable
+static inline void print_literal(char * buf, const char * s) // copy s to buf, convert unprintable
 {
-       Byte c, b[2];
+       unsigned char c;
+       char b[2];
 
        b[1] = '\0';
-       strcpy((char *) buf, "");       // init buf
-       if (strlen((char *) s) <= 0)
-               s = (Byte *) "(NULL)";
-       for (; *s > '\0'; s++) {
+       buf[0] = '\0';
+       if (!s[0])
+               s = "(NULL)";
+       for (; *s; s++) {
                int c_is_no_print;
 
                c = *s;
-               c_is_no_print = c > 127 && !Isprint(c);
+               c_is_no_print = (c & 0x80) && !Isprint(c);
                if (c_is_no_print) {
-                       strcat((char *) buf, SOn);
+                       strcat(buf, SOn);
                        c = '.';
                }
                if (c < ' ' || c == 127) {
-                       strcat((char *) buf, "^");
-                       if(c == 127)
+                       strcat(buf, "^");
+                       if (c == 127)
                                c = '?';
-                        else
-                       c += '@';
+                       else
+                               c += '@';
                }
                b[0] = c;
-               strcat((char *) buf, (char *) b);
+               strcat(buf, b);
                if (c_is_no_print)
-                       strcat((char *) buf, SOs);
-               if (*s == '\n') {
-                       strcat((char *) buf, "$");
-               }
+                       strcat(buf, SOs);
+               if (*s == '\n')
+                       strcat(buf, "$");
        }
 }
 
-#ifdef CONFIG_FEATURE_VI_DOT_CMD
-static void start_new_cmd_q(Byte c)
+#if ENABLE_FEATURE_VI_DOT_CMD
+static void start_new_cmd_q(char c)
 {
        // release old cmd
        free(last_modifying_cmd);
        // get buffer for new cmd
-       last_modifying_cmd = (Byte *) xmalloc(BUFSIZ);
-       memset(last_modifying_cmd, '\0', BUFSIZ);       // clear new cmd queue
+       last_modifying_cmd = xzalloc(MAX_LINELEN);
        // if there is a current cmd count put it in the buffer first
        if (cmdcnt > 0)
-               sprintf((char *) last_modifying_cmd, "%d%c", cmdcnt, c);
+               sprintf(last_modifying_cmd, "%d%c", cmdcnt, c);
        else // just save char c onto queue
                last_modifying_cmd[0] = c;
        adding2q = 1;
@@ -2000,37 +1995,38 @@ static void start_new_cmd_q(Byte c)
 
 static void end_cmd_q(void)
 {
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
        YDreg = 26;                     // go back to default Yank/Delete reg
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+#endif
        adding2q = 0;
-       return;
 }
-#endif                                                 /* CONFIG_FEATURE_VI_DOT_CMD */
+#endif /* FEATURE_VI_DOT_CMD */
 
-#if defined(CONFIG_FEATURE_VI_YANKMARK) || defined(CONFIG_FEATURE_VI_SEARCH) || defined(CONFIG_FEATURE_VI_CRASHME)
-static Byte *string_insert(Byte * p, Byte * s) // insert the string at 'p'
+#if ENABLE_FEATURE_VI_YANKMARK \
+ || (ENABLE_FEATURE_VI_COLON && ENABLE_FEATURE_VI_SEARCH) \
+ || ENABLE_FEATURE_VI_CRASHME
+static char *string_insert(char * p, char * s) // insert the string at 'p'
 {
        int cnt, i;
 
-       i = strlen((char *) s);
+       i = strlen(s);
        p = text_hole_make(p, i);
-       strncpy((char *) p, (char *) s, i);
+       strncpy(p, s, i);
        for (cnt = 0; *s != '\0'; s++) {
                if (*s == '\n')
                        cnt++;
        }
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
        psb("Put %d lines (%d chars) from [%c]", cnt, i, what_reg());
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
-       return (p);
+#endif
+       return p;
 }
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK || CONFIG_FEATURE_VI_COLON || CONFIG_FEATURE_VI_CRASHME */
+#endif
 
-#ifdef CONFIG_FEATURE_VI_YANKMARK
-static Byte *text_yank(Byte * p, Byte * q, int dest)   // copy text into a register
+#if ENABLE_FEATURE_VI_YANKMARK
+static char *text_yank(char * p, char * q, int dest)   // copy text into a register
 {
-       Byte *t;
+       char *t;
        int cnt;
 
        if (q < p) {            // they are backwards- reverse them
@@ -2041,36 +2037,34 @@ static Byte *text_yank(Byte * p, Byte * q, int dest)    // copy text into a registe
        cnt = q - p + 1;
        t = reg[dest];
        free(t);                //  if already a yank register, free it
-       t = (Byte *) xmalloc(cnt + 1);  // get a new register
+       t = xmalloc(cnt + 1);   // get a new register
        memset(t, '\0', cnt + 1);       // clear new text[]
-       strncpy((char *) t, (char *) p, cnt);   // copy text[] into bufer
+       strncpy(t, p, cnt);     // copy text[] into bufer
        reg[dest] = t;
-       return (p);
+       return p;
 }
 
-static Byte what_reg(void)
+static char what_reg(void)
 {
-       Byte c;
-       int i;
+       char c;
 
-       i = 0;
        c = 'D';                        // default to D-reg
        if (0 <= YDreg && YDreg <= 25)
-               c = 'a' + (Byte) YDreg;
+               c = 'a' + (char) YDreg;
        if (YDreg == 26)
                c = 'D';
        if (YDreg == 27)
                c = 'U';
-       return (c);
+       return c;
 }
 
-static void check_context(Byte cmd)
+static void check_context(char cmd)
 {
        // A context is defined to be "modifying text"
        // Any modifying command establishes a new context.
 
        if (dot < context_start || dot > context_end) {
-               if (strchr((char *) modifying_cmds, cmd) != NULL) {
+               if (strchr(modifying_cmds, cmd) != NULL) {
                        // we are trying to modify text[]- make this the current context
                        mark[27] = mark[26];    // move cur to prev
                        mark[26] = dot; // move local to cur
@@ -2079,12 +2073,11 @@ static void check_context(Byte cmd)
                        //loiter= start_loiter= now;
                }
        }
-       return;
 }
 
-static inline Byte *swap_context(Byte * p) // goto new context for '' command make this the current context
+static inline char *swap_context(char * p) // goto new context for '' command make this the current context
 {
-       Byte *tmp;
+       char *tmp;
 
        // the current context is in mark[26]
        // the previous context is in mark[27]
@@ -2097,11 +2090,11 @@ static inline Byte *swap_context(Byte * p) // goto new context for '' command ma
                context_start = prev_line(prev_line(prev_line(p)));
                context_end = next_line(next_line(next_line(p)));
        }
-       return (p);
+       return p;
 }
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+#endif /* FEATURE_VI_YANKMARK */
 
-static int isblnk(Byte c) // is the char a blank or tab
+static int isblnk(char c) // is the char a blank or tab
 {
        return (c == ' ' || c == '\t');
 }
@@ -2127,13 +2120,12 @@ static void cookmode(void)
 }
 
 //----- Come here when we get a window resize signal ---------
-#ifdef CONFIG_FEATURE_VI_USE_SIGNALS
+#if ENABLE_FEATURE_VI_USE_SIGNALS
 static void winch_sig(int sig ATTRIBUTE_UNUSED)
 {
        signal(SIGWINCH, winch_sig);
-#ifdef CONFIG_FEATURE_VI_WIN_RESIZE
-       window_size_get(0);
-#endif                                                 /* CONFIG_FEATURE_VI_WIN_RESIZE */
+       if (ENABLE_FEATURE_VI_WIN_RESIZE)
+               get_terminal_width_height(0, &columns, &rows);
        new_screen(rows, columns);      // get memory for virtual screen
        redraw(TRUE);           // re-draw the screen
 }
@@ -2165,37 +2157,17 @@ static void suspend_sig(int sig ATTRIBUTE_UNUSED)
 //----- Come here when we get a signal ---------------------------
 static void catch_sig(int sig)
 {
-       signal(SIGHUP, catch_sig);
        signal(SIGINT, catch_sig);
-       signal(SIGTERM, catch_sig);
-       signal(SIGALRM, catch_sig);
-       if(sig)
+       if (sig)
                longjmp(restart, sig);
 }
-
-//----- Come here when we get a core dump signal -----------------
-static void core_sig(int sig)
-{
-       signal(SIGQUIT, core_sig);
-       signal(SIGILL, core_sig);
-       signal(SIGTRAP, core_sig);
-       signal(SIGABRT, core_sig);
-       signal(SIGFPE, core_sig);
-       signal(SIGBUS, core_sig);
-       signal(SIGSEGV, core_sig);
-#ifdef SIGSYS
-       signal(SIGSYS, core_sig);
-#endif
-
-       if(sig) {       // signaled
-               dot = bound_dot(dot);   // make sure "dot" is valid
-               longjmp(restart, sig);
-       }
-}
-#endif                                                 /* CONFIG_FEATURE_VI_USE_SIGNALS */
+#endif /* FEATURE_VI_USE_SIGNALS */
 
 static int mysleep(int hund)   // sleep for 'h' 1/100 seconds
 {
+       fd_set rfds;
+       struct timeval tv;
+
        // Don't hang- Wait 5/100 seconds-  1 Sec= 1000000
        fflush(stdout);
        FD_ZERO(&rfds);
@@ -2203,7 +2175,7 @@ static int mysleep(int hund)      // sleep for 'h' 1/100 seconds
        tv.tv_sec = 0;
        tv.tv_usec = hund * 10000;
        select(1, &rfds, NULL, NULL, &tv);
-       return (FD_ISSET(0, &rfds));
+       return FD_ISSET(0, &rfds);
 }
 
 #define readbuffer bb_common_bufsiz1
@@ -2211,61 +2183,60 @@ static int mysleep(int hund)    // sleep for 'h' 1/100 seconds
 static int readed_for_parse;
 
 //----- IO Routines --------------------------------------------
-static Byte readit(void)       // read (maybe cursor) key from stdin
+static char readit(void)       // read (maybe cursor) key from stdin
 {
-       Byte c;
+       char c;
        int n;
        struct esc_cmds {
                const char *seq;
-               Byte val;
+               char val;
        };
 
        static const struct esc_cmds esccmds[] = {
-               {"OA", (Byte) VI_K_UP},       // cursor key Up
-               {"OB", (Byte) VI_K_DOWN},     // cursor key Down
-               {"OC", (Byte) VI_K_RIGHT},    // Cursor Key Right
-               {"OD", (Byte) VI_K_LEFT},     // cursor key Left
-               {"OH", (Byte) VI_K_HOME},     // Cursor Key Home
-               {"OF", (Byte) VI_K_END},      // Cursor Key End
-               {"[A", (Byte) VI_K_UP},       // cursor key Up
-               {"[B", (Byte) VI_K_DOWN},     // cursor key Down
-               {"[C", (Byte) VI_K_RIGHT},    // Cursor Key Right
-               {"[D", (Byte) VI_K_LEFT},     // cursor key Left
-               {"[H", (Byte) VI_K_HOME},     // Cursor Key Home
-               {"[F", (Byte) VI_K_END},      // Cursor Key End
-               {"[1~", (Byte) VI_K_HOME},     // Cursor Key Home
-               {"[2~", (Byte) VI_K_INSERT},  // Cursor Key Insert
-               {"[4~", (Byte) VI_K_END},      // Cursor Key End
-               {"[5~", (Byte) VI_K_PAGEUP},  // Cursor Key Page Up
-               {"[6~", (Byte) VI_K_PAGEDOWN},        // Cursor Key Page Down
-               {"OP", (Byte) VI_K_FUN1},     // Function Key F1
-               {"OQ", (Byte) VI_K_FUN2},     // Function Key F2
-               {"OR", (Byte) VI_K_FUN3},     // Function Key F3
-               {"OS", (Byte) VI_K_FUN4},     // Function Key F4
-               {"[15~", (Byte) VI_K_FUN5},   // Function Key F5
-               {"[17~", (Byte) VI_K_FUN6},   // Function Key F6
-               {"[18~", (Byte) VI_K_FUN7},   // Function Key F7
-               {"[19~", (Byte) VI_K_FUN8},   // Function Key F8
-               {"[20~", (Byte) VI_K_FUN9},   // Function Key F9
-               {"[21~", (Byte) VI_K_FUN10},  // Function Key F10
-               {"[23~", (Byte) VI_K_FUN11},  // Function Key F11
-               {"[24~", (Byte) VI_K_FUN12},  // Function Key F12
-               {"[11~", (Byte) VI_K_FUN1},   // Function Key F1
-               {"[12~", (Byte) VI_K_FUN2},   // Function Key F2
-               {"[13~", (Byte) VI_K_FUN3},   // Function Key F3
-               {"[14~", (Byte) VI_K_FUN4},   // Function Key F4
+               {"OA", VI_K_UP},       // cursor key Up
+               {"OB", VI_K_DOWN},     // cursor key Down
+               {"OC", VI_K_RIGHT},    // Cursor Key Right
+               {"OD", VI_K_LEFT},     // cursor key Left
+               {"OH", VI_K_HOME},     // Cursor Key Home
+               {"OF", VI_K_END},      // Cursor Key End
+               {"[A", VI_K_UP},       // cursor key Up
+               {"[B", VI_K_DOWN},     // cursor key Down
+               {"[C", VI_K_RIGHT},    // Cursor Key Right
+               {"[D", VI_K_LEFT},     // cursor key Left
+               {"[H", VI_K_HOME},     // Cursor Key Home
+               {"[F", VI_K_END},      // Cursor Key End
+               {"[1~", VI_K_HOME},    // Cursor Key Home
+               {"[2~", VI_K_INSERT},  // Cursor Key Insert
+               {"[4~", VI_K_END},     // Cursor Key End
+               {"[5~", VI_K_PAGEUP},  // Cursor Key Page Up
+               {"[6~", VI_K_PAGEDOWN},// Cursor Key Page Down
+               {"OP", VI_K_FUN1},     // Function Key F1
+               {"OQ", VI_K_FUN2},     // Function Key F2
+               {"OR", VI_K_FUN3},     // Function Key F3
+               {"OS", VI_K_FUN4},     // Function Key F4
+               {"[15~", VI_K_FUN5},   // Function Key F5
+               {"[17~", VI_K_FUN6},   // Function Key F6
+               {"[18~", VI_K_FUN7},   // Function Key F7
+               {"[19~", VI_K_FUN8},   // Function Key F8
+               {"[20~", VI_K_FUN9},   // Function Key F9
+               {"[21~", VI_K_FUN10},  // Function Key F10
+               {"[23~", VI_K_FUN11},  // Function Key F11
+               {"[24~", VI_K_FUN12},  // Function Key F12
+               {"[11~", VI_K_FUN1},   // Function Key F1
+               {"[12~", VI_K_FUN2},   // Function Key F2
+               {"[13~", VI_K_FUN3},   // Function Key F3
+               {"[14~", VI_K_FUN4},   // Function Key F4
        };
+       enum { ESCCMDS_COUNT = ARRAY_SIZE(esccmds) };
 
-#define ESCCMDS_COUNT (sizeof(esccmds)/sizeof(struct esc_cmds))
-
-       (void) alarm(0);        // turn alarm OFF while we wait for input
+       alarm(0);       // turn alarm OFF while we wait for input
        fflush(stdout);
        n = readed_for_parse;
        // get input from User- are there already input chars in Q?
        if (n <= 0) {
        ri0:
+ ri0:
                // the Q is empty, wait for a typed char
-               n = read(0, readbuffer, BUFSIZ - 1);
+               n = read(0, readbuffer, MAX_LINELEN - 1);
                if (n < 0) {
                        if (errno == EINTR)
                                goto ri0;       // interrupted sys call
@@ -2279,22 +2250,25 @@ static Byte readit(void)        // read (maybe cursor) key from stdin
                                editing = 0;
                        errno = 0;
                }
-               if(n <= 0)
+               if (n <= 0)
                        return 0;       // error
                if (readbuffer[0] == 27) {
-       // This is an ESC char. Is this Esc sequence?
-       // Could be bare Esc key. See if there are any
-       // more chars to read after the ESC. This would
-       // be a Function or Cursor Key sequence.
-       FD_ZERO(&rfds);
-       FD_SET(0, &rfds);
-       tv.tv_sec = 0;
-       tv.tv_usec = 50000;     // Wait 5/100 seconds- 1 Sec=1000000
-
-       // keep reading while there are input chars and room in buffer
-                       while (select(1, &rfds, NULL, NULL, &tv) > 0 && n <= (BUFSIZ - 5)) {
-               // read the rest of the ESC string
-                               int r = read(0, (void *) (readbuffer + n), BUFSIZ - n);
+                       fd_set rfds;
+                       struct timeval tv;
+
+                       // This is an ESC char. Is this Esc sequence?
+                       // Could be bare Esc key. See if there are any
+                       // more chars to read after the ESC. This would
+                       // be a Function or Cursor Key sequence.
+                       FD_ZERO(&rfds);
+                       FD_SET(0, &rfds);
+                       tv.tv_sec = 0;
+                       tv.tv_usec = 50000;     // Wait 5/100 seconds- 1 Sec=1000000
+
+                       // keep reading while there are input chars and room in buffer
+                       while (select(1, &rfds, NULL, NULL, &tv) > 0 && n <= (MAX_LINELEN - 5)) {
+                               // read the rest of the ESC string
+                               int r = read(0, (void *) (readbuffer + n), MAX_LINELEN - n);
                                if (r > 0) {
                                        n += r;
                                }
@@ -2303,16 +2277,16 @@ static Byte readit(void)        // read (maybe cursor) key from stdin
                readed_for_parse = n;
        }
        c = readbuffer[0];
-       if(c == 27 && n > 1) {
-       // Maybe cursor or function key?
+       if (c == 27 && n > 1) {
+               // Maybe cursor or function key?
                const struct esc_cmds *eindex;
 
                for (eindex = esccmds; eindex < &esccmds[ESCCMDS_COUNT]; eindex++) {
                        int cnt = strlen(eindex->seq);
 
-                       if(n <= cnt)
+                       if (n <= cnt)
                                continue;
-                       if(strncmp(eindex->seq, (char *) readbuffer + 1, cnt))
+                       if (strncmp(eindex->seq, readbuffer + 1, cnt))
                                continue;
                        // is a Cursor key- put derived value back into Q
                        c = eindex->val;
@@ -2320,7 +2294,7 @@ static Byte readit(void)  // read (maybe cursor) key from stdin
                        n = cnt + 1;
                        break;
                }
-               if(eindex == &esccmds[ESCCMDS_COUNT]) {
+               if (eindex == &esccmds[ESCCMDS_COUNT]) {
                        /* defined ESC sequence not found, set only one ESC */
                        n = 1;
        }
@@ -2329,17 +2303,17 @@ static Byte readit(void)        // read (maybe cursor) key from stdin
        }
        // remove key sequence from Q
        readed_for_parse -= n;
-       memmove(readbuffer, readbuffer + n, BUFSIZ - n);
-       (void) alarm(3);        // we are done waiting for input, turn alarm ON
-       return (c);
+       memmove(readbuffer, readbuffer + n, MAX_LINELEN - n);
+       alarm(3);       // we are done waiting for input, turn alarm ON
+       return c;
 }
 
 //----- IO Routines --------------------------------------------
-static Byte get_one_char(void)
+static char get_one_char(void)
 {
-       static Byte c;
+       static char c;
 
-#ifdef CONFIG_FEATURE_VI_DOT_CMD
+#if ENABLE_FEATURE_VI_DOT_CMD
        // ! adding2q  && ioq == 0  read()
        // ! adding2q  && ioq != 0  *ioq
        // adding2q         *last_modifying_cmd= read()
@@ -2363,8 +2337,8 @@ static Byte get_one_char(void)
                // adding STDIN chars to q
                c = readit();   // get the users input
                if (last_modifying_cmd != 0) {
-                       int len = strlen((char *) last_modifying_cmd);
-                       if (len + 1 >= BUFSIZ) {
+                       int len = strlen(last_modifying_cmd);
+                       if (len >= MAX_LINELEN - 1) {
                                psbs("last_modifying_cmd overrun");
                        } else {
                                // add new char to q
@@ -2372,26 +2346,28 @@ static Byte get_one_char(void)
                        }
                }
        }
-#else                                                  /* CONFIG_FEATURE_VI_DOT_CMD */
+#else
        c = readit();           // get the users input
-#endif                                                 /* CONFIG_FEATURE_VI_DOT_CMD */
-       return (c);                     // return the char, where ever it came from
+#endif /* FEATURE_VI_DOT_CMD */
+       return c;                       // return the char, where ever it came from
 }
 
-static Byte *get_input_line(Byte * prompt) // get input line- use "status line"
+static char *get_input_line(const char * prompt) // get input line- use "status line"
 {
-       Byte buf[BUFSIZ];
-       Byte c;
+       static char *obufp;
+
+       char buf[MAX_LINELEN];
+       char c;
        int i;
-       static Byte *obufp = NULL;
 
-       strcpy((char *) buf, (char *) prompt);
+       strcpy(buf, prompt);
        last_status_cksum = 0;  // force status update
        place_cursor(rows - 1, 0, FALSE);       // go to Status line, bottom of screen
        clear_to_eol();         // clear the line
-       write1((char *) prompt);      // write out the :, /, or ? prompt
+       write1(prompt);      // write out the :, /, or ? prompt
 
-       for (i = strlen((char *) buf); i < BUFSIZ;) {
+       i = strlen(buf);
+       while (i < MAX_LINELEN) {
                c = get_one_char();     // read user input
                if (c == '\n' || c == '\r' || c == 27)
                        break;          // is this end of input
@@ -2413,44 +2389,29 @@ static Byte *get_input_line(Byte * prompt) // get input line- use "status line"
        }
        refresh(FALSE);
        free(obufp);
-       obufp = (Byte *) bb_xstrdup((char *) buf);
-       return (obufp);
+       obufp = xstrdup(buf);
+       return obufp;
 }
 
-static int file_size(const Byte * fn) // what is the byte size of "fn"
+static int file_size(const char * fn) // what is the byte size of "fn"
 {
        struct stat st_buf;
-       int cnt, sr;
+       int cnt;
 
-       if (fn == 0 || strlen((char *)fn) <= 0)
-               return (-1);
        cnt = -1;
-       sr = stat((char *) fn, &st_buf);        // see if file exists
-       if (sr >= 0) {
+       if (fn && fn[0] && stat(fn, &st_buf) == 0)      // see if file exists
                cnt = (int) st_buf.st_size;
-       }
-       return (cnt);
+       return cnt;
 }
 
-static int file_insert(Byte * fn, Byte * p, int size)
+static int file_insert(char *fn, char *p)
 {
-       int fd, cnt;
-
-       cnt = -1;
-#ifdef CONFIG_FEATURE_VI_READONLY
-       readonly = FALSE;
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
-       if (fn == 0 || strlen((char*) fn) <= 0) {
-               psbs("No filename given");
-               goto fi0;
-       }
-       if (size == 0) {
-               // OK- this is just a no-op
-               cnt = 0;
-               goto fi0;
-       }
+       int cnt = -1;
+       int fd, size;
+       
+       size = file_size(fn);
        if (size < 0) {
-               psbs("Trying to insert a negative number (%d) of characters", size);
+               psbs("File does not exist");
                goto fi0;
        }
        if (p < text || p > end) {
@@ -2458,25 +2419,11 @@ static int file_insert(Byte * fn, Byte * p, int size)
                goto fi0;
        }
 
-       // see if we can open the file
-#ifdef CONFIG_FEATURE_VI_READONLY
-       if (vi_readonly) goto fi1;              // do not try write-mode
-#endif
-       fd = open((char *) fn, O_RDWR);                 // assume read & write
+       // read file to buffer
+       fd = open(fn, O_RDONLY);
        if (fd < 0) {
-               // could not open for writing- maybe file is read only
-#ifdef CONFIG_FEATURE_VI_READONLY
-  fi1:
-#endif
-               fd = open((char *) fn, O_RDONLY);       // try read-only
-               if (fd < 0) {
-                       psbs("\"%s\" %s", fn, "could not open file");
-                       goto fi0;
-               }
-#ifdef CONFIG_FEATURE_VI_READONLY
-               // got the file- read-only
-               readonly = TRUE;
-#endif                                                 /* CONFIG_FEATURE_VI_READONLY */
+               psbs("\"%s\" %s", fn, "cannot open file");
+               goto fi0;
        }
        p = text_hole_make(p, size);
        cnt = read(fd, p, size);
@@ -2484,41 +2431,54 @@ static int file_insert(Byte * fn, Byte * p, int size)
        if (cnt < 0) {
                cnt = -1;
                p = text_hole_delete(p, p + size - 1);  // un-do buffer insert
-               psbs("could not read file \"%s\"", fn);
+               psbs("cannot read file \"%s\"", fn);
        } else if (cnt < size) {
                // There was a partial read, shrink unused space text[]
                p = text_hole_delete(p + cnt, p + (size - cnt) - 1);    // un-do buffer insert
-               psbs("could not read all of file \"%s\"", fn);
+               psbs("cannot read all of file \"%s\"", fn);
        }
        if (cnt >= size)
                file_modified++;
-  fi0:
-       return (cnt);
+ fi0:
+       return cnt;
+}
+
+#if ENABLE_FEATURE_VI_READONLY
+static void update_ro_status(const char *fn)
+{
+       struct stat sb;
+       if (stat(fn, &sb) == 0) {
+               readonly = vi_readonly || (access(fn, W_OK) < 0) ||
+                       /* root will always have access()
+                        * so we check fileperms too */
+                       !(sb.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH));
+       }
 }
+#endif
 
-static int file_write(Byte * fn, Byte * first, Byte * last)
+static int file_write(char * fn, char * first, char * last)
 {
        int fd, cnt, charcnt;
 
        if (fn == 0) {
                psbs("No current filename");
-               return (-2);
+               return -2;
        }
        charcnt = 0;
        // FIXIT- use the correct umask()
-       fd = open((char *) fn, (O_WRONLY | O_CREAT | O_TRUNC), 0664);
+       fd = open(fn, (O_WRONLY | O_CREAT | O_TRUNC), 0664);
        if (fd < 0)
-               return (-1);
+               return -1;
        cnt = last - first + 1;
        charcnt = write(fd, first, cnt);
        if (charcnt == cnt) {
                // good write
-               //file_modified= FALSE; // the file has not been modified
+               //file_modified = FALSE; // the file has not been modified
        } else {
                charcnt = 0;
        }
        close(fd);
-       return (charcnt);
+       return charcnt;
 }
 
 //----- Terminal Drawing ---------------------------------------
@@ -2536,16 +2496,16 @@ static int file_write(Byte * fn, Byte * first, Byte * last)
 //----- Move the cursor to row x col (count from 0, not 1) -------
 static void place_cursor(int row, int col, int opti)
 {
-       char cm1[BUFSIZ];
+       char cm1[MAX_LINELEN];
        char *cm;
-#ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
-       char cm2[BUFSIZ];
-       Byte *screenp;
-       // char cm3[BUFSIZ];
-       int Rrow= last_row;
-#endif                                                 /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
+#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
+       char cm2[MAX_LINELEN];
+       char *screenp;
+       // char cm3[MAX_LINELEN];
+       int Rrow = last_row;
+#endif
 
-       memset(cm1, '\0', BUFSIZ - 1);  // clear the buffer
+       memset(cm1, '\0', MAX_LINELEN);  // clear the buffer
 
        if (row < 0) row = 0;
        if (row >= rows) row = rows - 1;
@@ -2553,14 +2513,15 @@ static void place_cursor(int row, int col, int opti)
        if (col >= columns) col = columns - 1;
 
        //----- 1.  Try the standard terminal ESC sequence
-       sprintf((char *) cm1, CMrc, row + 1, col + 1);
-       cm= cm1;
-       if (! opti) goto pc0;
+       sprintf(cm1, CMrc, row + 1, col + 1);
+       cm = cm1;
+       if (!opti)
+               goto pc0;
 
-#ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
+#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
        //----- find the minimum # of chars to move cursor -------------
        //----- 2.  Try moving with discreet chars (Newline, [back]space, ...)
-       memset(cm2, '\0', BUFSIZ - 1);  // clear the buffer
+       memset(cm2, '\0', MAX_LINELEN);  // clear the buffer
 
        // move to the correct row
        while (row < Rrow) {
@@ -2578,20 +2539,20 @@ static void place_cursor(int row, int col, int opti)
        strcat(cm2, "\r");                      // start at col 0
        // just send out orignal source char to get to correct place
        screenp = &screen[row * columns];       // start of screen line
-       strncat(cm2, (char* )screenp, col);
+       strncat(cm2, screenp, col);
 
        //----- 3.  Try some other way of moving cursor
        //---------------------------------------------
 
        // pick the shortest cursor motion to send out
-       cm= cm1;
+       cm = cm1;
        if (strlen(cm2) < strlen(cm)) {
-               cm= cm2;
+               cm = cm2;
        }  /* else if (strlen(cm3) < strlen(cm)) {
                cm= cm3;
        } */
-#endif                                                 /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
 pc0:
+#endif /* FEATURE_VI_OPTIMIZE_CURSOR */
+ pc0:
        write1(cm);                 // move the cursor
 }
 
@@ -2624,17 +2585,17 @@ static void flash(int h)
 {
        standout_start();       // send "start reverse video" sequence
        redraw(TRUE);
-       (void) mysleep(h);
+       mysleep(h);
        standout_end();         // send "end reverse video" sequence
        redraw(TRUE);
 }
 
 static void Indicate_Error(void)
 {
-#ifdef CONFIG_FEATURE_VI_CRASHME
+#if ENABLE_FEATURE_VI_CRASHME
        if (crashme > 0)
                return;                 // generate a random command
-#endif                                                 /* CONFIG_FEATURE_VI_CRASHME */
+#endif
        if (!err_method) {
                write1(bell);   // send out a bell character
        } else {
@@ -2649,12 +2610,13 @@ static void screen_erase(void)
        memset(screen, ' ', screensize);        // clear new screen
 }
 
-static int bufsum(unsigned char *buf, int count)
+static int bufsum(char *buf, int count)
 {
        int sum = 0;
-       unsigned char *e = buf + count;
+       char *e = buf + count;
+
        while (buf < e)
-               sum += *buf++;
+               sum += (unsigned char) *buf++;
        return sum;
 }
 
@@ -2672,10 +2634,10 @@ static void show_status_line(void)
        if (have_status_msg || ((cnt > 0 && last_status_cksum != cksum))) {
                last_status_cksum= cksum;               // remember if we have seen this line
                place_cursor(rows - 1, 0, FALSE);       // put cursor on status line
-               write1((char*)status_buffer);
+               write1(status_buffer);
                clear_to_eol();
                if (have_status_msg) {
-                       if (((int)strlen((char*)status_buffer) - (have_status_msg - 1)) >
+                       if (((int)strlen(status_buffer) - (have_status_msg - 1)) >
                                        (columns - 1) ) {
                                have_status_msg = 0;
                                Hit_Return();
@@ -2694,14 +2656,12 @@ static void psbs(const char *format, ...)
        va_list args;
 
        va_start(args, format);
-       strcpy((char *) status_buffer, SOs);    // Terminal standout mode on
-       vsprintf((char *) status_buffer + strlen((char *) status_buffer), format, args);
-       strcat((char *) status_buffer, SOn);    // Terminal standout mode off
+       strcpy(status_buffer, SOs);     // Terminal standout mode on
+       vsprintf(status_buffer + strlen(status_buffer), format, args);
+       strcat(status_buffer, SOn);     // Terminal standout mode off
        va_end(args);
 
        have_status_msg = 1 + sizeof(SOs) + sizeof(SOn) - 2;
-
-       return;
 }
 
 // format status buffer
@@ -2710,17 +2670,15 @@ static void psb(const char *format, ...)
        va_list args;
 
        va_start(args, format);
-       vsprintf((char *) status_buffer, format, args);
+       vsprintf(status_buffer, format, args);
        va_end(args);
 
        have_status_msg = 1;
-
-       return;
 }
 
-static void ni(Byte * s) // display messages
+static void ni(const char * s) // display messages
 {
-       Byte buf[BUFSIZ];
+       char buf[MAX_LINELEN];
 
        print_literal(buf, s);
        psbs("\'%s\' is not implemented", buf);
@@ -2728,9 +2686,10 @@ static void ni(Byte * s) // display messages
 
 static int format_edit_status(void)    // show file status on status line
 {
-       int cur, percent, ret, trunc_at;
        static int tot;
 
+       int cur, percent, ret, trunc_at;
+
        // file_modified is now a counter rather than a flag.  this
        // helps reduce the amount of line counting we need to do.
        // (this will cause a mis-reporting of modified status
@@ -2761,15 +2720,15 @@ static int format_edit_status(void)     // show file status on status line
        trunc_at = columns < STATUS_BUFFER_LEN-1 ?
                columns : STATUS_BUFFER_LEN-1;
 
-       ret = snprintf((char *) status_buffer, trunc_at+1,
-#ifdef CONFIG_FEATURE_VI_READONLY
+       ret = snprintf(status_buffer, trunc_at+1,
+#if ENABLE_FEATURE_VI_READONLY
                "%c %s%s%s %d/%d %d%%",
 #else
                "%c %s%s %d/%d %d%%",
 #endif
                (cmd_mode ? (cmd_mode == 2 ? 'R':'I'):'-'),
-               (cfn != 0 ? (char *) cfn : "No file"),
-#ifdef CONFIG_FEATURE_VI_READONLY
+               (cfn != 0 ? cfn : "No file"),
+#if ENABLE_FEATURE_VI_READONLY
                ((vi_readonly || readonly) ? " [Read-only]" : ""),
 #endif
                (file_modified ? " [modified]" : ""),
@@ -2793,13 +2752,13 @@ static void redraw(int full_screen)
 }
 
 //----- Format a text[] line into a buffer ---------------------
-static void format_line(Byte *dest, Byte *src, int li)
+static void format_line(char *dest, char *src, int li)
 {
        int co;
-       Byte c;
+       char c;
 
-       for (co= 0; co < MAX_SCR_COLS; co++) {
-               c= ' ';         // assume blank
+       for (co = 0; co < MAX_SCR_COLS; co++) {
+               c = ' ';                // assume blank
                if (li > 0 && co == 0) {
                        c = '~';        // not first line, assume Tilde
                }
@@ -2809,10 +2768,10 @@ static void format_line(Byte *dest, Byte *src, int li)
                }
                if (c == '\n')
                        break;
-               if (c > 127 && !Isprint(c)) {
+               if ((c & 0x80) && !Isprint(c)) {
                        c = '.';
                }
-               if (c < ' ' || c == 127) {
+               if ((unsigned char)(c) < ' ' || c == 0x7f) {
                        if (c == '\t') {
                                c = ' ';
                                //       co %    8     !=     7
@@ -2821,9 +2780,9 @@ static void format_line(Byte *dest, Byte *src, int li)
                                }
                        } else {
                                dest[co++] = '^';
-                               if(c == 127)
+                               if (c == 0x7f)
                                        c = '?';
-                                else
+                               else
                                        c += '@';       // make it visible
                        }
                }
@@ -2843,16 +2802,16 @@ static void format_line(Byte *dest, Byte *src, int li)
 static void refresh(int full_screen)
 {
        static int old_offset;
+
        int li, changed;
-       Byte buf[MAX_SCR_COLS];
-       Byte *tp, *sp;          // pointer into text[] and screen[]
-#ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
-       int last_li= -2;                                // last line that changed- for optimizing cursor movement
-#endif                                                 /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
-
-#ifdef CONFIG_FEATURE_VI_WIN_RESIZE
-       window_size_get(0);
-#endif                                                 /* CONFIG_FEATURE_VI_WIN_RESIZE */
+       char buf[MAX_SCR_COLS];
+       char *tp, *sp;          // pointer into text[] and screen[]
+#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
+       int last_li = -2; // last line that changed- for optimizing cursor movement
+#endif
+
+       if (ENABLE_FEATURE_VI_WIN_RESIZE)
+               get_terminal_width_height(0, &columns, &rows);
        sync_cursor(dot, &crow, &ccol); // where cursor will be (on "dot")
        tp = screenbegin;       // index into text[] of top line
 
@@ -2878,7 +2837,7 @@ static void refresh(int full_screen)
                }
                // compare newly formatted buffer with virtual screen
                // look forward for first difference between buf and screen
-               for ( ; cs <= ce; cs++) {
+               for (; cs <= ce; cs++) {
                        if (buf[cs + offset] != sp[cs]) {
                                changed = TRUE; // mark for redraw
                                break;
@@ -2896,7 +2855,7 @@ static void refresh(int full_screen)
 
                // if horz offset has changed, force a redraw
                if (offset != old_offset) {
 re0:
+ re0:
                        changed = TRUE;
                }
 
@@ -2915,39 +2874,39 @@ static void refresh(int full_screen)
                                // to handle offsets correctly
                                place_cursor(li, cs, FALSE);
                        } else {
-#ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
+#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
                                // if this just the next line
                                //  try to optimize cursor movement
                                //  otherwise, use standard ESC sequence
                                place_cursor(li, cs, li == (last_li+1) ? TRUE : FALSE);
                                last_li= li;
-#else                                                  /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
+#else
                                place_cursor(li, cs, FALSE);    // use standard ESC sequence
-#endif                                                 /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
+#endif /* FEATURE_VI_OPTIMIZE_CURSOR */
                        }
 
                        // write line out to terminal
                        {
-                               int nic = ce-cs+1;
-                               char *out = (char*)sp+cs;
+                               int nic = ce - cs + 1;
+                               char *out = sp + cs;
 
-                               while(nic-- > 0) {
+                               while (nic-- > 0) {
                                        putchar(*out);
                                        out++;
                                }
                        }
-#ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
+#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
                        last_row = li;
-#endif                                                 /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
+#endif
                }
        }
 
-#ifdef CONFIG_FEATURE_VI_OPTIMIZE_CURSOR
+#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
        place_cursor(crow, ccol, (crow == last_row) ? TRUE : FALSE);
        last_row = crow;
 #else
        place_cursor(crow, ccol, FALSE);
-#endif                                                 /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */
+#endif
 
        if (offset != old_offset)
                old_offset = offset;
@@ -2975,14 +2934,15 @@ static void refresh(int full_screen)
 //---------------------------------------------------------------------
 
 //----- Execute a Vi Command -----------------------------------
-static void do_cmd(Byte c)
+static void do_cmd(char c)
 {
-       Byte c1, *p, *q, *msg, buf[9], *save_dot;
+       const char *msg;
+       char c1, *p, *q, buf[9], *save_dot;
        int cnt, i, j, dir, yf;
 
        c1 = c;                         // quiet the compiler
        cnt = yf = dir = 0;     // quiet the compiler
-       p = q = save_dot = msg = buf;   // quiet the compiler
+       msg = p = q = save_dot = buf;   // quiet the compiler
        memset(buf, '\0', 9);   // clear buf
 
        show_status_line();
@@ -3002,7 +2962,8 @@ static void do_cmd(Byte c)
 
        if (cmd_mode == 2) {
                //  flip-flop Insert/Replace mode
-               if (c == VI_K_INSERT) goto dc_i;
+               if (c == VI_K_INSERT)
+                       goto dc_i;
                // we are 'R'eplacing the current *dot with new char
                if (*dot == '\n') {
                        // don't Replace past E-o-l
@@ -3026,7 +2987,7 @@ static void do_cmd(Byte c)
                goto dc1;
        }
 
-key_cmd_mode:
+ key_cmd_mode:
        switch (c) {
                //case 0x01:    // soh
                //case 0x09:    // ht
@@ -3036,11 +2997,11 @@ key_cmd_mode:
                //case 0x10:    // dle
                //case 0x11:    // dc1
                //case 0x13:    // dc3
-#ifdef CONFIG_FEATURE_VI_CRASHME
+#if ENABLE_FEATURE_VI_CRASHME
        case 0x14:                      // dc4  ctrl-T
                crashme = (crashme == 0) ? 1 : 0;
                break;
-#endif                                                 /* CONFIG_FEATURE_VI_CRASHME */
+#endif
                //case 0x16:    // syn
                //case 0x17:    // etb
                //case 0x18:    // can
@@ -3079,7 +3040,7 @@ key_cmd_mode:
                        buf[1] = c + '@';
                        buf[2] = '\0';
                }
-               ni((Byte *) buf);
+               ni(buf);
                end_cmd_q();    // stop adding to q
        case 0x00:                      // nul- ignore
                break;
@@ -3087,14 +3048,14 @@ key_cmd_mode:
        case VI_K_PAGEUP:       // Cursor Key Page Up
                dot_scroll(rows - 2, -1);
                break;
-#ifdef CONFIG_FEATURE_VI_USE_SIGNALS
+#if ENABLE_FEATURE_VI_USE_SIGNALS
        case 0x03:                      // ctrl-C   interrupt
                longjmp(restart, 1);
                break;
        case 26:                        // ctrl-Z suspend
                suspend_sig(SIGTSTP);
                break;
-#endif                                                 /* CONFIG_FEATURE_VI_USE_SIGNALS */
+#endif
        case 4:                 // ctrl-D  scroll down half screen
                dot_scroll((rows - 2) / 2, 1);
                break;
@@ -3111,7 +3072,7 @@ key_cmd_mode:
        case 'h':                       // h- move left
        case VI_K_LEFT: // cursor key Left
        case 8:         // ctrl-H- move left    (This may be ERASE char)
-       case 127:       // DEL- move left   (This may be ERASE char)
+       case 0x7f:      // DEL- move left   (This may be ERASE char)
                if (cmdcnt-- > 1) {
                        do_cmd(c);
                }                               // repeat cnt
@@ -3130,7 +3091,7 @@ key_cmd_mode:
        case 18:                        // ctrl-R  force redraw
                place_cursor(0, 0, FALSE);      // put cursor in correct place
                clear_to_eos(); // tel terminal to erase display
-               (void) mysleep(10);
+               mysleep(10);
                screen_erase(); // erase the internal screen buffer
                last_status_cksum = 0;  // force status update
                refresh(TRUE);  // this will redraw the entire display
@@ -3164,7 +3125,7 @@ key_cmd_mode:
                }                               // repeat cnt
                dot_right();
                break;
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
        case '"':                       // "- name a register to use for Delete/Yank
                c1 = get_one_char();
                c1 = tolower(c1);
@@ -3180,7 +3141,7 @@ key_cmd_mode:
                if (islower(c1)) {
                        c1 = c1 - 'a';
                        // get the b-o-l
-                       q = mark[(int) c1];
+                       q = mark[(unsigned char) c1];
                        if (text <= q && q < end) {
                                dot = q;
                                dot_begin();    // go to B-o-l
@@ -3217,7 +3178,7 @@ key_cmd_mode:
                        break;
                }
                // are we putting whole lines or strings
-               if (strchr((char *) p, '\n') != NULL) {
+               if (strchr(p, '\n') != NULL) {
                        if (c == 'P') {
                                dot_begin();    // putting lines- Put above
                        }
@@ -3246,7 +3207,7 @@ key_cmd_mode:
                        dot_skip_over_ws();
                }
                break;
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+#endif /* FEATURE_VI_YANKMARK */
        case '$':                       // $- goto end of line
        case VI_K_END:          // Cursor Key End
                if (cmdcnt-- > 1) {
@@ -3280,7 +3241,8 @@ key_cmd_mode:
                if (cmdcnt-- > 1) {
                        do_cmd(';');
                }                               // repeat cnt
-               if (last_forward_char == 0) break;
+               if (last_forward_char == 0)
+                       break;
                q = dot + 1;
                while (q < end - 1 && *q != '\n' && *q != last_forward_char) {
                        q++;
@@ -3295,27 +3257,27 @@ key_cmd_mode:
                dot_prev();
                dot_skip_over_ws();
                break;
-#ifdef CONFIG_FEATURE_VI_DOT_CMD
+#if ENABLE_FEATURE_VI_DOT_CMD
        case '.':                       // .- repeat the last modifying command
                // Stuff the last_modifying_cmd back into stdin
                // and let it be re-executed.
                if (last_modifying_cmd != 0) {
-                       ioq = ioq_start = (Byte *) bb_xstrdup((char *) last_modifying_cmd);
+                       ioq = ioq_start = xstrdup(last_modifying_cmd);
                }
                break;
-#endif                                                 /* CONFIG_FEATURE_VI_DOT_CMD */
-#ifdef CONFIG_FEATURE_VI_SEARCH
+#endif
+#if ENABLE_FEATURE_VI_SEARCH
        case '?':                       // /- search for a pattern
        case '/':                       // /- search for a pattern
                buf[0] = c;
                buf[1] = '\0';
                q = get_input_line(buf);        // get input line- use "status line"
-               if (strlen((char *) q) == 1)
-                       goto dc3;       // if no pat re-use old pat
-               if (strlen((char *) q) > 1) {   // new pat- save it and find
+               if (q[0] && !q[1])
+                       goto dc3; // if no pat re-use old pat
+               if (q[0]) {       // strlen(q) > 1: new pat- save it and find
                        // there is a new pat
                        free(last_search_pattern);
-                       last_search_pattern = (Byte *) bb_xstrdup((char *) q);
+                       last_search_pattern = xstrdup(q);
                        goto dc3;       // now find the pattern
                }
                // user changed mind and erased the "/"-  do nothing
@@ -3338,9 +3300,9 @@ key_cmd_mode:
                if (cmdcnt-- > 1) {
                        do_cmd(c);
                }                               // repeat cnt
        dc3:
+ dc3:
                if (last_search_pattern == 0) {
-                       msg = (Byte *) "No previous regular expression";
+                       msg = "No previous regular expression";
                        goto dc2;
                }
                if (last_search_pattern[0] == '/') {
@@ -3351,11 +3313,11 @@ key_cmd_mode:
                        dir = BACK;
                        p = dot - 1;
                }
        dc4:
+ dc4:
                q = char_search(p, last_search_pattern + 1, dir, FULL);
                if (q != NULL) {
                        dot = q;        // good search, update "dot"
-                       msg = (Byte *) "";
+                       msg = "";
                        goto dc2;
                }
                // no pattern found between "dot" and "end"- continue at top
@@ -3366,29 +3328,30 @@ key_cmd_mode:
                q = char_search(p, last_search_pattern + 1, dir, FULL);
                if (q != NULL) {        // found something
                        dot = q;        // found new pattern- goto it
-                       msg = (Byte *) "search hit BOTTOM, continuing at TOP";
+                       msg = "search hit BOTTOM, continuing at TOP";
                        if (dir == BACK) {
-                               msg = (Byte *) "search hit TOP, continuing at BOTTOM";
+                               msg = "search hit TOP, continuing at BOTTOM";
                        }
                } else {
-                       msg = (Byte *) "Pattern not found";
+                       msg = "Pattern not found";
                }
-         dc2:
-               if (*msg) psbs("%s", msg);
+ dc2:
+               if (*msg)
+                       psbs("%s", msg);
                break;
        case '{':                       // {- move backward paragraph
-               q = char_search(dot, (Byte *) "\n\n", BACK, FULL);
+               q = char_search(dot, "\n\n", BACK, FULL);
                if (q != NULL) {        // found blank line
                        dot = next_line(q);     // move to next blank line
                }
                break;
        case '}':                       // }- move forward paragraph
-               q = char_search(dot, (Byte *) "\n\n", FORWARD, FULL);
+               q = char_search(dot, "\n\n", FORWARD, FULL);
                if (q != NULL) {        // found blank line
                        dot = next_line(q);     // move to next blank line
                }
                break;
-#endif                                                 /* CONFIG_FEATURE_VI_SEARCH */
+#endif /* FEATURE_VI_SEARCH */
        case '0':                       // 0- goto begining of line
        case '1':                       // 1-
        case '2':                       // 2-
@@ -3406,26 +3369,28 @@ key_cmd_mode:
                }
                break;
        case ':':                       // :- the colon mode commands
-               p = get_input_line((Byte *) ":");       // get input line- use "status line"
-#ifdef CONFIG_FEATURE_VI_COLON
+               p = get_input_line(":");        // get input line- use "status line"
+#if ENABLE_FEATURE_VI_COLON
                colon(p);               // execute the command
-#else                                                  /* CONFIG_FEATURE_VI_COLON */
+#else
                if (*p == ':')
                        p++;                            // move past the ':'
-               cnt = strlen((char *) p);
+               cnt = strlen(p);
                if (cnt <= 0)
                        break;
-               if (strncasecmp((char *) p, "quit", cnt) == 0 ||
-                       strncasecmp((char *) p, "q!", cnt) == 0) {      // delete lines
+               if (strncasecmp(p, "quit", cnt) == 0
+                || strncasecmp(p, "q!", cnt) == 0   // delete lines
+               ) {
                        if (file_modified && p[1] != '!') {
                                psbs("No write since last change (:quit! overrides)");
                        } else {
                                editing = 0;
                        }
-               } else if (strncasecmp((char *) p, "write", cnt) == 0
-                               || strncasecmp((char *) p, "wq", cnt) == 0
-                               || strncasecmp((char *) p, "wn", cnt) == 0
-                               || strncasecmp((char *) p, "x", cnt) == 0) {
+               } else if (strncasecmp(p, "write", cnt) == 0
+                       || strncasecmp(p, "wq", cnt) == 0
+                       || strncasecmp(p, "wn", cnt) == 0
+                       || strncasecmp(p, "x", cnt) == 0
+               ) {
                        cnt = file_write(cfn, text, end - 1);
                        if (cnt < 0) {
                                if (cnt == -1)
@@ -3434,27 +3399,28 @@ key_cmd_mode:
                                file_modified = 0;
                                last_file_modified = -1;
                                psb("\"%s\" %dL, %dC", cfn, count_lines(text, end - 1), cnt);
-                               if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n' ||
-                                   p[0] == 'X' || p[1] == 'Q' || p[1] == 'N') {
+                               if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
+                                || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
+                               ) {
                                        editing = 0;
                                }
                        }
-               } else if (strncasecmp((char *) p, "file", cnt) == 0 ) {
+               } else if (strncasecmp(p, "file", cnt) == 0) {
                        last_status_cksum = 0;  // force status update
-               } else if (sscanf((char *) p, "%d", &j) > 0) {
+               } else if (sscanf(p, "%d", &j) > 0) {
                        dot = find_line(j);             // go to line # j
                        dot_skip_over_ws();
                } else {                // unrecognised cmd
-                       ni((Byte *) p);
+                       ni(p);
                }
-#endif                                                 /* CONFIG_FEATURE_VI_COLON */
+#endif /* !FEATURE_VI_COLON */
                break;
        case '<':                       // <- Left  shift something
        case '>':                       // >- Right shift something
                cnt = count_lines(text, dot);   // remember what line we are on
                c1 = get_one_char();    // get the type of thing to delete
                find_range(&p, &q, c1);
-               (void) yank_delete(p, q, 1, YANKONLY);  // save copy before change
+               yank_delete(p, q, 1, YANKONLY); // save copy before change
                p = begin_line(p);
                q = end_line(q);
                i = count_lines(p, q);  // # of lines we are shifting
@@ -3463,16 +3429,16 @@ key_cmd_mode:
                                // shift left- remove tab or 8 spaces
                                if (*p == '\t') {
                                        // shrink buffer 1 char
-                                       (void) text_hole_delete(p, p);
+                                       text_hole_delete(p, p);
                                } else if (*p == ' ') {
                                        // we should be calculating columns, not just SPACE
                                        for (j = 0; *p == ' ' && j < tabstop; j++) {
-                                               (void) text_hole_delete(p, p);
+                                               text_hole_delete(p, p);
                                        }
                                }
                        } else if (c == '>') {
                                // shift right -- add tab or 8 spaces
-                               (void) char_insert(p, '\t');
+                               char_insert(p, '\t');
                        }
                }
                dot = find_line(cnt);   // what line were we on
@@ -3511,10 +3477,10 @@ key_cmd_mode:
                dot = yank_delete(save_dot, dot, 0, YANKDEL);   // delete to e-o-l
                if (c == 'C')
                        goto dc_i;      // start inserting
-#ifdef CONFIG_FEATURE_VI_DOT_CMD
+#if ENABLE_FEATURE_VI_DOT_CMD
                if (c == 'D')
                        end_cmd_q();    // stop adding to q
-#endif                                                 /* CONFIG_FEATURE_VI_DOT_CMD */
+#endif
                break;
        case 'G':               // G- goto to a line number (default= E-O-F)
                dot = end - 1;                          // assume E-O-F
@@ -3539,7 +3505,7 @@ key_cmd_mode:
                //**** fall thru to ... 'i'
        case 'i':                       // i- insert before current char
        case VI_K_INSERT:       // Cursor Key Insert
        dc_i:
+ dc_i:
                cmd_mode = 1;   // start insrting
                break;
        case 'J':                       // J- join current and next lines together
@@ -3588,7 +3554,7 @@ key_cmd_mode:
                goto dc_i;
                break;
        case 'R':                       // R- continuous Replace char
        dc5:
+ dc5:
                cmd_mode = 2;
                break;
        case 'X':                       // X- delete char before dot
@@ -3617,12 +3583,12 @@ key_cmd_mode:
                        break;
                }
                if (file_modified) {
-#ifdef CONFIG_FEATURE_VI_READONLY
+#if ENABLE_FEATURE_VI_READONLY
                        if (vi_readonly || readonly) {
-                           psbs("\"%s\" File is read only", cfn);
-                           break;
+                               psbs("\"%s\" File is read only", cfn);
+                               break;
                        }
-#endif         /* CONFIG_FEATURE_VI_READONLY */
+#endif
                        cnt = file_write(cfn, text, end - 1);
                        if (cnt < 0) {
                                if (cnt == -1)
@@ -3660,15 +3626,15 @@ key_cmd_mode:
                break;
        case 'c':                       // c- change something
        case 'd':                       // d- delete something
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
        case 'y':                       // y- yank   something
        case 'Y':                       // Y- Yank a line
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+#endif
                yf = YANKDEL;   // assume either "c" or "d"
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
                if (c == 'y' || c == 'Y')
                        yf = YANKONLY;
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+#endif
                c1 = 'y';
                if (c != 'Y')
                        c1 = get_one_char();    // get the type of thing to delete
@@ -3709,25 +3675,25 @@ key_cmd_mode:
                if (c1 != 27) {
                        // if CHANGING, not deleting, start inserting after the delete
                        if (c == 'c') {
-                               strcpy((char *) buf, "Change");
+                               strcpy(buf, "Change");
                                goto dc_i;      // start inserting
                        }
                        if (c == 'd') {
-                               strcpy((char *) buf, "Delete");
+                               strcpy(buf, "Delete");
                        }
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
                        if (c == 'y' || c == 'Y') {
-                               strcpy((char *) buf, "Yank");
+                               strcpy(buf, "Yank");
                        }
                        p = reg[YDreg];
-                       q = p + strlen((char *) p);
+                       q = p + strlen(p);
                        for (cnt = 0; p <= q; p++) {
                                if (*p == '\n')
                                        cnt++;
                        }
                        psb("%s %d lines (%d chars) using [%c]",
-                               buf, cnt, strlen((char *) reg[YDreg]), what_reg());
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+                               buf, cnt, strlen(reg[YDreg]), what_reg());
+#endif
                        end_cmd_q();    // stop adding to q
                }
                break;
@@ -3816,19 +3782,19 @@ key_cmd_mode:
                break;
        }
 
 dc1:
+ dc1:
        // if text[] just became empty, add back an empty line
        if (end == text) {
-               (void) char_insert(text, '\n'); // start empty buf with dummy line
+               char_insert(text, '\n');        // start empty buf with dummy line
                dot = text;
        }
        // it is OK for dot to exactly equal to end, otherwise check dot validity
        if (dot != end) {
                dot = bound_dot(dot);   // make sure "dot" is valid
        }
-#ifdef CONFIG_FEATURE_VI_YANKMARK
+#if ENABLE_FEATURE_VI_YANKMARK
        check_context(c);       // update the current context
-#endif                                                 /* CONFIG_FEATURE_VI_YANKMARK */
+#endif
 
        if (!isdigit(c))
                cmdcnt = 0;             // cmd was not a number, reset cmdcnt
@@ -3838,7 +3804,7 @@ key_cmd_mode:
                dot--;
 }
 
-#ifdef CONFIG_FEATURE_VI_CRASHME
+#if ENABLE_FEATURE_VI_CRASHME
 static int totalcmds = 0;
 static int Mp = 85;             // Movement command Probability
 static int Np = 90;             // Non-movement command Probability
@@ -3847,14 +3813,15 @@ static int Ip = 97;             // Insert command Probability
 static int Yp = 98;             // Yank command Probability
 static int Pp = 99;             // Put command Probability
 static int M = 0, N = 0, I = 0, D = 0, Y = 0, P = 0, U = 0;
-char chars[20] = "\t012345 abcdABCD-=.$";
-char *words[20] = { "this", "is", "a", "test",
+const char chars[20] = "\t012345 abcdABCD-=.$";
+const char *const words[20] = {
+       "this", "is", "a", "test",
        "broadcast", "the", "emergency", "of",
        "system", "quick", "brown", "fox",
        "jumped", "over", "lazy", "dogs",
        "back", "January", "Febuary", "March"
 };
-char *lines[20] = {
+const char *const lines[20] = {
        "You should have received a copy of the GNU General Public License\n",
        "char c, cm, *cmd, *cmd1;\n",
        "generate a command by percentages\n",
@@ -3912,10 +3879,10 @@ static void crash_dummy()
        // is there already a command running?
        if (readed_for_parse > 0)
                goto cd1;
 cd0:
+ cd0:
        startrbi = rbi = 0;
        sleeptime = 0;          // how long to pause between commands
-       memset(readbuffer, '\0', BUFSIZ);   // clear the read buffer
+       memset(readbuffer, '\0', MAX_LINELEN);   // clear the read buffer
        // generate a command by percentages
        percent = (int) lrand48() % 100;        // get a number from 0-99
        if (percent < Mp) {     //  Movement commands
@@ -3974,54 +3941,55 @@ static void crash_dummy()
                        if (thing == 0) {       // insert chars
                                readbuffer[rbi++] = chars[((int) lrand48() % strlen(chars))];
                        } else if (thing == 1) {        // insert words
-                               strcat((char *) readbuffer, words[(int) lrand48() % 20]);
-                               strcat((char *) readbuffer, " ");
+                               strcat(readbuffer, words[(int) lrand48() % 20]);
+                               strcat(readbuffer, " ");
                                sleeptime = 0;  // how fast to type
                        } else if (thing == 2) {        // insert lines
-                               strcat((char *) readbuffer, lines[(int) lrand48() % 20]);
+                               strcat(readbuffer, lines[(int) lrand48() % 20]);
                                sleeptime = 0;  // how fast to type
                        } else {        // insert multi-lines
-                               strcat((char *) readbuffer, multilines[(int) lrand48() % 20]);
+                               strcat(readbuffer, multilines[(int) lrand48() % 20]);
                                sleeptime = 0;  // how fast to type
                        }
                }
-               strcat((char *) readbuffer, "\033");
+               strcat(readbuffer, "\033");
        }
        readed_for_parse = strlen(readbuffer);
 cd1:
+ cd1:
        totalcmds++;
        if (sleeptime > 0)
-               (void) mysleep(sleeptime);      // sleep 1/100 sec
+               mysleep(sleeptime);      // sleep 1/100 sec
 }
 
 // test to see if there are any errors
 static void crash_test()
 {
        static time_t oldtim;
+
        time_t tim;
-       char d[2], msg[BUFSIZ];
+       char d[2], msg[MAX_LINELEN];
 
        msg[0] = '\0';
        if (end < text) {
-               strcat((char *) msg, "end<text ");
+               strcat(msg, "end<text ");
        }
        if (end > textend) {
-               strcat((char *) msg, "end>textend ");
+               strcat(msg, "end>textend ");
        }
        if (dot < text) {
-               strcat((char *) msg, "dot<text ");
+               strcat(msg, "dot<text ");
        }
        if (dot > end) {
-               strcat((char *) msg, "dot>end ");
+               strcat(msg, "dot>end ");
        }
        if (screenbegin < text) {
-               strcat((char *) msg, "screenbegin<text ");
+               strcat(msg, "screenbegin<text ");
        }
        if (screenbegin > end - 1) {
-               strcat((char *) msg, "screenbegin>end-1 ");
+               strcat(msg, "screenbegin>end-1 ");
        }
 
-       if (strlen(msg) > 0) {
+       if (msg[0]) {
                alarm(0);
                printf("\n\n%d: \'%c\' %s\n\n\n%s[Hit return to continue]%s",
                        totalcmds, last_input_char, msg, SOs, SOn);
@@ -4034,11 +4002,10 @@ static void crash_test()
        }
        tim = (time_t) time((time_t *) 0);
        if (tim >= (oldtim + 3)) {
-               sprintf((char *) status_buffer,
+               sprintf(status_buffer,
                                "Tot=%d: M=%d N=%d I=%d D=%d Y=%d P=%d U=%d size=%d",
                                totalcmds, M, N, I, D, Y, P, U, end - text + 1);
                oldtim = tim;
        }
-       return;
 }
-#endif                                           /* CONFIG_FEATURE_VI_CRASHME */
+#endif